1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 #include <vtkUnstructuredGridWriter.h>
84 // to pass CORBA exception through SMESH_TRY
85 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
87 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
90 static int MYDEBUG = 0;
92 static int MYDEBUG = 0;
96 using SMESH::TPythonDump;
98 int SMESH_Mesh_i::_idGenerator = 0;
100 //=============================================================================
104 //=============================================================================
106 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
108 CORBA::Long studyId )
109 : SALOME::GenericObj_i( thePOA )
111 MESSAGE("SMESH_Mesh_i");
114 _id = _idGenerator++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
130 MESSAGE("~SMESH_Mesh_i");
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 aGroup->UnRegister();
138 SMESH::SMESH_GroupBase_var( itGr->second );
143 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
144 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
145 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
147 aSubMesh->UnRegister();
148 SMESH::SMESH_subMesh_var( itSM->second );
150 _mapSubMeshIor.clear();
152 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
156 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
157 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
160 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
164 // clear cashed shapes if no more meshes remain; (the cash is blame,
165 // together with publishing, of spent time increasing in issue 22874)
166 if ( _impl->NbMeshes() == 1 )
167 _gen_i->GetShapeReader()->ClearClientBuffer();
169 delete _editor; _editor = NULL;
170 delete _previewEditor; _previewEditor = NULL;
171 delete _impl; _impl = NULL;
172 delete _preMeshInfo; _preMeshInfo = NULL;
175 //=============================================================================
179 * Associates <this> mesh with <theShape> and puts a reference
180 * to <theShape> into the current study;
181 * the previous shape is substituted by the new one.
183 //=============================================================================
185 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
186 throw (SALOME::SALOME_Exception)
188 Unexpect aCatch(SALOME_SalomeException);
190 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
192 catch(SALOME_Exception & S_ex) {
193 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
195 // to track changes of GEOM groups
196 SMESH::SMESH_Mesh_var mesh = _this();
197 addGeomGroupData( theShapeObject, mesh );
198 if ( !CORBA::is_nil( theShapeObject ))
199 _mainShapeTick = theShapeObject->GetTick();
202 //================================================================================
204 * \brief return true if mesh has a shape to build a shape on
206 //================================================================================
208 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
209 throw (SALOME::SALOME_Exception)
211 Unexpect aCatch(SALOME_SalomeException);
214 res = _impl->HasShapeToMesh();
216 catch(SALOME_Exception & S_ex) {
217 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
222 //=======================================================================
223 //function : GetShapeToMesh
225 //=======================================================================
227 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
228 throw (SALOME::SALOME_Exception)
230 Unexpect aCatch(SALOME_SalomeException);
231 GEOM::GEOM_Object_var aShapeObj;
233 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
237 catch(SALOME_Exception & S_ex) {
238 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
240 return aShapeObj._retn();
243 //================================================================================
245 * \brief Return false if the mesh is not yet fully loaded from the study file
247 //================================================================================
249 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
251 Unexpect aCatch(SALOME_SalomeException);
252 return !_preMeshInfo;
255 //================================================================================
257 * \brief Load full mesh data from the study file
259 //================================================================================
261 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
263 Unexpect aCatch(SALOME_SalomeException);
265 _preMeshInfo->FullLoadFromFile();
268 //================================================================================
270 * \brief Remove all nodes and elements
272 //================================================================================
274 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
276 Unexpect aCatch(SALOME_SalomeException);
278 _preMeshInfo->ForgetAllData();
282 //CheckGeomGroupModif(); // issue 20145
284 catch(SALOME_Exception & S_ex) {
285 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
287 _impl->GetMeshDS()->Modified();
289 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
292 //================================================================================
294 * \brief Remove all nodes and elements for indicated shape
296 //================================================================================
298 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
299 throw (SALOME::SALOME_Exception)
301 Unexpect aCatch(SALOME_SalomeException);
303 _preMeshInfo->FullLoadFromFile();
306 _impl->ClearSubMesh( ShapeID );
308 catch(SALOME_Exception & S_ex) {
309 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
311 _impl->GetMeshDS()->Modified();
313 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
316 //=============================================================================
318 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
320 //=============================================================================
322 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
324 SMESH::DriverMED_ReadStatus res;
327 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
328 res = SMESH::DRS_OK; break;
329 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
330 res = SMESH::DRS_EMPTY; break;
331 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
332 res = SMESH::DRS_WARN_RENUMBER; break;
333 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
334 res = SMESH::DRS_WARN_SKIP_ELEM; break;
335 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
336 res = SMESH::DRS_WARN_DESCENDING; break;
337 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
339 res = SMESH::DRS_FAIL; break;
344 //=============================================================================
346 * Convert ::SMESH_ComputeError to SMESH::ComputeError
348 //=============================================================================
350 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
352 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
353 errVar->subShapeID = -1;
354 errVar->hasBadMesh = false;
356 if ( !errorPtr || errorPtr->IsOK() )
358 errVar->code = SMESH::COMPERR_OK;
362 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
363 errVar->comment = errorPtr->myComment.c_str();
365 return errVar._retn();
368 //=============================================================================
372 * Imports mesh data from MED file
374 //=============================================================================
376 SMESH::DriverMED_ReadStatus
377 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
378 throw ( SALOME::SALOME_Exception )
380 Unexpect aCatch(SALOME_SalomeException);
383 status = _impl->MEDToMesh( theFileName, theMeshName );
385 catch( SALOME_Exception& S_ex ) {
386 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
389 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
392 CreateGroupServants();
394 int major, minor, release;
395 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
396 major = minor = release = -1;
397 _medFileInfo = new SMESH::MedFileInfo();
398 _medFileInfo->fileName = theFileName;
399 _medFileInfo->fileSize = 0;
400 _medFileInfo->major = major;
401 _medFileInfo->minor = minor;
402 _medFileInfo->release = release;
403 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
405 return ConvertDriverMEDReadStatus(status);
408 //================================================================================
410 * \brief Imports mesh data from the CGNS file
412 //================================================================================
414 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
415 const int theMeshIndex,
416 std::string& theMeshName )
417 throw ( SALOME::SALOME_Exception )
419 Unexpect aCatch(SALOME_SalomeException);
422 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
424 catch( SALOME_Exception& S_ex ) {
425 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
428 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
431 CreateGroupServants();
433 return ConvertDriverMEDReadStatus(status);
436 //================================================================================
438 * \brief Return string representation of a MED file version comprising nbDigits
440 //================================================================================
442 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
444 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
446 return CORBA::string_dup( ver.c_str() );
449 //=============================================================================
453 * Imports mesh data from MED file
455 //=============================================================================
457 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
458 throw ( SALOME::SALOME_Exception )
462 // Read mesh with name = <theMeshName> into SMESH_Mesh
463 _impl->UNVToMesh( theFileName );
465 CreateGroupServants();
467 SMESH_CATCH( SMESH::throwCorbaException );
472 //=============================================================================
476 * Imports mesh data from STL file
478 //=============================================================================
479 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
480 throw ( SALOME::SALOME_Exception )
484 // Read mesh with name = <theMeshName> into SMESH_Mesh
485 _impl->STLToMesh( theFileName );
487 SMESH_CATCH( SMESH::throwCorbaException );
492 //================================================================================
494 * \brief Function used in SMESH_CATCH by ImportGMFFile()
496 //================================================================================
500 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
502 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
506 //================================================================================
508 * \brief Imports data from a GMF file and returns an error description
510 //================================================================================
512 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
513 bool theMakeRequiredGroups )
514 throw (SALOME::SALOME_Exception)
516 SMESH_ComputeErrorPtr error;
519 #define SMESH_CAUGHT error =
522 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
524 SMESH_CATCH( exceptionToComputeError );
528 CreateGroupServants();
530 return ConvertComputeError( error );
533 //=============================================================================
537 //=============================================================================
539 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
541 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
542 (SMESH_Hypothesis::Hypothesis_Status theStatus)
545 RETURNCASE( HYP_OK );
546 RETURNCASE( HYP_MISSING );
547 RETURNCASE( HYP_CONCURENT );
548 RETURNCASE( HYP_BAD_PARAMETER );
549 RETURNCASE( HYP_HIDDEN_ALGO );
550 RETURNCASE( HYP_HIDING_ALGO );
551 RETURNCASE( HYP_UNKNOWN_FATAL );
552 RETURNCASE( HYP_INCOMPATIBLE );
553 RETURNCASE( HYP_NOTCONFORM );
554 RETURNCASE( HYP_ALREADY_EXIST );
555 RETURNCASE( HYP_BAD_DIM );
556 RETURNCASE( HYP_BAD_SUBSHAPE );
557 RETURNCASE( HYP_BAD_GEOMETRY );
558 RETURNCASE( HYP_NEED_SHAPE );
559 RETURNCASE( HYP_INCOMPAT_HYPS );
562 return SMESH::HYP_UNKNOWN_FATAL;
565 //=============================================================================
569 * calls internal addHypothesis() and then adds a reference to <anHyp> under
570 * the SObject actually having a reference to <aSubShape>.
571 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
573 //=============================================================================
575 SMESH::Hypothesis_Status
576 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
577 SMESH::SMESH_Hypothesis_ptr anHyp,
578 CORBA::String_out anErrorText)
579 throw(SALOME::SALOME_Exception)
581 Unexpect aCatch(SALOME_SalomeException);
583 _preMeshInfo->ForgetOrLoad();
586 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
587 anErrorText = error.c_str();
589 SMESH::SMESH_Mesh_var mesh( _this() );
590 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
592 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
593 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
595 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
597 // Update Python script
598 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
599 << aSubShape << ", " << anHyp << " )";
601 return ConvertHypothesisStatus(status);
604 //=============================================================================
608 //=============================================================================
610 SMESH_Hypothesis::Hypothesis_Status
611 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
612 SMESH::SMESH_Hypothesis_ptr anHyp,
613 std::string* anErrorText)
615 if(MYDEBUG) MESSAGE("addHypothesis");
617 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
618 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
620 if (CORBA::is_nil( anHyp ))
621 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
623 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
626 TopoDS_Shape myLocSubShape;
627 //use PseudoShape in case if mesh has no shape
629 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
631 myLocSubShape = _impl->GetShapeToMesh();
633 const int hypId = anHyp->GetId();
635 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
636 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
638 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
640 // assure there is a corresponding submesh
641 if ( !_impl->IsMainShape( myLocSubShape )) {
642 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
643 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
644 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
647 else if ( anErrorText )
649 *anErrorText = error;
652 catch(SALOME_Exception & S_ex)
654 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
659 //=============================================================================
663 //=============================================================================
665 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
666 SMESH::SMESH_Hypothesis_ptr anHyp)
667 throw(SALOME::SALOME_Exception)
669 Unexpect aCatch(SALOME_SalomeException);
671 _preMeshInfo->ForgetOrLoad();
673 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
674 SMESH::SMESH_Mesh_var mesh = _this();
676 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
678 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
679 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
681 // Update Python script
682 if(_impl->HasShapeToMesh())
683 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
684 << aSubShape << ", " << anHyp << " )";
686 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
689 return ConvertHypothesisStatus(status);
692 //=============================================================================
696 //=============================================================================
698 SMESH_Hypothesis::Hypothesis_Status
699 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
700 SMESH::SMESH_Hypothesis_ptr anHyp)
702 if(MYDEBUG) MESSAGE("removeHypothesis()");
704 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
705 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
707 if (CORBA::is_nil( anHyp ))
708 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
710 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
713 TopoDS_Shape myLocSubShape;
714 //use PseudoShape in case if mesh has no shape
715 if( _impl->HasShapeToMesh() )
716 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
718 myLocSubShape = _impl->GetShapeToMesh();
720 const int hypId = anHyp->GetId();
721 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
722 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
724 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
728 catch(SALOME_Exception & S_ex)
730 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
735 //=============================================================================
739 //=============================================================================
741 SMESH::ListOfHypothesis *
742 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
743 throw(SALOME::SALOME_Exception)
745 Unexpect aCatch(SALOME_SalomeException);
746 if (MYDEBUG) MESSAGE("GetHypothesisList");
747 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
748 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
750 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
753 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
754 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
755 myLocSubShape = _impl->GetShapeToMesh();
756 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
757 int i = 0, n = aLocalList.size();
760 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
761 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
762 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
764 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
765 if ( id_hypptr != _mapHypo.end() )
766 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
770 catch(SALOME_Exception & S_ex) {
771 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
774 return aList._retn();
777 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
779 Unexpect aCatch(SALOME_SalomeException);
780 if (MYDEBUG) MESSAGE("GetSubMeshes");
782 SMESH::submesh_array_var aList = new SMESH::submesh_array();
785 TPythonDump aPythonDump;
786 if ( !_mapSubMeshIor.empty() )
790 aList->length( _mapSubMeshIor.size() );
792 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
793 for ( ; it != _mapSubMeshIor.end(); it++ ) {
794 if ( CORBA::is_nil( it->second )) continue;
795 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
797 if (i > 1) aPythonDump << ", ";
798 aPythonDump << it->second;
802 catch(SALOME_Exception & S_ex) {
803 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
806 // Update Python script
807 if ( !_mapSubMeshIor.empty() )
808 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
810 return aList._retn();
813 //=============================================================================
817 //=============================================================================
819 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
820 const char* theName )
821 throw(SALOME::SALOME_Exception)
823 Unexpect aCatch(SALOME_SalomeException);
824 if (CORBA::is_nil(aSubShape))
825 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
827 SMESH::SMESH_subMesh_var subMesh;
828 SMESH::SMESH_Mesh_var aMesh = _this();
830 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
832 //Get or Create the SMESH_subMesh object implementation
834 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
836 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
838 TopoDS_Iterator it( myLocSubShape );
840 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
842 subMesh = getSubMesh( subMeshId );
844 // create a new subMesh object servant if there is none for the shape
845 if ( subMesh->_is_nil() )
846 subMesh = createSubMesh( aSubShape );
847 if ( _gen_i->CanPublishInStudy( subMesh ))
849 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
850 SALOMEDS::SObject_wrap aSO =
851 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
852 if ( !aSO->_is_nil()) {
853 // Update Python script
854 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
855 << aSubShape << ", '" << theName << "' )";
859 catch(SALOME_Exception & S_ex) {
860 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
862 return subMesh._retn();
865 //=============================================================================
869 //=============================================================================
871 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
872 throw (SALOME::SALOME_Exception)
876 if ( theSubMesh->_is_nil() )
879 GEOM::GEOM_Object_var aSubShape;
880 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
881 if ( !aStudy->_is_nil() ) {
882 // Remove submesh's SObject
883 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
884 if ( !anSO->_is_nil() ) {
885 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
886 SALOMEDS::SObject_wrap anObj, aRef;
887 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
888 anObj->ReferencedObject( aRef.inout() ))
890 CORBA::Object_var obj = aRef->GetObject();
891 aSubShape = GEOM::GEOM_Object::_narrow( obj );
893 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
894 // aSubShape = theSubMesh->GetSubShape();
896 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
897 builder->RemoveObjectWithChildren( anSO );
899 // Update Python script
900 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
904 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
906 _preMeshInfo->ForgetOrLoad();
908 SMESH_CATCH( SMESH::throwCorbaException );
911 //=============================================================================
915 //=============================================================================
917 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
918 const char* theName )
919 throw(SALOME::SALOME_Exception)
921 Unexpect aCatch(SALOME_SalomeException);
923 _preMeshInfo->FullLoadFromFile();
925 SMESH::SMESH_Group_var aNewGroup =
926 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
928 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
930 SMESH::SMESH_Mesh_var mesh = _this();
931 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
932 SALOMEDS::SObject_wrap aSO =
933 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
934 if ( !aSO->_is_nil())
935 // Update Python script
936 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
937 << theElemType << ", '" << theName << "' )";
939 return aNewGroup._retn();
942 //=============================================================================
946 //=============================================================================
947 SMESH::SMESH_GroupOnGeom_ptr
948 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
950 GEOM::GEOM_Object_ptr theGeomObj)
951 throw(SALOME::SALOME_Exception)
953 Unexpect aCatch(SALOME_SalomeException);
955 _preMeshInfo->FullLoadFromFile();
957 SMESH::SMESH_GroupOnGeom_var aNewGroup;
959 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
960 if ( !aShape.IsNull() )
963 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
965 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
967 SMESH::SMESH_Mesh_var mesh = _this();
968 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
969 SALOMEDS::SObject_wrap aSO =
970 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
971 if ( !aSO->_is_nil())
972 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
973 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
977 return aNewGroup._retn();
980 //================================================================================
982 * \brief Creates a group whose contents is defined by filter
983 * \param theElemType - group type
984 * \param theName - group name
985 * \param theFilter - the filter
986 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
988 //================================================================================
990 SMESH::SMESH_GroupOnFilter_ptr
991 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
993 SMESH::Filter_ptr theFilter )
994 throw (SALOME::SALOME_Exception)
996 Unexpect aCatch(SALOME_SalomeException);
998 _preMeshInfo->FullLoadFromFile();
1000 if ( CORBA::is_nil( theFilter ))
1001 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1003 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1005 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1007 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1008 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1011 if ( !aNewGroup->_is_nil() )
1012 aNewGroup->SetFilter( theFilter );
1014 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1016 SMESH::SMESH_Mesh_var mesh = _this();
1017 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1018 SALOMEDS::SObject_wrap aSO =
1019 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1021 if ( !aSO->_is_nil())
1022 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1023 << theElemType << ", '" << theName << "', " << theFilter << " )";
1025 return aNewGroup._retn();
1028 //=============================================================================
1032 //=============================================================================
1034 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1035 throw (SALOME::SALOME_Exception)
1037 if ( theGroup->_is_nil() )
1042 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1046 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1047 if ( !aStudy->_is_nil() )
1049 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1050 if ( !aGroupSO->_is_nil() )
1052 // Update Python script
1053 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1055 // Remove group's SObject
1056 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1057 builder->RemoveObjectWithChildren( aGroupSO );
1060 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1062 // Remove the group from SMESH data structures
1063 removeGroup( aGroup->GetLocalID() );
1065 SMESH_CATCH( SMESH::throwCorbaException );
1068 //=============================================================================
1070 * Remove group with its contents
1072 //=============================================================================
1074 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1075 throw (SALOME::SALOME_Exception)
1079 _preMeshInfo->FullLoadFromFile();
1081 if ( theGroup->_is_nil() )
1084 vector<int> nodeIds; // to remove nodes becoming free
1085 if ( !theGroup->IsEmpty() )
1087 CORBA::Long elemID = theGroup->GetID( 1 );
1088 int nbElemNodes = GetElemNbNodes( elemID );
1089 if ( nbElemNodes > 0 )
1090 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1094 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1095 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1096 while ( elemIt->more() )
1098 const SMDS_MeshElement* e = elemIt->next();
1100 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1101 while ( nIt->more() )
1102 nodeIds.push_back( nIt->next()->GetID() );
1104 _impl->GetMeshDS()->RemoveElement( e );
1107 // Remove free nodes
1108 if ( theGroup->GetType() != SMESH::NODE )
1109 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1110 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1111 if ( n->NbInverseElements() == 0 )
1112 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1114 TPythonDump pyDump; // Supress dump from RemoveGroup()
1116 // Update Python script (theGroup must be alive for this)
1117 pyDump << SMESH::SMESH_Mesh_var(_this())
1118 << ".RemoveGroupWithContents( " << theGroup << " )";
1121 RemoveGroup( theGroup );
1123 SMESH_CATCH( SMESH::throwCorbaException );
1126 //================================================================================
1128 * \brief Get the list of groups existing in the mesh
1129 * \retval SMESH::ListOfGroups * - list of groups
1131 //================================================================================
1133 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1135 Unexpect aCatch(SALOME_SalomeException);
1136 if (MYDEBUG) MESSAGE("GetGroups");
1138 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1141 TPythonDump aPythonDump;
1142 if ( !_mapGroups.empty() )
1144 aPythonDump << "[ ";
1146 aList->length( _mapGroups.size() );
1148 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1149 for ( ; it != _mapGroups.end(); it++ ) {
1150 if ( CORBA::is_nil( it->second )) continue;
1151 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1153 if (i > 1) aPythonDump << ", ";
1154 aPythonDump << it->second;
1158 catch(SALOME_Exception & S_ex) {
1159 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1161 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1163 return aList._retn();
1166 //=============================================================================
1168 * Get number of groups existing in the mesh
1170 //=============================================================================
1172 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1174 Unexpect aCatch(SALOME_SalomeException);
1175 return _mapGroups.size();
1178 //=============================================================================
1180 * New group including all mesh elements present in initial groups is created.
1182 //=============================================================================
1184 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1185 SMESH::SMESH_GroupBase_ptr theGroup2,
1186 const char* theName )
1187 throw (SALOME::SALOME_Exception)
1189 SMESH::SMESH_Group_var aResGrp;
1193 _preMeshInfo->FullLoadFromFile();
1195 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1196 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1198 if ( theGroup1->GetType() != theGroup2->GetType() )
1199 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1204 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1205 if ( aResGrp->_is_nil() )
1206 return SMESH::SMESH_Group::_nil();
1208 aResGrp->AddFrom( theGroup1 );
1209 aResGrp->AddFrom( theGroup2 );
1211 // Update Python script
1212 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1213 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1215 SMESH_CATCH( SMESH::throwCorbaException );
1217 return aResGrp._retn();
1220 //=============================================================================
1222 * \brief New group including all mesh elements present in initial groups is created.
1223 * \param theGroups list of groups
1224 * \param theName name of group to be created
1225 * \return pointer to the new group
1227 //=============================================================================
1229 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1230 const char* theName )
1231 throw (SALOME::SALOME_Exception)
1233 SMESH::SMESH_Group_var aResGrp;
1236 _preMeshInfo->FullLoadFromFile();
1239 return SMESH::SMESH_Group::_nil();
1244 SMESH::ElementType aType = SMESH::ALL;
1245 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1247 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1248 if ( CORBA::is_nil( aGrp ) )
1250 if ( aType == SMESH::ALL )
1251 aType = aGrp->GetType();
1252 else if ( aType != aGrp->GetType() )
1253 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1256 if ( aType == SMESH::ALL )
1257 return SMESH::SMESH_Group::_nil();
1262 aResGrp = CreateGroup( aType, theName );
1263 if ( aResGrp->_is_nil() )
1264 return SMESH::SMESH_Group::_nil();
1266 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1267 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1269 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1270 if ( !CORBA::is_nil( aGrp ) )
1272 aResGrp->AddFrom( aGrp );
1273 if ( g > 0 ) pyDump << ", ";
1277 pyDump << " ], '" << theName << "' )";
1279 SMESH_CATCH( SMESH::throwCorbaException );
1281 return aResGrp._retn();
1284 //=============================================================================
1286 * New group is created. All mesh elements that are
1287 * present in both initial groups are added to the new one.
1289 //=============================================================================
1291 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1292 SMESH::SMESH_GroupBase_ptr theGroup2,
1293 const char* theName )
1294 throw (SALOME::SALOME_Exception)
1296 SMESH::SMESH_Group_var aResGrp;
1301 _preMeshInfo->FullLoadFromFile();
1303 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1304 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1306 if ( theGroup1->GetType() != theGroup2->GetType() )
1307 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1311 // Create Intersection
1312 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1313 if ( aResGrp->_is_nil() )
1314 return aResGrp._retn();
1316 SMESHDS_GroupBase* groupDS1 = 0;
1317 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1318 groupDS1 = grp_i->GetGroupDS();
1320 SMESHDS_GroupBase* groupDS2 = 0;
1321 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1322 groupDS2 = grp_i->GetGroupDS();
1324 SMESHDS_Group* resGroupDS = 0;
1325 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1326 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1328 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1330 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1331 while ( elemIt1->more() )
1333 const SMDS_MeshElement* e = elemIt1->next();
1334 if ( groupDS2->Contains( e ))
1335 resGroupDS->SMDSGroup().Add( e );
1338 // Update Python script
1339 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1340 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1342 SMESH_CATCH( SMESH::throwCorbaException );
1344 return aResGrp._retn();
1347 //=============================================================================
1349 \brief Intersect list of groups. New group is created. All mesh elements that
1350 are present in all initial groups simultaneously are added to the new one.
1351 \param theGroups list of groups
1352 \param theName name of group to be created
1353 \return pointer on the group
1355 //=============================================================================
1356 SMESH::SMESH_Group_ptr
1357 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1358 const char* theName )
1359 throw (SALOME::SALOME_Exception)
1361 SMESH::SMESH_Group_var aResGrp;
1366 _preMeshInfo->FullLoadFromFile();
1369 return SMESH::SMESH_Group::_nil();
1371 // check types and get SMESHDS_GroupBase's
1372 SMESH::ElementType aType = SMESH::ALL;
1373 vector< SMESHDS_GroupBase* > groupVec;
1374 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1376 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1377 if ( CORBA::is_nil( aGrp ) )
1379 if ( aType == SMESH::ALL )
1380 aType = aGrp->GetType();
1381 else if ( aType != aGrp->GetType() )
1382 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1385 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1386 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1388 if ( grpDS->IsEmpty() )
1393 groupVec.push_back( grpDS );
1396 if ( aType == SMESH::ALL ) // all groups are nil
1397 return SMESH::SMESH_Group::_nil();
1402 aResGrp = CreateGroup( aType, theName );
1404 SMESHDS_Group* resGroupDS = 0;
1405 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1406 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1407 if ( !resGroupDS || groupVec.empty() )
1408 return aResGrp._retn();
1411 size_t i, nb = groupVec.size();
1412 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1413 while ( elemIt1->more() )
1415 const SMDS_MeshElement* e = elemIt1->next();
1417 for ( i = 1; ( i < nb && inAll ); ++i )
1418 inAll = groupVec[i]->Contains( e );
1421 resGroupDS->SMDSGroup().Add( e );
1424 // Update Python script
1425 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1426 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1428 SMESH_CATCH( SMESH::throwCorbaException );
1430 return aResGrp._retn();
1433 //=============================================================================
1435 * New group is created. All mesh elements that are present in
1436 * a main group but is not present in a tool group are added to the new one
1438 //=============================================================================
1440 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1441 SMESH::SMESH_GroupBase_ptr theGroup2,
1442 const char* theName )
1443 throw (SALOME::SALOME_Exception)
1445 SMESH::SMESH_Group_var aResGrp;
1450 _preMeshInfo->FullLoadFromFile();
1452 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1453 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1455 if ( theGroup1->GetType() != theGroup2->GetType() )
1456 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1460 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1461 if ( aResGrp->_is_nil() )
1462 return aResGrp._retn();
1464 SMESHDS_GroupBase* groupDS1 = 0;
1465 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1466 groupDS1 = grp_i->GetGroupDS();
1468 SMESHDS_GroupBase* groupDS2 = 0;
1469 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1470 groupDS2 = grp_i->GetGroupDS();
1472 SMESHDS_Group* resGroupDS = 0;
1473 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1474 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1476 if ( groupDS1 && groupDS2 && resGroupDS )
1478 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1479 while ( elemIt1->more() )
1481 const SMDS_MeshElement* e = elemIt1->next();
1482 if ( !groupDS2->Contains( e ))
1483 resGroupDS->SMDSGroup().Add( e );
1486 // Update Python script
1487 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1488 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1490 SMESH_CATCH( SMESH::throwCorbaException );
1492 return aResGrp._retn();
1495 //=============================================================================
1497 \brief Cut lists of groups. New group is created. All mesh elements that are
1498 present in main groups but do not present in tool groups are added to the new one
1499 \param theMainGroups list of main groups
1500 \param theToolGroups list of tool groups
1501 \param theName name of group to be created
1502 \return pointer on the group
1504 //=============================================================================
1505 SMESH::SMESH_Group_ptr
1506 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1507 const SMESH::ListOfGroups& theToolGroups,
1508 const char* theName )
1509 throw (SALOME::SALOME_Exception)
1511 SMESH::SMESH_Group_var aResGrp;
1516 _preMeshInfo->FullLoadFromFile();
1519 return SMESH::SMESH_Group::_nil();
1521 // check types and get SMESHDS_GroupBase's
1522 SMESH::ElementType aType = SMESH::ALL;
1523 vector< SMESHDS_GroupBase* > toolGroupVec;
1524 vector< SMDS_ElemIteratorPtr > mainIterVec;
1526 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1528 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1529 if ( CORBA::is_nil( aGrp ) )
1531 if ( aType == SMESH::ALL )
1532 aType = aGrp->GetType();
1533 else if ( aType != aGrp->GetType() )
1534 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1536 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1537 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1538 if ( !grpDS->IsEmpty() )
1539 mainIterVec.push_back( grpDS->GetElements() );
1541 if ( aType == SMESH::ALL ) // all main groups are nil
1542 return SMESH::SMESH_Group::_nil();
1543 if ( mainIterVec.empty() ) // all main groups are empty
1544 return aResGrp._retn();
1546 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1548 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1549 if ( CORBA::is_nil( aGrp ) )
1551 if ( aType != aGrp->GetType() )
1552 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1554 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1555 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1556 toolGroupVec.push_back( grpDS );
1562 aResGrp = CreateGroup( aType, theName );
1564 SMESHDS_Group* resGroupDS = 0;
1565 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1566 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1568 return aResGrp._retn();
1571 size_t i, nb = toolGroupVec.size();
1572 SMDS_ElemIteratorPtr mainElemIt
1573 ( new SMDS_IteratorOnIterators
1574 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1575 while ( mainElemIt->more() )
1577 const SMDS_MeshElement* e = mainElemIt->next();
1579 for ( i = 0; ( i < nb && !isIn ); ++i )
1580 isIn = toolGroupVec[i]->Contains( e );
1583 resGroupDS->SMDSGroup().Add( e );
1586 // Update Python script
1587 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1588 << ".CutListOfGroups( " << theMainGroups << ", "
1589 << theToolGroups << ", '" << theName << "' )";
1591 SMESH_CATCH( SMESH::throwCorbaException );
1593 return aResGrp._retn();
1596 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1598 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1599 bool & toStopChecking )
1601 toStopChecking = ( nbCommon < nbChecked );
1602 return nbCommon == nbNodes;
1604 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1605 bool & toStopChecking )
1607 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1608 return nbCommon == nbCorners;
1610 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1611 bool & toStopChecking )
1613 return nbCommon > 0;
1615 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1616 bool & toStopChecking )
1618 return nbCommon >= (nbNodes+1) / 2;
1622 //=============================================================================
1624 * Create a group of entities basing on nodes of other groups.
1625 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1626 * \param [in] anElemType - a type of elements to include to the new group.
1627 * \param [in] theName - a name of the new group.
1628 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1629 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1630 * new group provided that it is based on nodes of an element of \a aListOfGroups
1631 * \return SMESH_Group - the created group
1633 // IMP 19939, bug 22010, IMP 22635
1634 //=============================================================================
1636 SMESH::SMESH_Group_ptr
1637 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1638 SMESH::ElementType theElemType,
1639 const char* theName,
1640 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1641 CORBA::Boolean theUnderlyingOnly)
1642 throw (SALOME::SALOME_Exception)
1644 SMESH::SMESH_Group_var aResGrp;
1648 _preMeshInfo->FullLoadFromFile();
1650 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1652 if ( !theName || !aMeshDS )
1653 return SMESH::SMESH_Group::_nil();
1655 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1657 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1658 SMESH_Comment nbCoNoStr( "SMESH.");
1659 switch ( theNbCommonNodes ) {
1660 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1661 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1662 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1663 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1664 default: return aResGrp._retn();
1666 int nbChecked, nbCommon, nbNodes, nbCorners;
1672 aResGrp = CreateGroup( theElemType, theName );
1673 if ( aResGrp->_is_nil() )
1674 return SMESH::SMESH_Group::_nil();
1676 SMESHDS_GroupBase* groupBaseDS =
1677 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1678 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1680 vector<bool> isNodeInGroups;
1682 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1684 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1685 if ( CORBA::is_nil( aGrp ) )
1687 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1688 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1691 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1692 if ( !elIt ) continue;
1694 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1696 while ( elIt->more() ) {
1697 const SMDS_MeshElement* el = elIt->next();
1698 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1699 while ( nIt->more() )
1700 resGroupCore.Add( nIt->next() );
1703 // get elements of theElemType based on nodes of every element of group
1704 else if ( theUnderlyingOnly )
1706 while ( elIt->more() )
1708 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1709 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1710 TIDSortedElemSet checkedElems;
1711 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1712 while ( nIt->more() )
1714 const SMDS_MeshNode* n = nIt->next();
1715 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1716 // check nodes of elements of theElemType around el
1717 while ( elOfTypeIt->more() )
1719 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1720 if ( !checkedElems.insert( elOfType ).second ) continue;
1721 nbNodes = elOfType->NbNodes();
1722 nbCorners = elOfType->NbCornerNodes();
1724 bool toStopChecking = false;
1725 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1726 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1727 if ( elNodes.count( nIt2->next() ) &&
1728 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1730 resGroupCore.Add( elOfType );
1737 // get all nodes of elements of groups
1740 while ( elIt->more() )
1742 const SMDS_MeshElement* el = elIt->next(); // an element of group
1743 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1744 while ( nIt->more() )
1746 const SMDS_MeshNode* n = nIt->next();
1747 if ( n->GetID() >= isNodeInGroups.size() )
1748 isNodeInGroups.resize( n->GetID() + 1, false );
1749 isNodeInGroups[ n->GetID() ] = true;
1755 // Get elements of theElemType based on a certain number of nodes of elements of groups
1756 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1758 const SMDS_MeshNode* n;
1759 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1760 const int isNodeInGroupsSize = isNodeInGroups.size();
1761 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1763 if ( !isNodeInGroups[ iN ] ||
1764 !( n = aMeshDS->FindNode( iN )))
1767 // check nodes of elements of theElemType around n
1768 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1769 while ( elOfTypeIt->more() )
1771 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1772 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1777 nbNodes = elOfType->NbNodes();
1778 nbCorners = elOfType->NbCornerNodes();
1780 bool toStopChecking = false;
1781 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1782 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1784 const int nID = nIt->next()->GetID();
1785 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1786 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1788 resGroupCore.Add( elOfType );
1796 // Update Python script
1797 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1798 << ".CreateDimGroup( "
1799 << theGroups << ", " << theElemType << ", '" << theName << "', "
1800 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1802 SMESH_CATCH( SMESH::throwCorbaException );
1804 return aResGrp._retn();
1807 //================================================================================
1809 * \brief Remember GEOM group data
1811 //================================================================================
1813 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1814 CORBA::Object_ptr theSmeshObj)
1816 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1819 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1820 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1821 if ( groupSO->_is_nil() )
1824 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1825 GEOM::GEOM_IGroupOperations_wrap groupOp =
1826 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1827 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1830 _geomGroupData.push_back( TGeomGroupData() );
1831 TGeomGroupData & groupData = _geomGroupData.back();
1833 CORBA::String_var entry = groupSO->GetID();
1834 groupData._groupEntry = entry.in();
1836 for ( int i = 0; i < ids->length(); ++i )
1837 groupData._indices.insert( ids[i] );
1839 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1840 // shape index in SMESHDS
1841 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1842 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1845 //================================================================================
1847 * Remove GEOM group data relating to removed smesh object
1849 //================================================================================
1851 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1853 list<TGeomGroupData>::iterator
1854 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1855 for ( ; data != dataEnd; ++data ) {
1856 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1857 _geomGroupData.erase( data );
1863 //================================================================================
1865 * \brief Return new group contents if it has been changed and update group data
1867 //================================================================================
1869 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1871 TopoDS_Shape newShape;
1874 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1875 if ( study->_is_nil() ) return newShape; // means "not changed"
1876 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1877 if ( !groupSO->_is_nil() )
1879 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1880 if ( CORBA::is_nil( groupObj )) return newShape;
1881 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1883 // get indices of group items
1884 set<int> curIndices;
1885 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1886 GEOM::GEOM_IGroupOperations_wrap groupOp =
1887 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1888 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1889 for ( int i = 0; i < ids->length(); ++i )
1890 curIndices.insert( ids[i] );
1892 if ( groupData._indices == curIndices )
1893 return newShape; // group not changed
1896 groupData._indices = curIndices;
1898 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1899 if ( !geomClient ) return newShape;
1900 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1901 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1902 newShape = _gen_i->GeomObjectToShape( geomGroup );
1905 if ( newShape.IsNull() ) {
1906 // geom group becomes empty - return empty compound
1907 TopoDS_Compound compound;
1908 BRep_Builder().MakeCompound(compound);
1909 newShape = compound;
1916 //-----------------------------------------------------------------------------
1918 * \brief Storage of shape and index used in CheckGeomGroupModif()
1920 struct TIndexedShape
1923 TopoDS_Shape _shape;
1924 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1926 //-----------------------------------------------------------------------------
1928 * \brief Data to re-create a group on geometry
1930 struct TGroupOnGeomData
1934 SMDSAbs_ElementType _type;
1936 Quantity_Color _color;
1940 //=============================================================================
1942 * \brief Update data if geometry changes
1946 //=============================================================================
1948 void SMESH_Mesh_i::CheckGeomModif()
1950 if ( !_impl->HasShapeToMesh() ) return;
1952 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1953 if ( study->_is_nil() ) return;
1955 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1956 if ( mainGO->_is_nil() ) return;
1958 if ( mainGO->GetType() == GEOM_GROUP ||
1959 mainGO->GetTick() == _mainShapeTick )
1961 CheckGeomGroupModif();
1965 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1966 if ( !geomClient ) return;
1967 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1968 if ( geomGen->_is_nil() ) return;
1970 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1971 geomClient->RemoveShapeFromBuffer( ior.in() );
1973 // Update data taking into account that
1974 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1977 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1978 if ( newShape.IsNull() )
1981 _mainShapeTick = mainGO->GetTick();
1983 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1985 // store data of groups on geometry
1986 vector< TGroupOnGeomData > groupsData;
1987 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1988 groupsData.reserve( groups.size() );
1989 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1990 for ( ; g != groups.end(); ++g )
1991 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1993 TGroupOnGeomData data;
1994 data._oldID = group->GetID();
1995 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1996 data._type = group->GetType();
1997 data._name = group->GetStoreName();
1998 data._color = group->GetColor();
1999 groupsData.push_back( data );
2001 // store assigned hypotheses
2002 vector< pair< int, THypList > > ids2Hyps;
2003 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2004 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2006 const TopoDS_Shape& s = s2hyps.Key();
2007 const THypList& hyps = s2hyps.ChangeValue();
2008 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2011 // change shape to mesh
2012 int oldNbSubShapes = meshDS->MaxShapeIndex();
2013 _impl->ShapeToMesh( TopoDS_Shape() );
2014 _impl->ShapeToMesh( newShape );
2016 // re-add shapes of geom groups
2017 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2018 for ( ; data != _geomGroupData.end(); ++data )
2020 TopoDS_Shape newShape = newGroupShape( *data );
2021 if ( !newShape.IsNull() )
2023 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2025 TopoDS_Compound compound;
2026 BRep_Builder().MakeCompound( compound );
2027 BRep_Builder().Add( compound, newShape );
2028 newShape = compound;
2030 _impl->GetSubMesh( newShape );
2033 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2034 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2035 SALOME::INTERNAL_ERROR );
2037 // re-assign hypotheses
2038 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2040 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2041 const THypList& hyps = ids2Hyps[i].second;
2042 THypList::const_iterator h = hyps.begin();
2043 for ( ; h != hyps.end(); ++h )
2044 _impl->AddHypothesis( s, (*h)->GetID() );
2048 for ( size_t i = 0; i < groupsData.size(); ++i )
2050 const TGroupOnGeomData& data = groupsData[i];
2052 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2053 if ( i2g == _mapGroups.end() ) continue;
2055 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2056 if ( !gr_i ) continue;
2059 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2060 meshDS->IndexToShape( data._shapeID ));
2063 _mapGroups.erase( i2g );
2067 g->GetGroupDS()->SetColor( data._color );
2068 gr_i->changeLocalId( id );
2069 _mapGroups[ id ] = i2g->second;
2070 if ( data._oldID != id )
2071 _mapGroups.erase( i2g );
2075 // update _mapSubMesh
2076 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2077 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2078 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2082 //=============================================================================
2084 * \brief Update objects depending on changed geom groups
2086 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2087 * issue 0020210: Update of a smesh group after modification of the associated geom group
2089 //=============================================================================
2091 void SMESH_Mesh_i::CheckGeomGroupModif()
2093 if ( !_impl->HasShapeToMesh() ) return;
2095 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2096 if ( study->_is_nil() ) return;
2098 CORBA::Long nbEntities = NbNodes() + NbElements();
2100 // Check if group contents changed
2102 typedef map< string, TopoDS_Shape > TEntry2Geom;
2103 TEntry2Geom newGroupContents;
2105 list<TGeomGroupData>::iterator
2106 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2107 for ( ; data != dataEnd; ++data )
2109 pair< TEntry2Geom::iterator, bool > it_new =
2110 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2111 bool processedGroup = !it_new.second;
2112 TopoDS_Shape& newShape = it_new.first->second;
2113 if ( !processedGroup )
2114 newShape = newGroupShape( *data );
2115 if ( newShape.IsNull() )
2116 continue; // no changes
2119 _preMeshInfo->ForgetOrLoad();
2121 if ( processedGroup ) { // update group indices
2122 list<TGeomGroupData>::iterator data2 = data;
2123 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2124 data->_indices = data2->_indices;
2127 // Update SMESH objects according to new GEOM group contents
2129 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2130 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2132 int oldID = submesh->GetId();
2133 if ( !_mapSubMeshIor.count( oldID ))
2135 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2137 // update hypotheses
2138 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2139 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2140 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2142 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2143 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2145 // care of submeshes
2146 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2147 int newID = newSubmesh->GetId();
2148 if ( newID != oldID ) {
2149 _mapSubMesh [ newID ] = newSubmesh;
2150 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2151 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2152 _mapSubMesh. erase(oldID);
2153 _mapSubMesh_i. erase(oldID);
2154 _mapSubMeshIor.erase(oldID);
2155 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2160 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2161 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2162 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2164 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2166 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2167 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2168 ds->SetShape( newShape );
2173 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2174 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2176 // Remove groups and submeshes basing on removed sub-shapes
2178 TopTools_MapOfShape newShapeMap;
2179 TopoDS_Iterator shapeIt( newShape );
2180 for ( ; shapeIt.More(); shapeIt.Next() )
2181 newShapeMap.Add( shapeIt.Value() );
2183 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2184 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2186 if ( newShapeMap.Contains( shapeIt.Value() ))
2188 TopTools_IndexedMapOfShape oldShapeMap;
2189 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2190 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2192 const TopoDS_Shape& oldShape = oldShapeMap(i);
2193 int oldInd = meshDS->ShapeToIndex( oldShape );
2195 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2196 if ( i_smIor != _mapSubMeshIor.end() ) {
2197 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2200 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2201 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2203 // check if a group bases on oldInd shape
2204 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2205 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2206 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2207 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2209 RemoveGroup( i_grp->second ); // several groups can base on same shape
2210 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2215 // Reassign hypotheses and update groups after setting the new shape to mesh
2217 // collect anassigned hypotheses
2218 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2219 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2220 TShapeHypList assignedHyps;
2221 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2223 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2224 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2225 if ( !hyps.empty() ) {
2226 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2227 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2228 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2231 // collect shapes supporting groups
2232 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2233 TShapeTypeList groupData;
2234 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2235 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2236 for ( ; grIt != groups.end(); ++grIt )
2238 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2240 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2242 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2243 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2244 _impl->ShapeToMesh( newShape );
2246 // reassign hypotheses
2247 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2248 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2250 TIndexedShape& geom = indS_hyps->first;
2251 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2252 int oldID = geom._index;
2253 int newID = meshDS->ShapeToIndex( geom._shape );
2254 if ( oldID == 1 ) { // main shape
2256 geom._shape = newShape;
2260 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2261 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2262 // care of sub-meshes
2263 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2264 if ( newID != oldID ) {
2265 _mapSubMesh [ newID ] = newSubmesh;
2266 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2267 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2268 _mapSubMesh. erase(oldID);
2269 _mapSubMesh_i. erase(oldID);
2270 _mapSubMeshIor.erase(oldID);
2271 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2275 TShapeTypeList::iterator geomType = groupData.begin();
2276 for ( ; geomType != groupData.end(); ++geomType )
2278 const TIndexedShape& geom = geomType->first;
2279 int oldID = geom._index;
2280 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2283 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2284 CORBA::String_var name = groupSO->GetName();
2286 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2288 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2289 group_i->changeLocalId( newID );
2292 break; // everything has been updated
2295 } // loop on group data
2299 CORBA::Long newNbEntities = NbNodes() + NbElements();
2300 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2301 if ( newNbEntities != nbEntities )
2303 // Add all SObjects with icons to soToUpdateIcons
2304 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2306 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2307 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2308 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2310 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2311 i_gr != _mapGroups.end(); ++i_gr ) // groups
2312 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2315 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2316 for ( ; so != soToUpdateIcons.end(); ++so )
2317 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2320 //=============================================================================
2322 * \brief Create standalone group from a group on geometry or filter
2324 //=============================================================================
2326 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2327 throw (SALOME::SALOME_Exception)
2329 SMESH::SMESH_Group_var aGroup;
2334 _preMeshInfo->FullLoadFromFile();
2336 if ( theGroup->_is_nil() )
2337 return aGroup._retn();
2339 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2341 return aGroup._retn();
2343 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2345 const int anId = aGroupToRem->GetLocalID();
2346 if ( !_impl->ConvertToStandalone( anId ) )
2347 return aGroup._retn();
2348 removeGeomGroupData( theGroup );
2350 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2352 // remove old instance of group from own map
2353 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2354 _mapGroups.erase( anId );
2356 SALOMEDS::StudyBuilder_var builder;
2357 SALOMEDS::SObject_wrap aGroupSO;
2358 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2359 if ( !aStudy->_is_nil() ) {
2360 builder = aStudy->NewBuilder();
2361 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2362 if ( !aGroupSO->_is_nil() )
2364 // remove reference to geometry
2365 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2366 for ( ; chItr->More(); chItr->Next() )
2367 // Remove group's child SObject
2368 builder->RemoveObject( chItr->Value() );
2370 // Update Python script
2371 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2372 << ".ConvertToStandalone( " << aGroupSO << " )";
2374 // change icon of Group on Filter
2377 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2378 const int isEmpty = ( elemTypes->length() == 0 );
2381 SALOMEDS::GenericAttribute_wrap anAttr =
2382 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2383 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2384 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2390 // remember new group in own map
2391 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2392 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2394 // register CORBA object for persistence
2395 _gen_i->RegisterObject( aGroup );
2397 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2398 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2399 //aGroup->Register();
2400 aGroupToRem->UnRegister();
2402 SMESH_CATCH( SMESH::throwCorbaException );
2404 return aGroup._retn();
2407 //=============================================================================
2411 //=============================================================================
2413 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2415 if(MYDEBUG) MESSAGE( "createSubMesh" );
2416 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2417 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2418 const int subMeshId = mySubMesh->GetId();
2420 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2421 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2423 _mapSubMesh [subMeshId] = mySubMesh;
2424 _mapSubMesh_i [subMeshId] = subMeshServant;
2425 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2427 subMeshServant->Register();
2429 // register CORBA object for persistence
2430 int nextId = _gen_i->RegisterObject( subMesh );
2431 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2432 else { nextId = 0; } // avoid "unused variable" warning
2434 // to track changes of GEOM groups
2435 addGeomGroupData( theSubShapeObject, subMesh );
2437 return subMesh._retn();
2440 //=======================================================================
2441 //function : getSubMesh
2443 //=======================================================================
2445 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2447 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2448 if ( it == _mapSubMeshIor.end() )
2449 return SMESH::SMESH_subMesh::_nil();
2451 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2454 //=============================================================================
2458 //=============================================================================
2460 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2461 GEOM::GEOM_Object_ptr theSubShapeObject )
2463 bool isHypChanged = false;
2464 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2465 return isHypChanged;
2467 const int subMeshId = theSubMesh->GetId();
2469 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2471 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2473 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2476 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2477 isHypChanged = !hyps.empty();
2478 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2479 for ( ; hyp != hyps.end(); ++hyp )
2480 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2487 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2488 isHypChanged = ( aHypList->length() > 0 );
2489 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2490 removeHypothesis( theSubShapeObject, aHypList[i] );
2493 catch( const SALOME::SALOME_Exception& ) {
2494 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2496 removeGeomGroupData( theSubShapeObject );
2500 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2501 if ( id_smi != _mapSubMesh_i.end() )
2502 id_smi->second->UnRegister();
2504 // remove a CORBA object
2505 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2506 if ( id_smptr != _mapSubMeshIor.end() )
2507 SMESH::SMESH_subMesh_var( id_smptr->second );
2509 _mapSubMesh.erase(subMeshId);
2510 _mapSubMesh_i.erase(subMeshId);
2511 _mapSubMeshIor.erase(subMeshId);
2513 return isHypChanged;
2516 //=============================================================================
2520 //=============================================================================
2522 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2523 const char* theName,
2524 const TopoDS_Shape& theShape,
2525 const SMESH_PredicatePtr& thePredicate )
2527 std::string newName;
2528 if ( !theName || strlen( theName ) == 0 )
2530 std::set< std::string > presentNames;
2531 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2532 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2534 CORBA::String_var name = i_gr->second->GetName();
2535 presentNames.insert( name.in() );
2538 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2539 } while ( !presentNames.insert( newName ).second );
2540 theName = newName.c_str();
2543 SMESH::SMESH_GroupBase_var aGroup;
2544 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2546 SMESH_GroupBase_i* aGroupImpl;
2547 if ( !theShape.IsNull() )
2548 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2549 else if ( thePredicate )
2550 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2552 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2554 aGroup = aGroupImpl->_this();
2555 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2556 aGroupImpl->Register();
2558 // register CORBA object for persistence
2559 int nextId = _gen_i->RegisterObject( aGroup );
2560 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2561 else { nextId = 0; } // avoid "unused variable" warning in release mode
2563 // to track changes of GEOM groups
2564 if ( !theShape.IsNull() ) {
2565 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2566 addGeomGroupData( geom, aGroup );
2569 return aGroup._retn();
2572 //=============================================================================
2574 * SMESH_Mesh_i::removeGroup
2576 * Should be called by ~SMESH_Group_i()
2578 //=============================================================================
2580 void SMESH_Mesh_i::removeGroup( const int theId )
2582 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2583 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2584 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2585 _mapGroups.erase( theId );
2586 removeGeomGroupData( group );
2587 if ( !_impl->RemoveGroup( theId ))
2589 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2590 RemoveGroup( group );
2592 group->UnRegister();
2596 //=============================================================================
2600 //=============================================================================
2602 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2603 throw(SALOME::SALOME_Exception)
2605 SMESH::log_array_var aLog;
2609 _preMeshInfo->FullLoadFromFile();
2611 list < SMESHDS_Command * >logDS = _impl->GetLog();
2612 aLog = new SMESH::log_array;
2614 int lg = logDS.size();
2617 list < SMESHDS_Command * >::iterator its = logDS.begin();
2618 while(its != logDS.end()){
2619 SMESHDS_Command *com = *its;
2620 int comType = com->GetType();
2622 int lgcom = com->GetNumber();
2624 const list < int >&intList = com->GetIndexes();
2625 int inum = intList.size();
2627 list < int >::const_iterator ii = intList.begin();
2628 const list < double >&coordList = com->GetCoords();
2629 int rnum = coordList.size();
2631 list < double >::const_iterator ir = coordList.begin();
2632 aLog[indexLog].commandType = comType;
2633 aLog[indexLog].number = lgcom;
2634 aLog[indexLog].coords.length(rnum);
2635 aLog[indexLog].indexes.length(inum);
2636 for(int i = 0; i < rnum; i++){
2637 aLog[indexLog].coords[i] = *ir;
2638 //MESSAGE(" "<<i<<" "<<ir.Value());
2641 for(int i = 0; i < inum; i++){
2642 aLog[indexLog].indexes[i] = *ii;
2643 //MESSAGE(" "<<i<<" "<<ii.Value());
2652 SMESH_CATCH( SMESH::throwCorbaException );
2654 return aLog._retn();
2658 //=============================================================================
2662 //=============================================================================
2664 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2668 SMESH_CATCH( SMESH::throwCorbaException );
2671 //=============================================================================
2675 //=============================================================================
2677 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2682 //=============================================================================
2686 //=============================================================================
2688 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2693 //=============================================================================
2696 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2697 // issue 0020918: groups removal is caused by hyp modification
2698 // issue 0021208: to forget not loaded mesh data at hyp modification
2699 struct TCallUp_i : public SMESH_Mesh::TCallUp
2701 SMESH_Mesh_i* _mesh;
2702 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2703 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2704 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2705 virtual void Load () { _mesh->Load(); }
2709 //================================================================================
2711 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2713 //================================================================================
2715 void SMESH_Mesh_i::onHypothesisModified()
2718 _preMeshInfo->ForgetOrLoad();
2721 //=============================================================================
2725 //=============================================================================
2727 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2729 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2732 _impl->SetCallUp( new TCallUp_i(this));
2735 //=============================================================================
2739 //=============================================================================
2741 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2743 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2747 //=============================================================================
2749 * Return mesh editor
2751 //=============================================================================
2753 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2754 throw (SALOME::SALOME_Exception)
2756 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2760 _preMeshInfo->FullLoadFromFile();
2762 // Create MeshEditor
2764 _editor = new SMESH_MeshEditor_i( this, false );
2765 aMeshEdVar = _editor->_this();
2767 // Update Python script
2768 TPythonDump() << _editor << " = "
2769 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2771 SMESH_CATCH( SMESH::throwCorbaException );
2773 return aMeshEdVar._retn();
2776 //=============================================================================
2778 * Return mesh edition previewer
2780 //=============================================================================
2782 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2783 throw (SALOME::SALOME_Exception)
2785 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2789 _preMeshInfo->FullLoadFromFile();
2791 if ( !_previewEditor )
2792 _previewEditor = new SMESH_MeshEditor_i( this, true );
2793 aMeshEdVar = _previewEditor->_this();
2795 SMESH_CATCH( SMESH::throwCorbaException );
2797 return aMeshEdVar._retn();
2800 //================================================================================
2802 * \brief Return true if the mesh has been edited since a last total re-compute
2803 * and those modifications may prevent successful partial re-compute
2805 //================================================================================
2807 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2809 Unexpect aCatch(SALOME_SalomeException);
2810 return _impl->HasModificationsToDiscard();
2813 //================================================================================
2815 * \brief Returns a random unique color
2817 //================================================================================
2819 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2821 const int MAX_ATTEMPTS = 100;
2823 double tolerance = 0.5;
2824 SALOMEDS::Color col;
2828 // generate random color
2829 double red = (double)rand() / RAND_MAX;
2830 double green = (double)rand() / RAND_MAX;
2831 double blue = (double)rand() / RAND_MAX;
2832 // check existence in the list of the existing colors
2833 bool matched = false;
2834 std::list<SALOMEDS::Color>::const_iterator it;
2835 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2836 SALOMEDS::Color color = *it;
2837 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2838 matched = tol < tolerance;
2840 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2841 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2849 //=============================================================================
2851 * Sets auto-color mode. If it is on, groups get unique random colors
2853 //=============================================================================
2855 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2857 Unexpect aCatch(SALOME_SalomeException);
2858 _impl->SetAutoColor(theAutoColor);
2860 TPythonDump pyDump; // not to dump group->SetColor() from below code
2861 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2863 std::list<SALOMEDS::Color> aReservedColors;
2864 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2865 for ( ; it != _mapGroups.end(); it++ ) {
2866 if ( CORBA::is_nil( it->second )) continue;
2867 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2868 it->second->SetColor( aColor );
2869 aReservedColors.push_back( aColor );
2873 //=============================================================================
2875 * Returns true if auto-color mode is on
2877 //=============================================================================
2879 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2881 Unexpect aCatch(SALOME_SalomeException);
2882 return _impl->GetAutoColor();
2885 //=============================================================================
2887 * Checks if there are groups with equal names
2889 //=============================================================================
2891 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2893 return _impl->HasDuplicatedGroupNamesMED();
2896 //================================================================================
2898 * \brief Care of a file before exporting mesh into it
2900 //================================================================================
2902 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2904 SMESH_File aFile( file );
2906 if (aFile.exists()) {
2907 // existing filesystem node
2908 if ( !aFile.isDirectory() ) {
2909 if ( aFile.openForWriting() ) {
2910 if ( overwrite && ! aFile.remove()) {
2911 msg << "Can't replace " << aFile.getName();
2914 msg << "Can't write into " << aFile.getName();
2917 msg << "Location " << aFile.getName() << " is not a file";
2921 // nonexisting file; check if it can be created
2922 if ( !aFile.openForWriting() ) {
2923 msg << "You cannot create the file "
2925 << ". Check the directory existance and access rights";
2933 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2937 //================================================================================
2939 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2940 * \param file - file name
2941 * \param overwrite - to erase the file or not
2942 * \retval string - mesh name
2944 //================================================================================
2946 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2947 CORBA::Boolean overwrite)
2950 PrepareForWriting(file, overwrite);
2951 string aMeshName = "Mesh";
2952 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2953 if ( !aStudy->_is_nil() ) {
2954 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2955 if ( !aMeshSO->_is_nil() ) {
2956 CORBA::String_var name = aMeshSO->GetName();
2958 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2959 if ( !aStudy->GetProperties()->IsLocked() )
2961 SALOMEDS::GenericAttribute_wrap anAttr;
2962 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2963 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2964 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2965 ASSERT(!aFileName->_is_nil());
2966 aFileName->SetValue(file);
2967 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2968 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2969 ASSERT(!aFileType->_is_nil());
2970 aFileType->SetValue("FICHIERMED");
2974 // Update Python script
2975 // set name of mesh before export
2976 TPythonDump() << _gen_i << ".SetName("
2977 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2979 // check names of groups
2985 //================================================================================
2987 * \brief Export to med file
2989 //================================================================================
2991 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2992 CORBA::Boolean auto_groups,
2993 SMESH::MED_VERSION theVersion,
2994 CORBA::Boolean overwrite,
2995 CORBA::Boolean autoDimension)
2996 throw(SALOME::SALOME_Exception)
3000 _preMeshInfo->FullLoadFromFile();
3002 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3003 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3005 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3006 << file << "', " << auto_groups << ", "
3007 << theVersion << ", " << overwrite << ", "
3008 << autoDimension << " )";
3010 SMESH_CATCH( SMESH::throwCorbaException );
3013 //================================================================================
3015 * \brief Export a mesh to a med file
3017 //================================================================================
3019 void SMESH_Mesh_i::ExportToMED (const char* file,
3020 CORBA::Boolean auto_groups,
3021 SMESH::MED_VERSION theVersion)
3022 throw(SALOME::SALOME_Exception)
3024 ExportToMEDX(file,auto_groups,theVersion,true);
3027 //================================================================================
3029 * \brief Export a mesh to a med file
3031 //================================================================================
3033 void SMESH_Mesh_i::ExportMED (const char* file,
3034 CORBA::Boolean auto_groups)
3035 throw(SALOME::SALOME_Exception)
3037 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3040 //================================================================================
3042 * \brief Export a mesh to a SAUV file
3044 //================================================================================
3046 void SMESH_Mesh_i::ExportSAUV (const char* file,
3047 CORBA::Boolean auto_groups)
3048 throw(SALOME::SALOME_Exception)
3050 Unexpect aCatch(SALOME_SalomeException);
3052 _preMeshInfo->FullLoadFromFile();
3054 string aMeshName = prepareMeshNameAndGroups(file, true);
3055 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3056 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3057 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3061 //================================================================================
3063 * \brief Export a mesh to a DAT file
3065 //================================================================================
3067 void SMESH_Mesh_i::ExportDAT (const char *file)
3068 throw(SALOME::SALOME_Exception)
3070 Unexpect aCatch(SALOME_SalomeException);
3072 _preMeshInfo->FullLoadFromFile();
3074 // Update Python script
3075 // check names of groups
3077 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3080 PrepareForWriting(file);
3081 _impl->ExportDAT(file);
3084 //================================================================================
3086 * \brief Export a mesh to an UNV file
3088 //================================================================================
3090 void SMESH_Mesh_i::ExportUNV (const char *file)
3091 throw(SALOME::SALOME_Exception)
3093 Unexpect aCatch(SALOME_SalomeException);
3095 _preMeshInfo->FullLoadFromFile();
3097 // Update Python script
3098 // check names of groups
3100 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3103 PrepareForWriting(file);
3104 _impl->ExportUNV(file);
3107 //================================================================================
3109 * \brief Export a mesh to an STL file
3111 //================================================================================
3113 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3114 throw(SALOME::SALOME_Exception)
3116 Unexpect aCatch(SALOME_SalomeException);
3118 _preMeshInfo->FullLoadFromFile();
3120 // Update Python script
3121 // check names of groups
3123 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3124 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3127 PrepareForWriting(file);
3128 _impl->ExportSTL(file, isascii);
3131 //================================================================================
3133 * \brief Export a part of mesh to a med file
3135 //================================================================================
3137 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3139 CORBA::Boolean auto_groups,
3140 SMESH::MED_VERSION version,
3141 CORBA::Boolean overwrite,
3142 CORBA::Boolean autoDimension,
3143 const GEOM::ListOfFields& fields,
3144 const char* geomAssocFields)
3145 throw (SALOME::SALOME_Exception)
3149 _preMeshInfo->FullLoadFromFile();
3152 bool have0dField = false;
3153 if ( fields.length() > 0 )
3155 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3156 if ( shapeToMesh->_is_nil() )
3157 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3159 for ( size_t i = 0; i < fields.length(); ++i )
3161 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3162 THROW_SALOME_CORBA_EXCEPTION
3163 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3164 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3165 if ( fieldShape->_is_nil() )
3166 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3167 if ( !fieldShape->IsSame( shapeToMesh ) )
3168 THROW_SALOME_CORBA_EXCEPTION
3169 ( "Field defined not on shape", SALOME::BAD_PARAM);
3170 if ( fields[i]->GetDimension() == 0 )
3173 if ( geomAssocFields )
3174 for ( int i = 0; geomAssocFields[i]; ++i )
3175 switch ( geomAssocFields[i] ) {
3176 case 'v':case 'e':case 'f':case 's': break;
3177 case 'V':case 'E':case 'F':case 'S': break;
3178 default: THROW_SALOME_CORBA_EXCEPTION
3179 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3183 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3187 string aMeshName = "Mesh";
3188 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3189 if ( CORBA::is_nil( meshPart ) ||
3190 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3192 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3193 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3194 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3195 meshDS = _impl->GetMeshDS();
3200 _preMeshInfo->FullLoadFromFile();
3202 PrepareForWriting(file, overwrite);
3204 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3205 if ( !aStudy->_is_nil() ) {
3206 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3207 if ( !SO->_is_nil() ) {
3208 CORBA::String_var name = SO->GetName();
3212 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3213 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3214 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3215 meshDS = tmpDSDeleter._obj = partDS;
3220 if ( _impl->HasShapeToMesh() )
3222 DriverMED_W_Field fieldWriter;
3223 fieldWriter.SetFile( file );
3224 fieldWriter.SetMeshName( aMeshName );
3225 fieldWriter.AddODOnVertices( have0dField );
3227 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3231 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3232 goList->length( fields.length() );
3233 for ( size_t i = 0; i < fields.length(); ++i )
3235 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3238 TPythonDump() << _this() << ".ExportPartToMED( "
3239 << meshPart << ", r'" << file << "', "
3240 << auto_groups << ", " << version << ", " << overwrite << ", "
3241 << autoDimension << ", " << goList
3242 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3244 SMESH_CATCH( SMESH::throwCorbaException );
3247 //================================================================================
3249 * Write GEOM fields to MED file
3251 //================================================================================
3253 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3254 SMESHDS_Mesh* meshDS,
3255 const GEOM::ListOfFields& fields,
3256 const char* geomAssocFields)
3258 #define METH "SMESH_Mesh_i::exportMEDFields() "
3260 if (( fields.length() < 1 ) &&
3261 ( !geomAssocFields || !geomAssocFields[0] ))
3264 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3265 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3266 std::vector< int > subIdsByDim[ 4 ];
3267 const double noneDblValue = 0.;
3268 const double noneIntValue = 0;
3270 for ( size_t iF = 0; iF < fields.length(); ++iF )
3274 int dim = fields[ iF ]->GetDimension();
3275 SMDSAbs_ElementType elemType;
3276 TopAbs_ShapeEnum shapeType;
3278 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3279 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3280 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3281 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3283 continue; // skip fields on whole shape
3285 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3286 if ( dataType == GEOM::FDT_String )
3288 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3289 if ( stepIDs->length() < 1 )
3291 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3292 if ( comps->length() < 1 )
3294 CORBA::String_var name = fields[ iF ]->GetName();
3296 if ( !fieldWriter.Set( meshDS,
3300 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3303 for ( size_t iC = 0; iC < comps->length(); ++iC )
3304 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3306 // find sub-shape IDs
3308 std::vector< int >& subIds = subIdsByDim[ dim ];
3309 if ( subIds.empty() )
3310 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3311 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3312 subIds.push_back( id );
3316 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3320 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3322 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3323 if ( step->_is_nil() )
3326 CORBA::Long stamp = step->GetStamp();
3327 CORBA::Long id = step->GetID();
3328 fieldWriter.SetDtIt( int( stamp ), int( id ));
3330 // fill dblVals or intVals
3333 case GEOM::FDT_Double:
3335 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3336 if ( dblStep->_is_nil() ) continue;
3337 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3338 if ( vv->length() != subIds.size() )
3339 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3340 for ( size_t i = 0; i < vv->length(); ++i )
3341 dblVals[ subIds[ i ]] = vv[ i ];
3346 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3347 if ( intStep->_is_nil() ) continue;
3348 GEOM::ListOfLong_var vv = intStep->GetValues();
3349 if ( vv->length() != subIds.size() )
3350 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3351 for ( size_t i = 0; i < vv->length(); ++i )
3352 intVals[ subIds[ i ]] = (int) vv[ i ];
3355 case GEOM::FDT_Bool:
3357 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3358 if ( boolStep->_is_nil() ) continue;
3359 GEOM::short_array_var vv = boolStep->GetValues();
3360 if ( vv->length() != subIds.size() )
3361 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3362 for ( size_t i = 0; i < vv->length(); ++i )
3363 intVals[ subIds[ i ]] = (int) vv[ i ];
3369 // pass values to fieldWriter
3370 elemIt = fieldWriter.GetOrderedElems();
3371 if ( dataType == GEOM::FDT_Double )
3372 while ( elemIt->more() )
3374 const SMDS_MeshElement* e = elemIt->next();
3375 const int shapeID = e->getshapeId();
3376 if ( shapeID < 1 || shapeID >= dblVals.size() )
3377 fieldWriter.AddValue( noneDblValue );
3379 fieldWriter.AddValue( dblVals[ shapeID ]);
3382 while ( elemIt->more() )
3384 const SMDS_MeshElement* e = elemIt->next();
3385 const int shapeID = e->getshapeId();
3386 if ( shapeID < 1 || shapeID >= intVals.size() )
3387 fieldWriter.AddValue( (double) noneIntValue );
3389 fieldWriter.AddValue( (double) intVals[ shapeID ]);
3393 fieldWriter.Perform();
3394 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3395 if ( res && res->IsKO() )
3397 if ( res->myComment.empty() )
3398 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3400 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3406 if ( !geomAssocFields || !geomAssocFields[0] )
3409 // write geomAssocFields
3411 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3412 shapeDim[ TopAbs_COMPOUND ] = 3;
3413 shapeDim[ TopAbs_COMPSOLID ] = 3;
3414 shapeDim[ TopAbs_SOLID ] = 3;
3415 shapeDim[ TopAbs_SHELL ] = 2;
3416 shapeDim[ TopAbs_FACE ] = 2;
3417 shapeDim[ TopAbs_WIRE ] = 1;
3418 shapeDim[ TopAbs_EDGE ] = 1;
3419 shapeDim[ TopAbs_VERTEX ] = 0;
3420 shapeDim[ TopAbs_SHAPE ] = 3;
3422 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3424 std::vector< std::string > compNames;
3425 switch ( geomAssocFields[ iF ]) {
3427 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3428 compNames.push_back( "dim" );
3431 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3434 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3437 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3441 compNames.push_back( "id" );
3442 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3443 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3445 fieldWriter.SetDtIt( -1, -1 );
3447 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3451 if ( compNames.size() == 2 ) // _vertices_
3452 while ( elemIt->more() )
3454 const SMDS_MeshElement* e = elemIt->next();
3455 const int shapeID = e->getshapeId();
3458 fieldWriter.AddValue( (double) -1 );
3459 fieldWriter.AddValue( (double) -1 );
3463 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3464 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3465 fieldWriter.AddValue( (double) shapeID );
3469 while ( elemIt->more() )
3471 const SMDS_MeshElement* e = elemIt->next();
3472 const int shapeID = e->getshapeId();
3474 fieldWriter.AddValue( (double) -1 );
3476 fieldWriter.AddValue( (double) shapeID );
3480 fieldWriter.Perform();
3481 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3482 if ( res && res->IsKO() )
3484 if ( res->myComment.empty() )
3485 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3487 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3490 } // loop on geomAssocFields
3495 //================================================================================
3497 * \brief Export a part of mesh to a DAT file
3499 //================================================================================
3501 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3503 throw (SALOME::SALOME_Exception)
3505 Unexpect aCatch(SALOME_SalomeException);
3507 _preMeshInfo->FullLoadFromFile();
3509 PrepareForWriting(file);
3511 SMESH_MeshPartDS partDS( meshPart );
3512 _impl->ExportDAT(file,&partDS);
3514 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3515 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3517 //================================================================================
3519 * \brief Export a part of mesh to an UNV file
3521 //================================================================================
3523 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3525 throw (SALOME::SALOME_Exception)
3527 Unexpect aCatch(SALOME_SalomeException);
3529 _preMeshInfo->FullLoadFromFile();
3531 PrepareForWriting(file);
3533 SMESH_MeshPartDS partDS( meshPart );
3534 _impl->ExportUNV(file, &partDS);
3536 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3537 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3539 //================================================================================
3541 * \brief Export a part of mesh to an STL file
3543 //================================================================================
3545 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3547 ::CORBA::Boolean isascii)
3548 throw (SALOME::SALOME_Exception)
3550 Unexpect aCatch(SALOME_SalomeException);
3552 _preMeshInfo->FullLoadFromFile();
3554 PrepareForWriting(file);
3556 SMESH_MeshPartDS partDS( meshPart );
3557 _impl->ExportSTL(file, isascii, &partDS);
3559 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3560 << meshPart<< ", r'" << file << "', " << isascii << ")";
3563 //================================================================================
3565 * \brief Export a part of mesh to an STL file
3567 //================================================================================
3569 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3571 CORBA::Boolean overwrite)
3572 throw (SALOME::SALOME_Exception)
3575 Unexpect aCatch(SALOME_SalomeException);
3577 _preMeshInfo->FullLoadFromFile();
3579 PrepareForWriting(file,overwrite);
3581 std::string meshName("");
3582 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3583 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3584 if ( !so->_is_nil() )
3586 CORBA::String_var name = so->GetName();
3587 meshName = name.in();
3589 SMESH_MeshPartDS partDS( meshPart );
3590 _impl->ExportCGNS(file, &partDS, meshName.c_str() );
3592 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3593 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3595 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3599 //================================================================================
3601 * \brief Export a part of mesh to a GMF file
3603 //================================================================================
3605 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3607 bool withRequiredGroups)
3608 throw (SALOME::SALOME_Exception)
3610 Unexpect aCatch(SALOME_SalomeException);
3612 _preMeshInfo->FullLoadFromFile();
3614 PrepareForWriting(file,/*overwrite=*/true);
3616 SMESH_MeshPartDS partDS( meshPart );
3617 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3619 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3620 << meshPart<< ", r'"
3622 << withRequiredGroups << ")";
3625 //=============================================================================
3627 * Return computation progress [0.,1]
3629 //=============================================================================
3631 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3635 return _impl->GetComputeProgress();
3637 SMESH_CATCH( SMESH::doNothing );
3641 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3643 Unexpect aCatch(SALOME_SalomeException);
3645 return _preMeshInfo->NbNodes();
3647 return _impl->NbNodes();
3650 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3652 Unexpect aCatch(SALOME_SalomeException);
3654 return _preMeshInfo->NbElements();
3656 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3659 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3661 Unexpect aCatch(SALOME_SalomeException);
3663 return _preMeshInfo->Nb0DElements();
3665 return _impl->Nb0DElements();
3668 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3670 Unexpect aCatch(SALOME_SalomeException);
3672 return _preMeshInfo->NbBalls();
3674 return _impl->NbBalls();
3677 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3679 Unexpect aCatch(SALOME_SalomeException);
3681 return _preMeshInfo->NbEdges();
3683 return _impl->NbEdges();
3686 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3687 throw(SALOME::SALOME_Exception)
3689 Unexpect aCatch(SALOME_SalomeException);
3691 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3693 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3696 //=============================================================================
3698 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3700 Unexpect aCatch(SALOME_SalomeException);
3702 return _preMeshInfo->NbFaces();
3704 return _impl->NbFaces();
3707 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3709 Unexpect aCatch(SALOME_SalomeException);
3711 return _preMeshInfo->NbTriangles();
3713 return _impl->NbTriangles();
3716 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3718 Unexpect aCatch(SALOME_SalomeException);
3720 return _preMeshInfo->NbBiQuadTriangles();
3722 return _impl->NbBiQuadTriangles();
3725 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3727 Unexpect aCatch(SALOME_SalomeException);
3729 return _preMeshInfo->NbQuadrangles();
3731 return _impl->NbQuadrangles();
3734 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3736 Unexpect aCatch(SALOME_SalomeException);
3738 return _preMeshInfo->NbBiQuadQuadrangles();
3740 return _impl->NbBiQuadQuadrangles();
3743 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3745 Unexpect aCatch(SALOME_SalomeException);
3747 return _preMeshInfo->NbPolygons();
3749 return _impl->NbPolygons();
3752 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3753 throw(SALOME::SALOME_Exception)
3755 Unexpect aCatch(SALOME_SalomeException);
3757 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3759 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3762 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3763 throw(SALOME::SALOME_Exception)
3765 Unexpect aCatch(SALOME_SalomeException);
3767 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3769 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3772 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3773 throw(SALOME::SALOME_Exception)
3775 Unexpect aCatch(SALOME_SalomeException);
3777 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3779 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3782 //=============================================================================
3784 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3786 Unexpect aCatch(SALOME_SalomeException);
3788 return _preMeshInfo->NbVolumes();
3790 return _impl->NbVolumes();
3793 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3795 Unexpect aCatch(SALOME_SalomeException);
3797 return _preMeshInfo->NbTetras();
3799 return _impl->NbTetras();
3802 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3804 Unexpect aCatch(SALOME_SalomeException);
3806 return _preMeshInfo->NbHexas();
3808 return _impl->NbHexas();
3811 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3813 Unexpect aCatch(SALOME_SalomeException);
3815 return _preMeshInfo->NbTriQuadHexas();
3817 return _impl->NbTriQuadraticHexas();
3820 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3822 Unexpect aCatch(SALOME_SalomeException);
3824 return _preMeshInfo->NbPyramids();
3826 return _impl->NbPyramids();
3829 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3831 Unexpect aCatch(SALOME_SalomeException);
3833 return _preMeshInfo->NbPrisms();
3835 return _impl->NbPrisms();
3838 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3840 Unexpect aCatch(SALOME_SalomeException);
3842 return _preMeshInfo->NbHexPrisms();
3844 return _impl->NbHexagonalPrisms();
3847 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3849 Unexpect aCatch(SALOME_SalomeException);
3851 return _preMeshInfo->NbPolyhedrons();
3853 return _impl->NbPolyhedrons();
3856 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3857 throw(SALOME::SALOME_Exception)
3859 Unexpect aCatch(SALOME_SalomeException);
3861 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3863 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3866 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3867 throw(SALOME::SALOME_Exception)
3869 Unexpect aCatch(SALOME_SalomeException);
3871 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3873 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3876 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3877 throw(SALOME::SALOME_Exception)
3879 Unexpect aCatch(SALOME_SalomeException);
3881 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3883 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3886 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3887 throw(SALOME::SALOME_Exception)
3889 Unexpect aCatch(SALOME_SalomeException);
3891 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3893 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3896 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3897 throw(SALOME::SALOME_Exception)
3899 Unexpect aCatch(SALOME_SalomeException);
3901 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3903 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3906 //=============================================================================
3908 * Returns nb of published sub-meshes
3910 //=============================================================================
3912 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3914 Unexpect aCatch(SALOME_SalomeException);
3915 return _mapSubMesh_i.size();
3918 //=============================================================================
3920 * Dumps mesh into a string
3922 //=============================================================================
3924 char* SMESH_Mesh_i::Dump()
3928 return CORBA::string_dup( os.str().c_str() );
3931 //=============================================================================
3933 * Method of SMESH_IDSource interface
3935 //=============================================================================
3937 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3939 return GetElementsId();
3942 //=============================================================================
3944 * Returns ids of all elements
3946 //=============================================================================
3948 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3949 throw (SALOME::SALOME_Exception)
3951 Unexpect aCatch(SALOME_SalomeException);
3953 _preMeshInfo->FullLoadFromFile();
3955 SMESH::long_array_var aResult = new SMESH::long_array();
3956 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3958 if ( aSMESHDS_Mesh == NULL )
3959 return aResult._retn();
3961 long nbElements = NbElements();
3962 aResult->length( nbElements );
3963 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3964 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3965 aResult[i] = anIt->next()->GetID();
3967 return aResult._retn();
3971 //=============================================================================
3973 * Returns ids of all elements of given type
3975 //=============================================================================
3977 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3978 throw (SALOME::SALOME_Exception)
3980 Unexpect aCatch(SALOME_SalomeException);
3982 _preMeshInfo->FullLoadFromFile();
3984 SMESH::long_array_var aResult = new SMESH::long_array();
3985 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3987 if ( aSMESHDS_Mesh == NULL )
3988 return aResult._retn();
3990 long nbElements = NbElements();
3992 // No sense in returning ids of elements along with ids of nodes:
3993 // when theElemType == SMESH::ALL, return node ids only if
3994 // there are no elements
3995 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3996 return GetNodesId();
3998 aResult->length( nbElements );
4002 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4003 while ( i < nbElements && anIt->more() )
4004 aResult[i++] = anIt->next()->GetID();
4006 aResult->length( i );
4008 return aResult._retn();
4011 //=============================================================================
4013 * Returns ids of all nodes
4015 //=============================================================================
4017 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4018 throw (SALOME::SALOME_Exception)
4020 Unexpect aCatch(SALOME_SalomeException);
4022 _preMeshInfo->FullLoadFromFile();
4024 SMESH::long_array_var aResult = new SMESH::long_array();
4025 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4027 if ( aSMESHDS_Mesh == NULL )
4028 return aResult._retn();
4030 long nbNodes = NbNodes();
4031 aResult->length( nbNodes );
4032 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4033 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4034 aResult[i] = anIt->next()->GetID();
4036 return aResult._retn();
4039 //=============================================================================
4043 //=============================================================================
4045 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4046 throw (SALOME::SALOME_Exception)
4048 SMESH::ElementType type;
4052 _preMeshInfo->FullLoadFromFile();
4054 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4056 SMESH_CATCH( SMESH::throwCorbaException );
4061 //=============================================================================
4065 //=============================================================================
4067 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4068 throw (SALOME::SALOME_Exception)
4071 _preMeshInfo->FullLoadFromFile();
4073 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4075 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4077 return ( SMESH::EntityType ) e->GetEntityType();
4080 //=============================================================================
4084 //=============================================================================
4086 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4087 throw (SALOME::SALOME_Exception)
4090 _preMeshInfo->FullLoadFromFile();
4092 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4094 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4096 return ( SMESH::GeometryType ) e->GetGeomType();
4099 //=============================================================================
4101 * Returns ID of elements for given submesh
4103 //=============================================================================
4104 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4105 throw (SALOME::SALOME_Exception)
4107 SMESH::long_array_var aResult = new SMESH::long_array();
4111 _preMeshInfo->FullLoadFromFile();
4113 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4114 if(!SM) return aResult._retn();
4116 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4117 if(!SDSM) return aResult._retn();
4119 aResult->length(SDSM->NbElements());
4121 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4123 while ( eIt->more() ) {
4124 aResult[i++] = eIt->next()->GetID();
4127 SMESH_CATCH( SMESH::throwCorbaException );
4129 return aResult._retn();
4132 //=============================================================================
4134 * Returns ID of nodes for given submesh
4135 * If param all==true - returns all nodes, else -
4136 * returns only nodes on shapes.
4138 //=============================================================================
4140 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4142 throw (SALOME::SALOME_Exception)
4144 SMESH::long_array_var aResult = new SMESH::long_array();
4148 _preMeshInfo->FullLoadFromFile();
4150 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4151 if(!SM) return aResult._retn();
4153 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4154 if(!SDSM) return aResult._retn();
4157 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4158 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4159 while ( nIt->more() ) {
4160 const SMDS_MeshNode* elem = nIt->next();
4161 theElems.insert( elem->GetID() );
4164 else { // all nodes of submesh elements
4165 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4166 while ( eIt->more() ) {
4167 const SMDS_MeshElement* anElem = eIt->next();
4168 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4169 while ( nIt->more() ) {
4170 const SMDS_MeshElement* elem = nIt->next();
4171 theElems.insert( elem->GetID() );
4176 aResult->length(theElems.size());
4177 set<int>::iterator itElem;
4179 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4180 aResult[i++] = *itElem;
4182 SMESH_CATCH( SMESH::throwCorbaException );
4184 return aResult._retn();
4187 //=============================================================================
4189 * Returns type of elements for given submesh
4191 //=============================================================================
4193 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4194 throw (SALOME::SALOME_Exception)
4196 SMESH::ElementType type;
4200 _preMeshInfo->FullLoadFromFile();
4202 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4203 if(!SM) return SMESH::ALL;
4205 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4206 if(!SDSM) return SMESH::ALL;
4208 if(SDSM->NbElements()==0)
4209 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4211 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4212 const SMDS_MeshElement* anElem = eIt->next();
4214 type = ( SMESH::ElementType ) anElem->GetType();
4216 SMESH_CATCH( SMESH::throwCorbaException );
4222 //=============================================================================
4224 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4226 //=============================================================================
4228 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4231 _preMeshInfo->FullLoadFromFile();
4233 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4235 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4240 //=============================================================================
4242 * Get XYZ coordinates of node as list of double
4243 * If there is not node for given ID - returns empty list
4245 //=============================================================================
4247 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4250 _preMeshInfo->FullLoadFromFile();
4252 SMESH::double_array_var aResult = new SMESH::double_array();
4253 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4254 if ( aSMESHDS_Mesh == NULL )
4255 return aResult._retn();
4258 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4260 return aResult._retn();
4264 aResult[0] = aNode->X();
4265 aResult[1] = aNode->Y();
4266 aResult[2] = aNode->Z();
4267 return aResult._retn();
4271 //=============================================================================
4273 * For given node returns list of IDs of inverse elements
4274 * If there is not node for given ID - returns empty list
4276 //=============================================================================
4278 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4281 _preMeshInfo->FullLoadFromFile();
4283 SMESH::long_array_var aResult = new SMESH::long_array();
4284 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4285 if ( aSMESHDS_Mesh == NULL )
4286 return aResult._retn();
4289 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4291 return aResult._retn();
4293 // find inverse elements
4294 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4295 aResult->length( aNode->NbInverseElements() );
4296 for( int i = 0; eIt->more(); ++i )
4298 const SMDS_MeshElement* elem = eIt->next();
4299 aResult[ i ] = elem->GetID();
4301 return aResult._retn();
4304 //=============================================================================
4306 * \brief Return position of a node on shape
4308 //=============================================================================
4310 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4313 _preMeshInfo->FullLoadFromFile();
4315 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4316 aNodePosition->shapeID = 0;
4317 aNodePosition->shapeType = GEOM::SHAPE;
4319 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4320 if ( !mesh ) return aNodePosition;
4322 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4324 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4326 aNodePosition->shapeID = aNode->getshapeId();
4327 switch ( pos->GetTypeOfPosition() ) {
4329 aNodePosition->shapeType = GEOM::EDGE;
4330 aNodePosition->params.length(1);
4331 aNodePosition->params[0] =
4332 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4335 aNodePosition->shapeType = GEOM::FACE;
4336 aNodePosition->params.length(2);
4337 aNodePosition->params[0] =
4338 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4339 aNodePosition->params[1] =
4340 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4342 case SMDS_TOP_VERTEX:
4343 aNodePosition->shapeType = GEOM::VERTEX;
4345 case SMDS_TOP_3DSPACE:
4346 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4347 aNodePosition->shapeType = GEOM::SOLID;
4348 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4349 aNodePosition->shapeType = GEOM::SHELL;
4355 return aNodePosition;
4358 //=============================================================================
4360 * \brief Return position of an element on shape
4362 //=============================================================================
4364 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4367 _preMeshInfo->FullLoadFromFile();
4369 SMESH::ElementPosition anElementPosition;
4370 anElementPosition.shapeID = 0;
4371 anElementPosition.shapeType = GEOM::SHAPE;
4373 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4374 if ( !mesh ) return anElementPosition;
4376 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4378 anElementPosition.shapeID = anElem->getshapeId();
4379 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4380 if ( !aSp.IsNull() ) {
4381 switch ( aSp.ShapeType() ) {
4383 anElementPosition.shapeType = GEOM::EDGE;
4386 anElementPosition.shapeType = GEOM::FACE;
4389 anElementPosition.shapeType = GEOM::VERTEX;
4392 anElementPosition.shapeType = GEOM::SOLID;
4395 anElementPosition.shapeType = GEOM::SHELL;
4401 return anElementPosition;
4404 //=============================================================================
4406 * If given element is node returns IDs of shape from position
4407 * If there is not node for given ID - returns -1
4409 //=============================================================================
4411 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4414 _preMeshInfo->FullLoadFromFile();
4416 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4417 if ( aSMESHDS_Mesh == NULL )
4421 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4423 return aNode->getshapeId();
4430 //=============================================================================
4432 * For given element returns ID of result shape after
4433 * ::FindShape() from SMESH_MeshEditor
4434 * If there is not element for given ID - returns -1
4436 //=============================================================================
4438 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4441 _preMeshInfo->FullLoadFromFile();
4443 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4444 if ( aSMESHDS_Mesh == NULL )
4447 // try to find element
4448 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4452 ::SMESH_MeshEditor aMeshEditor(_impl);
4453 int index = aMeshEditor.FindShape( elem );
4461 //=============================================================================
4463 * Returns number of nodes for given element
4464 * If there is not element for given ID - returns -1
4466 //=============================================================================
4468 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4471 _preMeshInfo->FullLoadFromFile();
4473 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4474 if ( aSMESHDS_Mesh == NULL ) return -1;
4475 // try to find element
4476 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4477 if(!elem) return -1;
4478 return elem->NbNodes();
4482 //=============================================================================
4484 * Returns ID of node by given index for given element
4485 * If there is not element for given ID - returns -1
4486 * If there is not node for given index - returns -2
4488 //=============================================================================
4490 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4493 _preMeshInfo->FullLoadFromFile();
4495 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4496 if ( aSMESHDS_Mesh == NULL ) return -1;
4497 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4498 if(!elem) return -1;
4499 if( index>=elem->NbNodes() || index<0 ) return -1;
4500 return elem->GetNode(index)->GetID();
4503 //=============================================================================
4505 * Returns IDs of nodes of given element
4507 //=============================================================================
4509 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4512 _preMeshInfo->FullLoadFromFile();
4514 SMESH::long_array_var aResult = new SMESH::long_array();
4515 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4517 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4519 aResult->length( elem->NbNodes() );
4520 for ( int i = 0; i < elem->NbNodes(); ++i )
4521 aResult[ i ] = elem->GetNode( i )->GetID();
4524 return aResult._retn();
4527 //=============================================================================
4529 * Returns true if given node is medium node
4530 * in given quadratic element
4532 //=============================================================================
4534 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4537 _preMeshInfo->FullLoadFromFile();
4539 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4540 if ( aSMESHDS_Mesh == NULL ) return false;
4542 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4543 if(!aNode) return false;
4544 // try to find element
4545 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4546 if(!elem) return false;
4548 return elem->IsMediumNode(aNode);
4552 //=============================================================================
4554 * Returns true if given node is medium node
4555 * in one of quadratic elements
4557 //=============================================================================
4559 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4560 SMESH::ElementType theElemType)
4563 _preMeshInfo->FullLoadFromFile();
4565 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4566 if ( aSMESHDS_Mesh == NULL ) return false;
4569 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4570 if(!aNode) return false;
4572 SMESH_MesherHelper aHelper( *(_impl) );
4574 SMDSAbs_ElementType aType;
4575 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4576 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4577 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4578 else aType = SMDSAbs_All;
4580 return aHelper.IsMedium(aNode,aType);
4584 //=============================================================================
4586 * Returns number of edges for given element
4588 //=============================================================================
4590 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4593 _preMeshInfo->FullLoadFromFile();
4595 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4596 if ( aSMESHDS_Mesh == NULL ) return -1;
4597 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4598 if(!elem) return -1;
4599 return elem->NbEdges();
4603 //=============================================================================
4605 * Returns number of faces for given element
4607 //=============================================================================
4609 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4612 _preMeshInfo->FullLoadFromFile();
4614 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4615 if ( aSMESHDS_Mesh == NULL ) return -1;
4616 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4617 if(!elem) return -1;
4618 return elem->NbFaces();
4621 //=======================================================================
4622 //function : GetElemFaceNodes
4623 //purpose : Returns nodes of given face (counted from zero) for given element.
4624 //=======================================================================
4626 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4627 CORBA::Short faceIndex)
4630 _preMeshInfo->FullLoadFromFile();
4632 SMESH::long_array_var aResult = new SMESH::long_array();
4633 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4635 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4637 SMDS_VolumeTool vtool( elem );
4638 if ( faceIndex < vtool.NbFaces() )
4640 aResult->length( vtool.NbFaceNodes( faceIndex ));
4641 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4642 for ( int i = 0; i < aResult->length(); ++i )
4643 aResult[ i ] = nn[ i ]->GetID();
4647 return aResult._retn();
4650 //=======================================================================
4651 //function : GetElemFaceNodes
4652 //purpose : Returns three components of normal of given mesh face.
4653 //=======================================================================
4655 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4656 CORBA::Boolean normalized)
4659 _preMeshInfo->FullLoadFromFile();
4661 SMESH::double_array_var aResult = new SMESH::double_array();
4663 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4666 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4668 aResult->length( 3 );
4669 aResult[ 0 ] = normal.X();
4670 aResult[ 1 ] = normal.Y();
4671 aResult[ 2 ] = normal.Z();
4674 return aResult._retn();
4677 //=======================================================================
4678 //function : FindElementByNodes
4679 //purpose : Returns an element based on all given nodes.
4680 //=======================================================================
4682 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4685 _preMeshInfo->FullLoadFromFile();
4687 CORBA::Long elemID(0);
4688 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4690 vector< const SMDS_MeshNode * > nn( nodes.length() );
4691 for ( int i = 0; i < nodes.length(); ++i )
4692 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4695 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4696 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4697 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4698 _impl->NbVolumes( ORDER_QUADRATIC )))
4699 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4701 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4706 //=============================================================================
4708 * Returns true if given element is polygon
4710 //=============================================================================
4712 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4715 _preMeshInfo->FullLoadFromFile();
4717 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4718 if ( aSMESHDS_Mesh == NULL ) return false;
4719 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4720 if(!elem) return false;
4721 return elem->IsPoly();
4725 //=============================================================================
4727 * Returns true if given element is quadratic
4729 //=============================================================================
4731 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4734 _preMeshInfo->FullLoadFromFile();
4736 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4737 if ( aSMESHDS_Mesh == NULL ) return false;
4738 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4739 if(!elem) return false;
4740 return elem->IsQuadratic();
4743 //=============================================================================
4745 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4747 //=============================================================================
4749 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4752 _preMeshInfo->FullLoadFromFile();
4754 if ( const SMDS_BallElement* ball =
4755 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4756 return ball->GetDiameter();
4761 //=============================================================================
4763 * Returns bary center for given element
4765 //=============================================================================
4767 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4770 _preMeshInfo->FullLoadFromFile();
4772 SMESH::double_array_var aResult = new SMESH::double_array();
4773 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4774 if ( aSMESHDS_Mesh == NULL )
4775 return aResult._retn();
4777 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4779 return aResult._retn();
4781 if(elem->GetType()==SMDSAbs_Volume) {
4782 SMDS_VolumeTool aTool;
4783 if(aTool.Set(elem)) {
4785 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4790 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4792 double x=0., y=0., z=0.;
4793 for(; anIt->more(); ) {
4795 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4809 return aResult._retn();
4812 //================================================================================
4814 * \brief Create a group of elements preventing computation of a sub-shape
4816 //================================================================================
4818 SMESH::ListOfGroups*
4819 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4820 const char* theGroupName )
4821 throw ( SALOME::SALOME_Exception )
4823 Unexpect aCatch(SALOME_SalomeException);
4825 if ( !theGroupName || strlen( theGroupName) == 0 )
4826 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4828 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4830 // submesh by subshape id
4831 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4832 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4835 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4836 if ( error && !error->myBadElements.empty())
4838 // sort bad elements by type
4839 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4840 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4841 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4842 for ( ; elemIt != elemEnd; ++elemIt )
4844 const SMDS_MeshElement* elem = *elemIt;
4845 if ( !elem ) continue;
4847 if ( elem->GetID() < 1 )
4849 // elem is a temporary element, make a real element
4850 vector< const SMDS_MeshNode* > nodes;
4851 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4852 while ( nIt->more() && elem )
4854 nodes.push_back( nIt->next() );
4855 if ( nodes.back()->GetID() < 1 )
4856 elem = 0; // a temporary element on temporary nodes
4860 ::SMESH_MeshEditor editor( _impl );
4861 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4865 elemsByType[ elem->GetType() ].push_back( elem );
4868 // how many groups to create?
4870 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4871 nbTypes += int( !elemsByType[ i ].empty() );
4872 groups->length( nbTypes );
4875 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4877 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4878 if ( elems.empty() ) continue;
4880 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4881 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4883 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4884 SMESH::SMESH_Mesh_var mesh = _this();
4885 SALOMEDS::SObject_wrap aSO =
4886 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4887 GEOM::GEOM_Object::_nil(), theGroupName);
4889 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4890 if ( !grp_i ) continue;
4892 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4893 for ( size_t iE = 0; iE < elems.size(); ++iE )
4894 grpDS->SMDSGroup().Add( elems[ iE ]);
4899 return groups._retn();
4902 //=============================================================================
4904 * Create and publish group servants if any groups were imported or created anyhow
4906 //=============================================================================
4908 void SMESH_Mesh_i::CreateGroupServants()
4910 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4911 SMESH::SMESH_Mesh_var aMesh = _this();
4914 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4915 while ( groupIt->more() )
4917 ::SMESH_Group* group = groupIt->next();
4918 int anId = group->GetGroupDS()->GetID();
4920 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4921 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4923 addedIDs.insert( anId );
4925 SMESH_GroupBase_i* aGroupImpl;
4927 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4928 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4930 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4931 shape = groupOnGeom->GetShape();
4934 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4937 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4938 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4939 aGroupImpl->Register();
4941 // register CORBA object for persistence
4942 int nextId = _gen_i->RegisterObject( groupVar );
4943 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4944 else { nextId = 0; } // avoid "unused variable" warning in release mode
4946 // publishing the groups in the study
4947 if ( !aStudy->_is_nil() ) {
4948 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4949 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4952 if ( !addedIDs.empty() )
4955 set<int>::iterator id = addedIDs.begin();
4956 for ( ; id != addedIDs.end(); ++id )
4958 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4959 int i = std::distance( _mapGroups.begin(), it );
4960 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4965 //=============================================================================
4967 * \brief Return groups cantained in _mapGroups by their IDs
4969 //=============================================================================
4971 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4973 int nbGroups = groupIDs.size();
4974 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4975 aList->length( nbGroups );
4977 list<int>::const_iterator ids = groupIDs.begin();
4978 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4980 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4981 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4982 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4984 aList->length( nbGroups );
4985 return aList._retn();
4988 //=============================================================================
4990 * \brief Return information about imported file
4992 //=============================================================================
4994 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4996 SMESH::MedFileInfo_var res( _medFileInfo );
4997 if ( !res.operator->() ) {
4998 res = new SMESH::MedFileInfo;
5000 res->fileSize = res->major = res->minor = res->release = -1;
5005 //=============================================================================
5007 * \brief Pass names of mesh groups from study to mesh DS
5009 //=============================================================================
5011 void SMESH_Mesh_i::checkGroupNames()
5013 int nbGrp = NbGroups();
5017 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5018 if ( aStudy->_is_nil() )
5019 return; // nothing to do
5021 SMESH::ListOfGroups* grpList = 0;
5022 // avoid dump of "GetGroups"
5024 // store python dump into a local variable inside local scope
5025 SMESH::TPythonDump pDump; // do not delete this line of code
5026 grpList = GetGroups();
5029 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5030 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5033 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5034 if ( aGrpSO->_is_nil() )
5036 // correct name of the mesh group if necessary
5037 const char* guiName = aGrpSO->GetName();
5038 if ( strcmp(guiName, aGrp->GetName()) )
5039 aGrp->SetName( guiName );
5043 //=============================================================================
5045 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5047 //=============================================================================
5048 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5050 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5054 //=============================================================================
5056 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5058 //=============================================================================
5060 char* SMESH_Mesh_i::GetParameters()
5062 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5065 //=============================================================================
5067 * \brief Returns list of notebook variables used for last Mesh operation
5069 //=============================================================================
5070 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5072 SMESH::string_array_var aResult = new SMESH::string_array();
5073 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5075 CORBA::String_var aParameters = GetParameters();
5076 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5077 if ( !aStudy->_is_nil()) {
5078 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5079 if(aSections->length() > 0) {
5080 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
5081 aResult->length(aVars.length());
5082 for(int i = 0;i < aVars.length();i++)
5083 aResult[i] = CORBA::string_dup( aVars[i]);
5087 return aResult._retn();
5090 //=======================================================================
5091 //function : GetTypes
5092 //purpose : Returns types of elements it contains
5093 //=======================================================================
5095 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5098 return _preMeshInfo->GetTypes();
5100 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5104 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5105 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5106 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5107 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5108 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5109 types->length( nbTypes );
5111 return types._retn();
5114 //=======================================================================
5115 //function : GetMesh
5116 //purpose : Returns self
5117 //=======================================================================
5119 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5121 return SMESH::SMESH_Mesh::_duplicate( _this() );
5124 //=======================================================================
5125 //function : IsMeshInfoCorrect
5126 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5127 // * happen if mesh data is not yet fully loaded from the file of study.
5128 //=======================================================================
5130 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5132 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5135 //=============================================================================
5137 * \brief Returns number of mesh elements per each \a EntityType
5139 //=============================================================================
5141 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5144 return _preMeshInfo->GetMeshInfo();
5146 SMESH::long_array_var aRes = new SMESH::long_array();
5147 aRes->length(SMESH::Entity_Last);
5148 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5150 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5152 return aRes._retn();
5153 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5154 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5155 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5156 return aRes._retn();
5159 //=============================================================================
5161 * \brief Returns number of mesh elements per each \a ElementType
5163 //=============================================================================
5165 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5167 SMESH::long_array_var aRes = new SMESH::long_array();
5168 aRes->length(SMESH::NB_ELEMENT_TYPES);
5169 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5172 const SMDS_MeshInfo* meshInfo = 0;
5174 meshInfo = _preMeshInfo;
5175 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5176 meshInfo = & meshDS->GetMeshInfo();
5179 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5180 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5182 return aRes._retn();
5185 //=============================================================================
5187 * Collect statistic of mesh elements given by iterator
5189 //=============================================================================
5191 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5192 SMESH::long_array& theInfo)
5194 if (!theItr) return;
5195 while (theItr->more())
5196 theInfo[ theItr->next()->GetEntityType() ]++;
5198 //=============================================================================
5200 * Returns mesh unstructed grid information.
5202 //=============================================================================
5204 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5206 SALOMEDS::TMPFile_var SeqFile;
5207 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5208 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5210 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5211 aWriter->WriteToOutputStringOn();
5212 aWriter->SetInputData(aGrid);
5213 aWriter->SetFileTypeToBinary();
5215 char* str = aWriter->GetOutputString();
5216 int size = aWriter->GetOutputStringLength();
5218 //Allocate octect buffer of required size
5219 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5220 //Copy ostrstream content to the octect buffer
5221 memcpy(OctetBuf, str, size);
5222 //Create and return TMPFile
5223 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5227 return SeqFile._retn();
5230 //=============================================================================
5231 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5232 * SMESH::ElementType type) */
5234 using namespace SMESH::Controls;
5235 //-----------------------------------------------------------------------------
5236 struct PredicateIterator : public SMDS_ElemIterator
5238 SMDS_ElemIteratorPtr _elemIter;
5239 PredicatePtr _predicate;
5240 const SMDS_MeshElement* _elem;
5242 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5243 PredicatePtr predicate):
5244 _elemIter(iterator), _predicate(predicate)
5252 virtual const SMDS_MeshElement* next()
5254 const SMDS_MeshElement* res = _elem;
5256 while ( _elemIter->more() && !_elem )
5258 _elem = _elemIter->next();
5259 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5266 //-----------------------------------------------------------------------------
5267 struct IDSourceIterator : public SMDS_ElemIterator
5269 const CORBA::Long* _idPtr;
5270 const CORBA::Long* _idEndPtr;
5271 SMESH::long_array_var _idArray;
5272 const SMDS_Mesh* _mesh;
5273 const SMDSAbs_ElementType _type;
5274 const SMDS_MeshElement* _elem;
5276 IDSourceIterator( const SMDS_Mesh* mesh,
5277 const CORBA::Long* ids,
5279 SMDSAbs_ElementType type):
5280 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5282 if ( _idPtr && nbIds && _mesh )
5285 IDSourceIterator( const SMDS_Mesh* mesh,
5286 SMESH::long_array* idArray,
5287 SMDSAbs_ElementType type):
5288 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5290 if ( idArray && _mesh )
5292 _idPtr = &_idArray[0];
5293 _idEndPtr = _idPtr + _idArray->length();
5301 virtual const SMDS_MeshElement* next()
5303 const SMDS_MeshElement* res = _elem;
5305 while ( _idPtr < _idEndPtr && !_elem )
5307 if ( _type == SMDSAbs_Node )
5309 _elem = _mesh->FindNode( *_idPtr++ );
5311 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5312 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5320 //-----------------------------------------------------------------------------
5322 struct NodeOfElemIterator : public SMDS_ElemIterator
5324 TColStd_MapOfInteger _checkedNodeIDs;
5325 SMDS_ElemIteratorPtr _elemIter;
5326 SMDS_ElemIteratorPtr _nodeIter;
5327 const SMDS_MeshElement* _node;
5329 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5331 if ( _elemIter && _elemIter->more() )
5333 _nodeIter = _elemIter->next()->nodesIterator();
5341 virtual const SMDS_MeshElement* next()
5343 const SMDS_MeshElement* res = _node;
5345 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5347 if ( _nodeIter->more() )
5349 _node = _nodeIter->next();
5350 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5355 _nodeIter = _elemIter->next()->nodesIterator();
5363 //=============================================================================
5365 * Return iterator on elements of given type in given object
5367 //=============================================================================
5369 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5370 SMESH::ElementType theType)
5372 SMDS_ElemIteratorPtr elemIt;
5373 bool typeOK = false;
5374 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5376 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5377 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5378 if ( !mesh_i ) return elemIt;
5379 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5381 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5383 elemIt = meshDS->elementsIterator( elemType );
5386 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5388 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5391 elemIt = sm->GetElements();
5392 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5394 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5395 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5399 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5401 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5402 if ( groupDS && ( elemType == groupDS->GetType() ||
5403 elemType == SMDSAbs_Node ||
5404 elemType == SMDSAbs_All ))
5406 elemIt = groupDS->GetElements();
5407 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5410 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5412 if ( filter_i->GetElementType() == theType ||
5413 elemType == SMDSAbs_Node ||
5414 elemType == SMDSAbs_All)
5416 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5417 if ( pred_i && pred_i->GetPredicate() )
5419 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5420 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5421 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5422 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5428 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5429 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5430 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5432 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5435 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5436 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5440 SMESH::long_array_var ids = theObject->GetIDs();
5441 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5443 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5446 if ( elemIt && elemIt->more() && !typeOK )
5448 if ( elemType == SMDSAbs_Node )
5450 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5454 elemIt = SMDS_ElemIteratorPtr();
5460 //=============================================================================
5461 namespace // Finding concurrent hypotheses
5462 //=============================================================================
5466 * \brief mapping of mesh dimension into shape type
5468 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5470 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5472 case 0: aType = TopAbs_VERTEX; break;
5473 case 1: aType = TopAbs_EDGE; break;
5474 case 2: aType = TopAbs_FACE; break;
5476 default:aType = TopAbs_SOLID; break;
5481 //-----------------------------------------------------------------------------
5483 * \brief Internal structure used to find concurent submeshes
5485 * It represents a pair < submesh, concurent dimension >, where
5486 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5487 * with another submesh. In other words, it is dimension of a hypothesis assigned
5494 int _dim; //!< a dimension the algo can build (concurrent dimension)
5495 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5496 TopTools_MapOfShape _shapeMap;
5497 SMESH_subMesh* _subMesh;
5498 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5500 //-----------------------------------------------------------------------------
5501 // Return the algorithm
5502 const SMESH_Algo* GetAlgo() const
5503 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5505 //-----------------------------------------------------------------------------
5507 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5509 const TopoDS_Shape& theShape)
5511 _subMesh = (SMESH_subMesh*)theSubMesh;
5512 SetShape( theDim, theShape );
5515 //-----------------------------------------------------------------------------
5517 void SetShape(const int theDim,
5518 const TopoDS_Shape& theShape)
5521 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5522 if (_dim >= _ownDim)
5523 _shapeMap.Add( theShape );
5525 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5526 for( ; anExp.More(); anExp.Next() )
5527 _shapeMap.Add( anExp.Current() );
5531 //-----------------------------------------------------------------------------
5532 //! Check sharing of sub-shapes
5533 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5534 const TopTools_MapOfShape& theToFind,
5535 const TopAbs_ShapeEnum theType)
5537 bool isShared = false;
5538 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5539 for (; !isShared && anItr.More(); anItr.Next() )
5541 const TopoDS_Shape aSubSh = anItr.Key();
5542 // check for case when concurrent dimensions are same
5543 isShared = theToFind.Contains( aSubSh );
5544 // check for sub-shape with concurrent dimension
5545 TopExp_Explorer anExp( aSubSh, theType );
5546 for ( ; !isShared && anExp.More(); anExp.Next() )
5547 isShared = theToFind.Contains( anExp.Current() );
5552 //-----------------------------------------------------------------------------
5553 //! check algorithms
5554 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5555 const SMESHDS_Hypothesis* theA2)
5557 if ( !theA1 || !theA2 ||
5558 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5559 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5560 return false; // one of the hypothesis is not algorithm
5561 // check algorithm names (should be equal)
5562 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5566 //-----------------------------------------------------------------------------
5567 //! Check if sub-shape hypotheses are concurrent
5568 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5570 if ( _subMesh == theOther->_subMesh )
5571 return false; // same sub-shape - should not be
5573 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5574 // any of the two submeshes is not on COMPOUND shape )
5575 // -> no concurrency
5576 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5577 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5578 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5579 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5580 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5583 // bool checkSubShape = ( _dim >= theOther->_dim )
5584 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5585 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5586 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5587 if ( !checkSubShape )
5590 // check algorithms to be same
5591 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5592 return true; // different algorithms -> concurrency !
5594 // check hypothesises for concurrence (skip first as algorithm)
5596 // pointers should be same, because it is referened from mesh hypothesis partition
5597 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5598 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5599 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5600 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5602 // the submeshes are concurrent if their algorithms has different parameters
5603 return nbSame != theOther->_hypotheses.size() - 1;
5606 // Return true if algorithm of this SMESH_DimHyp is used if no
5607 // sub-mesh order is imposed by the user
5608 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5610 // NeedDiscreteBoundary() algo has a higher priority
5611 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5612 theOther->GetAlgo()->NeedDiscreteBoundary() )
5613 return !this->GetAlgo()->NeedDiscreteBoundary();
5615 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5618 }; // end of SMESH_DimHyp
5619 //-----------------------------------------------------------------------------
5621 typedef list<const SMESH_DimHyp*> TDimHypList;
5623 //-----------------------------------------------------------------------------
5625 void addDimHypInstance(const int theDim,
5626 const TopoDS_Shape& theShape,
5627 const SMESH_Algo* theAlgo,
5628 const SMESH_subMesh* theSubMesh,
5629 const list <const SMESHDS_Hypothesis*>& theHypList,
5630 TDimHypList* theDimHypListArr )
5632 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5633 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5634 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5635 dimHyp->_hypotheses.push_front(theAlgo);
5636 listOfdimHyp.push_back( dimHyp );
5639 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5640 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5641 theHypList.begin(), theHypList.end() );
5644 //-----------------------------------------------------------------------------
5645 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5646 TDimHypList& theListOfConcurr)
5648 if ( theListOfConcurr.empty() )
5650 theListOfConcurr.push_back( theDimHyp );
5654 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5655 while ( hypIt != theListOfConcurr.end() &&
5656 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5658 theListOfConcurr.insert( hypIt, theDimHyp );
5662 //-----------------------------------------------------------------------------
5663 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5664 const TDimHypList& theListOfDimHyp,
5665 TDimHypList& theListOfConcurrHyp,
5666 set<int>& theSetOfConcurrId )
5668 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5669 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5671 const SMESH_DimHyp* curDimHyp = *rIt;
5672 if ( curDimHyp == theDimHyp )
5673 break; // meet own dimHyp pointer in same dimension
5675 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5676 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5678 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5683 //-----------------------------------------------------------------------------
5684 void unionLists(TListOfInt& theListOfId,
5685 TListOfListOfInt& theListOfListOfId,
5688 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5689 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5691 continue; //skip already treated lists
5692 // check if other list has any same submesh object
5693 TListOfInt& otherListOfId = *it;
5694 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5695 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5698 // union two lists (from source into target)
5699 TListOfInt::iterator it2 = otherListOfId.begin();
5700 for ( ; it2 != otherListOfId.end(); it2++ ) {
5701 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5702 theListOfId.push_back(*it2);
5704 // clear source list
5705 otherListOfId.clear();
5708 //-----------------------------------------------------------------------------
5710 //! free memory allocated for dimension-hypothesis objects
5711 void removeDimHyps( TDimHypList* theArrOfList )
5713 for (int i = 0; i < 4; i++ ) {
5714 TDimHypList& listOfdimHyp = theArrOfList[i];
5715 TDimHypList::const_iterator it = listOfdimHyp.begin();
5716 for ( ; it != listOfdimHyp.end(); it++ )
5721 //-----------------------------------------------------------------------------
5723 * \brief find common submeshes with given submesh
5724 * \param theSubMeshList list of already collected submesh to check
5725 * \param theSubMesh given submesh to intersect with other
5726 * \param theCommonSubMeshes collected common submeshes
5728 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5729 const SMESH_subMesh* theSubMesh,
5730 set<const SMESH_subMesh*>& theCommon )
5734 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5735 for ( ; it != theSubMeshList.end(); it++ )
5736 theSubMesh->FindIntersection( *it, theCommon );
5737 theSubMeshList.push_back( theSubMesh );
5738 //theCommon.insert( theSubMesh );
5741 //-----------------------------------------------------------------------------
5742 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5744 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5745 for ( ; listsIt != smLists.end(); ++listsIt )
5747 const TListOfInt& smIDs = *listsIt;
5748 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5756 //=============================================================================
5758 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5760 //=============================================================================
5762 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5764 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5765 if ( isSubMeshInList( submeshID, anOrder ))
5768 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5769 return isSubMeshInList( submeshID, allConurrent );
5772 //=============================================================================
5774 * \brief Return submesh objects list in meshing order
5776 //=============================================================================
5778 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5780 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5782 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5784 return aResult._retn();
5786 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5787 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5788 anOrder.splice( anOrder.end(), allConurrent );
5791 TListOfListOfInt::iterator listIt = anOrder.begin();
5792 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5793 unionLists( *listIt, anOrder, listIndx + 1 );
5795 // convert submesh ids into interface instances
5796 // and dump command into python
5797 convertMeshOrder( anOrder, aResult, false );
5799 return aResult._retn();
5802 //=============================================================================
5804 * \brief Finds concurrent sub-meshes
5806 //=============================================================================
5808 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5810 TListOfListOfInt anOrder;
5811 ::SMESH_Mesh& mesh = GetImpl();
5813 // collect submeshes and detect concurrent algorithms and hypothesises
5814 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5816 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5817 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5818 ::SMESH_subMesh* sm = (*i_sm).second;
5820 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5822 // list of assigned hypothesises
5823 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5824 // Find out dimensions where the submesh can be concurrent.
5825 // We define the dimensions by algo of each of hypotheses in hypList
5826 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5827 for( ; hypIt != hypList.end(); hypIt++ ) {
5828 SMESH_Algo* anAlgo = 0;
5829 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5830 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5831 // hyp it-self is algo
5832 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5834 // try to find algorithm with help of sub-shapes
5835 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5836 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5837 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5840 continue; // no algorithm assigned to a current submesh
5842 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5843 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5845 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5846 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5847 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5849 } // end iterations on submesh
5851 // iterate on created dimension-hypotheses and check for concurrents
5852 for ( int i = 0; i < 4; i++ ) {
5853 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5854 // check for concurrents in own and other dimensions (step-by-step)
5855 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5856 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5857 const SMESH_DimHyp* dimHyp = *dhIt;
5858 TDimHypList listOfConcurr;
5859 set<int> setOfConcurrIds;
5860 // looking for concurrents and collect into own list
5861 for ( int j = i; j < 4; j++ )
5862 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5863 // check if any concurrents found
5864 if ( listOfConcurr.size() > 0 ) {
5865 // add own submesh to list of concurrent
5866 addInOrderOfPriority( dimHyp, listOfConcurr );
5867 list<int> listOfConcurrIds;
5868 TDimHypList::iterator hypIt = listOfConcurr.begin();
5869 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5870 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5871 anOrder.push_back( listOfConcurrIds );
5876 removeDimHyps(dimHypListArr);
5878 // now, minimise the number of concurrent groups
5879 // Here we assume that lists of submeshes can have same submesh
5880 // in case of multi-dimension algorithms, as result
5881 // list with common submesh has to be united into one list
5883 TListOfListOfInt::iterator listIt = anOrder.begin();
5884 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5885 unionLists( *listIt, anOrder, listIndx + 1 );
5891 //=============================================================================
5893 * \brief Set submesh object order
5894 * \param theSubMeshArray submesh array order
5896 //=============================================================================
5898 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5901 _preMeshInfo->ForgetOrLoad();
5904 ::SMESH_Mesh& mesh = GetImpl();
5906 TPythonDump aPythonDump; // prevent dump of called methods
5907 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5909 TListOfListOfInt subMeshOrder;
5910 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5912 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5913 TListOfInt subMeshIds;
5915 aPythonDump << ", ";
5916 aPythonDump << "[ ";
5917 // Collect subMeshes which should be clear
5918 // do it list-by-list, because modification of submesh order
5919 // take effect between concurrent submeshes only
5920 set<const SMESH_subMesh*> subMeshToClear;
5921 list<const SMESH_subMesh*> subMeshList;
5922 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5924 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5926 aPythonDump << ", ";
5927 aPythonDump << subMesh;
5928 subMeshIds.push_back( subMesh->GetId() );
5929 // detect common parts of submeshes
5930 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5931 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5933 aPythonDump << " ]";
5934 subMeshOrder.push_back( subMeshIds );
5936 // clear collected submeshes
5937 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5938 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5939 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5940 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5942 aPythonDump << " ])";
5944 mesh.SetMeshOrder( subMeshOrder );
5950 //=============================================================================
5952 * \brief Convert submesh ids into submesh interfaces
5954 //=============================================================================
5956 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5957 SMESH::submesh_array_array& theResOrder,
5958 const bool theIsDump)
5960 int nbSet = theIdsOrder.size();
5961 TPythonDump aPythonDump; // prevent dump of called methods
5963 aPythonDump << "[ ";
5964 theResOrder.length(nbSet);
5965 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5967 for( ; it != theIdsOrder.end(); it++ ) {
5968 // translate submesh identificators into submesh objects
5969 // takeing into account real number of concurrent lists
5970 const TListOfInt& aSubOrder = (*it);
5971 if (!aSubOrder.size())
5974 aPythonDump << "[ ";
5975 // convert shape indeces into interfaces
5976 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5977 aResSubSet->length(aSubOrder.size());
5978 TListOfInt::const_iterator subIt = aSubOrder.begin();
5980 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5981 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5983 SMESH::SMESH_subMesh_var subMesh =
5984 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5987 aPythonDump << ", ";
5988 aPythonDump << subMesh;
5990 aResSubSet[ j++ ] = subMesh;
5993 aPythonDump << " ]";
5995 theResOrder[ listIndx++ ] = aResSubSet;
5997 // correct number of lists
5998 theResOrder.length( listIndx );
6001 // finilise python dump
6002 aPythonDump << " ]";
6003 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6007 //================================================================================
6009 // Implementation of SMESH_MeshPartDS
6011 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6012 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6014 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6015 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6017 _meshDS = mesh_i->GetImpl().GetMeshDS();
6019 SetPersistentId( _meshDS->GetPersistentId() );
6021 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6023 // <meshPart> is the whole mesh
6024 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6026 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6027 myGroupSet = _meshDS->GetGroups();
6032 SMESH::long_array_var anIDs = meshPart->GetIDs();
6033 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6034 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6036 for (int i=0; i < anIDs->length(); i++)
6037 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
6038 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6043 for (int i=0; i < anIDs->length(); i++)
6044 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6045 if ( _elements[ e->GetType() ].insert( e ).second )
6048 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6049 while ( nIt->more() )
6051 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6052 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6059 ShapeToMesh( _meshDS->ShapeToMesh() );
6061 _meshDS = 0; // to enforce iteration on _elements and _nodes
6064 // -------------------------------------------------------------------------------------
6065 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6066 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6069 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6070 for ( ; partIt != meshPart.end(); ++partIt )
6071 if ( const SMDS_MeshElement * e = *partIt )
6072 if ( _elements[ e->GetType() ].insert( e ).second )
6075 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6076 while ( nIt->more() )
6078 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6079 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6085 // -------------------------------------------------------------------------------------
6086 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6088 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6090 typedef SMDS_SetIterator
6091 <const SMDS_MeshElement*,
6092 TIDSortedElemSet::const_iterator,
6093 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6094 SMDS_MeshElement::GeomFilter
6097 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6099 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6100 _elements[type].end(),
6101 SMDS_MeshElement::GeomFilter( geomType )));
6103 // -------------------------------------------------------------------------------------
6104 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6106 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6108 typedef SMDS_SetIterator
6109 <const SMDS_MeshElement*,
6110 TIDSortedElemSet::const_iterator,
6111 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6112 SMDS_MeshElement::EntityFilter
6115 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6117 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6118 _elements[type].end(),
6119 SMDS_MeshElement::EntityFilter( entity )));
6121 // -------------------------------------------------------------------------------------
6122 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6124 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6125 if ( type == SMDSAbs_All && !_meshDS )
6127 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6129 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6130 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6132 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6134 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6135 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6137 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6138 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6140 // -------------------------------------------------------------------------------------
6141 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6142 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6144 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6145 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6146 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6148 // -------------------------------------------------------------------------------------
6149 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6150 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6151 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6152 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6153 #undef _GET_ITER_DEFINE
6155 // END Implementation of SMESH_MeshPartDS
6157 //================================================================================