1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 #include <vtkUnstructuredGridWriter.h>
84 // to pass CORBA exception through SMESH_TRY
85 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
87 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
90 static int MYDEBUG = 0;
92 static int MYDEBUG = 0;
96 using SMESH::TPythonDump;
98 int SMESH_Mesh_i::_idGenerator = 0;
100 //=============================================================================
104 //=============================================================================
106 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
108 CORBA::Long studyId )
109 : SALOME::GenericObj_i( thePOA )
111 MESSAGE("SMESH_Mesh_i");
114 _id = _idGenerator++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
130 MESSAGE("~SMESH_Mesh_i");
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 aGroup->UnRegister();
138 SMESH::SMESH_GroupBase_var( itGr->second );
143 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
144 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
145 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
147 aSubMesh->UnRegister();
148 SMESH::SMESH_subMesh_var( itSM->second );
150 _mapSubMeshIor.clear();
152 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
156 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
157 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
160 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
164 // clear cashed shapes if no more meshes remain; (the cash is blame,
165 // together with publishing, of spent time increasing in issue 22874)
166 if ( _impl->NbMeshes() == 1 )
167 _gen_i->GetShapeReader()->ClearClientBuffer();
169 delete _editor; _editor = NULL;
170 delete _previewEditor; _previewEditor = NULL;
171 delete _impl; _impl = NULL;
172 delete _preMeshInfo; _preMeshInfo = NULL;
175 //=============================================================================
179 * Associates <this> mesh with <theShape> and puts a reference
180 * to <theShape> into the current study;
181 * the previous shape is substituted by the new one.
183 //=============================================================================
185 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
186 throw (SALOME::SALOME_Exception)
188 Unexpect aCatch(SALOME_SalomeException);
190 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
192 catch(SALOME_Exception & S_ex) {
193 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
195 // to track changes of GEOM groups
196 SMESH::SMESH_Mesh_var mesh = _this();
197 addGeomGroupData( theShapeObject, mesh );
198 if ( !CORBA::is_nil( theShapeObject ))
199 _mainShapeTick = theShapeObject->GetTick();
202 //================================================================================
204 * \brief return true if mesh has a shape to build a shape on
206 //================================================================================
208 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
209 throw (SALOME::SALOME_Exception)
211 Unexpect aCatch(SALOME_SalomeException);
214 res = _impl->HasShapeToMesh();
216 catch(SALOME_Exception & S_ex) {
217 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
222 //=======================================================================
223 //function : GetShapeToMesh
225 //=======================================================================
227 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
228 throw (SALOME::SALOME_Exception)
230 Unexpect aCatch(SALOME_SalomeException);
231 GEOM::GEOM_Object_var aShapeObj;
233 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
237 catch(SALOME_Exception & S_ex) {
238 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
240 return aShapeObj._retn();
243 //================================================================================
245 * \brief Return false if the mesh is not yet fully loaded from the study file
247 //================================================================================
249 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
251 Unexpect aCatch(SALOME_SalomeException);
252 return !_preMeshInfo;
255 //================================================================================
257 * \brief Load full mesh data from the study file
259 //================================================================================
261 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
263 Unexpect aCatch(SALOME_SalomeException);
265 _preMeshInfo->FullLoadFromFile();
268 //================================================================================
270 * \brief Remove all nodes and elements
272 //================================================================================
274 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
276 Unexpect aCatch(SALOME_SalomeException);
278 _preMeshInfo->ForgetAllData();
282 //CheckGeomGroupModif(); // issue 20145
284 catch(SALOME_Exception & S_ex) {
285 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
287 _impl->GetMeshDS()->Modified();
289 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
292 //================================================================================
294 * \brief Remove all nodes and elements for indicated shape
296 //================================================================================
298 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
299 throw (SALOME::SALOME_Exception)
301 Unexpect aCatch(SALOME_SalomeException);
303 _preMeshInfo->FullLoadFromFile();
306 _impl->ClearSubMesh( ShapeID );
308 catch(SALOME_Exception & S_ex) {
309 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
311 _impl->GetMeshDS()->Modified();
313 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
316 //=============================================================================
318 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
320 //=============================================================================
322 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
324 SMESH::DriverMED_ReadStatus res;
327 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
328 res = SMESH::DRS_OK; break;
329 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
330 res = SMESH::DRS_EMPTY; break;
331 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
332 res = SMESH::DRS_WARN_RENUMBER; break;
333 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
334 res = SMESH::DRS_WARN_SKIP_ELEM; break;
335 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
336 res = SMESH::DRS_WARN_DESCENDING; break;
337 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
339 res = SMESH::DRS_FAIL; break;
344 //=============================================================================
346 * Convert ::SMESH_ComputeError to SMESH::ComputeError
348 //=============================================================================
350 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
352 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
353 errVar->subShapeID = -1;
354 errVar->hasBadMesh = false;
356 if ( !errorPtr || errorPtr->IsOK() )
358 errVar->code = SMESH::COMPERR_OK;
362 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
363 errVar->comment = errorPtr->myComment.c_str();
365 return errVar._retn();
368 //=============================================================================
372 * Imports mesh data from MED file
374 //=============================================================================
376 SMESH::DriverMED_ReadStatus
377 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
378 throw ( SALOME::SALOME_Exception )
380 Unexpect aCatch(SALOME_SalomeException);
383 status = _impl->MEDToMesh( theFileName, theMeshName );
385 catch( SALOME_Exception& S_ex ) {
386 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
389 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
392 CreateGroupServants();
394 int major, minor, release;
395 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
396 major = minor = release = -1;
397 _medFileInfo = new SMESH::MedFileInfo();
398 _medFileInfo->fileName = theFileName;
399 _medFileInfo->fileSize = 0;
400 _medFileInfo->major = major;
401 _medFileInfo->minor = minor;
402 _medFileInfo->release = release;
403 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
405 return ConvertDriverMEDReadStatus(status);
408 //================================================================================
410 * \brief Imports mesh data from the CGNS file
412 //================================================================================
414 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
415 const int theMeshIndex,
416 std::string& theMeshName )
417 throw ( SALOME::SALOME_Exception )
419 Unexpect aCatch(SALOME_SalomeException);
422 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
424 catch( SALOME_Exception& S_ex ) {
425 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
428 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
431 CreateGroupServants();
433 return ConvertDriverMEDReadStatus(status);
436 //================================================================================
438 * \brief Return string representation of a MED file version comprising nbDigits
440 //================================================================================
442 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
444 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
446 return CORBA::string_dup( ver.c_str() );
449 //=============================================================================
453 * Imports mesh data from MED file
455 //=============================================================================
457 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
458 throw ( SALOME::SALOME_Exception )
462 // Read mesh with name = <theMeshName> into SMESH_Mesh
463 _impl->UNVToMesh( theFileName );
465 CreateGroupServants();
467 SMESH_CATCH( SMESH::throwCorbaException );
472 //=============================================================================
476 * Imports mesh data from STL file
478 //=============================================================================
479 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
480 throw ( SALOME::SALOME_Exception )
484 // Read mesh with name = <theMeshName> into SMESH_Mesh
485 _impl->STLToMesh( theFileName );
487 SMESH_CATCH( SMESH::throwCorbaException );
492 //================================================================================
494 * \brief Function used in SMESH_CATCH by ImportGMFFile()
496 //================================================================================
500 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
502 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
506 //================================================================================
508 * \brief Imports data from a GMF file and returns an error description
510 //================================================================================
512 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
513 bool theMakeRequiredGroups )
514 throw (SALOME::SALOME_Exception)
516 SMESH_ComputeErrorPtr error;
519 #define SMESH_CAUGHT error =
522 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
524 SMESH_CATCH( exceptionToComputeError );
528 CreateGroupServants();
530 return ConvertComputeError( error );
533 //=============================================================================
537 //=============================================================================
539 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
541 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
542 (SMESH_Hypothesis::Hypothesis_Status theStatus)
545 RETURNCASE( HYP_OK );
546 RETURNCASE( HYP_MISSING );
547 RETURNCASE( HYP_CONCURENT );
548 RETURNCASE( HYP_BAD_PARAMETER );
549 RETURNCASE( HYP_HIDDEN_ALGO );
550 RETURNCASE( HYP_HIDING_ALGO );
551 RETURNCASE( HYP_UNKNOWN_FATAL );
552 RETURNCASE( HYP_INCOMPATIBLE );
553 RETURNCASE( HYP_NOTCONFORM );
554 RETURNCASE( HYP_ALREADY_EXIST );
555 RETURNCASE( HYP_BAD_DIM );
556 RETURNCASE( HYP_BAD_SUBSHAPE );
557 RETURNCASE( HYP_BAD_GEOMETRY );
558 RETURNCASE( HYP_NEED_SHAPE );
559 RETURNCASE( HYP_INCOMPAT_HYPS );
562 return SMESH::HYP_UNKNOWN_FATAL;
565 //=============================================================================
569 * calls internal addHypothesis() and then adds a reference to <anHyp> under
570 * the SObject actually having a reference to <aSubShape>.
571 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
573 //=============================================================================
575 SMESH::Hypothesis_Status
576 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
577 SMESH::SMESH_Hypothesis_ptr anHyp,
578 CORBA::String_out anErrorText)
579 throw(SALOME::SALOME_Exception)
581 Unexpect aCatch(SALOME_SalomeException);
583 _preMeshInfo->ForgetOrLoad();
586 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
587 anErrorText = error.c_str();
589 SMESH::SMESH_Mesh_var mesh( _this() );
590 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
592 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
593 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
595 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
597 // Update Python script
598 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
599 << aSubShape << ", " << anHyp << " )";
601 return ConvertHypothesisStatus(status);
604 //=============================================================================
608 //=============================================================================
610 SMESH_Hypothesis::Hypothesis_Status
611 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
612 SMESH::SMESH_Hypothesis_ptr anHyp,
613 std::string* anErrorText)
615 if(MYDEBUG) MESSAGE("addHypothesis");
617 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
618 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
620 if (CORBA::is_nil( anHyp ))
621 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
623 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
626 TopoDS_Shape myLocSubShape;
627 //use PseudoShape in case if mesh has no shape
629 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
631 myLocSubShape = _impl->GetShapeToMesh();
633 const int hypId = anHyp->GetId();
635 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
636 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
638 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
640 // assure there is a corresponding submesh
641 if ( !_impl->IsMainShape( myLocSubShape )) {
642 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
643 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
644 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
647 else if ( anErrorText )
649 *anErrorText = error;
652 catch(SALOME_Exception & S_ex)
654 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
659 //=============================================================================
663 //=============================================================================
665 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
666 SMESH::SMESH_Hypothesis_ptr anHyp)
667 throw(SALOME::SALOME_Exception)
669 Unexpect aCatch(SALOME_SalomeException);
671 _preMeshInfo->ForgetOrLoad();
673 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
674 SMESH::SMESH_Mesh_var mesh = _this();
676 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
678 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
679 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
681 // Update Python script
682 if(_impl->HasShapeToMesh())
683 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
684 << aSubShape << ", " << anHyp << " )";
686 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
689 return ConvertHypothesisStatus(status);
692 //=============================================================================
696 //=============================================================================
698 SMESH_Hypothesis::Hypothesis_Status
699 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
700 SMESH::SMESH_Hypothesis_ptr anHyp)
702 if(MYDEBUG) MESSAGE("removeHypothesis()");
704 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
705 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
707 if (CORBA::is_nil( anHyp ))
708 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
710 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
713 TopoDS_Shape myLocSubShape;
714 //use PseudoShape in case if mesh has no shape
715 if( _impl->HasShapeToMesh() )
716 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
718 myLocSubShape = _impl->GetShapeToMesh();
720 const int hypId = anHyp->GetId();
721 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
722 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
724 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
728 catch(SALOME_Exception & S_ex)
730 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
735 //=============================================================================
739 //=============================================================================
741 SMESH::ListOfHypothesis *
742 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
743 throw(SALOME::SALOME_Exception)
745 Unexpect aCatch(SALOME_SalomeException);
746 if (MYDEBUG) MESSAGE("GetHypothesisList");
747 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
748 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
750 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
753 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
754 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
755 myLocSubShape = _impl->GetShapeToMesh();
756 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
757 int i = 0, n = aLocalList.size();
760 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
761 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
762 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
764 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
765 if ( id_hypptr != _mapHypo.end() )
766 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
770 catch(SALOME_Exception & S_ex) {
771 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
774 return aList._retn();
777 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
779 Unexpect aCatch(SALOME_SalomeException);
780 if (MYDEBUG) MESSAGE("GetSubMeshes");
782 SMESH::submesh_array_var aList = new SMESH::submesh_array();
785 TPythonDump aPythonDump;
786 if ( !_mapSubMeshIor.empty() )
790 aList->length( _mapSubMeshIor.size() );
792 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
793 for ( ; it != _mapSubMeshIor.end(); it++ ) {
794 if ( CORBA::is_nil( it->second )) continue;
795 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
797 if (i > 1) aPythonDump << ", ";
798 aPythonDump << it->second;
802 catch(SALOME_Exception & S_ex) {
803 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
806 // Update Python script
807 if ( !_mapSubMeshIor.empty() )
808 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
810 return aList._retn();
813 //=============================================================================
817 //=============================================================================
819 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
820 const char* theName )
821 throw(SALOME::SALOME_Exception)
823 Unexpect aCatch(SALOME_SalomeException);
824 if (CORBA::is_nil(aSubShape))
825 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
827 SMESH::SMESH_subMesh_var subMesh;
828 SMESH::SMESH_Mesh_var aMesh = _this();
830 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
832 //Get or Create the SMESH_subMesh object implementation
834 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
836 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
838 TopoDS_Iterator it( myLocSubShape );
840 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
842 subMesh = getSubMesh( subMeshId );
844 // create a new subMesh object servant if there is none for the shape
845 if ( subMesh->_is_nil() )
846 subMesh = createSubMesh( aSubShape );
847 if ( _gen_i->CanPublishInStudy( subMesh ))
849 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
850 SALOMEDS::SObject_wrap aSO =
851 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
852 if ( !aSO->_is_nil()) {
853 // Update Python script
854 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
855 << aSubShape << ", '" << theName << "' )";
859 catch(SALOME_Exception & S_ex) {
860 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
862 return subMesh._retn();
865 //=============================================================================
869 //=============================================================================
871 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
872 throw (SALOME::SALOME_Exception)
876 if ( theSubMesh->_is_nil() )
879 GEOM::GEOM_Object_var aSubShape;
880 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
881 if ( !aStudy->_is_nil() ) {
882 // Remove submesh's SObject
883 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
884 if ( !anSO->_is_nil() ) {
885 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
886 SALOMEDS::SObject_wrap anObj, aRef;
887 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
888 anObj->ReferencedObject( aRef.inout() ))
890 CORBA::Object_var obj = aRef->GetObject();
891 aSubShape = GEOM::GEOM_Object::_narrow( obj );
893 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
894 // aSubShape = theSubMesh->GetSubShape();
896 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
897 builder->RemoveObjectWithChildren( anSO );
899 // Update Python script
900 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
904 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
906 _preMeshInfo->ForgetOrLoad();
908 SMESH_CATCH( SMESH::throwCorbaException );
911 //=============================================================================
915 //=============================================================================
917 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
918 const char* theName )
919 throw(SALOME::SALOME_Exception)
921 Unexpect aCatch(SALOME_SalomeException);
923 _preMeshInfo->FullLoadFromFile();
925 SMESH::SMESH_Group_var aNewGroup =
926 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
928 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
930 SMESH::SMESH_Mesh_var mesh = _this();
931 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
932 SALOMEDS::SObject_wrap aSO =
933 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
934 if ( !aSO->_is_nil())
935 // Update Python script
936 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
937 << theElemType << ", '" << theName << "' )";
939 return aNewGroup._retn();
942 //=============================================================================
946 //=============================================================================
947 SMESH::SMESH_GroupOnGeom_ptr
948 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
950 GEOM::GEOM_Object_ptr theGeomObj)
951 throw(SALOME::SALOME_Exception)
953 Unexpect aCatch(SALOME_SalomeException);
955 _preMeshInfo->FullLoadFromFile();
957 SMESH::SMESH_GroupOnGeom_var aNewGroup;
959 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
960 if ( !aShape.IsNull() )
963 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
965 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
967 SMESH::SMESH_Mesh_var mesh = _this();
968 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
969 SALOMEDS::SObject_wrap aSO =
970 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
971 if ( !aSO->_is_nil())
972 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
973 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
977 return aNewGroup._retn();
980 //================================================================================
982 * \brief Creates a group whose contents is defined by filter
983 * \param theElemType - group type
984 * \param theName - group name
985 * \param theFilter - the filter
986 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
988 //================================================================================
990 SMESH::SMESH_GroupOnFilter_ptr
991 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
993 SMESH::Filter_ptr theFilter )
994 throw (SALOME::SALOME_Exception)
996 Unexpect aCatch(SALOME_SalomeException);
998 _preMeshInfo->FullLoadFromFile();
1000 if ( CORBA::is_nil( theFilter ))
1001 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1003 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1005 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1007 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1008 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1011 if ( !aNewGroup->_is_nil() )
1012 aNewGroup->SetFilter( theFilter );
1014 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1016 SMESH::SMESH_Mesh_var mesh = _this();
1017 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1018 SALOMEDS::SObject_wrap aSO =
1019 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1021 if ( !aSO->_is_nil())
1022 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1023 << theElemType << ", '" << theName << "', " << theFilter << " )";
1025 return aNewGroup._retn();
1028 //=============================================================================
1032 //=============================================================================
1034 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1035 throw (SALOME::SALOME_Exception)
1037 if ( theGroup->_is_nil() )
1042 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1046 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1047 if ( !aStudy->_is_nil() )
1049 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1050 if ( !aGroupSO->_is_nil() )
1052 // Update Python script
1053 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1055 // Remove group's SObject
1056 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1057 builder->RemoveObjectWithChildren( aGroupSO );
1061 // Remove the group from SMESH data structures
1062 removeGroup( aGroup->GetLocalID() );
1064 SMESH_CATCH( SMESH::throwCorbaException );
1067 //=============================================================================
1069 * Remove group with its contents
1071 //=============================================================================
1073 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1074 throw (SALOME::SALOME_Exception)
1078 _preMeshInfo->FullLoadFromFile();
1080 if ( theGroup->_is_nil() )
1083 vector<int> nodeIds; // to remove nodes becoming free
1084 if ( !theGroup->IsEmpty() )
1086 CORBA::Long elemID = theGroup->GetID( 1 );
1087 int nbElemNodes = GetElemNbNodes( elemID );
1088 if ( nbElemNodes > 0 )
1089 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1093 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1094 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1095 while ( elemIt->more() )
1097 const SMDS_MeshElement* e = elemIt->next();
1099 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1100 while ( nIt->more() )
1101 nodeIds.push_back( nIt->next()->GetID() );
1103 _impl->GetMeshDS()->RemoveElement( e );
1106 // Remove free nodes
1107 if ( theGroup->GetType() != SMESH::NODE )
1108 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1109 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1110 if ( n->NbInverseElements() == 0 )
1111 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1113 TPythonDump pyDump; // Supress dump from RemoveGroup()
1115 // Update Python script (theGroup must be alive for this)
1116 pyDump << SMESH::SMESH_Mesh_var(_this())
1117 << ".RemoveGroupWithContents( " << theGroup << " )";
1120 RemoveGroup( theGroup );
1122 SMESH_CATCH( SMESH::throwCorbaException );
1125 //================================================================================
1127 * \brief Get the list of groups existing in the mesh
1128 * \retval SMESH::ListOfGroups * - list of groups
1130 //================================================================================
1132 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1134 Unexpect aCatch(SALOME_SalomeException);
1135 if (MYDEBUG) MESSAGE("GetGroups");
1137 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1140 TPythonDump aPythonDump;
1141 if ( !_mapGroups.empty() )
1143 aPythonDump << "[ ";
1145 aList->length( _mapGroups.size() );
1147 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1148 for ( ; it != _mapGroups.end(); it++ ) {
1149 if ( CORBA::is_nil( it->second )) continue;
1150 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1152 if (i > 1) aPythonDump << ", ";
1153 aPythonDump << it->second;
1157 catch(SALOME_Exception & S_ex) {
1158 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1160 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1162 return aList._retn();
1165 //=============================================================================
1167 * Get number of groups existing in the mesh
1169 //=============================================================================
1171 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1173 Unexpect aCatch(SALOME_SalomeException);
1174 return _mapGroups.size();
1177 //=============================================================================
1179 * New group including all mesh elements present in initial groups is created.
1181 //=============================================================================
1183 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1184 SMESH::SMESH_GroupBase_ptr theGroup2,
1185 const char* theName )
1186 throw (SALOME::SALOME_Exception)
1188 SMESH::SMESH_Group_var aResGrp;
1192 _preMeshInfo->FullLoadFromFile();
1194 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1195 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1197 if ( theGroup1->GetType() != theGroup2->GetType() )
1198 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1203 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1204 if ( aResGrp->_is_nil() )
1205 return SMESH::SMESH_Group::_nil();
1207 aResGrp->AddFrom( theGroup1 );
1208 aResGrp->AddFrom( theGroup2 );
1210 // Update Python script
1211 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1212 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1214 SMESH_CATCH( SMESH::throwCorbaException );
1216 return aResGrp._retn();
1219 //=============================================================================
1221 * \brief New group including all mesh elements present in initial groups is created.
1222 * \param theGroups list of groups
1223 * \param theName name of group to be created
1224 * \return pointer to the new group
1226 //=============================================================================
1228 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1229 const char* theName )
1230 throw (SALOME::SALOME_Exception)
1232 SMESH::SMESH_Group_var aResGrp;
1235 _preMeshInfo->FullLoadFromFile();
1238 return SMESH::SMESH_Group::_nil();
1243 SMESH::ElementType aType = SMESH::ALL;
1244 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1246 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1247 if ( CORBA::is_nil( aGrp ) )
1249 if ( aType == SMESH::ALL )
1250 aType = aGrp->GetType();
1251 else if ( aType != aGrp->GetType() )
1252 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1255 if ( aType == SMESH::ALL )
1256 return SMESH::SMESH_Group::_nil();
1261 aResGrp = CreateGroup( aType, theName );
1262 if ( aResGrp->_is_nil() )
1263 return SMESH::SMESH_Group::_nil();
1265 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1266 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1268 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1269 if ( !CORBA::is_nil( aGrp ) )
1271 aResGrp->AddFrom( aGrp );
1272 if ( g > 0 ) pyDump << ", ";
1276 pyDump << " ], '" << theName << "' )";
1278 SMESH_CATCH( SMESH::throwCorbaException );
1280 return aResGrp._retn();
1283 //=============================================================================
1285 * New group is created. All mesh elements that are
1286 * present in both initial groups are added to the new one.
1288 //=============================================================================
1290 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1291 SMESH::SMESH_GroupBase_ptr theGroup2,
1292 const char* theName )
1293 throw (SALOME::SALOME_Exception)
1295 SMESH::SMESH_Group_var aResGrp;
1300 _preMeshInfo->FullLoadFromFile();
1302 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1303 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1305 if ( theGroup1->GetType() != theGroup2->GetType() )
1306 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1310 // Create Intersection
1311 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1312 if ( aResGrp->_is_nil() )
1313 return aResGrp._retn();
1315 SMESHDS_GroupBase* groupDS1 = 0;
1316 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1317 groupDS1 = grp_i->GetGroupDS();
1319 SMESHDS_GroupBase* groupDS2 = 0;
1320 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1321 groupDS2 = grp_i->GetGroupDS();
1323 SMESHDS_Group* resGroupDS = 0;
1324 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1325 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1327 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1329 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1330 while ( elemIt1->more() )
1332 const SMDS_MeshElement* e = elemIt1->next();
1333 if ( groupDS2->Contains( e ))
1334 resGroupDS->SMDSGroup().Add( e );
1337 // Update Python script
1338 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1339 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1341 SMESH_CATCH( SMESH::throwCorbaException );
1343 return aResGrp._retn();
1346 //=============================================================================
1348 \brief Intersect list of groups. New group is created. All mesh elements that
1349 are present in all initial groups simultaneously are added to the new one.
1350 \param theGroups list of groups
1351 \param theName name of group to be created
1352 \return pointer on the group
1354 //=============================================================================
1355 SMESH::SMESH_Group_ptr
1356 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1357 const char* theName )
1358 throw (SALOME::SALOME_Exception)
1360 SMESH::SMESH_Group_var aResGrp;
1365 _preMeshInfo->FullLoadFromFile();
1368 return SMESH::SMESH_Group::_nil();
1370 // check types and get SMESHDS_GroupBase's
1371 SMESH::ElementType aType = SMESH::ALL;
1372 vector< SMESHDS_GroupBase* > groupVec;
1373 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1375 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1376 if ( CORBA::is_nil( aGrp ) )
1378 if ( aType == SMESH::ALL )
1379 aType = aGrp->GetType();
1380 else if ( aType != aGrp->GetType() )
1381 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1384 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1385 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1387 if ( grpDS->IsEmpty() )
1392 groupVec.push_back( grpDS );
1395 if ( aType == SMESH::ALL ) // all groups are nil
1396 return SMESH::SMESH_Group::_nil();
1401 aResGrp = CreateGroup( aType, theName );
1403 SMESHDS_Group* resGroupDS = 0;
1404 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1405 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1406 if ( !resGroupDS || groupVec.empty() )
1407 return aResGrp._retn();
1410 size_t i, nb = groupVec.size();
1411 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1412 while ( elemIt1->more() )
1414 const SMDS_MeshElement* e = elemIt1->next();
1416 for ( i = 1; ( i < nb && inAll ); ++i )
1417 inAll = groupVec[i]->Contains( e );
1420 resGroupDS->SMDSGroup().Add( e );
1423 // Update Python script
1424 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1425 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1427 SMESH_CATCH( SMESH::throwCorbaException );
1429 return aResGrp._retn();
1432 //=============================================================================
1434 * New group is created. All mesh elements that are present in
1435 * a main group but is not present in a tool group are added to the new one
1437 //=============================================================================
1439 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1440 SMESH::SMESH_GroupBase_ptr theGroup2,
1441 const char* theName )
1442 throw (SALOME::SALOME_Exception)
1444 SMESH::SMESH_Group_var aResGrp;
1449 _preMeshInfo->FullLoadFromFile();
1451 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1452 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1454 if ( theGroup1->GetType() != theGroup2->GetType() )
1455 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1459 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1460 if ( aResGrp->_is_nil() )
1461 return aResGrp._retn();
1463 SMESHDS_GroupBase* groupDS1 = 0;
1464 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1465 groupDS1 = grp_i->GetGroupDS();
1467 SMESHDS_GroupBase* groupDS2 = 0;
1468 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1469 groupDS2 = grp_i->GetGroupDS();
1471 SMESHDS_Group* resGroupDS = 0;
1472 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1473 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1475 if ( groupDS1 && groupDS2 && resGroupDS )
1477 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1478 while ( elemIt1->more() )
1480 const SMDS_MeshElement* e = elemIt1->next();
1481 if ( !groupDS2->Contains( e ))
1482 resGroupDS->SMDSGroup().Add( e );
1485 // Update Python script
1486 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1487 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1489 SMESH_CATCH( SMESH::throwCorbaException );
1491 return aResGrp._retn();
1494 //=============================================================================
1496 \brief Cut lists of groups. New group is created. All mesh elements that are
1497 present in main groups but do not present in tool groups are added to the new one
1498 \param theMainGroups list of main groups
1499 \param theToolGroups list of tool groups
1500 \param theName name of group to be created
1501 \return pointer on the group
1503 //=============================================================================
1504 SMESH::SMESH_Group_ptr
1505 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1506 const SMESH::ListOfGroups& theToolGroups,
1507 const char* theName )
1508 throw (SALOME::SALOME_Exception)
1510 SMESH::SMESH_Group_var aResGrp;
1515 _preMeshInfo->FullLoadFromFile();
1518 return SMESH::SMESH_Group::_nil();
1520 // check types and get SMESHDS_GroupBase's
1521 SMESH::ElementType aType = SMESH::ALL;
1522 vector< SMESHDS_GroupBase* > toolGroupVec;
1523 vector< SMDS_ElemIteratorPtr > mainIterVec;
1525 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1527 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1528 if ( CORBA::is_nil( aGrp ) )
1530 if ( aType == SMESH::ALL )
1531 aType = aGrp->GetType();
1532 else if ( aType != aGrp->GetType() )
1533 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1535 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1536 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1537 if ( !grpDS->IsEmpty() )
1538 mainIterVec.push_back( grpDS->GetElements() );
1540 if ( aType == SMESH::ALL ) // all main groups are nil
1541 return SMESH::SMESH_Group::_nil();
1542 if ( mainIterVec.empty() ) // all main groups are empty
1543 return aResGrp._retn();
1545 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1547 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1548 if ( CORBA::is_nil( aGrp ) )
1550 if ( aType != aGrp->GetType() )
1551 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1553 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1554 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1555 toolGroupVec.push_back( grpDS );
1561 aResGrp = CreateGroup( aType, theName );
1563 SMESHDS_Group* resGroupDS = 0;
1564 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1565 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1567 return aResGrp._retn();
1570 size_t i, nb = toolGroupVec.size();
1571 SMDS_ElemIteratorPtr mainElemIt
1572 ( new SMDS_IteratorOnIterators
1573 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1574 while ( mainElemIt->more() )
1576 const SMDS_MeshElement* e = mainElemIt->next();
1578 for ( i = 0; ( i < nb && !isIn ); ++i )
1579 isIn = toolGroupVec[i]->Contains( e );
1582 resGroupDS->SMDSGroup().Add( e );
1585 // Update Python script
1586 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1587 << ".CutListOfGroups( " << theMainGroups << ", "
1588 << theToolGroups << ", '" << theName << "' )";
1590 SMESH_CATCH( SMESH::throwCorbaException );
1592 return aResGrp._retn();
1595 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1597 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1598 bool & toStopChecking )
1600 toStopChecking = ( nbCommon < nbChecked );
1601 return nbCommon == nbNodes;
1603 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1604 bool & toStopChecking )
1606 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1607 return nbCommon == nbCorners;
1609 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1610 bool & toStopChecking )
1612 return nbCommon > 0;
1614 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1615 bool & toStopChecking )
1617 return nbCommon >= nbNodes / 2;
1621 //=============================================================================
1623 * Create a group of entities basing on nodes of other groups.
1624 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1625 * \param [in] anElemType - a type of elements to include to the new group.
1626 * \param [in] theName - a name of the new group.
1627 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1628 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1629 * new group provided that it is based on nodes of an element of \a aListOfGroups
1630 * \return SMESH_Group - the created group
1632 // IMP 19939, bug 22010, IMP 22635
1633 //=============================================================================
1635 SMESH::SMESH_Group_ptr
1636 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1637 SMESH::ElementType theElemType,
1638 const char* theName,
1639 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1640 CORBA::Boolean theUnderlyingOnly)
1641 throw (SALOME::SALOME_Exception)
1643 SMESH::SMESH_Group_var aResGrp;
1647 _preMeshInfo->FullLoadFromFile();
1649 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1651 if ( !theName || !aMeshDS )
1652 return SMESH::SMESH_Group::_nil();
1654 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1656 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1657 SMESH_Comment nbCoNoStr( "SMESH.");
1658 switch ( theNbCommonNodes ) {
1659 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1660 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1661 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1662 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1663 default: return aResGrp._retn();
1665 int nbChecked, nbCommon, nbNodes, nbCorners;
1671 aResGrp = CreateGroup( theElemType, theName );
1672 if ( aResGrp->_is_nil() )
1673 return SMESH::SMESH_Group::_nil();
1675 SMESHDS_GroupBase* groupBaseDS =
1676 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1677 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1679 vector<bool> isNodeInGroups;
1681 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1683 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1684 if ( CORBA::is_nil( aGrp ) )
1686 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1687 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1690 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1691 if ( !elIt ) continue;
1693 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1695 while ( elIt->more() ) {
1696 const SMDS_MeshElement* el = elIt->next();
1697 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1698 while ( nIt->more() )
1699 resGroupCore.Add( nIt->next() );
1702 // get elements of theElemType based on nodes of every element of group
1703 else if ( theUnderlyingOnly )
1705 while ( elIt->more() )
1707 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1708 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1709 TIDSortedElemSet checkedElems;
1710 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1711 while ( nIt->more() )
1713 const SMDS_MeshNode* n = nIt->next();
1714 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1715 // check nodes of elements of theElemType around el
1716 while ( elOfTypeIt->more() )
1718 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1719 if ( !checkedElems.insert( elOfType ).second ) continue;
1720 nbNodes = elOfType->NbNodes();
1721 nbCorners = elOfType->NbCornerNodes();
1723 bool toStopChecking = false;
1724 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1725 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1726 if ( elNodes.count( nIt2->next() ) &&
1727 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1729 resGroupCore.Add( elOfType );
1736 // get all nodes of elements of groups
1739 while ( elIt->more() )
1741 const SMDS_MeshElement* el = elIt->next(); // an element of group
1742 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1743 while ( nIt->more() )
1745 const SMDS_MeshNode* n = nIt->next();
1746 if ( n->GetID() >= isNodeInGroups.size() )
1747 isNodeInGroups.resize( n->GetID() + 1, false );
1748 isNodeInGroups[ n->GetID() ] = true;
1754 // Get elements of theElemType based on a certain number of nodes of elements of groups
1755 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1757 const SMDS_MeshNode* n;
1758 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1759 const int isNodeInGroupsSize = isNodeInGroups.size();
1760 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1762 if ( !isNodeInGroups[ iN ] ||
1763 !( n = aMeshDS->FindNode( iN )))
1766 // check nodes of elements of theElemType around n
1767 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1768 while ( elOfTypeIt->more() )
1770 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1771 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1776 nbNodes = elOfType->NbNodes();
1777 nbCorners = elOfType->NbCornerNodes();
1779 bool toStopChecking = false;
1780 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1781 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1783 const int nID = nIt->next()->GetID();
1784 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1785 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1787 resGroupCore.Add( elOfType );
1795 // Update Python script
1796 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1797 << ".CreateDimGroup( "
1798 << theGroups << ", " << theElemType << ", '" << theName << "', "
1799 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1801 SMESH_CATCH( SMESH::throwCorbaException );
1803 return aResGrp._retn();
1806 //================================================================================
1808 * \brief Remember GEOM group data
1810 //================================================================================
1812 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1813 CORBA::Object_ptr theSmeshObj)
1815 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1818 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1819 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1820 if ( groupSO->_is_nil() )
1823 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1824 GEOM::GEOM_IGroupOperations_wrap groupOp =
1825 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1826 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1829 _geomGroupData.push_back( TGeomGroupData() );
1830 TGeomGroupData & groupData = _geomGroupData.back();
1832 CORBA::String_var entry = groupSO->GetID();
1833 groupData._groupEntry = entry.in();
1835 for ( int i = 0; i < ids->length(); ++i )
1836 groupData._indices.insert( ids[i] );
1838 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1839 // shape index in SMESHDS
1840 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1841 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1844 //================================================================================
1846 * Remove GEOM group data relating to removed smesh object
1848 //================================================================================
1850 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1852 list<TGeomGroupData>::iterator
1853 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1854 for ( ; data != dataEnd; ++data ) {
1855 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1856 _geomGroupData.erase( data );
1862 //================================================================================
1864 * \brief Return new group contents if it has been changed and update group data
1866 //================================================================================
1868 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1870 TopoDS_Shape newShape;
1873 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1874 if ( study->_is_nil() ) return newShape; // means "not changed"
1875 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1876 if ( !groupSO->_is_nil() )
1878 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1879 if ( CORBA::is_nil( groupObj )) return newShape;
1880 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1882 // get indices of group items
1883 set<int> curIndices;
1884 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1885 GEOM::GEOM_IGroupOperations_wrap groupOp =
1886 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1887 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1888 for ( int i = 0; i < ids->length(); ++i )
1889 curIndices.insert( ids[i] );
1891 if ( groupData._indices == curIndices )
1892 return newShape; // group not changed
1895 groupData._indices = curIndices;
1897 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1898 if ( !geomClient ) return newShape;
1899 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1900 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1901 newShape = _gen_i->GeomObjectToShape( geomGroup );
1904 if ( newShape.IsNull() ) {
1905 // geom group becomes empty - return empty compound
1906 TopoDS_Compound compound;
1907 BRep_Builder().MakeCompound(compound);
1908 newShape = compound;
1915 //-----------------------------------------------------------------------------
1917 * \brief Storage of shape and index used in CheckGeomGroupModif()
1919 struct TIndexedShape
1922 TopoDS_Shape _shape;
1923 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1925 //-----------------------------------------------------------------------------
1927 * \brief Data to re-create a group on geometry
1929 struct TGroupOnGeomData
1933 SMDSAbs_ElementType _type;
1935 Quantity_Color _color;
1939 //=============================================================================
1941 * \brief Update data if geometry changes
1945 //=============================================================================
1947 void SMESH_Mesh_i::CheckGeomModif()
1949 if ( !_impl->HasShapeToMesh() ) return;
1951 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1952 if ( study->_is_nil() ) return;
1954 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1955 if ( mainGO->_is_nil() ) return;
1957 if ( mainGO->GetType() == GEOM_GROUP ||
1958 mainGO->GetTick() == _mainShapeTick )
1960 CheckGeomGroupModif();
1964 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1965 if ( !geomClient ) return;
1966 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1967 if ( geomGen->_is_nil() ) return;
1969 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1970 geomClient->RemoveShapeFromBuffer( ior.in() );
1972 // Update data taking into account that
1973 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1976 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1977 if ( newShape.IsNull() )
1980 _mainShapeTick = mainGO->GetTick();
1982 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1984 // store data of groups on geometry
1985 vector< TGroupOnGeomData > groupsData;
1986 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1987 groupsData.reserve( groups.size() );
1988 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1989 for ( ; g != groups.end(); ++g )
1990 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1992 TGroupOnGeomData data;
1993 data._oldID = group->GetID();
1994 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1995 data._type = group->GetType();
1996 data._name = group->GetStoreName();
1997 data._color = group->GetColor();
1998 groupsData.push_back( data );
2000 // store assigned hypotheses
2001 vector< pair< int, THypList > > ids2Hyps;
2002 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2003 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2005 const TopoDS_Shape& s = s2hyps.Key();
2006 const THypList& hyps = s2hyps.ChangeValue();
2007 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2010 // change shape to mesh
2011 int oldNbSubShapes = meshDS->MaxShapeIndex();
2012 _impl->ShapeToMesh( TopoDS_Shape() );
2013 _impl->ShapeToMesh( newShape );
2015 // re-add shapes of geom groups
2016 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2017 for ( ; data != _geomGroupData.end(); ++data )
2019 TopoDS_Shape newShape = newGroupShape( *data );
2020 if ( !newShape.IsNull() )
2022 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2024 TopoDS_Compound compound;
2025 BRep_Builder().MakeCompound( compound );
2026 BRep_Builder().Add( compound, newShape );
2027 newShape = compound;
2029 _impl->GetSubMesh( newShape );
2032 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2033 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2034 SALOME::INTERNAL_ERROR );
2036 // re-assign hypotheses
2037 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2039 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2040 const THypList& hyps = ids2Hyps[i].second;
2041 THypList::const_iterator h = hyps.begin();
2042 for ( ; h != hyps.end(); ++h )
2043 _impl->AddHypothesis( s, (*h)->GetID() );
2047 for ( size_t i = 0; i < groupsData.size(); ++i )
2049 const TGroupOnGeomData& data = groupsData[i];
2051 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2052 if ( i2g == _mapGroups.end() ) continue;
2054 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2055 if ( !gr_i ) continue;
2058 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2059 meshDS->IndexToShape( data._shapeID ));
2062 _mapGroups.erase( i2g );
2066 g->GetGroupDS()->SetColor( data._color );
2067 gr_i->changeLocalId( id );
2068 _mapGroups[ id ] = i2g->second;
2069 if ( data._oldID != id )
2070 _mapGroups.erase( i2g );
2074 // update _mapSubMesh
2075 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2076 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2077 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2081 //=============================================================================
2083 * \brief Update objects depending on changed geom groups
2085 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2086 * issue 0020210: Update of a smesh group after modification of the associated geom group
2088 //=============================================================================
2090 void SMESH_Mesh_i::CheckGeomGroupModif()
2092 if ( !_impl->HasShapeToMesh() ) return;
2094 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2095 if ( study->_is_nil() ) return;
2097 CORBA::Long nbEntities = NbNodes() + NbElements();
2099 // Check if group contents changed
2101 typedef map< string, TopoDS_Shape > TEntry2Geom;
2102 TEntry2Geom newGroupContents;
2104 list<TGeomGroupData>::iterator
2105 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2106 for ( ; data != dataEnd; ++data )
2108 pair< TEntry2Geom::iterator, bool > it_new =
2109 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2110 bool processedGroup = !it_new.second;
2111 TopoDS_Shape& newShape = it_new.first->second;
2112 if ( !processedGroup )
2113 newShape = newGroupShape( *data );
2114 if ( newShape.IsNull() )
2115 continue; // no changes
2118 _preMeshInfo->ForgetOrLoad();
2120 if ( processedGroup ) { // update group indices
2121 list<TGeomGroupData>::iterator data2 = data;
2122 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2123 data->_indices = data2->_indices;
2126 // Update SMESH objects according to new GEOM group contents
2128 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2129 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2131 int oldID = submesh->GetId();
2132 if ( !_mapSubMeshIor.count( oldID ))
2134 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2136 // update hypotheses
2137 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2138 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2139 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2141 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2142 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2144 // care of submeshes
2145 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2146 int newID = newSubmesh->GetId();
2147 if ( newID != oldID ) {
2148 _mapSubMesh [ newID ] = newSubmesh;
2149 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2150 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2151 _mapSubMesh. erase(oldID);
2152 _mapSubMesh_i. erase(oldID);
2153 _mapSubMeshIor.erase(oldID);
2154 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2159 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2160 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2161 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2163 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2165 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2166 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2167 ds->SetShape( newShape );
2172 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2173 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2175 // Remove groups and submeshes basing on removed sub-shapes
2177 TopTools_MapOfShape newShapeMap;
2178 TopoDS_Iterator shapeIt( newShape );
2179 for ( ; shapeIt.More(); shapeIt.Next() )
2180 newShapeMap.Add( shapeIt.Value() );
2182 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2183 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2185 if ( newShapeMap.Contains( shapeIt.Value() ))
2187 TopTools_IndexedMapOfShape oldShapeMap;
2188 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2189 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2191 const TopoDS_Shape& oldShape = oldShapeMap(i);
2192 int oldInd = meshDS->ShapeToIndex( oldShape );
2194 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2195 if ( i_smIor != _mapSubMeshIor.end() ) {
2196 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2199 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2200 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2202 // check if a group bases on oldInd shape
2203 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2204 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2205 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2206 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2208 RemoveGroup( i_grp->second ); // several groups can base on same shape
2209 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2214 // Reassign hypotheses and update groups after setting the new shape to mesh
2216 // collect anassigned hypotheses
2217 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2218 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2219 TShapeHypList assignedHyps;
2220 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2222 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2223 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2224 if ( !hyps.empty() ) {
2225 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2226 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2227 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2230 // collect shapes supporting groups
2231 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2232 TShapeTypeList groupData;
2233 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2234 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2235 for ( ; grIt != groups.end(); ++grIt )
2237 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2239 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2241 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2242 _impl->ShapeToMesh( newShape );
2244 // reassign hypotheses
2245 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2246 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2248 TIndexedShape& geom = indS_hyps->first;
2249 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2250 int oldID = geom._index;
2251 int newID = meshDS->ShapeToIndex( geom._shape );
2252 if ( oldID == 1 ) { // main shape
2254 geom._shape = newShape;
2258 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2259 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2260 // care of submeshes
2261 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2262 if ( newID != oldID ) {
2263 _mapSubMesh [ newID ] = newSubmesh;
2264 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2265 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2266 _mapSubMesh. erase(oldID);
2267 _mapSubMesh_i. erase(oldID);
2268 _mapSubMeshIor.erase(oldID);
2269 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2273 TShapeTypeList::iterator geomType = groupData.begin();
2274 for ( ; geomType != groupData.end(); ++geomType )
2276 const TIndexedShape& geom = geomType->first;
2277 int oldID = geom._index;
2278 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2281 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2282 CORBA::String_var name = groupSO->GetName();
2284 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2286 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2287 group_i->changeLocalId( newID );
2290 break; // everything has been updated
2293 } // loop on group data
2297 CORBA::Long newNbEntities = NbNodes() + NbElements();
2298 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2299 if ( newNbEntities != nbEntities )
2301 // Add all SObjects with icons to soToUpdateIcons
2302 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2304 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2305 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2306 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2308 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2309 i_gr != _mapGroups.end(); ++i_gr ) // groups
2310 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2313 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2314 for ( ; so != soToUpdateIcons.end(); ++so )
2315 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2318 //=============================================================================
2320 * \brief Create standalone group from a group on geometry or filter
2322 //=============================================================================
2324 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2325 throw (SALOME::SALOME_Exception)
2327 SMESH::SMESH_Group_var aGroup;
2332 _preMeshInfo->FullLoadFromFile();
2334 if ( theGroup->_is_nil() )
2335 return aGroup._retn();
2337 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2339 return aGroup._retn();
2341 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2343 const int anId = aGroupToRem->GetLocalID();
2344 if ( !_impl->ConvertToStandalone( anId ) )
2345 return aGroup._retn();
2346 removeGeomGroupData( theGroup );
2348 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2350 // remove old instance of group from own map
2351 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2352 _mapGroups.erase( anId );
2354 SALOMEDS::StudyBuilder_var builder;
2355 SALOMEDS::SObject_wrap aGroupSO;
2356 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2357 if ( !aStudy->_is_nil() ) {
2358 builder = aStudy->NewBuilder();
2359 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2360 if ( !aGroupSO->_is_nil() )
2362 // remove reference to geometry
2363 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2364 for ( ; chItr->More(); chItr->Next() )
2365 // Remove group's child SObject
2366 builder->RemoveObject( chItr->Value() );
2368 // Update Python script
2369 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2370 << ".ConvertToStandalone( " << aGroupSO << " )";
2372 // change icon of Group on Filter
2375 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2376 const int isEmpty = ( elemTypes->length() == 0 );
2379 SALOMEDS::GenericAttribute_wrap anAttr =
2380 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2381 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2382 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2388 // remember new group in own map
2389 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2390 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2392 // register CORBA object for persistence
2393 _gen_i->RegisterObject( aGroup );
2395 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2396 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2397 //aGroup->Register();
2398 aGroupToRem->UnRegister();
2400 SMESH_CATCH( SMESH::throwCorbaException );
2402 return aGroup._retn();
2405 //=============================================================================
2409 //=============================================================================
2411 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2413 if(MYDEBUG) MESSAGE( "createSubMesh" );
2414 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2415 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2416 const int subMeshId = mySubMesh->GetId();
2418 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2419 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2421 _mapSubMesh [subMeshId] = mySubMesh;
2422 _mapSubMesh_i [subMeshId] = subMeshServant;
2423 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2425 subMeshServant->Register();
2427 // register CORBA object for persistence
2428 int nextId = _gen_i->RegisterObject( subMesh );
2429 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2430 else { nextId = 0; } // avoid "unused variable" warning
2432 // to track changes of GEOM groups
2433 addGeomGroupData( theSubShapeObject, subMesh );
2435 return subMesh._retn();
2438 //=======================================================================
2439 //function : getSubMesh
2441 //=======================================================================
2443 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2445 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2446 if ( it == _mapSubMeshIor.end() )
2447 return SMESH::SMESH_subMesh::_nil();
2449 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2452 //=============================================================================
2456 //=============================================================================
2458 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2459 GEOM::GEOM_Object_ptr theSubShapeObject )
2461 bool isHypChanged = false;
2462 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2463 return isHypChanged;
2465 const int subMeshId = theSubMesh->GetId();
2467 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2469 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2471 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2474 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2475 isHypChanged = !hyps.empty();
2476 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2477 for ( ; hyp != hyps.end(); ++hyp )
2478 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2485 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2486 isHypChanged = ( aHypList->length() > 0 );
2487 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2488 removeHypothesis( theSubShapeObject, aHypList[i] );
2491 catch( const SALOME::SALOME_Exception& ) {
2492 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2494 removeGeomGroupData( theSubShapeObject );
2498 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2499 if ( id_smi != _mapSubMesh_i.end() )
2500 id_smi->second->UnRegister();
2502 // remove a CORBA object
2503 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2504 if ( id_smptr != _mapSubMeshIor.end() )
2505 SMESH::SMESH_subMesh_var( id_smptr->second );
2507 _mapSubMesh.erase(subMeshId);
2508 _mapSubMesh_i.erase(subMeshId);
2509 _mapSubMeshIor.erase(subMeshId);
2511 return isHypChanged;
2514 //=============================================================================
2518 //=============================================================================
2520 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2521 const char* theName,
2522 const TopoDS_Shape& theShape,
2523 const SMESH_PredicatePtr& thePredicate )
2525 std::string newName;
2526 if ( !theName || strlen( theName ) == 0 )
2528 std::set< std::string > presentNames;
2529 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2530 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2532 CORBA::String_var name = i_gr->second->GetName();
2533 presentNames.insert( name.in() );
2536 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2537 } while ( !presentNames.insert( newName ).second );
2538 theName = newName.c_str();
2541 SMESH::SMESH_GroupBase_var aGroup;
2542 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2544 SMESH_GroupBase_i* aGroupImpl;
2545 if ( !theShape.IsNull() )
2546 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2547 else if ( thePredicate )
2548 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2550 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2552 aGroup = aGroupImpl->_this();
2553 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2554 aGroupImpl->Register();
2556 // register CORBA object for persistence
2557 int nextId = _gen_i->RegisterObject( aGroup );
2558 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2559 else { nextId = 0; } // avoid "unused variable" warning in release mode
2561 // to track changes of GEOM groups
2562 if ( !theShape.IsNull() ) {
2563 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2564 addGeomGroupData( geom, aGroup );
2567 return aGroup._retn();
2570 //=============================================================================
2572 * SMESH_Mesh_i::removeGroup
2574 * Should be called by ~SMESH_Group_i()
2576 //=============================================================================
2578 void SMESH_Mesh_i::removeGroup( const int theId )
2580 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2581 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2582 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2583 _mapGroups.erase( theId );
2584 removeGeomGroupData( group );
2585 if ( !_impl->RemoveGroup( theId ))
2587 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2588 RemoveGroup( group );
2590 group->UnRegister();
2594 //=============================================================================
2598 //=============================================================================
2600 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2601 throw(SALOME::SALOME_Exception)
2603 SMESH::log_array_var aLog;
2607 _preMeshInfo->FullLoadFromFile();
2609 list < SMESHDS_Command * >logDS = _impl->GetLog();
2610 aLog = new SMESH::log_array;
2612 int lg = logDS.size();
2615 list < SMESHDS_Command * >::iterator its = logDS.begin();
2616 while(its != logDS.end()){
2617 SMESHDS_Command *com = *its;
2618 int comType = com->GetType();
2620 int lgcom = com->GetNumber();
2622 const list < int >&intList = com->GetIndexes();
2623 int inum = intList.size();
2625 list < int >::const_iterator ii = intList.begin();
2626 const list < double >&coordList = com->GetCoords();
2627 int rnum = coordList.size();
2629 list < double >::const_iterator ir = coordList.begin();
2630 aLog[indexLog].commandType = comType;
2631 aLog[indexLog].number = lgcom;
2632 aLog[indexLog].coords.length(rnum);
2633 aLog[indexLog].indexes.length(inum);
2634 for(int i = 0; i < rnum; i++){
2635 aLog[indexLog].coords[i] = *ir;
2636 //MESSAGE(" "<<i<<" "<<ir.Value());
2639 for(int i = 0; i < inum; i++){
2640 aLog[indexLog].indexes[i] = *ii;
2641 //MESSAGE(" "<<i<<" "<<ii.Value());
2650 SMESH_CATCH( SMESH::throwCorbaException );
2652 return aLog._retn();
2656 //=============================================================================
2660 //=============================================================================
2662 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2666 SMESH_CATCH( SMESH::throwCorbaException );
2669 //=============================================================================
2673 //=============================================================================
2675 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2680 //=============================================================================
2684 //=============================================================================
2686 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2691 //=============================================================================
2694 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2695 // issue 0020918: groups removal is caused by hyp modification
2696 // issue 0021208: to forget not loaded mesh data at hyp modification
2697 struct TCallUp_i : public SMESH_Mesh::TCallUp
2699 SMESH_Mesh_i* _mesh;
2700 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2701 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2702 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2703 virtual void Load () { _mesh->Load(); }
2707 //================================================================================
2709 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2711 //================================================================================
2713 void SMESH_Mesh_i::onHypothesisModified()
2716 _preMeshInfo->ForgetOrLoad();
2719 //=============================================================================
2723 //=============================================================================
2725 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2727 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2730 _impl->SetCallUp( new TCallUp_i(this));
2733 //=============================================================================
2737 //=============================================================================
2739 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2741 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2745 //=============================================================================
2747 * Return mesh editor
2749 //=============================================================================
2751 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2752 throw (SALOME::SALOME_Exception)
2754 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2758 _preMeshInfo->FullLoadFromFile();
2760 // Create MeshEditor
2762 _editor = new SMESH_MeshEditor_i( this, false );
2763 aMeshEdVar = _editor->_this();
2765 // Update Python script
2766 TPythonDump() << _editor << " = "
2767 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2769 SMESH_CATCH( SMESH::throwCorbaException );
2771 return aMeshEdVar._retn();
2774 //=============================================================================
2776 * Return mesh edition previewer
2778 //=============================================================================
2780 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2781 throw (SALOME::SALOME_Exception)
2783 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2787 _preMeshInfo->FullLoadFromFile();
2789 if ( !_previewEditor )
2790 _previewEditor = new SMESH_MeshEditor_i( this, true );
2791 aMeshEdVar = _previewEditor->_this();
2793 SMESH_CATCH( SMESH::throwCorbaException );
2795 return aMeshEdVar._retn();
2798 //================================================================================
2800 * \brief Return true if the mesh has been edited since a last total re-compute
2801 * and those modifications may prevent successful partial re-compute
2803 //================================================================================
2805 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2807 Unexpect aCatch(SALOME_SalomeException);
2808 return _impl->HasModificationsToDiscard();
2811 //================================================================================
2813 * \brief Returns a random unique color
2815 //================================================================================
2817 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2819 const int MAX_ATTEMPTS = 100;
2821 double tolerance = 0.5;
2822 SALOMEDS::Color col;
2826 // generate random color
2827 double red = (double)rand() / RAND_MAX;
2828 double green = (double)rand() / RAND_MAX;
2829 double blue = (double)rand() / RAND_MAX;
2830 // check existence in the list of the existing colors
2831 bool matched = false;
2832 std::list<SALOMEDS::Color>::const_iterator it;
2833 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2834 SALOMEDS::Color color = *it;
2835 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2836 matched = tol < tolerance;
2838 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2839 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2847 //=============================================================================
2849 * Sets auto-color mode. If it is on, groups get unique random colors
2851 //=============================================================================
2853 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2855 Unexpect aCatch(SALOME_SalomeException);
2856 _impl->SetAutoColor(theAutoColor);
2858 TPythonDump pyDump; // not to dump group->SetColor() from below code
2859 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2861 std::list<SALOMEDS::Color> aReservedColors;
2862 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2863 for ( ; it != _mapGroups.end(); it++ ) {
2864 if ( CORBA::is_nil( it->second )) continue;
2865 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2866 it->second->SetColor( aColor );
2867 aReservedColors.push_back( aColor );
2871 //=============================================================================
2873 * Returns true if auto-color mode is on
2875 //=============================================================================
2877 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2879 Unexpect aCatch(SALOME_SalomeException);
2880 return _impl->GetAutoColor();
2883 //=============================================================================
2885 * Checks if there are groups with equal names
2887 //=============================================================================
2889 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2891 return _impl->HasDuplicatedGroupNamesMED();
2894 //================================================================================
2896 * \brief Care of a file before exporting mesh into it
2898 //================================================================================
2900 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2902 SMESH_File aFile( file );
2904 if (aFile.exists()) {
2905 // existing filesystem node
2906 if ( !aFile.isDirectory() ) {
2907 if ( aFile.openForWriting() ) {
2908 if ( overwrite && ! aFile.remove()) {
2909 msg << "Can't replace " << aFile.getName();
2912 msg << "Can't write into " << aFile.getName();
2915 msg << "Location " << aFile.getName() << " is not a file";
2919 // nonexisting file; check if it can be created
2920 if ( !aFile.openForWriting() ) {
2921 msg << "You cannot create the file "
2923 << ". Check the directory existance and access rights";
2931 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2935 //================================================================================
2937 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2938 * \param file - file name
2939 * \param overwrite - to erase the file or not
2940 * \retval string - mesh name
2942 //================================================================================
2944 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2945 CORBA::Boolean overwrite)
2948 PrepareForWriting(file, overwrite);
2949 string aMeshName = "Mesh";
2950 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2951 if ( !aStudy->_is_nil() ) {
2952 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2953 if ( !aMeshSO->_is_nil() ) {
2954 CORBA::String_var name = aMeshSO->GetName();
2956 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2957 if ( !aStudy->GetProperties()->IsLocked() )
2959 SALOMEDS::GenericAttribute_wrap anAttr;
2960 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2961 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2962 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2963 ASSERT(!aFileName->_is_nil());
2964 aFileName->SetValue(file);
2965 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2966 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2967 ASSERT(!aFileType->_is_nil());
2968 aFileType->SetValue("FICHIERMED");
2972 // Update Python script
2973 // set name of mesh before export
2974 TPythonDump() << _gen_i << ".SetName("
2975 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2977 // check names of groups
2983 //================================================================================
2985 * \brief Export to med file
2987 //================================================================================
2989 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2990 CORBA::Boolean auto_groups,
2991 SMESH::MED_VERSION theVersion,
2992 CORBA::Boolean overwrite,
2993 CORBA::Boolean autoDimension)
2994 throw(SALOME::SALOME_Exception)
2998 _preMeshInfo->FullLoadFromFile();
3000 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3001 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3003 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3004 << file << "', " << auto_groups << ", "
3005 << theVersion << ", " << overwrite << ", "
3006 << autoDimension << " )";
3008 SMESH_CATCH( SMESH::throwCorbaException );
3011 //================================================================================
3013 * \brief Export a mesh to a med file
3015 //================================================================================
3017 void SMESH_Mesh_i::ExportToMED (const char* file,
3018 CORBA::Boolean auto_groups,
3019 SMESH::MED_VERSION theVersion)
3020 throw(SALOME::SALOME_Exception)
3022 ExportToMEDX(file,auto_groups,theVersion,true);
3025 //================================================================================
3027 * \brief Export a mesh to a med file
3029 //================================================================================
3031 void SMESH_Mesh_i::ExportMED (const char* file,
3032 CORBA::Boolean auto_groups)
3033 throw(SALOME::SALOME_Exception)
3035 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3038 //================================================================================
3040 * \brief Export a mesh to a SAUV file
3042 //================================================================================
3044 void SMESH_Mesh_i::ExportSAUV (const char* file,
3045 CORBA::Boolean auto_groups)
3046 throw(SALOME::SALOME_Exception)
3048 Unexpect aCatch(SALOME_SalomeException);
3050 _preMeshInfo->FullLoadFromFile();
3052 string aMeshName = prepareMeshNameAndGroups(file, true);
3053 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3054 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3055 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3059 //================================================================================
3061 * \brief Export a mesh to a DAT file
3063 //================================================================================
3065 void SMESH_Mesh_i::ExportDAT (const char *file)
3066 throw(SALOME::SALOME_Exception)
3068 Unexpect aCatch(SALOME_SalomeException);
3070 _preMeshInfo->FullLoadFromFile();
3072 // Update Python script
3073 // check names of groups
3075 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3078 PrepareForWriting(file);
3079 _impl->ExportDAT(file);
3082 //================================================================================
3084 * \brief Export a mesh to an UNV file
3086 //================================================================================
3088 void SMESH_Mesh_i::ExportUNV (const char *file)
3089 throw(SALOME::SALOME_Exception)
3091 Unexpect aCatch(SALOME_SalomeException);
3093 _preMeshInfo->FullLoadFromFile();
3095 // Update Python script
3096 // check names of groups
3098 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3101 PrepareForWriting(file);
3102 _impl->ExportUNV(file);
3105 //================================================================================
3107 * \brief Export a mesh to an STL file
3109 //================================================================================
3111 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3112 throw(SALOME::SALOME_Exception)
3114 Unexpect aCatch(SALOME_SalomeException);
3116 _preMeshInfo->FullLoadFromFile();
3118 // Update Python script
3119 // check names of groups
3121 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3122 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3125 PrepareForWriting(file);
3126 _impl->ExportSTL(file, isascii);
3129 //================================================================================
3131 * \brief Export a part of mesh to a med file
3133 //================================================================================
3135 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3137 CORBA::Boolean auto_groups,
3138 SMESH::MED_VERSION version,
3139 CORBA::Boolean overwrite,
3140 CORBA::Boolean autoDimension,
3141 const GEOM::ListOfFields& fields,
3142 const char* geomAssocFields)
3143 throw (SALOME::SALOME_Exception)
3147 _preMeshInfo->FullLoadFromFile();
3150 bool have0dField = false;
3151 if ( fields.length() > 0 )
3153 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3154 if ( shapeToMesh->_is_nil() )
3155 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3157 for ( size_t i = 0; i < fields.length(); ++i )
3159 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3160 THROW_SALOME_CORBA_EXCEPTION
3161 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3162 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3163 if ( fieldShape->_is_nil() )
3164 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3165 if ( !fieldShape->IsSame( shapeToMesh ) )
3166 THROW_SALOME_CORBA_EXCEPTION
3167 ( "Field defined not on shape", SALOME::BAD_PARAM);
3168 if ( fields[i]->GetDimension() == 0 )
3171 if ( geomAssocFields )
3172 for ( int i = 0; geomAssocFields[i]; ++i )
3173 switch ( geomAssocFields[i] ) {
3174 case 'v':case 'e':case 'f':case 's': break;
3175 case 'V':case 'E':case 'F':case 'S': break;
3176 default: THROW_SALOME_CORBA_EXCEPTION
3177 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3181 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3185 string aMeshName = "Mesh";
3186 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3187 if ( CORBA::is_nil( meshPart ) ||
3188 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3190 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3191 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3192 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3193 meshDS = _impl->GetMeshDS();
3198 _preMeshInfo->FullLoadFromFile();
3200 PrepareForWriting(file, overwrite);
3202 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3203 if ( !aStudy->_is_nil() ) {
3204 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3205 if ( !SO->_is_nil() ) {
3206 CORBA::String_var name = SO->GetName();
3210 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3211 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3212 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3213 meshDS = tmpDSDeleter._obj = partDS;
3218 if ( _impl->HasShapeToMesh() )
3220 DriverMED_W_Field fieldWriter;
3221 fieldWriter.SetFile( file );
3222 fieldWriter.SetMeshName( aMeshName );
3223 fieldWriter.AddODOnVertices( have0dField );
3225 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3229 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3230 goList->length( fields.length() );
3231 for ( size_t i = 0; i < fields.length(); ++i )
3233 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3236 TPythonDump() << _this() << ".ExportPartToMED( "
3237 << meshPart << ", r'" << file << "', "
3238 << auto_groups << ", " << version << ", " << overwrite << ", "
3239 << autoDimension << ", " << goList
3240 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3242 SMESH_CATCH( SMESH::throwCorbaException );
3245 //================================================================================
3247 * Write GEOM fields to MED file
3249 //================================================================================
3251 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3252 SMESHDS_Mesh* meshDS,
3253 const GEOM::ListOfFields& fields,
3254 const char* geomAssocFields)
3256 #define METH "SMESH_Mesh_i::exportMEDFields() "
3258 if (( fields.length() < 1 ) &&
3259 ( !geomAssocFields || !geomAssocFields[0] ))
3262 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3263 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3264 std::vector< int > subIdsByDim[ 4 ];
3265 const double noneDblValue = 0.;
3266 const double noneIntValue = 0;
3268 for ( size_t iF = 0; iF < fields.length(); ++iF )
3272 int dim = fields[ iF ]->GetDimension();
3273 SMDSAbs_ElementType elemType;
3274 TopAbs_ShapeEnum shapeType;
3276 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3277 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3278 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3279 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3281 continue; // skip fields on whole shape
3283 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3284 if ( dataType == GEOM::FDT_String )
3286 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3287 if ( stepIDs->length() < 1 )
3289 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3290 if ( comps->length() < 1 )
3292 CORBA::String_var name = fields[ iF ]->GetName();
3294 if ( !fieldWriter.Set( meshDS,
3298 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3301 for ( size_t iC = 0; iC < comps->length(); ++iC )
3302 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3304 // find sub-shape IDs
3306 std::vector< int >& subIds = subIdsByDim[ dim ];
3307 if ( subIds.empty() )
3308 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3309 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3310 subIds.push_back( id );
3314 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3318 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3320 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3321 if ( step->_is_nil() )
3324 CORBA::Long stamp = step->GetStamp();
3325 CORBA::Long id = step->GetID();
3326 fieldWriter.SetDtIt( int( stamp ), int( id ));
3328 // fill dblVals or intVals
3331 case GEOM::FDT_Double:
3333 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3334 if ( dblStep->_is_nil() ) continue;
3335 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3336 if ( vv->length() != subIds.size() )
3337 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3338 for ( size_t i = 0; i < vv->length(); ++i )
3339 dblVals[ subIds[ i ]] = vv[ i ];
3344 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3345 if ( intStep->_is_nil() ) continue;
3346 GEOM::ListOfLong_var vv = intStep->GetValues();
3347 if ( vv->length() != subIds.size() )
3348 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3349 for ( size_t i = 0; i < vv->length(); ++i )
3350 intVals[ subIds[ i ]] = (int) vv[ i ];
3353 case GEOM::FDT_Bool:
3355 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3356 if ( boolStep->_is_nil() ) continue;
3357 GEOM::short_array_var vv = boolStep->GetValues();
3358 if ( vv->length() != subIds.size() )
3359 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3360 for ( size_t i = 0; i < vv->length(); ++i )
3361 intVals[ subIds[ i ]] = (int) vv[ i ];
3367 // pass values to fieldWriter
3368 elemIt = fieldWriter.GetOrderedElems();
3369 if ( dataType == GEOM::FDT_Double )
3370 while ( elemIt->more() )
3372 const SMDS_MeshElement* e = elemIt->next();
3373 const int shapeID = e->getshapeId();
3374 if ( shapeID < 1 || shapeID >= dblVals.size() )
3375 fieldWriter.AddValue( noneDblValue );
3377 fieldWriter.AddValue( dblVals[ shapeID ]);
3380 while ( elemIt->more() )
3382 const SMDS_MeshElement* e = elemIt->next();
3383 const int shapeID = e->getshapeId();
3384 if ( shapeID < 1 || shapeID >= intVals.size() )
3385 fieldWriter.AddValue( (double) noneIntValue );
3387 fieldWriter.AddValue( (double) intVals[ shapeID ]);
3391 fieldWriter.Perform();
3392 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3393 if ( res && res->IsKO() )
3395 if ( res->myComment.empty() )
3396 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3398 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3404 if ( !geomAssocFields || !geomAssocFields[0] )
3407 // write geomAssocFields
3409 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3410 shapeDim[ TopAbs_COMPOUND ] = 3;
3411 shapeDim[ TopAbs_COMPSOLID ] = 3;
3412 shapeDim[ TopAbs_SOLID ] = 3;
3413 shapeDim[ TopAbs_SHELL ] = 2;
3414 shapeDim[ TopAbs_FACE ] = 2;
3415 shapeDim[ TopAbs_WIRE ] = 1;
3416 shapeDim[ TopAbs_EDGE ] = 1;
3417 shapeDim[ TopAbs_VERTEX ] = 0;
3418 shapeDim[ TopAbs_SHAPE ] = 3;
3420 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3422 std::vector< std::string > compNames;
3423 switch ( geomAssocFields[ iF ]) {
3425 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3426 compNames.push_back( "dim" );
3429 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3432 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3435 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3439 compNames.push_back( "id" );
3440 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3441 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3443 fieldWriter.SetDtIt( -1, -1 );
3445 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3449 if ( compNames.size() == 2 ) // _vertices_
3450 while ( elemIt->more() )
3452 const SMDS_MeshElement* e = elemIt->next();
3453 const int shapeID = e->getshapeId();
3456 fieldWriter.AddValue( (double) -1 );
3457 fieldWriter.AddValue( (double) -1 );
3461 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3462 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3463 fieldWriter.AddValue( (double) shapeID );
3467 while ( elemIt->more() )
3469 const SMDS_MeshElement* e = elemIt->next();
3470 const int shapeID = e->getshapeId();
3472 fieldWriter.AddValue( (double) -1 );
3474 fieldWriter.AddValue( (double) shapeID );
3478 fieldWriter.Perform();
3479 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3480 if ( res && res->IsKO() )
3482 if ( res->myComment.empty() )
3483 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3485 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3488 } // loop on geomAssocFields
3493 //================================================================================
3495 * \brief Export a part of mesh to a DAT file
3497 //================================================================================
3499 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3501 throw (SALOME::SALOME_Exception)
3503 Unexpect aCatch(SALOME_SalomeException);
3505 _preMeshInfo->FullLoadFromFile();
3507 PrepareForWriting(file);
3509 SMESH_MeshPartDS partDS( meshPart );
3510 _impl->ExportDAT(file,&partDS);
3512 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3513 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3515 //================================================================================
3517 * \brief Export a part of mesh to an UNV file
3519 //================================================================================
3521 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3523 throw (SALOME::SALOME_Exception)
3525 Unexpect aCatch(SALOME_SalomeException);
3527 _preMeshInfo->FullLoadFromFile();
3529 PrepareForWriting(file);
3531 SMESH_MeshPartDS partDS( meshPart );
3532 _impl->ExportUNV(file, &partDS);
3534 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3535 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3537 //================================================================================
3539 * \brief Export a part of mesh to an STL file
3541 //================================================================================
3543 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3545 ::CORBA::Boolean isascii)
3546 throw (SALOME::SALOME_Exception)
3548 Unexpect aCatch(SALOME_SalomeException);
3550 _preMeshInfo->FullLoadFromFile();
3552 PrepareForWriting(file);
3554 SMESH_MeshPartDS partDS( meshPart );
3555 _impl->ExportSTL(file, isascii, &partDS);
3557 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3558 << meshPart<< ", r'" << file << "', " << isascii << ")";
3561 //================================================================================
3563 * \brief Export a part of mesh to an STL file
3565 //================================================================================
3567 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3569 CORBA::Boolean overwrite)
3570 throw (SALOME::SALOME_Exception)
3573 Unexpect aCatch(SALOME_SalomeException);
3575 _preMeshInfo->FullLoadFromFile();
3577 PrepareForWriting(file,overwrite);
3579 SMESH_MeshPartDS partDS( meshPart );
3580 _impl->ExportCGNS(file, &partDS);
3582 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3583 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3585 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3589 //================================================================================
3591 * \brief Export a part of mesh to a GMF file
3593 //================================================================================
3595 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3597 bool withRequiredGroups)
3598 throw (SALOME::SALOME_Exception)
3600 Unexpect aCatch(SALOME_SalomeException);
3602 _preMeshInfo->FullLoadFromFile();
3604 PrepareForWriting(file,/*overwrite=*/true);
3606 SMESH_MeshPartDS partDS( meshPart );
3607 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3609 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3610 << meshPart<< ", r'"
3612 << withRequiredGroups << ")";
3615 //=============================================================================
3617 * Return computation progress [0.,1]
3619 //=============================================================================
3621 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3625 return _impl->GetComputeProgress();
3627 SMESH_CATCH( SMESH::doNothing );
3631 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3633 Unexpect aCatch(SALOME_SalomeException);
3635 return _preMeshInfo->NbNodes();
3637 return _impl->NbNodes();
3640 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3642 Unexpect aCatch(SALOME_SalomeException);
3644 return _preMeshInfo->NbElements();
3646 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3649 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3651 Unexpect aCatch(SALOME_SalomeException);
3653 return _preMeshInfo->Nb0DElements();
3655 return _impl->Nb0DElements();
3658 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3660 Unexpect aCatch(SALOME_SalomeException);
3662 return _preMeshInfo->NbBalls();
3664 return _impl->NbBalls();
3667 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3669 Unexpect aCatch(SALOME_SalomeException);
3671 return _preMeshInfo->NbEdges();
3673 return _impl->NbEdges();
3676 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3677 throw(SALOME::SALOME_Exception)
3679 Unexpect aCatch(SALOME_SalomeException);
3681 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3683 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3686 //=============================================================================
3688 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3690 Unexpect aCatch(SALOME_SalomeException);
3692 return _preMeshInfo->NbFaces();
3694 return _impl->NbFaces();
3697 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3699 Unexpect aCatch(SALOME_SalomeException);
3701 return _preMeshInfo->NbTriangles();
3703 return _impl->NbTriangles();
3706 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3708 Unexpect aCatch(SALOME_SalomeException);
3710 return _preMeshInfo->NbBiQuadTriangles();
3712 return _impl->NbBiQuadTriangles();
3715 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3717 Unexpect aCatch(SALOME_SalomeException);
3719 return _preMeshInfo->NbQuadrangles();
3721 return _impl->NbQuadrangles();
3724 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3726 Unexpect aCatch(SALOME_SalomeException);
3728 return _preMeshInfo->NbBiQuadQuadrangles();
3730 return _impl->NbBiQuadQuadrangles();
3733 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3735 Unexpect aCatch(SALOME_SalomeException);
3737 return _preMeshInfo->NbPolygons();
3739 return _impl->NbPolygons();
3742 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3743 throw(SALOME::SALOME_Exception)
3745 Unexpect aCatch(SALOME_SalomeException);
3747 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3749 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3752 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3753 throw(SALOME::SALOME_Exception)
3755 Unexpect aCatch(SALOME_SalomeException);
3757 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3759 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3762 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3763 throw(SALOME::SALOME_Exception)
3765 Unexpect aCatch(SALOME_SalomeException);
3767 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3769 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3772 //=============================================================================
3774 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3776 Unexpect aCatch(SALOME_SalomeException);
3778 return _preMeshInfo->NbVolumes();
3780 return _impl->NbVolumes();
3783 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3785 Unexpect aCatch(SALOME_SalomeException);
3787 return _preMeshInfo->NbTetras();
3789 return _impl->NbTetras();
3792 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3794 Unexpect aCatch(SALOME_SalomeException);
3796 return _preMeshInfo->NbHexas();
3798 return _impl->NbHexas();
3801 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3803 Unexpect aCatch(SALOME_SalomeException);
3805 return _preMeshInfo->NbTriQuadHexas();
3807 return _impl->NbTriQuadraticHexas();
3810 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3812 Unexpect aCatch(SALOME_SalomeException);
3814 return _preMeshInfo->NbPyramids();
3816 return _impl->NbPyramids();
3819 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3821 Unexpect aCatch(SALOME_SalomeException);
3823 return _preMeshInfo->NbPrisms();
3825 return _impl->NbPrisms();
3828 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3830 Unexpect aCatch(SALOME_SalomeException);
3832 return _preMeshInfo->NbHexPrisms();
3834 return _impl->NbHexagonalPrisms();
3837 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3839 Unexpect aCatch(SALOME_SalomeException);
3841 return _preMeshInfo->NbPolyhedrons();
3843 return _impl->NbPolyhedrons();
3846 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3847 throw(SALOME::SALOME_Exception)
3849 Unexpect aCatch(SALOME_SalomeException);
3851 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3853 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3856 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3857 throw(SALOME::SALOME_Exception)
3859 Unexpect aCatch(SALOME_SalomeException);
3861 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3863 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3866 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3867 throw(SALOME::SALOME_Exception)
3869 Unexpect aCatch(SALOME_SalomeException);
3871 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3873 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3876 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3877 throw(SALOME::SALOME_Exception)
3879 Unexpect aCatch(SALOME_SalomeException);
3881 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3883 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3886 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3887 throw(SALOME::SALOME_Exception)
3889 Unexpect aCatch(SALOME_SalomeException);
3891 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3893 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3896 //=============================================================================
3898 * Returns nb of published sub-meshes
3900 //=============================================================================
3902 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3904 Unexpect aCatch(SALOME_SalomeException);
3905 return _mapSubMesh_i.size();
3908 //=============================================================================
3910 * Dumps mesh into a string
3912 //=============================================================================
3914 char* SMESH_Mesh_i::Dump()
3918 return CORBA::string_dup( os.str().c_str() );
3921 //=============================================================================
3923 * Method of SMESH_IDSource interface
3925 //=============================================================================
3927 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3929 return GetElementsId();
3932 //=============================================================================
3934 * Returns ids of all elements
3936 //=============================================================================
3938 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3939 throw (SALOME::SALOME_Exception)
3941 Unexpect aCatch(SALOME_SalomeException);
3943 _preMeshInfo->FullLoadFromFile();
3945 SMESH::long_array_var aResult = new SMESH::long_array();
3946 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3948 if ( aSMESHDS_Mesh == NULL )
3949 return aResult._retn();
3951 long nbElements = NbElements();
3952 aResult->length( nbElements );
3953 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3954 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3955 aResult[i] = anIt->next()->GetID();
3957 return aResult._retn();
3961 //=============================================================================
3963 * Returns ids of all elements of given type
3965 //=============================================================================
3967 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3968 throw (SALOME::SALOME_Exception)
3970 Unexpect aCatch(SALOME_SalomeException);
3972 _preMeshInfo->FullLoadFromFile();
3974 SMESH::long_array_var aResult = new SMESH::long_array();
3975 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3977 if ( aSMESHDS_Mesh == NULL )
3978 return aResult._retn();
3980 long nbElements = NbElements();
3982 // No sense in returning ids of elements along with ids of nodes:
3983 // when theElemType == SMESH::ALL, return node ids only if
3984 // there are no elements
3985 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3986 return GetNodesId();
3988 aResult->length( nbElements );
3992 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3993 while ( i < nbElements && anIt->more() )
3994 aResult[i++] = anIt->next()->GetID();
3996 aResult->length( i );
3998 return aResult._retn();
4001 //=============================================================================
4003 * Returns ids of all nodes
4005 //=============================================================================
4007 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4008 throw (SALOME::SALOME_Exception)
4010 Unexpect aCatch(SALOME_SalomeException);
4012 _preMeshInfo->FullLoadFromFile();
4014 SMESH::long_array_var aResult = new SMESH::long_array();
4015 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4017 if ( aSMESHDS_Mesh == NULL )
4018 return aResult._retn();
4020 long nbNodes = NbNodes();
4021 aResult->length( nbNodes );
4022 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4023 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4024 aResult[i] = anIt->next()->GetID();
4026 return aResult._retn();
4029 //=============================================================================
4033 //=============================================================================
4035 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4036 throw (SALOME::SALOME_Exception)
4038 SMESH::ElementType type;
4042 _preMeshInfo->FullLoadFromFile();
4044 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4046 SMESH_CATCH( SMESH::throwCorbaException );
4051 //=============================================================================
4055 //=============================================================================
4057 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4058 throw (SALOME::SALOME_Exception)
4061 _preMeshInfo->FullLoadFromFile();
4063 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4065 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4067 return ( SMESH::EntityType ) e->GetEntityType();
4070 //=============================================================================
4074 //=============================================================================
4076 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4077 throw (SALOME::SALOME_Exception)
4080 _preMeshInfo->FullLoadFromFile();
4082 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4084 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4086 return ( SMESH::GeometryType ) e->GetGeomType();
4089 //=============================================================================
4091 * Returns ID of elements for given submesh
4093 //=============================================================================
4094 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4095 throw (SALOME::SALOME_Exception)
4097 SMESH::long_array_var aResult = new SMESH::long_array();
4101 _preMeshInfo->FullLoadFromFile();
4103 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4104 if(!SM) return aResult._retn();
4106 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4107 if(!SDSM) return aResult._retn();
4109 aResult->length(SDSM->NbElements());
4111 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4113 while ( eIt->more() ) {
4114 aResult[i++] = eIt->next()->GetID();
4117 SMESH_CATCH( SMESH::throwCorbaException );
4119 return aResult._retn();
4122 //=============================================================================
4124 * Returns ID of nodes for given submesh
4125 * If param all==true - returns all nodes, else -
4126 * returns only nodes on shapes.
4128 //=============================================================================
4130 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4132 throw (SALOME::SALOME_Exception)
4134 SMESH::long_array_var aResult = new SMESH::long_array();
4138 _preMeshInfo->FullLoadFromFile();
4140 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4141 if(!SM) return aResult._retn();
4143 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4144 if(!SDSM) return aResult._retn();
4147 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4148 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4149 while ( nIt->more() ) {
4150 const SMDS_MeshNode* elem = nIt->next();
4151 theElems.insert( elem->GetID() );
4154 else { // all nodes of submesh elements
4155 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4156 while ( eIt->more() ) {
4157 const SMDS_MeshElement* anElem = eIt->next();
4158 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4159 while ( nIt->more() ) {
4160 const SMDS_MeshElement* elem = nIt->next();
4161 theElems.insert( elem->GetID() );
4166 aResult->length(theElems.size());
4167 set<int>::iterator itElem;
4169 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4170 aResult[i++] = *itElem;
4172 SMESH_CATCH( SMESH::throwCorbaException );
4174 return aResult._retn();
4177 //=============================================================================
4179 * Returns type of elements for given submesh
4181 //=============================================================================
4183 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4184 throw (SALOME::SALOME_Exception)
4186 SMESH::ElementType type;
4190 _preMeshInfo->FullLoadFromFile();
4192 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4193 if(!SM) return SMESH::ALL;
4195 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4196 if(!SDSM) return SMESH::ALL;
4198 if(SDSM->NbElements()==0)
4199 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4201 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4202 const SMDS_MeshElement* anElem = eIt->next();
4204 type = ( SMESH::ElementType ) anElem->GetType();
4206 SMESH_CATCH( SMESH::throwCorbaException );
4212 //=============================================================================
4214 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4216 //=============================================================================
4218 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4221 _preMeshInfo->FullLoadFromFile();
4223 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4225 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4230 //=============================================================================
4232 * Get XYZ coordinates of node as list of double
4233 * If there is not node for given ID - returns empty list
4235 //=============================================================================
4237 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4240 _preMeshInfo->FullLoadFromFile();
4242 SMESH::double_array_var aResult = new SMESH::double_array();
4243 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4244 if ( aSMESHDS_Mesh == NULL )
4245 return aResult._retn();
4248 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4250 return aResult._retn();
4254 aResult[0] = aNode->X();
4255 aResult[1] = aNode->Y();
4256 aResult[2] = aNode->Z();
4257 return aResult._retn();
4261 //=============================================================================
4263 * For given node returns list of IDs of inverse elements
4264 * If there is not node for given ID - returns empty list
4266 //=============================================================================
4268 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4271 _preMeshInfo->FullLoadFromFile();
4273 SMESH::long_array_var aResult = new SMESH::long_array();
4274 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4275 if ( aSMESHDS_Mesh == NULL )
4276 return aResult._retn();
4279 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4281 return aResult._retn();
4283 // find inverse elements
4284 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4285 aResult->length( aNode->NbInverseElements() );
4286 for( int i = 0; eIt->more(); ++i )
4288 const SMDS_MeshElement* elem = eIt->next();
4289 aResult[ i ] = elem->GetID();
4291 return aResult._retn();
4294 //=============================================================================
4296 * \brief Return position of a node on shape
4298 //=============================================================================
4300 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4303 _preMeshInfo->FullLoadFromFile();
4305 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4306 aNodePosition->shapeID = 0;
4307 aNodePosition->shapeType = GEOM::SHAPE;
4309 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4310 if ( !mesh ) return aNodePosition;
4312 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4314 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4316 aNodePosition->shapeID = aNode->getshapeId();
4317 switch ( pos->GetTypeOfPosition() ) {
4319 aNodePosition->shapeType = GEOM::EDGE;
4320 aNodePosition->params.length(1);
4321 aNodePosition->params[0] =
4322 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4325 aNodePosition->shapeType = GEOM::FACE;
4326 aNodePosition->params.length(2);
4327 aNodePosition->params[0] =
4328 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4329 aNodePosition->params[1] =
4330 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4332 case SMDS_TOP_VERTEX:
4333 aNodePosition->shapeType = GEOM::VERTEX;
4335 case SMDS_TOP_3DSPACE:
4336 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4337 aNodePosition->shapeType = GEOM::SOLID;
4338 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4339 aNodePosition->shapeType = GEOM::SHELL;
4345 return aNodePosition;
4348 //=============================================================================
4350 * \brief Return position of an element on shape
4352 //=============================================================================
4354 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4357 _preMeshInfo->FullLoadFromFile();
4359 SMESH::ElementPosition anElementPosition;
4360 anElementPosition.shapeID = 0;
4361 anElementPosition.shapeType = GEOM::SHAPE;
4363 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4364 if ( !mesh ) return anElementPosition;
4366 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4368 anElementPosition.shapeID = anElem->getshapeId();
4369 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4370 if ( !aSp.IsNull() ) {
4371 switch ( aSp.ShapeType() ) {
4373 anElementPosition.shapeType = GEOM::EDGE;
4376 anElementPosition.shapeType = GEOM::FACE;
4379 anElementPosition.shapeType = GEOM::VERTEX;
4382 anElementPosition.shapeType = GEOM::SOLID;
4385 anElementPosition.shapeType = GEOM::SHELL;
4391 return anElementPosition;
4394 //=============================================================================
4396 * If given element is node returns IDs of shape from position
4397 * If there is not node for given ID - returns -1
4399 //=============================================================================
4401 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4404 _preMeshInfo->FullLoadFromFile();
4406 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4407 if ( aSMESHDS_Mesh == NULL )
4411 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4413 return aNode->getshapeId();
4420 //=============================================================================
4422 * For given element returns ID of result shape after
4423 * ::FindShape() from SMESH_MeshEditor
4424 * If there is not element for given ID - returns -1
4426 //=============================================================================
4428 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4431 _preMeshInfo->FullLoadFromFile();
4433 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4434 if ( aSMESHDS_Mesh == NULL )
4437 // try to find element
4438 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4442 ::SMESH_MeshEditor aMeshEditor(_impl);
4443 int index = aMeshEditor.FindShape( elem );
4451 //=============================================================================
4453 * Returns number of nodes for given element
4454 * If there is not element for given ID - returns -1
4456 //=============================================================================
4458 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4461 _preMeshInfo->FullLoadFromFile();
4463 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4464 if ( aSMESHDS_Mesh == NULL ) return -1;
4465 // try to find element
4466 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4467 if(!elem) return -1;
4468 return elem->NbNodes();
4472 //=============================================================================
4474 * Returns ID of node by given index for given element
4475 * If there is not element for given ID - returns -1
4476 * If there is not node for given index - returns -2
4478 //=============================================================================
4480 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4483 _preMeshInfo->FullLoadFromFile();
4485 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4486 if ( aSMESHDS_Mesh == NULL ) return -1;
4487 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4488 if(!elem) return -1;
4489 if( index>=elem->NbNodes() || index<0 ) return -1;
4490 return elem->GetNode(index)->GetID();
4493 //=============================================================================
4495 * Returns IDs of nodes of given element
4497 //=============================================================================
4499 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4502 _preMeshInfo->FullLoadFromFile();
4504 SMESH::long_array_var aResult = new SMESH::long_array();
4505 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4507 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4509 aResult->length( elem->NbNodes() );
4510 for ( int i = 0; i < elem->NbNodes(); ++i )
4511 aResult[ i ] = elem->GetNode( i )->GetID();
4514 return aResult._retn();
4517 //=============================================================================
4519 * Returns true if given node is medium node
4520 * in given quadratic element
4522 //=============================================================================
4524 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4527 _preMeshInfo->FullLoadFromFile();
4529 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4530 if ( aSMESHDS_Mesh == NULL ) return false;
4532 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4533 if(!aNode) return false;
4534 // try to find element
4535 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4536 if(!elem) return false;
4538 return elem->IsMediumNode(aNode);
4542 //=============================================================================
4544 * Returns true if given node is medium node
4545 * in one of quadratic elements
4547 //=============================================================================
4549 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4550 SMESH::ElementType theElemType)
4553 _preMeshInfo->FullLoadFromFile();
4555 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4556 if ( aSMESHDS_Mesh == NULL ) return false;
4559 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4560 if(!aNode) return false;
4562 SMESH_MesherHelper aHelper( *(_impl) );
4564 SMDSAbs_ElementType aType;
4565 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4566 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4567 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4568 else aType = SMDSAbs_All;
4570 return aHelper.IsMedium(aNode,aType);
4574 //=============================================================================
4576 * Returns number of edges for given element
4578 //=============================================================================
4580 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4583 _preMeshInfo->FullLoadFromFile();
4585 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4586 if ( aSMESHDS_Mesh == NULL ) return -1;
4587 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4588 if(!elem) return -1;
4589 return elem->NbEdges();
4593 //=============================================================================
4595 * Returns number of faces for given element
4597 //=============================================================================
4599 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4602 _preMeshInfo->FullLoadFromFile();
4604 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4605 if ( aSMESHDS_Mesh == NULL ) return -1;
4606 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4607 if(!elem) return -1;
4608 return elem->NbFaces();
4611 //=======================================================================
4612 //function : GetElemFaceNodes
4613 //purpose : Returns nodes of given face (counted from zero) for given element.
4614 //=======================================================================
4616 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4617 CORBA::Short faceIndex)
4620 _preMeshInfo->FullLoadFromFile();
4622 SMESH::long_array_var aResult = new SMESH::long_array();
4623 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4625 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4627 SMDS_VolumeTool vtool( elem );
4628 if ( faceIndex < vtool.NbFaces() )
4630 aResult->length( vtool.NbFaceNodes( faceIndex ));
4631 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4632 for ( int i = 0; i < aResult->length(); ++i )
4633 aResult[ i ] = nn[ i ]->GetID();
4637 return aResult._retn();
4640 //=======================================================================
4641 //function : GetElemFaceNodes
4642 //purpose : Returns three components of normal of given mesh face.
4643 //=======================================================================
4645 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4646 CORBA::Boolean normalized)
4649 _preMeshInfo->FullLoadFromFile();
4651 SMESH::double_array_var aResult = new SMESH::double_array();
4653 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4656 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4658 aResult->length( 3 );
4659 aResult[ 0 ] = normal.X();
4660 aResult[ 1 ] = normal.Y();
4661 aResult[ 2 ] = normal.Z();
4664 return aResult._retn();
4667 //=======================================================================
4668 //function : FindElementByNodes
4669 //purpose : Returns an element based on all given nodes.
4670 //=======================================================================
4672 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4675 _preMeshInfo->FullLoadFromFile();
4677 CORBA::Long elemID(0);
4678 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4680 vector< const SMDS_MeshNode * > nn( nodes.length() );
4681 for ( int i = 0; i < nodes.length(); ++i )
4682 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4685 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4686 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4687 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4688 _impl->NbVolumes( ORDER_QUADRATIC )))
4689 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4691 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4696 //=============================================================================
4698 * Returns true if given element is polygon
4700 //=============================================================================
4702 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4705 _preMeshInfo->FullLoadFromFile();
4707 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4708 if ( aSMESHDS_Mesh == NULL ) return false;
4709 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4710 if(!elem) return false;
4711 return elem->IsPoly();
4715 //=============================================================================
4717 * Returns true if given element is quadratic
4719 //=============================================================================
4721 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4724 _preMeshInfo->FullLoadFromFile();
4726 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4727 if ( aSMESHDS_Mesh == NULL ) return false;
4728 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4729 if(!elem) return false;
4730 return elem->IsQuadratic();
4733 //=============================================================================
4735 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4737 //=============================================================================
4739 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4742 _preMeshInfo->FullLoadFromFile();
4744 if ( const SMDS_BallElement* ball =
4745 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4746 return ball->GetDiameter();
4751 //=============================================================================
4753 * Returns bary center for given element
4755 //=============================================================================
4757 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4760 _preMeshInfo->FullLoadFromFile();
4762 SMESH::double_array_var aResult = new SMESH::double_array();
4763 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4764 if ( aSMESHDS_Mesh == NULL )
4765 return aResult._retn();
4767 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4769 return aResult._retn();
4771 if(elem->GetType()==SMDSAbs_Volume) {
4772 SMDS_VolumeTool aTool;
4773 if(aTool.Set(elem)) {
4775 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4780 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4782 double x=0., y=0., z=0.;
4783 for(; anIt->more(); ) {
4785 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4799 return aResult._retn();
4802 //================================================================================
4804 * \brief Create a group of elements preventing computation of a sub-shape
4806 //================================================================================
4808 SMESH::ListOfGroups*
4809 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4810 const char* theGroupName )
4811 throw ( SALOME::SALOME_Exception )
4813 Unexpect aCatch(SALOME_SalomeException);
4815 if ( !theGroupName || strlen( theGroupName) == 0 )
4816 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4818 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4820 // submesh by subshape id
4821 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4822 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4825 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4826 if ( error && !error->myBadElements.empty())
4828 // sort bad elements by type
4829 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4830 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4831 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4832 for ( ; elemIt != elemEnd; ++elemIt )
4834 const SMDS_MeshElement* elem = *elemIt;
4835 if ( !elem ) continue;
4837 if ( elem->GetID() < 1 )
4839 // elem is a temporary element, make a real element
4840 vector< const SMDS_MeshNode* > nodes;
4841 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4842 while ( nIt->more() && elem )
4844 nodes.push_back( nIt->next() );
4845 if ( nodes.back()->GetID() < 1 )
4846 elem = 0; // a temporary element on temporary nodes
4850 ::SMESH_MeshEditor editor( _impl );
4851 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4855 elemsByType[ elem->GetType() ].push_back( elem );
4858 // how many groups to create?
4860 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4861 nbTypes += int( !elemsByType[ i ].empty() );
4862 groups->length( nbTypes );
4865 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4867 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4868 if ( elems.empty() ) continue;
4870 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4871 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4873 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4874 SMESH::SMESH_Mesh_var mesh = _this();
4875 SALOMEDS::SObject_wrap aSO =
4876 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4877 GEOM::GEOM_Object::_nil(), theGroupName);
4879 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4880 if ( !grp_i ) continue;
4882 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4883 for ( size_t iE = 0; iE < elems.size(); ++iE )
4884 grpDS->SMDSGroup().Add( elems[ iE ]);
4889 return groups._retn();
4892 //=============================================================================
4894 * Create and publish group servants if any groups were imported or created anyhow
4896 //=============================================================================
4898 void SMESH_Mesh_i::CreateGroupServants()
4900 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4901 SMESH::SMESH_Mesh_var aMesh = _this();
4904 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4905 while ( groupIt->more() )
4907 ::SMESH_Group* group = groupIt->next();
4908 int anId = group->GetGroupDS()->GetID();
4910 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4911 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4913 addedIDs.insert( anId );
4915 SMESH_GroupBase_i* aGroupImpl;
4917 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4918 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4920 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4921 shape = groupOnGeom->GetShape();
4924 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4927 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4928 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4929 aGroupImpl->Register();
4931 // register CORBA object for persistence
4932 int nextId = _gen_i->RegisterObject( groupVar );
4933 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4934 else { nextId = 0; } // avoid "unused variable" warning in release mode
4936 // publishing the groups in the study
4937 if ( !aStudy->_is_nil() ) {
4938 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4939 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4942 if ( !addedIDs.empty() )
4945 set<int>::iterator id = addedIDs.begin();
4946 for ( ; id != addedIDs.end(); ++id )
4948 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4949 int i = std::distance( _mapGroups.begin(), it );
4950 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4955 //=============================================================================
4957 * \brief Return groups cantained in _mapGroups by their IDs
4959 //=============================================================================
4961 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4963 int nbGroups = groupIDs.size();
4964 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4965 aList->length( nbGroups );
4967 list<int>::const_iterator ids = groupIDs.begin();
4968 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4970 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4971 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4972 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4974 aList->length( nbGroups );
4975 return aList._retn();
4978 //=============================================================================
4980 * \brief Return information about imported file
4982 //=============================================================================
4984 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4986 SMESH::MedFileInfo_var res( _medFileInfo );
4987 if ( !res.operator->() ) {
4988 res = new SMESH::MedFileInfo;
4990 res->fileSize = res->major = res->minor = res->release = -1;
4995 //=============================================================================
4997 * \brief Pass names of mesh groups from study to mesh DS
4999 //=============================================================================
5001 void SMESH_Mesh_i::checkGroupNames()
5003 int nbGrp = NbGroups();
5007 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5008 if ( aStudy->_is_nil() )
5009 return; // nothing to do
5011 SMESH::ListOfGroups* grpList = 0;
5012 // avoid dump of "GetGroups"
5014 // store python dump into a local variable inside local scope
5015 SMESH::TPythonDump pDump; // do not delete this line of code
5016 grpList = GetGroups();
5019 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5020 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5023 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5024 if ( aGrpSO->_is_nil() )
5026 // correct name of the mesh group if necessary
5027 const char* guiName = aGrpSO->GetName();
5028 if ( strcmp(guiName, aGrp->GetName()) )
5029 aGrp->SetName( guiName );
5033 //=============================================================================
5035 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5037 //=============================================================================
5038 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5040 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5044 //=============================================================================
5046 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5048 //=============================================================================
5050 char* SMESH_Mesh_i::GetParameters()
5052 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5055 //=============================================================================
5057 * \brief Returns list of notebook variables used for last Mesh operation
5059 //=============================================================================
5060 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5062 SMESH::string_array_var aResult = new SMESH::string_array();
5063 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5065 CORBA::String_var aParameters = GetParameters();
5066 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5067 if ( !aStudy->_is_nil()) {
5068 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5069 if(aSections->length() > 0) {
5070 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
5071 aResult->length(aVars.length());
5072 for(int i = 0;i < aVars.length();i++)
5073 aResult[i] = CORBA::string_dup( aVars[i]);
5077 return aResult._retn();
5080 //=======================================================================
5081 //function : GetTypes
5082 //purpose : Returns types of elements it contains
5083 //=======================================================================
5085 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5088 return _preMeshInfo->GetTypes();
5090 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5094 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5095 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5096 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5097 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5098 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5099 types->length( nbTypes );
5101 return types._retn();
5104 //=======================================================================
5105 //function : GetMesh
5106 //purpose : Returns self
5107 //=======================================================================
5109 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5111 return SMESH::SMESH_Mesh::_duplicate( _this() );
5114 //=======================================================================
5115 //function : IsMeshInfoCorrect
5116 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5117 // * happen if mesh data is not yet fully loaded from the file of study.
5118 //=======================================================================
5120 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5122 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5125 //=============================================================================
5127 * \brief Returns number of mesh elements per each \a EntityType
5129 //=============================================================================
5131 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5134 return _preMeshInfo->GetMeshInfo();
5136 SMESH::long_array_var aRes = new SMESH::long_array();
5137 aRes->length(SMESH::Entity_Last);
5138 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5140 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5142 return aRes._retn();
5143 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5144 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5145 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5146 return aRes._retn();
5149 //=============================================================================
5151 * \brief Returns number of mesh elements per each \a ElementType
5153 //=============================================================================
5155 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5157 SMESH::long_array_var aRes = new SMESH::long_array();
5158 aRes->length(SMESH::NB_ELEMENT_TYPES);
5159 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5162 const SMDS_MeshInfo* meshInfo = 0;
5164 meshInfo = _preMeshInfo;
5165 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5166 meshInfo = & meshDS->GetMeshInfo();
5169 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5170 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5172 return aRes._retn();
5175 //=============================================================================
5177 * Collect statistic of mesh elements given by iterator
5179 //=============================================================================
5181 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5182 SMESH::long_array& theInfo)
5184 if (!theItr) return;
5185 while (theItr->more())
5186 theInfo[ theItr->next()->GetEntityType() ]++;
5188 //=============================================================================
5190 * Returns mesh unstructed grid information.
5192 //=============================================================================
5194 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5196 SALOMEDS::TMPFile_var SeqFile;
5197 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5198 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5200 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5201 aWriter->WriteToOutputStringOn();
5202 aWriter->SetInputData(aGrid);
5203 aWriter->SetFileTypeToBinary();
5205 char* str = aWriter->GetOutputString();
5206 int size = aWriter->GetOutputStringLength();
5208 //Allocate octect buffer of required size
5209 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5210 //Copy ostrstream content to the octect buffer
5211 memcpy(OctetBuf, str, size);
5212 //Create and return TMPFile
5213 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5217 return SeqFile._retn();
5220 //=============================================================================
5221 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5222 * SMESH::ElementType type) */
5224 using namespace SMESH::Controls;
5225 //-----------------------------------------------------------------------------
5226 struct PredicateIterator : public SMDS_ElemIterator
5228 SMDS_ElemIteratorPtr _elemIter;
5229 PredicatePtr _predicate;
5230 const SMDS_MeshElement* _elem;
5232 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5233 PredicatePtr predicate):
5234 _elemIter(iterator), _predicate(predicate)
5242 virtual const SMDS_MeshElement* next()
5244 const SMDS_MeshElement* res = _elem;
5246 while ( _elemIter->more() && !_elem )
5248 _elem = _elemIter->next();
5249 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5256 //-----------------------------------------------------------------------------
5257 struct IDSourceIterator : public SMDS_ElemIterator
5259 const CORBA::Long* _idPtr;
5260 const CORBA::Long* _idEndPtr;
5261 SMESH::long_array_var _idArray;
5262 const SMDS_Mesh* _mesh;
5263 const SMDSAbs_ElementType _type;
5264 const SMDS_MeshElement* _elem;
5266 IDSourceIterator( const SMDS_Mesh* mesh,
5267 const CORBA::Long* ids,
5269 SMDSAbs_ElementType type):
5270 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5272 if ( _idPtr && nbIds && _mesh )
5275 IDSourceIterator( const SMDS_Mesh* mesh,
5276 SMESH::long_array* idArray,
5277 SMDSAbs_ElementType type):
5278 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5280 if ( idArray && _mesh )
5282 _idPtr = &_idArray[0];
5283 _idEndPtr = _idPtr + _idArray->length();
5291 virtual const SMDS_MeshElement* next()
5293 const SMDS_MeshElement* res = _elem;
5295 while ( _idPtr < _idEndPtr && !_elem )
5297 if ( _type == SMDSAbs_Node )
5299 _elem = _mesh->FindNode( *_idPtr++ );
5301 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5302 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5310 //-----------------------------------------------------------------------------
5312 struct NodeOfElemIterator : public SMDS_ElemIterator
5314 TColStd_MapOfInteger _checkedNodeIDs;
5315 SMDS_ElemIteratorPtr _elemIter;
5316 SMDS_ElemIteratorPtr _nodeIter;
5317 const SMDS_MeshElement* _node;
5319 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5321 if ( _elemIter && _elemIter->more() )
5323 _nodeIter = _elemIter->next()->nodesIterator();
5331 virtual const SMDS_MeshElement* next()
5333 const SMDS_MeshElement* res = _node;
5335 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5337 if ( _nodeIter->more() )
5339 _node = _nodeIter->next();
5340 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5345 _nodeIter = _elemIter->next()->nodesIterator();
5353 //=============================================================================
5355 * Return iterator on elements of given type in given object
5357 //=============================================================================
5359 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5360 SMESH::ElementType theType)
5362 SMDS_ElemIteratorPtr elemIt;
5363 bool typeOK = false;
5364 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5366 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5367 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5368 if ( !mesh_i ) return elemIt;
5369 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5371 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5373 elemIt = meshDS->elementsIterator( elemType );
5376 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5378 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5381 elemIt = sm->GetElements();
5382 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5384 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5385 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5389 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5391 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5392 if ( groupDS && ( elemType == groupDS->GetType() ||
5393 elemType == SMDSAbs_Node ||
5394 elemType == SMDSAbs_All ))
5396 elemIt = groupDS->GetElements();
5397 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5400 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5402 if ( filter_i->GetElementType() == theType ||
5403 elemType == SMDSAbs_Node ||
5404 elemType == SMDSAbs_All)
5406 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5407 if ( pred_i && pred_i->GetPredicate() )
5409 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5410 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5411 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5412 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5418 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5419 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5420 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5422 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5425 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5426 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5430 SMESH::long_array_var ids = theObject->GetIDs();
5431 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5433 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5436 if ( elemIt && elemIt->more() && !typeOK )
5438 if ( elemType == SMDSAbs_Node )
5440 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5444 elemIt = SMDS_ElemIteratorPtr();
5450 //=============================================================================
5451 namespace // Finding concurrent hypotheses
5452 //=============================================================================
5456 * \brief mapping of mesh dimension into shape type
5458 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5460 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5462 case 0: aType = TopAbs_VERTEX; break;
5463 case 1: aType = TopAbs_EDGE; break;
5464 case 2: aType = TopAbs_FACE; break;
5466 default:aType = TopAbs_SOLID; break;
5471 //-----------------------------------------------------------------------------
5473 * \brief Internal structure used to find concurent submeshes
5475 * It represents a pair < submesh, concurent dimension >, where
5476 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5477 * with another submesh. In other words, it is dimension of a hypothesis assigned
5484 int _dim; //!< a dimension the algo can build (concurrent dimension)
5485 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5486 TopTools_MapOfShape _shapeMap;
5487 SMESH_subMesh* _subMesh;
5488 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5490 //-----------------------------------------------------------------------------
5491 // Return the algorithm
5492 const SMESH_Algo* GetAlgo() const
5493 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5495 //-----------------------------------------------------------------------------
5497 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5499 const TopoDS_Shape& theShape)
5501 _subMesh = (SMESH_subMesh*)theSubMesh;
5502 SetShape( theDim, theShape );
5505 //-----------------------------------------------------------------------------
5507 void SetShape(const int theDim,
5508 const TopoDS_Shape& theShape)
5511 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5512 if (_dim >= _ownDim)
5513 _shapeMap.Add( theShape );
5515 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5516 for( ; anExp.More(); anExp.Next() )
5517 _shapeMap.Add( anExp.Current() );
5521 //-----------------------------------------------------------------------------
5522 //! Check sharing of sub-shapes
5523 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5524 const TopTools_MapOfShape& theToFind,
5525 const TopAbs_ShapeEnum theType)
5527 bool isShared = false;
5528 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5529 for (; !isShared && anItr.More(); anItr.Next() )
5531 const TopoDS_Shape aSubSh = anItr.Key();
5532 // check for case when concurrent dimensions are same
5533 isShared = theToFind.Contains( aSubSh );
5534 // check for sub-shape with concurrent dimension
5535 TopExp_Explorer anExp( aSubSh, theType );
5536 for ( ; !isShared && anExp.More(); anExp.Next() )
5537 isShared = theToFind.Contains( anExp.Current() );
5542 //-----------------------------------------------------------------------------
5543 //! check algorithms
5544 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5545 const SMESHDS_Hypothesis* theA2)
5547 if ( !theA1 || !theA2 ||
5548 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5549 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5550 return false; // one of the hypothesis is not algorithm
5551 // check algorithm names (should be equal)
5552 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5556 //-----------------------------------------------------------------------------
5557 //! Check if sub-shape hypotheses are concurrent
5558 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5560 if ( _subMesh == theOther->_subMesh )
5561 return false; // same sub-shape - should not be
5563 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5564 // any of the two submeshes is not on COMPOUND shape )
5565 // -> no concurrency
5566 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5567 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5568 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5569 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5570 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5573 // bool checkSubShape = ( _dim >= theOther->_dim )
5574 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5575 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5576 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5577 if ( !checkSubShape )
5580 // check algorithms to be same
5581 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5582 return true; // different algorithms -> concurrency !
5584 // check hypothesises for concurrence (skip first as algorithm)
5586 // pointers should be same, because it is referened from mesh hypothesis partition
5587 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5588 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5589 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5590 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5592 // the submeshes are concurrent if their algorithms has different parameters
5593 return nbSame != theOther->_hypotheses.size() - 1;
5596 // Return true if algorithm of this SMESH_DimHyp is used if no
5597 // sub-mesh order is imposed by the user
5598 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5600 // NeedDiscreteBoundary() algo has a higher priority
5601 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5602 theOther->GetAlgo()->NeedDiscreteBoundary() )
5603 return !this->GetAlgo()->NeedDiscreteBoundary();
5605 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5608 }; // end of SMESH_DimHyp
5609 //-----------------------------------------------------------------------------
5611 typedef list<const SMESH_DimHyp*> TDimHypList;
5613 //-----------------------------------------------------------------------------
5615 void addDimHypInstance(const int theDim,
5616 const TopoDS_Shape& theShape,
5617 const SMESH_Algo* theAlgo,
5618 const SMESH_subMesh* theSubMesh,
5619 const list <const SMESHDS_Hypothesis*>& theHypList,
5620 TDimHypList* theDimHypListArr )
5622 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5623 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5624 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5625 dimHyp->_hypotheses.push_front(theAlgo);
5626 listOfdimHyp.push_back( dimHyp );
5629 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5630 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5631 theHypList.begin(), theHypList.end() );
5634 //-----------------------------------------------------------------------------
5635 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5636 TDimHypList& theListOfConcurr)
5638 if ( theListOfConcurr.empty() )
5640 theListOfConcurr.push_back( theDimHyp );
5644 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5645 while ( hypIt != theListOfConcurr.end() &&
5646 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5648 theListOfConcurr.insert( hypIt, theDimHyp );
5652 //-----------------------------------------------------------------------------
5653 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5654 const TDimHypList& theListOfDimHyp,
5655 TDimHypList& theListOfConcurrHyp,
5656 set<int>& theSetOfConcurrId )
5658 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5659 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5661 const SMESH_DimHyp* curDimHyp = *rIt;
5662 if ( curDimHyp == theDimHyp )
5663 break; // meet own dimHyp pointer in same dimension
5665 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5666 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5668 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5673 //-----------------------------------------------------------------------------
5674 void unionLists(TListOfInt& theListOfId,
5675 TListOfListOfInt& theListOfListOfId,
5678 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5679 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5681 continue; //skip already treated lists
5682 // check if other list has any same submesh object
5683 TListOfInt& otherListOfId = *it;
5684 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5685 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5688 // union two lists (from source into target)
5689 TListOfInt::iterator it2 = otherListOfId.begin();
5690 for ( ; it2 != otherListOfId.end(); it2++ ) {
5691 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5692 theListOfId.push_back(*it2);
5694 // clear source list
5695 otherListOfId.clear();
5698 //-----------------------------------------------------------------------------
5700 //! free memory allocated for dimension-hypothesis objects
5701 void removeDimHyps( TDimHypList* theArrOfList )
5703 for (int i = 0; i < 4; i++ ) {
5704 TDimHypList& listOfdimHyp = theArrOfList[i];
5705 TDimHypList::const_iterator it = listOfdimHyp.begin();
5706 for ( ; it != listOfdimHyp.end(); it++ )
5711 //-----------------------------------------------------------------------------
5713 * \brief find common submeshes with given submesh
5714 * \param theSubMeshList list of already collected submesh to check
5715 * \param theSubMesh given submesh to intersect with other
5716 * \param theCommonSubMeshes collected common submeshes
5718 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5719 const SMESH_subMesh* theSubMesh,
5720 set<const SMESH_subMesh*>& theCommon )
5724 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5725 for ( ; it != theSubMeshList.end(); it++ )
5726 theSubMesh->FindIntersection( *it, theCommon );
5727 theSubMeshList.push_back( theSubMesh );
5728 //theCommon.insert( theSubMesh );
5731 //-----------------------------------------------------------------------------
5732 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5734 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5735 for ( ; listsIt != smLists.end(); ++listsIt )
5737 const TListOfInt& smIDs = *listsIt;
5738 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5746 //=============================================================================
5748 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5750 //=============================================================================
5752 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5754 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5755 if ( isSubMeshInList( submeshID, anOrder ))
5758 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5759 return isSubMeshInList( submeshID, allConurrent );
5762 //=============================================================================
5764 * \brief Return submesh objects list in meshing order
5766 //=============================================================================
5768 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5770 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5772 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5774 return aResult._retn();
5776 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5777 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5778 anOrder.splice( anOrder.end(), allConurrent );
5781 TListOfListOfInt::iterator listIt = anOrder.begin();
5782 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5783 unionLists( *listIt, anOrder, listIndx + 1 );
5785 // convert submesh ids into interface instances
5786 // and dump command into python
5787 convertMeshOrder( anOrder, aResult, false );
5789 return aResult._retn();
5792 //=============================================================================
5794 * \brief Finds concurrent sub-meshes
5796 //=============================================================================
5798 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5800 TListOfListOfInt anOrder;
5801 ::SMESH_Mesh& mesh = GetImpl();
5803 // collect submeshes and detect concurrent algorithms and hypothesises
5804 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5806 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5807 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5808 ::SMESH_subMesh* sm = (*i_sm).second;
5810 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5812 // list of assigned hypothesises
5813 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5814 // Find out dimensions where the submesh can be concurrent.
5815 // We define the dimensions by algo of each of hypotheses in hypList
5816 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5817 for( ; hypIt != hypList.end(); hypIt++ ) {
5818 SMESH_Algo* anAlgo = 0;
5819 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5820 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5821 // hyp it-self is algo
5822 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5824 // try to find algorithm with help of sub-shapes
5825 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5826 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5827 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5830 continue; // no algorithm assigned to a current submesh
5832 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5833 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5835 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5836 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5837 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5839 } // end iterations on submesh
5841 // iterate on created dimension-hypotheses and check for concurrents
5842 for ( int i = 0; i < 4; i++ ) {
5843 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5844 // check for concurrents in own and other dimensions (step-by-step)
5845 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5846 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5847 const SMESH_DimHyp* dimHyp = *dhIt;
5848 TDimHypList listOfConcurr;
5849 set<int> setOfConcurrIds;
5850 // looking for concurrents and collect into own list
5851 for ( int j = i; j < 4; j++ )
5852 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5853 // check if any concurrents found
5854 if ( listOfConcurr.size() > 0 ) {
5855 // add own submesh to list of concurrent
5856 addInOrderOfPriority( dimHyp, listOfConcurr );
5857 list<int> listOfConcurrIds;
5858 TDimHypList::iterator hypIt = listOfConcurr.begin();
5859 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5860 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5861 anOrder.push_back( listOfConcurrIds );
5866 removeDimHyps(dimHypListArr);
5868 // now, minimise the number of concurrent groups
5869 // Here we assume that lists of submeshes can have same submesh
5870 // in case of multi-dimension algorithms, as result
5871 // list with common submesh has to be united into one list
5873 TListOfListOfInt::iterator listIt = anOrder.begin();
5874 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5875 unionLists( *listIt, anOrder, listIndx + 1 );
5881 //=============================================================================
5883 * \brief Set submesh object order
5884 * \param theSubMeshArray submesh array order
5886 //=============================================================================
5888 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5891 _preMeshInfo->ForgetOrLoad();
5894 ::SMESH_Mesh& mesh = GetImpl();
5896 TPythonDump aPythonDump; // prevent dump of called methods
5897 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5899 TListOfListOfInt subMeshOrder;
5900 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5902 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5903 TListOfInt subMeshIds;
5905 aPythonDump << ", ";
5906 aPythonDump << "[ ";
5907 // Collect subMeshes which should be clear
5908 // do it list-by-list, because modification of submesh order
5909 // take effect between concurrent submeshes only
5910 set<const SMESH_subMesh*> subMeshToClear;
5911 list<const SMESH_subMesh*> subMeshList;
5912 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5914 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5916 aPythonDump << ", ";
5917 aPythonDump << subMesh;
5918 subMeshIds.push_back( subMesh->GetId() );
5919 // detect common parts of submeshes
5920 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5921 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5923 aPythonDump << " ]";
5924 subMeshOrder.push_back( subMeshIds );
5926 // clear collected submeshes
5927 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5928 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5929 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5930 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5932 aPythonDump << " ])";
5934 mesh.SetMeshOrder( subMeshOrder );
5940 //=============================================================================
5942 * \brief Convert submesh ids into submesh interfaces
5944 //=============================================================================
5946 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5947 SMESH::submesh_array_array& theResOrder,
5948 const bool theIsDump)
5950 int nbSet = theIdsOrder.size();
5951 TPythonDump aPythonDump; // prevent dump of called methods
5953 aPythonDump << "[ ";
5954 theResOrder.length(nbSet);
5955 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5957 for( ; it != theIdsOrder.end(); it++ ) {
5958 // translate submesh identificators into submesh objects
5959 // takeing into account real number of concurrent lists
5960 const TListOfInt& aSubOrder = (*it);
5961 if (!aSubOrder.size())
5964 aPythonDump << "[ ";
5965 // convert shape indeces into interfaces
5966 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5967 aResSubSet->length(aSubOrder.size());
5968 TListOfInt::const_iterator subIt = aSubOrder.begin();
5970 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5971 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5973 SMESH::SMESH_subMesh_var subMesh =
5974 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5977 aPythonDump << ", ";
5978 aPythonDump << subMesh;
5980 aResSubSet[ j++ ] = subMesh;
5983 aPythonDump << " ]";
5985 theResOrder[ listIndx++ ] = aResSubSet;
5987 // correct number of lists
5988 theResOrder.length( listIndx );
5991 // finilise python dump
5992 aPythonDump << " ]";
5993 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5997 //================================================================================
5999 // Implementation of SMESH_MeshPartDS
6001 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6002 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6004 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6005 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6007 _meshDS = mesh_i->GetImpl().GetMeshDS();
6009 SetPersistentId( _meshDS->GetPersistentId() );
6011 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6013 // <meshPart> is the whole mesh
6014 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6016 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6017 myGroupSet = _meshDS->GetGroups();
6022 SMESH::long_array_var anIDs = meshPart->GetIDs();
6023 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6024 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6026 for (int i=0; i < anIDs->length(); i++)
6027 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
6028 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6033 for (int i=0; i < anIDs->length(); i++)
6034 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6035 if ( _elements[ e->GetType() ].insert( e ).second )
6038 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6039 while ( nIt->more() )
6041 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6042 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6049 ShapeToMesh( _meshDS->ShapeToMesh() );
6051 _meshDS = 0; // to enforce iteration on _elements and _nodes
6054 // -------------------------------------------------------------------------------------
6055 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6056 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6059 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6060 for ( ; partIt != meshPart.end(); ++partIt )
6061 if ( const SMDS_MeshElement * e = *partIt )
6062 if ( _elements[ e->GetType() ].insert( e ).second )
6065 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6066 while ( nIt->more() )
6068 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6069 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6075 // -------------------------------------------------------------------------------------
6076 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6078 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6080 typedef SMDS_SetIterator
6081 <const SMDS_MeshElement*,
6082 TIDSortedElemSet::const_iterator,
6083 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6084 SMDS_MeshElement::GeomFilter
6087 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6089 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6090 _elements[type].end(),
6091 SMDS_MeshElement::GeomFilter( geomType )));
6093 // -------------------------------------------------------------------------------------
6094 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6096 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6098 typedef SMDS_SetIterator
6099 <const SMDS_MeshElement*,
6100 TIDSortedElemSet::const_iterator,
6101 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6102 SMDS_MeshElement::EntityFilter
6105 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6107 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6108 _elements[type].end(),
6109 SMDS_MeshElement::EntityFilter( entity )));
6111 // -------------------------------------------------------------------------------------
6112 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6114 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6115 if ( type == SMDSAbs_All && !_meshDS )
6117 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6119 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6120 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6122 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6124 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6125 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6127 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6128 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6130 // -------------------------------------------------------------------------------------
6131 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6132 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6134 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6135 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6136 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6138 // -------------------------------------------------------------------------------------
6139 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6140 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6141 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6142 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6143 #undef _GET_ITER_DEFINE
6145 // END Implementation of SMESH_MeshPartDS
6147 //================================================================================