1 // Copyright (C) 2007-2016 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_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
100 int SMESH_Mesh_i::_idGenerator = 0;
102 //=============================================================================
106 //=============================================================================
108 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
110 CORBA::Long studyId )
111 : SALOME::GenericObj_i( thePOA )
115 _id = _idGenerator++;
118 _previewEditor = NULL;
123 //=============================================================================
127 //=============================================================================
129 SMESH_Mesh_i::~SMESH_Mesh_i()
132 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
133 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
134 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
136 aGroup->UnRegister();
137 SMESH::SMESH_GroupBase_var( itGr->second );
142 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
143 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
144 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
146 aSubMesh->UnRegister();
147 SMESH::SMESH_subMesh_var( itSM->second );
149 _mapSubMeshIor.clear();
151 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
152 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
153 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
154 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
155 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
156 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
159 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
163 // clear cashed shapes if no more meshes remain; (the cash is blame,
164 // together with publishing, of spent time increasing in issue 22874)
165 if ( _impl->NbMeshes() == 1 )
166 _gen_i->GetShapeReader()->ClearClientBuffer();
168 delete _editor; _editor = NULL;
169 delete _previewEditor; _previewEditor = NULL;
170 delete _impl; _impl = NULL;
171 delete _preMeshInfo; _preMeshInfo = NULL;
174 //=============================================================================
178 * Associates <this> mesh with <theShape> and puts a reference
179 * to <theShape> into the current study;
180 * the previous shape is substituted by the new one.
182 //=============================================================================
184 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
185 throw (SALOME::SALOME_Exception)
187 Unexpect aCatch(SALOME_SalomeException);
189 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
191 catch(SALOME_Exception & S_ex) {
192 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
194 // to track changes of GEOM groups
195 SMESH::SMESH_Mesh_var mesh = _this();
196 addGeomGroupData( theShapeObject, mesh );
197 if ( !CORBA::is_nil( theShapeObject ))
198 _mainShapeTick = theShapeObject->GetTick();
201 //================================================================================
203 * \brief return true if mesh has a shape to build a shape on
205 //================================================================================
207 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
208 throw (SALOME::SALOME_Exception)
210 Unexpect aCatch(SALOME_SalomeException);
213 res = _impl->HasShapeToMesh();
215 catch(SALOME_Exception & S_ex) {
216 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
221 //=======================================================================
222 //function : GetShapeToMesh
224 //=======================================================================
226 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
227 throw (SALOME::SALOME_Exception)
229 Unexpect aCatch(SALOME_SalomeException);
230 GEOM::GEOM_Object_var aShapeObj;
232 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
236 if ( aShapeObj->_is_nil() )
238 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
239 // find GEOM_Object by entry (IPAL52735)
240 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
241 for ( ; data != _geomGroupData.end(); ++data )
242 if ( data->_smeshObject->_is_equivalent( _this() ))
244 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
245 if ( study->_is_nil() ) break;
246 SALOMEDS::SObject_wrap so = study->FindObjectID( data->_groupEntry.c_str() );
247 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
248 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
254 catch(SALOME_Exception & S_ex) {
255 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
257 return aShapeObj._retn();
260 //================================================================================
262 * \brief Return false if the mesh is not yet fully loaded from the study file
264 //================================================================================
266 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
268 Unexpect aCatch(SALOME_SalomeException);
269 return !_preMeshInfo;
272 //================================================================================
274 * \brief Load full mesh data from the study file
276 //================================================================================
278 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
280 Unexpect aCatch(SALOME_SalomeException);
282 _preMeshInfo->FullLoadFromFile();
285 //================================================================================
287 * \brief Remove all nodes and elements
289 //================================================================================
291 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
293 Unexpect aCatch(SALOME_SalomeException);
295 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
299 //CheckGeomGroupModif(); // issue 20145
301 catch(SALOME_Exception & S_ex) {
302 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
305 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
308 //================================================================================
310 * \brief Remove all nodes and elements for indicated shape
312 //================================================================================
314 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
315 throw (SALOME::SALOME_Exception)
317 Unexpect aCatch(SALOME_SalomeException);
319 _preMeshInfo->FullLoadFromFile();
322 _impl->ClearSubMesh( ShapeID );
324 catch(SALOME_Exception & S_ex) {
325 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
327 _impl->GetMeshDS()->Modified();
329 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
332 //=============================================================================
334 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
336 //=============================================================================
338 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
340 SMESH::DriverMED_ReadStatus res;
343 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
344 res = SMESH::DRS_OK; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
346 res = SMESH::DRS_EMPTY; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
348 res = SMESH::DRS_WARN_RENUMBER; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
350 res = SMESH::DRS_WARN_SKIP_ELEM; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
352 res = SMESH::DRS_WARN_DESCENDING; break;
353 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
355 res = SMESH::DRS_FAIL; break;
360 //=============================================================================
362 * Convert ::SMESH_ComputeError to SMESH::ComputeError
364 //=============================================================================
366 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
368 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
369 errVar->subShapeID = -1;
370 errVar->hasBadMesh = false;
372 if ( !errorPtr || errorPtr->IsOK() )
374 errVar->code = SMESH::COMPERR_OK;
378 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
379 errVar->comment = errorPtr->myComment.c_str();
381 return errVar._retn();
384 //=============================================================================
388 * Imports mesh data from MED file
390 //=============================================================================
392 SMESH::DriverMED_ReadStatus
393 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
394 throw ( SALOME::SALOME_Exception )
396 Unexpect aCatch(SALOME_SalomeException);
399 status = _impl->MEDToMesh( theFileName, theMeshName );
401 catch( SALOME_Exception& S_ex ) {
402 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
405 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
408 CreateGroupServants();
410 int major, minor, release;
411 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
412 major = minor = release = -1;
413 _medFileInfo = new SMESH::MedFileInfo();
414 _medFileInfo->fileName = theFileName;
415 _medFileInfo->fileSize = 0;
416 _medFileInfo->major = major;
417 _medFileInfo->minor = minor;
418 _medFileInfo->release = release;
419 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
421 return ConvertDriverMEDReadStatus(status);
424 //================================================================================
426 * \brief Imports mesh data from the CGNS file
428 //================================================================================
430 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
431 const int theMeshIndex,
432 std::string& theMeshName )
433 throw ( SALOME::SALOME_Exception )
435 Unexpect aCatch(SALOME_SalomeException);
438 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
440 catch( SALOME_Exception& S_ex ) {
441 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
444 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
447 CreateGroupServants();
449 return ConvertDriverMEDReadStatus(status);
452 //================================================================================
454 * \brief Return string representation of a MED file version comprising nbDigits
456 //================================================================================
458 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
460 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
462 return CORBA::string_dup( ver.c_str() );
465 //=============================================================================
469 * Imports mesh data from MED file
471 //=============================================================================
473 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
474 throw ( SALOME::SALOME_Exception )
478 // Read mesh with name = <theMeshName> into SMESH_Mesh
479 _impl->UNVToMesh( theFileName );
481 CreateGroupServants();
483 SMESH_CATCH( SMESH::throwCorbaException );
488 //=============================================================================
492 * Imports mesh data from STL file
494 //=============================================================================
495 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
496 throw ( SALOME::SALOME_Exception )
500 // Read mesh with name = <theMeshName> into SMESH_Mesh
501 std::string name = _impl->STLToMesh( theFileName );
504 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
505 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( study, _this() );
506 _gen_i->SetName( meshSO, name.c_str() );
509 SMESH_CATCH( SMESH::throwCorbaException );
514 //================================================================================
516 * \brief Function used in SMESH_CATCH by ImportGMFFile()
518 //================================================================================
522 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
524 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
528 //================================================================================
530 * \brief Imports data from a GMF file and returns an error description
532 //================================================================================
534 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
535 bool theMakeRequiredGroups )
536 throw (SALOME::SALOME_Exception)
538 SMESH_ComputeErrorPtr error;
541 #define SMESH_CAUGHT error =
544 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
546 SMESH_CATCH( exceptionToComputeError );
550 CreateGroupServants();
552 return ConvertComputeError( error );
555 //=============================================================================
559 //=============================================================================
561 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
563 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
564 (SMESH_Hypothesis::Hypothesis_Status theStatus)
567 RETURNCASE( HYP_OK );
568 RETURNCASE( HYP_MISSING );
569 RETURNCASE( HYP_CONCURRENT );
570 RETURNCASE( HYP_BAD_PARAMETER );
571 RETURNCASE( HYP_HIDDEN_ALGO );
572 RETURNCASE( HYP_HIDING_ALGO );
573 RETURNCASE( HYP_UNKNOWN_FATAL );
574 RETURNCASE( HYP_INCOMPATIBLE );
575 RETURNCASE( HYP_NOTCONFORM );
576 RETURNCASE( HYP_ALREADY_EXIST );
577 RETURNCASE( HYP_BAD_DIM );
578 RETURNCASE( HYP_BAD_SUBSHAPE );
579 RETURNCASE( HYP_BAD_GEOMETRY );
580 RETURNCASE( HYP_NEED_SHAPE );
581 RETURNCASE( HYP_INCOMPAT_HYPS );
584 return SMESH::HYP_UNKNOWN_FATAL;
587 //=============================================================================
591 * calls internal addHypothesis() and then adds a reference to <anHyp> under
592 * the SObject actually having a reference to <aSubShape>.
593 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
595 //=============================================================================
597 SMESH::Hypothesis_Status
598 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
599 SMESH::SMESH_Hypothesis_ptr anHyp,
600 CORBA::String_out anErrorText)
601 throw(SALOME::SALOME_Exception)
603 Unexpect aCatch(SALOME_SalomeException);
605 _preMeshInfo->ForgetOrLoad();
608 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
609 anErrorText = error.c_str();
611 SMESH::SMESH_Mesh_var mesh( _this() );
612 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
614 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
615 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
617 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
619 // Update Python script
620 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
621 << aSubShape << ", " << anHyp << " )";
623 return ConvertHypothesisStatus(status);
626 //=============================================================================
630 //=============================================================================
632 SMESH_Hypothesis::Hypothesis_Status
633 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
634 SMESH::SMESH_Hypothesis_ptr anHyp,
635 std::string* anErrorText)
637 if(MYDEBUG) MESSAGE("addHypothesis");
639 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
640 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
642 if (CORBA::is_nil( anHyp ))
643 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
645 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
648 TopoDS_Shape myLocSubShape;
649 //use PseudoShape in case if mesh has no shape
651 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
653 myLocSubShape = _impl->GetShapeToMesh();
655 const int hypId = anHyp->GetId();
657 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
658 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
660 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
662 // assure there is a corresponding submesh
663 if ( !_impl->IsMainShape( myLocSubShape )) {
664 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
665 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
666 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
669 else if ( anErrorText )
671 *anErrorText = error;
674 catch(SALOME_Exception & S_ex)
676 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
681 //=============================================================================
685 //=============================================================================
687 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
688 SMESH::SMESH_Hypothesis_ptr anHyp)
689 throw(SALOME::SALOME_Exception)
691 Unexpect aCatch(SALOME_SalomeException);
693 _preMeshInfo->ForgetOrLoad();
695 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
696 SMESH::SMESH_Mesh_var mesh = _this();
698 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
700 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
701 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
703 // Update Python script
704 if(_impl->HasShapeToMesh())
705 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
706 << aSubShape << ", " << anHyp << " )";
708 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
711 return ConvertHypothesisStatus(status);
714 //=============================================================================
718 //=============================================================================
720 SMESH_Hypothesis::Hypothesis_Status
721 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
722 SMESH::SMESH_Hypothesis_ptr anHyp)
724 if(MYDEBUG) MESSAGE("removeHypothesis()");
726 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
727 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
729 if (CORBA::is_nil( anHyp ))
730 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
732 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
735 TopoDS_Shape myLocSubShape;
736 //use PseudoShape in case if mesh has no shape
737 if( _impl->HasShapeToMesh() )
738 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
740 myLocSubShape = _impl->GetShapeToMesh();
742 const int hypId = anHyp->GetId();
743 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
744 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
746 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
750 catch(SALOME_Exception & S_ex)
752 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
757 //=============================================================================
761 //=============================================================================
763 SMESH::ListOfHypothesis *
764 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
765 throw(SALOME::SALOME_Exception)
767 Unexpect aCatch(SALOME_SalomeException);
768 if (MYDEBUG) MESSAGE("GetHypothesisList");
769 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
770 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
772 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
775 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
776 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
777 myLocSubShape = _impl->GetShapeToMesh();
778 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
779 int i = 0, n = aLocalList.size();
782 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
783 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
784 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
786 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
787 if ( id_hypptr != _mapHypo.end() )
788 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
792 catch(SALOME_Exception & S_ex) {
793 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
796 return aList._retn();
799 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
801 Unexpect aCatch(SALOME_SalomeException);
802 if (MYDEBUG) MESSAGE("GetSubMeshes");
804 SMESH::submesh_array_var aList = new SMESH::submesh_array();
807 TPythonDump aPythonDump;
808 if ( !_mapSubMeshIor.empty() )
812 aList->length( _mapSubMeshIor.size() );
814 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
815 for ( ; it != _mapSubMeshIor.end(); it++ ) {
816 if ( CORBA::is_nil( it->second )) continue;
817 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
819 if (i > 1) aPythonDump << ", ";
820 aPythonDump << it->second;
824 catch(SALOME_Exception & S_ex) {
825 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
828 // Update Python script
829 if ( !_mapSubMeshIor.empty() )
830 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
832 return aList._retn();
835 //=============================================================================
839 //=============================================================================
841 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
842 const char* theName )
843 throw(SALOME::SALOME_Exception)
845 Unexpect aCatch(SALOME_SalomeException);
846 if (CORBA::is_nil(aSubShape))
847 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
849 SMESH::SMESH_subMesh_var subMesh;
850 SMESH::SMESH_Mesh_var aMesh = _this();
852 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
854 //Get or Create the SMESH_subMesh object implementation
856 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
858 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
860 TopoDS_Iterator it( myLocSubShape );
862 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
864 subMesh = getSubMesh( subMeshId );
866 // create a new subMesh object servant if there is none for the shape
867 if ( subMesh->_is_nil() )
868 subMesh = createSubMesh( aSubShape );
869 if ( _gen_i->CanPublishInStudy( subMesh ))
871 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
872 SALOMEDS::SObject_wrap aSO =
873 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
874 if ( !aSO->_is_nil()) {
875 // Update Python script
876 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
877 << aSubShape << ", '" << theName << "' )";
881 catch(SALOME_Exception & S_ex) {
882 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
884 return subMesh._retn();
887 //=============================================================================
891 //=============================================================================
893 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
894 throw (SALOME::SALOME_Exception)
898 if ( theSubMesh->_is_nil() )
901 GEOM::GEOM_Object_var aSubShape;
902 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
903 if ( !aStudy->_is_nil() ) {
904 // Remove submesh's SObject
905 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
906 if ( !anSO->_is_nil() ) {
907 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
908 SALOMEDS::SObject_wrap anObj, aRef;
909 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
910 anObj->ReferencedObject( aRef.inout() ))
912 CORBA::Object_var obj = aRef->GetObject();
913 aSubShape = GEOM::GEOM_Object::_narrow( obj );
915 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
916 // aSubShape = theSubMesh->GetSubShape();
918 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
919 builder->RemoveObjectWithChildren( anSO );
921 // Update Python script
922 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
926 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
928 _preMeshInfo->ForgetOrLoad();
930 SMESH_CATCH( SMESH::throwCorbaException );
933 //=============================================================================
937 //=============================================================================
939 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
940 const char* theName )
941 throw(SALOME::SALOME_Exception)
943 Unexpect aCatch(SALOME_SalomeException);
945 _preMeshInfo->FullLoadFromFile();
947 SMESH::SMESH_Group_var aNewGroup =
948 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
950 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
952 SMESH::SMESH_Mesh_var mesh = _this();
953 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
954 SALOMEDS::SObject_wrap aSO =
955 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
956 if ( !aSO->_is_nil())
957 // Update Python script
958 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
959 << theElemType << ", '" << theName << "' )";
961 return aNewGroup._retn();
964 //=============================================================================
968 //=============================================================================
969 SMESH::SMESH_GroupOnGeom_ptr
970 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
972 GEOM::GEOM_Object_ptr theGeomObj)
973 throw(SALOME::SALOME_Exception)
975 Unexpect aCatch(SALOME_SalomeException);
977 _preMeshInfo->FullLoadFromFile();
979 SMESH::SMESH_GroupOnGeom_var aNewGroup;
981 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
982 if ( !aShape.IsNull() )
985 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
987 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
989 SMESH::SMESH_Mesh_var mesh = _this();
990 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
991 SALOMEDS::SObject_wrap aSO =
992 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
993 if ( !aSO->_is_nil())
994 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
995 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
999 return aNewGroup._retn();
1002 //================================================================================
1004 * \brief Creates a group whose contents is defined by filter
1005 * \param theElemType - group type
1006 * \param theName - group name
1007 * \param theFilter - the filter
1008 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1010 //================================================================================
1012 SMESH::SMESH_GroupOnFilter_ptr
1013 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1014 const char* theName,
1015 SMESH::Filter_ptr theFilter )
1016 throw (SALOME::SALOME_Exception)
1018 Unexpect aCatch(SALOME_SalomeException);
1020 _preMeshInfo->FullLoadFromFile();
1022 if ( CORBA::is_nil( theFilter ))
1023 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1025 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1027 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1029 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1030 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1033 if ( !aNewGroup->_is_nil() )
1034 aNewGroup->SetFilter( theFilter );
1036 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1038 SMESH::SMESH_Mesh_var mesh = _this();
1039 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1040 SALOMEDS::SObject_wrap aSO =
1041 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1043 if ( !aSO->_is_nil())
1044 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1045 << theElemType << ", '" << theName << "', " << theFilter << " )";
1047 return aNewGroup._retn();
1050 //=============================================================================
1054 //=============================================================================
1056 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1057 throw (SALOME::SALOME_Exception)
1059 if ( theGroup->_is_nil() )
1064 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1068 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1069 if ( !aStudy->_is_nil() )
1071 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1072 if ( !aGroupSO->_is_nil() )
1074 // Update Python script
1075 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1077 // Remove group's SObject
1078 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1079 builder->RemoveObjectWithChildren( aGroupSO );
1082 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1084 // Remove the group from SMESH data structures
1085 removeGroup( aGroup->GetLocalID() );
1087 SMESH_CATCH( SMESH::throwCorbaException );
1090 //=============================================================================
1092 * Remove group with its contents
1094 //=============================================================================
1096 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1097 throw (SALOME::SALOME_Exception)
1101 _preMeshInfo->FullLoadFromFile();
1103 if ( theGroup->_is_nil() )
1106 vector<int> nodeIds; // to remove nodes becoming free
1107 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1108 if ( !isNodal && !theGroup->IsEmpty() )
1110 CORBA::Long elemID = theGroup->GetID( 1 );
1111 int nbElemNodes = GetElemNbNodes( elemID );
1112 if ( nbElemNodes > 0 )
1113 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1116 // Retrieve contents
1117 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1118 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1119 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1120 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1121 elems.assign( elemBeg, elemEnd );
1123 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1126 RemoveGroup( theGroup );
1129 for ( size_t i = 0; i < elems.size(); ++i )
1133 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1134 nodeIds.push_back( nIt->next()->GetID() );
1136 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1140 _impl->GetMeshDS()->RemoveElement( elems[i] );
1144 // Remove free nodes
1145 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1146 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1147 if ( n->NbInverseElements() == 0 )
1148 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1150 // Update Python script (theGroup must be alive for this)
1151 pyDump << SMESH::SMESH_Mesh_var(_this())
1152 << ".RemoveGroupWithContents( " << theGroup << " )";
1154 SMESH_CATCH( SMESH::throwCorbaException );
1157 //================================================================================
1159 * \brief Get the list of groups existing in the mesh
1160 * \retval SMESH::ListOfGroups * - list of groups
1162 //================================================================================
1164 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1166 Unexpect aCatch(SALOME_SalomeException);
1167 if (MYDEBUG) MESSAGE("GetGroups");
1169 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1172 TPythonDump aPythonDump;
1173 if ( !_mapGroups.empty() )
1175 aPythonDump << "[ ";
1177 aList->length( _mapGroups.size() );
1179 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1180 for ( ; it != _mapGroups.end(); it++ ) {
1181 if ( CORBA::is_nil( it->second )) continue;
1182 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1184 if (i > 1) aPythonDump << ", ";
1185 aPythonDump << it->second;
1189 catch(SALOME_Exception & S_ex) {
1190 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1192 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1194 return aList._retn();
1197 //=============================================================================
1199 * Get number of groups existing in the mesh
1201 //=============================================================================
1203 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1205 Unexpect aCatch(SALOME_SalomeException);
1206 return _mapGroups.size();
1209 //=============================================================================
1211 * New group including all mesh elements present in initial groups is created.
1213 //=============================================================================
1215 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1216 SMESH::SMESH_GroupBase_ptr theGroup2,
1217 const char* theName )
1218 throw (SALOME::SALOME_Exception)
1220 SMESH::SMESH_Group_var aResGrp;
1224 _preMeshInfo->FullLoadFromFile();
1226 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1227 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1229 if ( theGroup1->GetType() != theGroup2->GetType() )
1230 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1235 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1236 if ( aResGrp->_is_nil() )
1237 return SMESH::SMESH_Group::_nil();
1239 aResGrp->AddFrom( theGroup1 );
1240 aResGrp->AddFrom( theGroup2 );
1242 // Update Python script
1243 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1244 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1246 SMESH_CATCH( SMESH::throwCorbaException );
1248 return aResGrp._retn();
1251 //=============================================================================
1253 * \brief New group including all mesh elements present in initial groups is created.
1254 * \param theGroups list of groups
1255 * \param theName name of group to be created
1256 * \return pointer to the new group
1258 //=============================================================================
1260 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1261 const char* theName )
1262 throw (SALOME::SALOME_Exception)
1264 SMESH::SMESH_Group_var aResGrp;
1267 _preMeshInfo->FullLoadFromFile();
1270 return SMESH::SMESH_Group::_nil();
1275 SMESH::ElementType aType = SMESH::ALL;
1276 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1278 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1279 if ( CORBA::is_nil( aGrp ) )
1281 if ( aType == SMESH::ALL )
1282 aType = aGrp->GetType();
1283 else if ( aType != aGrp->GetType() )
1284 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1287 if ( aType == SMESH::ALL )
1288 return SMESH::SMESH_Group::_nil();
1293 aResGrp = CreateGroup( aType, theName );
1294 if ( aResGrp->_is_nil() )
1295 return SMESH::SMESH_Group::_nil();
1297 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1298 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1300 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1301 if ( !CORBA::is_nil( aGrp ) )
1303 aResGrp->AddFrom( aGrp );
1304 if ( g > 0 ) pyDump << ", ";
1308 pyDump << " ], '" << theName << "' )";
1310 SMESH_CATCH( SMESH::throwCorbaException );
1312 return aResGrp._retn();
1315 //=============================================================================
1317 * New group is created. All mesh elements that are
1318 * present in both initial groups are added to the new one.
1320 //=============================================================================
1322 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1323 SMESH::SMESH_GroupBase_ptr theGroup2,
1324 const char* theName )
1325 throw (SALOME::SALOME_Exception)
1327 SMESH::SMESH_Group_var aResGrp;
1332 _preMeshInfo->FullLoadFromFile();
1334 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1335 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1337 if ( theGroup1->GetType() != theGroup2->GetType() )
1338 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1342 // Create Intersection
1343 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1344 if ( aResGrp->_is_nil() )
1345 return aResGrp._retn();
1347 SMESHDS_GroupBase* groupDS1 = 0;
1348 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1349 groupDS1 = grp_i->GetGroupDS();
1351 SMESHDS_GroupBase* groupDS2 = 0;
1352 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1353 groupDS2 = grp_i->GetGroupDS();
1355 SMESHDS_Group* resGroupDS = 0;
1356 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1357 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1359 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1361 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1362 while ( elemIt1->more() )
1364 const SMDS_MeshElement* e = elemIt1->next();
1365 if ( groupDS2->Contains( e ))
1366 resGroupDS->SMDSGroup().Add( e );
1369 // Update Python script
1370 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1371 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1373 SMESH_CATCH( SMESH::throwCorbaException );
1375 return aResGrp._retn();
1378 //=============================================================================
1380 \brief Intersect list of groups. New group is created. All mesh elements that
1381 are present in all initial groups simultaneously are added to the new one.
1382 \param theGroups list of groups
1383 \param theName name of group to be created
1384 \return pointer on the group
1386 //=============================================================================
1387 SMESH::SMESH_Group_ptr
1388 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1389 const char* theName )
1390 throw (SALOME::SALOME_Exception)
1392 SMESH::SMESH_Group_var aResGrp;
1397 _preMeshInfo->FullLoadFromFile();
1400 return SMESH::SMESH_Group::_nil();
1402 // check types and get SMESHDS_GroupBase's
1403 SMESH::ElementType aType = SMESH::ALL;
1404 vector< SMESHDS_GroupBase* > groupVec;
1405 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1407 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1408 if ( CORBA::is_nil( aGrp ) )
1410 if ( aType == SMESH::ALL )
1411 aType = aGrp->GetType();
1412 else if ( aType != aGrp->GetType() )
1413 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1416 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1417 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1419 if ( grpDS->IsEmpty() )
1424 groupVec.push_back( grpDS );
1427 if ( aType == SMESH::ALL ) // all groups are nil
1428 return SMESH::SMESH_Group::_nil();
1433 aResGrp = CreateGroup( aType, theName );
1435 SMESHDS_Group* resGroupDS = 0;
1436 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1437 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1438 if ( !resGroupDS || groupVec.empty() )
1439 return aResGrp._retn();
1442 size_t i, nb = groupVec.size();
1443 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1444 while ( elemIt1->more() )
1446 const SMDS_MeshElement* e = elemIt1->next();
1448 for ( i = 1; ( i < nb && inAll ); ++i )
1449 inAll = groupVec[i]->Contains( e );
1452 resGroupDS->SMDSGroup().Add( e );
1455 // Update Python script
1456 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1457 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1459 SMESH_CATCH( SMESH::throwCorbaException );
1461 return aResGrp._retn();
1464 //=============================================================================
1466 * New group is created. All mesh elements that are present in
1467 * a main group but is not present in a tool group are added to the new one
1469 //=============================================================================
1471 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1472 SMESH::SMESH_GroupBase_ptr theGroup2,
1473 const char* theName )
1474 throw (SALOME::SALOME_Exception)
1476 SMESH::SMESH_Group_var aResGrp;
1481 _preMeshInfo->FullLoadFromFile();
1483 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1484 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1486 if ( theGroup1->GetType() != theGroup2->GetType() )
1487 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1491 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1492 if ( aResGrp->_is_nil() )
1493 return aResGrp._retn();
1495 SMESHDS_GroupBase* groupDS1 = 0;
1496 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1497 groupDS1 = grp_i->GetGroupDS();
1499 SMESHDS_GroupBase* groupDS2 = 0;
1500 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1501 groupDS2 = grp_i->GetGroupDS();
1503 SMESHDS_Group* resGroupDS = 0;
1504 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1505 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1507 if ( groupDS1 && groupDS2 && resGroupDS )
1509 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1510 while ( elemIt1->more() )
1512 const SMDS_MeshElement* e = elemIt1->next();
1513 if ( !groupDS2->Contains( e ))
1514 resGroupDS->SMDSGroup().Add( e );
1517 // Update Python script
1518 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1519 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1521 SMESH_CATCH( SMESH::throwCorbaException );
1523 return aResGrp._retn();
1526 //=============================================================================
1528 \brief Cut lists of groups. New group is created. All mesh elements that are
1529 present in main groups but do not present in tool groups are added to the new one
1530 \param theMainGroups list of main groups
1531 \param theToolGroups list of tool groups
1532 \param theName name of group to be created
1533 \return pointer on the group
1535 //=============================================================================
1536 SMESH::SMESH_Group_ptr
1537 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1538 const SMESH::ListOfGroups& theToolGroups,
1539 const char* theName )
1540 throw (SALOME::SALOME_Exception)
1542 SMESH::SMESH_Group_var aResGrp;
1547 _preMeshInfo->FullLoadFromFile();
1550 return SMESH::SMESH_Group::_nil();
1552 // check types and get SMESHDS_GroupBase's
1553 SMESH::ElementType aType = SMESH::ALL;
1554 vector< SMESHDS_GroupBase* > toolGroupVec;
1555 vector< SMDS_ElemIteratorPtr > mainIterVec;
1557 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1559 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1560 if ( CORBA::is_nil( aGrp ) )
1562 if ( aType == SMESH::ALL )
1563 aType = aGrp->GetType();
1564 else if ( aType != aGrp->GetType() )
1565 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1567 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1568 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1569 if ( !grpDS->IsEmpty() )
1570 mainIterVec.push_back( grpDS->GetElements() );
1572 if ( aType == SMESH::ALL ) // all main groups are nil
1573 return SMESH::SMESH_Group::_nil();
1574 if ( mainIterVec.empty() ) // all main groups are empty
1575 return aResGrp._retn();
1577 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1579 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1580 if ( CORBA::is_nil( aGrp ) )
1582 if ( aType != aGrp->GetType() )
1583 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1585 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1586 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1587 toolGroupVec.push_back( grpDS );
1593 aResGrp = CreateGroup( aType, theName );
1595 SMESHDS_Group* resGroupDS = 0;
1596 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1597 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1599 return aResGrp._retn();
1602 size_t i, nb = toolGroupVec.size();
1603 SMDS_ElemIteratorPtr mainElemIt
1604 ( new SMDS_IteratorOnIterators
1605 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1606 while ( mainElemIt->more() )
1608 const SMDS_MeshElement* e = mainElemIt->next();
1610 for ( i = 0; ( i < nb && !isIn ); ++i )
1611 isIn = toolGroupVec[i]->Contains( e );
1614 resGroupDS->SMDSGroup().Add( e );
1617 // Update Python script
1618 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1619 << ".CutListOfGroups( " << theMainGroups << ", "
1620 << theToolGroups << ", '" << theName << "' )";
1622 SMESH_CATCH( SMESH::throwCorbaException );
1624 return aResGrp._retn();
1627 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1629 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1630 bool & toStopChecking )
1632 toStopChecking = ( nbCommon < nbChecked );
1633 return nbCommon == nbNodes;
1635 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1636 bool & toStopChecking )
1638 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1639 return nbCommon == nbCorners;
1641 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1642 bool & toStopChecking )
1644 return nbCommon > 0;
1646 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1647 bool & toStopChecking )
1649 return nbCommon >= (nbNodes+1) / 2;
1653 //=============================================================================
1655 * Create a group of entities basing on nodes of other groups.
1656 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1657 * \param [in] anElemType - a type of elements to include to the new group.
1658 * \param [in] theName - a name of the new group.
1659 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1660 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1661 * new group provided that it is based on nodes of an element of \a aListOfGroups
1662 * \return SMESH_Group - the created group
1664 // IMP 19939, bug 22010, IMP 22635
1665 //=============================================================================
1667 SMESH::SMESH_Group_ptr
1668 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1669 SMESH::ElementType theElemType,
1670 const char* theName,
1671 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1672 CORBA::Boolean theUnderlyingOnly)
1673 throw (SALOME::SALOME_Exception)
1675 SMESH::SMESH_Group_var aResGrp;
1679 _preMeshInfo->FullLoadFromFile();
1681 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1683 if ( !theName || !aMeshDS )
1684 return SMESH::SMESH_Group::_nil();
1686 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1688 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1689 SMESH_Comment nbCoNoStr( "SMESH.");
1690 switch ( theNbCommonNodes ) {
1691 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1692 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1693 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1694 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1695 default: return aResGrp._retn();
1697 int nbChecked, nbCommon, nbNodes, nbCorners;
1703 aResGrp = CreateGroup( theElemType, theName );
1704 if ( aResGrp->_is_nil() )
1705 return SMESH::SMESH_Group::_nil();
1707 SMESHDS_GroupBase* groupBaseDS =
1708 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1709 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1711 vector<bool> isNodeInGroups;
1713 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1715 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1716 if ( CORBA::is_nil( aGrp ) )
1718 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1719 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1722 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1723 if ( !elIt ) continue;
1725 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1727 while ( elIt->more() ) {
1728 const SMDS_MeshElement* el = elIt->next();
1729 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1730 while ( nIt->more() )
1731 resGroupCore.Add( nIt->next() );
1734 // get elements of theElemType based on nodes of every element of group
1735 else if ( theUnderlyingOnly )
1737 while ( elIt->more() )
1739 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1740 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1741 TIDSortedElemSet checkedElems;
1742 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1743 while ( nIt->more() )
1745 const SMDS_MeshNode* n = nIt->next();
1746 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1747 // check nodes of elements of theElemType around el
1748 while ( elOfTypeIt->more() )
1750 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1751 if ( !checkedElems.insert( elOfType ).second ) continue;
1752 nbNodes = elOfType->NbNodes();
1753 nbCorners = elOfType->NbCornerNodes();
1755 bool toStopChecking = false;
1756 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1757 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1758 if ( elNodes.count( nIt2->next() ) &&
1759 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1761 resGroupCore.Add( elOfType );
1768 // get all nodes of elements of groups
1771 while ( elIt->more() )
1773 const SMDS_MeshElement* el = elIt->next(); // an element of group
1774 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1775 while ( nIt->more() )
1777 const SMDS_MeshNode* n = nIt->next();
1778 if ( n->GetID() >= (int) isNodeInGroups.size() )
1779 isNodeInGroups.resize( n->GetID() + 1, false );
1780 isNodeInGroups[ n->GetID() ] = true;
1786 // Get elements of theElemType based on a certain number of nodes of elements of groups
1787 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1789 const SMDS_MeshNode* n;
1790 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1791 const int isNodeInGroupsSize = isNodeInGroups.size();
1792 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1794 if ( !isNodeInGroups[ iN ] ||
1795 !( n = aMeshDS->FindNode( iN )))
1798 // check nodes of elements of theElemType around n
1799 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1800 while ( elOfTypeIt->more() )
1802 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1803 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1808 nbNodes = elOfType->NbNodes();
1809 nbCorners = elOfType->NbCornerNodes();
1811 bool toStopChecking = false;
1812 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1813 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1815 const int nID = nIt->next()->GetID();
1816 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1817 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1819 resGroupCore.Add( elOfType );
1827 // Update Python script
1828 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1829 << ".CreateDimGroup( "
1830 << theGroups << ", " << theElemType << ", '" << theName << "', "
1831 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1833 SMESH_CATCH( SMESH::throwCorbaException );
1835 return aResGrp._retn();
1838 //================================================================================
1840 * \brief Remember GEOM group data
1842 //================================================================================
1844 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1845 CORBA::Object_ptr theSmeshObj)
1847 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1850 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1851 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1852 if ( groupSO->_is_nil() )
1855 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1856 GEOM::GEOM_IGroupOperations_wrap groupOp =
1857 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1858 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1861 _geomGroupData.push_back( TGeomGroupData() );
1862 TGeomGroupData & groupData = _geomGroupData.back();
1864 CORBA::String_var entry = groupSO->GetID();
1865 groupData._groupEntry = entry.in();
1867 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1868 groupData._indices.insert( ids[i] );
1870 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1871 // shape index in SMESHDS
1872 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1873 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1876 //================================================================================
1878 * Remove GEOM group data relating to removed smesh object
1880 //================================================================================
1882 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1884 list<TGeomGroupData>::iterator
1885 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1886 for ( ; data != dataEnd; ++data ) {
1887 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1888 _geomGroupData.erase( data );
1894 //================================================================================
1896 * \brief Return new group contents if it has been changed and update group data
1898 //================================================================================
1900 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1902 TopoDS_Shape newShape;
1905 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1906 if ( study->_is_nil() ) return newShape; // means "not changed"
1907 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1908 if ( !groupSO->_is_nil() )
1910 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1911 if ( CORBA::is_nil( groupObj )) return newShape;
1912 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1914 // get indices of group items
1915 set<int> curIndices;
1916 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1917 GEOM::GEOM_IGroupOperations_wrap groupOp =
1918 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1919 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1920 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1921 curIndices.insert( ids[i] );
1923 if ( groupData._indices == curIndices )
1924 return newShape; // group not changed
1927 groupData._indices = curIndices;
1929 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1930 if ( !geomClient ) return newShape;
1931 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1932 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1933 newShape = _gen_i->GeomObjectToShape( geomGroup );
1936 if ( newShape.IsNull() ) {
1937 // geom group becomes empty - return empty compound
1938 TopoDS_Compound compound;
1939 BRep_Builder().MakeCompound(compound);
1940 newShape = compound;
1947 //-----------------------------------------------------------------------------
1949 * \brief Storage of shape and index used in CheckGeomGroupModif()
1951 struct TIndexedShape
1954 TopoDS_Shape _shape;
1955 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1957 //-----------------------------------------------------------------------------
1959 * \brief Data to re-create a group on geometry
1961 struct TGroupOnGeomData
1965 SMDSAbs_ElementType _type;
1967 Quantity_Color _color;
1971 //=============================================================================
1973 * \brief Update data if geometry changes
1977 //=============================================================================
1979 void SMESH_Mesh_i::CheckGeomModif()
1981 if ( !_impl->HasShapeToMesh() ) return;
1983 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1984 if ( study->_is_nil() ) return;
1986 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1987 //if ( mainGO->_is_nil() ) return;
1989 // Update after group modification
1991 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1992 called by other mesh (IPAL52735) */
1993 mainGO->GetType() == GEOM_GROUP ||
1994 mainGO->GetTick() == _mainShapeTick )
1996 CheckGeomGroupModif();
2000 // Update after shape transformation like Translate
2002 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2003 if ( !geomClient ) return;
2004 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2005 if ( geomGen->_is_nil() ) return;
2007 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2008 geomClient->RemoveShapeFromBuffer( ior.in() );
2010 // Update data taking into account that
2011 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2014 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2015 if ( newShape.IsNull() )
2018 _mainShapeTick = mainGO->GetTick();
2020 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2022 // store data of groups on geometry
2023 vector< TGroupOnGeomData > groupsData;
2024 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2025 groupsData.reserve( groups.size() );
2026 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2027 for ( ; g != groups.end(); ++g )
2028 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2030 TGroupOnGeomData data;
2031 data._oldID = group->GetID();
2032 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2033 data._type = group->GetType();
2034 data._name = group->GetStoreName();
2035 data._color = group->GetColor();
2036 groupsData.push_back( data );
2038 // store assigned hypotheses
2039 vector< pair< int, THypList > > ids2Hyps;
2040 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2041 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2043 const TopoDS_Shape& s = s2hyps.Key();
2044 const THypList& hyps = s2hyps.ChangeValue();
2045 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2048 // change shape to mesh
2049 int oldNbSubShapes = meshDS->MaxShapeIndex();
2050 _impl->ShapeToMesh( TopoDS_Shape() );
2051 _impl->ShapeToMesh( newShape );
2053 // re-add shapes of geom groups
2054 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2055 for ( ; data != _geomGroupData.end(); ++data )
2057 TopoDS_Shape newShape = newGroupShape( *data );
2058 if ( !newShape.IsNull() )
2060 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2062 TopoDS_Compound compound;
2063 BRep_Builder().MakeCompound( compound );
2064 BRep_Builder().Add( compound, newShape );
2065 newShape = compound;
2067 _impl->GetSubMesh( newShape );
2070 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2071 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2072 SALOME::INTERNAL_ERROR );
2074 // re-assign hypotheses
2075 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2077 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2078 const THypList& hyps = ids2Hyps[i].second;
2079 THypList::const_iterator h = hyps.begin();
2080 for ( ; h != hyps.end(); ++h )
2081 _impl->AddHypothesis( s, (*h)->GetID() );
2085 for ( size_t i = 0; i < groupsData.size(); ++i )
2087 const TGroupOnGeomData& data = groupsData[i];
2089 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2090 if ( i2g == _mapGroups.end() ) continue;
2092 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2093 if ( !gr_i ) continue;
2096 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2097 meshDS->IndexToShape( data._shapeID ));
2100 _mapGroups.erase( i2g );
2104 g->GetGroupDS()->SetColor( data._color );
2105 gr_i->changeLocalId( id );
2106 _mapGroups[ id ] = i2g->second;
2107 if ( data._oldID != id )
2108 _mapGroups.erase( i2g );
2112 // update _mapSubMesh
2113 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2114 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2115 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2119 //=============================================================================
2121 * \brief Update objects depending on changed geom groups
2123 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2124 * issue 0020210: Update of a smesh group after modification of the associated geom group
2126 //=============================================================================
2128 void SMESH_Mesh_i::CheckGeomGroupModif()
2130 if ( !_impl->HasShapeToMesh() ) return;
2132 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2133 if ( study->_is_nil() ) return;
2135 CORBA::Long nbEntities = NbNodes() + NbElements();
2137 // Check if group contents changed
2139 typedef map< string, TopoDS_Shape > TEntry2Geom;
2140 TEntry2Geom newGroupContents;
2142 list<TGeomGroupData>::iterator
2143 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2144 for ( ; data != dataEnd; ++data )
2146 pair< TEntry2Geom::iterator, bool > it_new =
2147 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2148 bool processedGroup = !it_new.second;
2149 TopoDS_Shape& newShape = it_new.first->second;
2150 if ( !processedGroup )
2151 newShape = newGroupShape( *data );
2152 if ( newShape.IsNull() )
2153 continue; // no changes
2156 _preMeshInfo->ForgetOrLoad();
2158 if ( processedGroup ) { // update group indices
2159 list<TGeomGroupData>::iterator data2 = data;
2160 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2161 data->_indices = data2->_indices;
2164 // Update SMESH objects according to new GEOM group contents
2166 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2167 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2169 int oldID = submesh->GetId();
2170 if ( !_mapSubMeshIor.count( oldID ))
2172 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2174 // update hypotheses
2175 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2176 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2177 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2179 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2180 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2182 // care of submeshes
2183 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2184 int newID = newSubmesh->GetId();
2185 if ( newID != oldID ) {
2186 _mapSubMesh [ newID ] = newSubmesh;
2187 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2188 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2189 _mapSubMesh. erase(oldID);
2190 _mapSubMesh_i. erase(oldID);
2191 _mapSubMeshIor.erase(oldID);
2192 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2197 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2198 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2199 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2201 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2203 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2204 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2205 ds->SetShape( newShape );
2210 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2211 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2213 // Remove groups and submeshes basing on removed sub-shapes
2215 TopTools_MapOfShape newShapeMap;
2216 TopoDS_Iterator shapeIt( newShape );
2217 for ( ; shapeIt.More(); shapeIt.Next() )
2218 newShapeMap.Add( shapeIt.Value() );
2220 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2221 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2223 if ( newShapeMap.Contains( shapeIt.Value() ))
2225 TopTools_IndexedMapOfShape oldShapeMap;
2226 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2227 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2229 const TopoDS_Shape& oldShape = oldShapeMap(i);
2230 int oldInd = meshDS->ShapeToIndex( oldShape );
2232 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2233 if ( i_smIor != _mapSubMeshIor.end() ) {
2234 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2237 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2238 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2240 // check if a group bases on oldInd shape
2241 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2242 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2243 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2244 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2246 RemoveGroup( i_grp->second ); // several groups can base on same shape
2247 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2252 // Reassign hypotheses and update groups after setting the new shape to mesh
2254 // collect anassigned hypotheses
2255 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2256 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2257 TShapeHypList assignedHyps;
2258 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2260 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2261 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2262 if ( !hyps.empty() ) {
2263 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2264 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2265 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2268 // collect shapes supporting groups
2269 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2270 TShapeTypeList groupData;
2271 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2272 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2273 for ( ; grIt != groups.end(); ++grIt )
2275 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2277 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2279 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2281 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2282 _impl->ShapeToMesh( newShape );
2284 // reassign hypotheses
2285 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2286 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2288 TIndexedShape& geom = indS_hyps->first;
2289 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2290 int oldID = geom._index;
2291 int newID = meshDS->ShapeToIndex( geom._shape );
2292 if ( oldID == 1 ) { // main shape
2294 geom._shape = newShape;
2298 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2299 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2300 // care of sub-meshes
2301 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2302 if ( newID != oldID ) {
2303 _mapSubMesh [ newID ] = newSubmesh;
2304 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2305 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2306 _mapSubMesh. erase(oldID);
2307 _mapSubMesh_i. erase(oldID);
2308 _mapSubMeshIor.erase(oldID);
2309 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2313 TShapeTypeList::iterator geomType = groupData.begin();
2314 for ( ; geomType != groupData.end(); ++geomType )
2316 const TIndexedShape& geom = geomType->first;
2317 int oldID = geom._index;
2318 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2321 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2322 CORBA::String_var name = groupSO->GetName();
2324 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2326 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2327 group_i->changeLocalId( newID );
2330 break; // everything has been updated
2333 } // loop on group data
2337 CORBA::Long newNbEntities = NbNodes() + NbElements();
2338 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2339 if ( newNbEntities != nbEntities )
2341 // Add all SObjects with icons to soToUpdateIcons
2342 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2344 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2345 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2346 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2348 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2349 i_gr != _mapGroups.end(); ++i_gr ) // groups
2350 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2353 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2354 for ( ; so != soToUpdateIcons.end(); ++so )
2355 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2358 //=============================================================================
2360 * \brief Create standalone group from a group on geometry or filter
2362 //=============================================================================
2364 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2365 throw (SALOME::SALOME_Exception)
2367 SMESH::SMESH_Group_var aGroup;
2372 _preMeshInfo->FullLoadFromFile();
2374 if ( theGroup->_is_nil() )
2375 return aGroup._retn();
2377 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2379 return aGroup._retn();
2381 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2383 const int anId = aGroupToRem->GetLocalID();
2384 if ( !_impl->ConvertToStandalone( anId ) )
2385 return aGroup._retn();
2386 removeGeomGroupData( theGroup );
2388 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2390 // remove old instance of group from own map
2391 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2392 _mapGroups.erase( anId );
2394 SALOMEDS::StudyBuilder_var builder;
2395 SALOMEDS::SObject_wrap aGroupSO;
2396 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2397 if ( !aStudy->_is_nil() ) {
2398 builder = aStudy->NewBuilder();
2399 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2400 if ( !aGroupSO->_is_nil() )
2402 // remove reference to geometry
2403 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2404 for ( ; chItr->More(); chItr->Next() )
2405 // Remove group's child SObject
2406 builder->RemoveObject( chItr->Value() );
2408 // Update Python script
2409 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2410 << ".ConvertToStandalone( " << aGroupSO << " )";
2412 // change icon of Group on Filter
2415 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2416 const int isEmpty = ( elemTypes->length() == 0 );
2419 SALOMEDS::GenericAttribute_wrap anAttr =
2420 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2421 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2422 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2428 // remember new group in own map
2429 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2430 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2432 // register CORBA object for persistence
2433 _gen_i->RegisterObject( aGroup );
2435 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2436 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2437 //aGroup->Register();
2438 aGroupToRem->UnRegister();
2440 SMESH_CATCH( SMESH::throwCorbaException );
2442 return aGroup._retn();
2445 //=============================================================================
2449 //=============================================================================
2451 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2453 if(MYDEBUG) MESSAGE( "createSubMesh" );
2454 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2455 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2456 const int subMeshId = mySubMesh->GetId();
2458 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2459 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2461 _mapSubMesh [subMeshId] = mySubMesh;
2462 _mapSubMesh_i [subMeshId] = subMeshServant;
2463 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2465 subMeshServant->Register();
2467 // register CORBA object for persistence
2468 int nextId = _gen_i->RegisterObject( subMesh );
2469 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2470 else { nextId = 0; } // avoid "unused variable" warning
2472 // to track changes of GEOM groups
2473 addGeomGroupData( theSubShapeObject, subMesh );
2475 return subMesh._retn();
2478 //=======================================================================
2479 //function : getSubMesh
2481 //=======================================================================
2483 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2485 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2486 if ( it == _mapSubMeshIor.end() )
2487 return SMESH::SMESH_subMesh::_nil();
2489 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2492 //=============================================================================
2496 //=============================================================================
2498 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2499 GEOM::GEOM_Object_ptr theSubShapeObject )
2501 bool isHypChanged = false;
2502 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2503 return isHypChanged;
2505 const int subMeshId = theSubMesh->GetId();
2507 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2509 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2511 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2514 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2515 isHypChanged = !hyps.empty();
2516 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2517 for ( ; hyp != hyps.end(); ++hyp )
2518 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2525 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2526 isHypChanged = ( aHypList->length() > 0 );
2527 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2528 removeHypothesis( theSubShapeObject, aHypList[i] );
2531 catch( const SALOME::SALOME_Exception& ) {
2532 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2534 removeGeomGroupData( theSubShapeObject );
2538 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2539 if ( id_smi != _mapSubMesh_i.end() )
2540 id_smi->second->UnRegister();
2542 // remove a CORBA object
2543 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2544 if ( id_smptr != _mapSubMeshIor.end() )
2545 SMESH::SMESH_subMesh_var( id_smptr->second );
2547 _mapSubMesh.erase(subMeshId);
2548 _mapSubMesh_i.erase(subMeshId);
2549 _mapSubMeshIor.erase(subMeshId);
2551 return isHypChanged;
2554 //=============================================================================
2558 //=============================================================================
2560 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2561 const char* theName,
2562 const TopoDS_Shape& theShape,
2563 const SMESH_PredicatePtr& thePredicate )
2565 std::string newName;
2566 if ( !theName || !theName[0] )
2568 std::set< std::string > presentNames;
2569 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2570 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2572 CORBA::String_var name = i_gr->second->GetName();
2573 presentNames.insert( name.in() );
2576 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2577 } while ( !presentNames.insert( newName ).second );
2578 theName = newName.c_str();
2581 SMESH::SMESH_GroupBase_var aGroup;
2582 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2584 SMESH_GroupBase_i* aGroupImpl;
2585 if ( !theShape.IsNull() )
2586 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2587 else if ( thePredicate )
2588 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2590 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2592 aGroup = aGroupImpl->_this();
2593 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2594 aGroupImpl->Register();
2596 // register CORBA object for persistence
2597 int nextId = _gen_i->RegisterObject( aGroup );
2598 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2599 else { nextId = 0; } // avoid "unused variable" warning in release mode
2601 // to track changes of GEOM groups
2602 if ( !theShape.IsNull() ) {
2603 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2604 addGeomGroupData( geom, aGroup );
2607 return aGroup._retn();
2610 //=============================================================================
2612 * SMESH_Mesh_i::removeGroup
2614 * Should be called by ~SMESH_Group_i()
2616 //=============================================================================
2618 void SMESH_Mesh_i::removeGroup( const int theId )
2620 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2621 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2622 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2623 _mapGroups.erase( theId );
2624 removeGeomGroupData( group );
2625 if ( !_impl->RemoveGroup( theId ))
2627 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2628 RemoveGroup( group );
2630 group->UnRegister();
2634 //=============================================================================
2638 //=============================================================================
2640 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2641 throw(SALOME::SALOME_Exception)
2643 SMESH::log_array_var aLog;
2647 _preMeshInfo->FullLoadFromFile();
2649 list < SMESHDS_Command * >logDS = _impl->GetLog();
2650 aLog = new SMESH::log_array;
2652 int lg = logDS.size();
2655 list < SMESHDS_Command * >::iterator its = logDS.begin();
2656 while(its != logDS.end()){
2657 SMESHDS_Command *com = *its;
2658 int comType = com->GetType();
2660 int lgcom = com->GetNumber();
2662 const list < int >&intList = com->GetIndexes();
2663 int inum = intList.size();
2665 list < int >::const_iterator ii = intList.begin();
2666 const list < double >&coordList = com->GetCoords();
2667 int rnum = coordList.size();
2669 list < double >::const_iterator ir = coordList.begin();
2670 aLog[indexLog].commandType = comType;
2671 aLog[indexLog].number = lgcom;
2672 aLog[indexLog].coords.length(rnum);
2673 aLog[indexLog].indexes.length(inum);
2674 for(int i = 0; i < rnum; i++){
2675 aLog[indexLog].coords[i] = *ir;
2676 //MESSAGE(" "<<i<<" "<<ir.Value());
2679 for(int i = 0; i < inum; i++){
2680 aLog[indexLog].indexes[i] = *ii;
2681 //MESSAGE(" "<<i<<" "<<ii.Value());
2690 SMESH_CATCH( SMESH::throwCorbaException );
2692 return aLog._retn();
2696 //=============================================================================
2700 //=============================================================================
2702 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2706 SMESH_CATCH( SMESH::throwCorbaException );
2709 //=============================================================================
2713 //=============================================================================
2715 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2720 //=============================================================================
2724 //=============================================================================
2726 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2731 //=============================================================================
2734 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2735 // issue 0020918: groups removal is caused by hyp modification
2736 // issue 0021208: to forget not loaded mesh data at hyp modification
2737 struct TCallUp_i : public SMESH_Mesh::TCallUp
2739 SMESH_Mesh_i* _mesh;
2740 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2741 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2742 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2743 virtual void Load () { _mesh->Load(); }
2747 //================================================================================
2749 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2751 //================================================================================
2753 void SMESH_Mesh_i::onHypothesisModified()
2756 _preMeshInfo->ForgetOrLoad();
2759 //=============================================================================
2763 //=============================================================================
2765 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2767 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2770 _impl->SetCallUp( new TCallUp_i(this));
2773 //=============================================================================
2777 //=============================================================================
2779 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2781 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2785 //=============================================================================
2787 * Return mesh editor
2789 //=============================================================================
2791 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2792 throw (SALOME::SALOME_Exception)
2794 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2798 _preMeshInfo->FullLoadFromFile();
2800 // Create MeshEditor
2802 _editor = new SMESH_MeshEditor_i( this, false );
2803 aMeshEdVar = _editor->_this();
2805 // Update Python script
2806 TPythonDump() << _editor << " = "
2807 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2809 SMESH_CATCH( SMESH::throwCorbaException );
2811 return aMeshEdVar._retn();
2814 //=============================================================================
2816 * Return mesh edition previewer
2818 //=============================================================================
2820 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2821 throw (SALOME::SALOME_Exception)
2823 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2827 _preMeshInfo->FullLoadFromFile();
2829 if ( !_previewEditor )
2830 _previewEditor = new SMESH_MeshEditor_i( this, true );
2831 aMeshEdVar = _previewEditor->_this();
2833 SMESH_CATCH( SMESH::throwCorbaException );
2835 return aMeshEdVar._retn();
2838 //================================================================================
2840 * \brief Return true if the mesh has been edited since a last total re-compute
2841 * and those modifications may prevent successful partial re-compute
2843 //================================================================================
2845 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2847 Unexpect aCatch(SALOME_SalomeException);
2848 return _impl->HasModificationsToDiscard();
2851 //================================================================================
2853 * \brief Returns a random unique color
2855 //================================================================================
2857 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2859 const int MAX_ATTEMPTS = 100;
2861 double tolerance = 0.5;
2862 SALOMEDS::Color col;
2866 // generate random color
2867 double red = (double)rand() / RAND_MAX;
2868 double green = (double)rand() / RAND_MAX;
2869 double blue = (double)rand() / RAND_MAX;
2870 // check existence in the list of the existing colors
2871 bool matched = false;
2872 std::list<SALOMEDS::Color>::const_iterator it;
2873 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2874 SALOMEDS::Color color = *it;
2875 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2876 matched = tol < tolerance;
2878 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2879 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2887 //=============================================================================
2889 * Sets auto-color mode. If it is on, groups get unique random colors
2891 //=============================================================================
2893 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2895 Unexpect aCatch(SALOME_SalomeException);
2896 _impl->SetAutoColor(theAutoColor);
2898 TPythonDump pyDump; // not to dump group->SetColor() from below code
2899 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2901 std::list<SALOMEDS::Color> aReservedColors;
2902 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2903 for ( ; it != _mapGroups.end(); it++ ) {
2904 if ( CORBA::is_nil( it->second )) continue;
2905 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2906 it->second->SetColor( aColor );
2907 aReservedColors.push_back( aColor );
2911 //=============================================================================
2913 * Returns true if auto-color mode is on
2915 //=============================================================================
2917 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2919 Unexpect aCatch(SALOME_SalomeException);
2920 return _impl->GetAutoColor();
2923 //=============================================================================
2925 * Checks if there are groups with equal names
2927 //=============================================================================
2929 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2931 return _impl->HasDuplicatedGroupNamesMED();
2934 //================================================================================
2936 * \brief Care of a file before exporting mesh into it
2938 //================================================================================
2940 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2942 SMESH_File aFile( file );
2944 if (aFile.exists()) {
2945 // existing filesystem node
2946 if ( !aFile.isDirectory() ) {
2947 if ( aFile.openForWriting() ) {
2948 if ( overwrite && ! aFile.remove()) {
2949 msg << "Can't replace " << aFile.getName();
2952 msg << "Can't write into " << aFile.getName();
2955 msg << "Location " << aFile.getName() << " is not a file";
2959 // nonexisting file; check if it can be created
2960 if ( !aFile.openForWriting() ) {
2961 msg << "You cannot create the file "
2963 << ". Check the directory existence and access rights";
2971 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2975 //================================================================================
2977 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2978 * \param file - file name
2979 * \param overwrite - to erase the file or not
2980 * \retval string - mesh name
2982 //================================================================================
2984 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2985 CORBA::Boolean overwrite)
2988 PrepareForWriting(file, overwrite);
2989 string aMeshName = "Mesh";
2990 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2991 if ( !aStudy->_is_nil() ) {
2992 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2993 if ( !aMeshSO->_is_nil() ) {
2994 CORBA::String_var name = aMeshSO->GetName();
2996 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2997 if ( !aStudy->GetProperties()->IsLocked() )
2999 SALOMEDS::GenericAttribute_wrap anAttr;
3000 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3001 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3002 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3003 ASSERT(!aFileName->_is_nil());
3004 aFileName->SetValue(file);
3005 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3006 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3007 ASSERT(!aFileType->_is_nil());
3008 aFileType->SetValue("FICHIERMED");
3012 // Update Python script
3013 // set name of mesh before export
3014 TPythonDump() << _gen_i << ".SetName("
3015 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3017 // check names of groups
3023 //================================================================================
3025 * \brief Export to med file
3027 //================================================================================
3029 void SMESH_Mesh_i::ExportToMEDX (const char* file,
3030 CORBA::Boolean auto_groups,
3031 SMESH::MED_VERSION theVersion,
3032 CORBA::Boolean overwrite,
3033 CORBA::Boolean autoDimension)
3034 throw(SALOME::SALOME_Exception)
3036 //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
3039 _preMeshInfo->FullLoadFromFile();
3041 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3042 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3044 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3045 << file << "', " << auto_groups << ", "
3046 << theVersion << ", " << overwrite << ", "
3047 << autoDimension << " )";
3049 SMESH_CATCH( SMESH::throwCorbaException );
3052 //================================================================================
3054 * \brief Export a mesh to a med file
3056 //================================================================================
3058 void SMESH_Mesh_i::ExportToMED (const char* file,
3059 CORBA::Boolean auto_groups,
3060 SMESH::MED_VERSION theVersion)
3061 throw(SALOME::SALOME_Exception)
3063 //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
3064 ExportToMEDX(file,auto_groups,theVersion,true);
3067 //================================================================================
3069 * \brief Export a mesh to a med file
3071 //================================================================================
3073 void SMESH_Mesh_i::ExportMED (const char* file,
3074 CORBA::Boolean auto_groups)
3075 throw(SALOME::SALOME_Exception)
3077 //MESSAGE("SMESH::MED_VERSION:"<< SMESH::MED_LATEST);
3078 ExportToMEDX(file,auto_groups,SMESH::MED_LATEST,true);
3081 //================================================================================
3083 * \brief Export a mesh to a SAUV file
3085 //================================================================================
3087 void SMESH_Mesh_i::ExportSAUV (const char* file,
3088 CORBA::Boolean auto_groups)
3089 throw(SALOME::SALOME_Exception)
3091 Unexpect aCatch(SALOME_SalomeException);
3093 _preMeshInfo->FullLoadFromFile();
3095 string aMeshName = prepareMeshNameAndGroups(file, true);
3096 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3097 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3098 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3102 //================================================================================
3104 * \brief Export a mesh to a DAT file
3106 //================================================================================
3108 void SMESH_Mesh_i::ExportDAT (const char *file)
3109 throw(SALOME::SALOME_Exception)
3111 Unexpect aCatch(SALOME_SalomeException);
3113 _preMeshInfo->FullLoadFromFile();
3115 // Update Python script
3116 // check names of groups
3118 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3121 PrepareForWriting(file);
3122 _impl->ExportDAT(file);
3125 //================================================================================
3127 * \brief Export a mesh to an UNV file
3129 //================================================================================
3131 void SMESH_Mesh_i::ExportUNV (const char *file)
3132 throw(SALOME::SALOME_Exception)
3134 Unexpect aCatch(SALOME_SalomeException);
3136 _preMeshInfo->FullLoadFromFile();
3138 // Update Python script
3139 // check names of groups
3141 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3144 PrepareForWriting(file);
3145 _impl->ExportUNV(file);
3148 //================================================================================
3150 * \brief Export a mesh to an STL file
3152 //================================================================================
3154 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3155 throw(SALOME::SALOME_Exception)
3157 Unexpect aCatch(SALOME_SalomeException);
3159 _preMeshInfo->FullLoadFromFile();
3161 // Update Python script
3162 // check names of groups
3164 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3165 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3167 CORBA::String_var name;
3168 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3169 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, _this() );
3170 if ( !so->_is_nil() )
3171 name = so->GetName();
3174 PrepareForWriting( file );
3175 _impl->ExportSTL( file, isascii, name.in() );
3178 //================================================================================
3180 * \brief Export a part of mesh to a med file
3182 //================================================================================
3184 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3186 CORBA::Boolean auto_groups,
3187 SMESH::MED_VERSION version,
3188 CORBA::Boolean overwrite,
3189 CORBA::Boolean autoDimension,
3190 const GEOM::ListOfFields& fields,
3191 const char* geomAssocFields)
3192 throw (SALOME::SALOME_Exception)
3196 _preMeshInfo->FullLoadFromFile();
3199 bool have0dField = false;
3200 if ( fields.length() > 0 )
3202 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3203 if ( shapeToMesh->_is_nil() )
3204 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3206 for ( size_t i = 0; i < fields.length(); ++i )
3208 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3209 THROW_SALOME_CORBA_EXCEPTION
3210 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3211 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3212 if ( fieldShape->_is_nil() )
3213 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3214 if ( !fieldShape->IsSame( shapeToMesh ) )
3215 THROW_SALOME_CORBA_EXCEPTION
3216 ( "Field defined not on shape", SALOME::BAD_PARAM);
3217 if ( fields[i]->GetDimension() == 0 )
3220 if ( geomAssocFields )
3221 for ( int i = 0; geomAssocFields[i]; ++i )
3222 switch ( geomAssocFields[i] ) {
3223 case 'v':case 'e':case 'f':case 's': break;
3224 case 'V':case 'E':case 'F':case 'S': break;
3225 default: THROW_SALOME_CORBA_EXCEPTION
3226 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3230 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3234 string aMeshName = "Mesh";
3235 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3236 if ( CORBA::is_nil( meshPart ) ||
3237 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3239 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3240 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3241 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3242 meshDS = _impl->GetMeshDS();
3247 _preMeshInfo->FullLoadFromFile();
3249 PrepareForWriting(file, overwrite);
3251 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3252 if ( !aStudy->_is_nil() ) {
3253 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3254 if ( !SO->_is_nil() ) {
3255 CORBA::String_var name = SO->GetName();
3259 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3260 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3261 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3262 meshDS = tmpDSDeleter._obj = partDS;
3267 if ( _impl->HasShapeToMesh() )
3269 DriverMED_W_Field fieldWriter;
3270 fieldWriter.SetFile( file );
3271 fieldWriter.SetMeshName( aMeshName );
3272 fieldWriter.AddODOnVertices( have0dField );
3274 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3278 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3279 goList->length( fields.length() );
3280 for ( size_t i = 0; i < fields.length(); ++i )
3282 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3285 TPythonDump() << _this() << ".ExportPartToMED( "
3286 << meshPart << ", r'" << file << "', "
3287 << auto_groups << ", " << version << ", " << overwrite << ", "
3288 << autoDimension << ", " << goList
3289 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3291 SMESH_CATCH( SMESH::throwCorbaException );
3294 //================================================================================
3296 * Write GEOM fields to MED file
3298 //================================================================================
3300 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3301 SMESHDS_Mesh* meshDS,
3302 const GEOM::ListOfFields& fields,
3303 const char* geomAssocFields)
3305 #define METH "SMESH_Mesh_i::exportMEDFields() "
3307 if (( fields.length() < 1 ) &&
3308 ( !geomAssocFields || !geomAssocFields[0] ))
3311 std::vector< std::vector< double > > dblVals;
3312 std::vector< std::vector< int > > intVals;
3313 std::vector< int > subIdsByDim[ 4 ];
3314 const double noneDblValue = 0.;
3315 const double noneIntValue = 0;
3317 for ( size_t iF = 0; iF < fields.length(); ++iF )
3321 int dim = fields[ iF ]->GetDimension();
3322 SMDSAbs_ElementType elemType;
3323 TopAbs_ShapeEnum shapeType;
3325 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3326 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3327 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3328 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3330 continue; // skip fields on whole shape
3332 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3333 if ( dataType == GEOM::FDT_String )
3335 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3336 if ( stepIDs->length() < 1 )
3338 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3339 if ( comps->length() < 1 )
3341 CORBA::String_var name = fields[ iF ]->GetName();
3343 if ( !fieldWriter.Set( meshDS,
3347 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3350 for ( size_t iC = 0; iC < comps->length(); ++iC )
3351 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3353 dblVals.resize( comps->length() );
3354 intVals.resize( comps->length() );
3356 // find sub-shape IDs
3358 std::vector< int >& subIds = subIdsByDim[ dim ];
3359 if ( subIds.empty() )
3360 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3361 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3362 subIds.push_back( id );
3366 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3370 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3372 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3373 if ( step->_is_nil() )
3376 CORBA::Long stamp = step->GetStamp();
3377 CORBA::Long id = step->GetID();
3378 fieldWriter.SetDtIt( int( stamp ), int( id ));
3380 // fill dblVals or intVals
3381 for ( size_t iC = 0; iC < comps->length(); ++iC )
3382 if ( dataType == GEOM::FDT_Double )
3384 dblVals[ iC ].clear();
3385 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3389 intVals[ iC ].clear();
3390 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3394 case GEOM::FDT_Double:
3396 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3397 if ( dblStep->_is_nil() ) continue;
3398 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3399 if ( vv->length() != subIds.size() * comps->length() )
3400 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3401 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3402 for ( size_t iC = 0; iC < comps->length(); ++iC )
3403 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3408 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3409 if ( intStep->_is_nil() ) continue;
3410 GEOM::ListOfLong_var vv = intStep->GetValues();
3411 if ( vv->length() != subIds.size() * comps->length() )
3412 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3413 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3414 for ( size_t iC = 0; iC < comps->length(); ++iC )
3415 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3418 case GEOM::FDT_Bool:
3420 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3421 if ( boolStep->_is_nil() ) continue;
3422 GEOM::short_array_var vv = boolStep->GetValues();
3423 if ( vv->length() != subIds.size() * comps->length() )
3424 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3425 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3426 for ( size_t iC = 0; iC < comps->length(); ++iC )
3427 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3433 // pass values to fieldWriter
3434 elemIt = fieldWriter.GetOrderedElems();
3435 if ( dataType == GEOM::FDT_Double )
3436 while ( elemIt->more() )
3438 const SMDS_MeshElement* e = elemIt->next();
3439 const int shapeID = e->getshapeId();
3440 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3441 for ( size_t iC = 0; iC < comps->length(); ++iC )
3442 fieldWriter.AddValue( noneDblValue );
3444 for ( size_t iC = 0; iC < comps->length(); ++iC )
3445 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3448 while ( elemIt->more() )
3450 const SMDS_MeshElement* e = elemIt->next();
3451 const int shapeID = e->getshapeId();
3452 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3453 for ( size_t iC = 0; iC < comps->length(); ++iC )
3454 fieldWriter.AddValue( (double) noneIntValue );
3456 for ( size_t iC = 0; iC < comps->length(); ++iC )
3457 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3461 fieldWriter.Perform();
3462 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3463 if ( res && res->IsKO() )
3465 if ( res->myComment.empty() )
3466 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3468 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3474 if ( !geomAssocFields || !geomAssocFields[0] )
3477 // write geomAssocFields
3479 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3480 shapeDim[ TopAbs_COMPOUND ] = 3;
3481 shapeDim[ TopAbs_COMPSOLID ] = 3;
3482 shapeDim[ TopAbs_SOLID ] = 3;
3483 shapeDim[ TopAbs_SHELL ] = 2;
3484 shapeDim[ TopAbs_FACE ] = 2;
3485 shapeDim[ TopAbs_WIRE ] = 1;
3486 shapeDim[ TopAbs_EDGE ] = 1;
3487 shapeDim[ TopAbs_VERTEX ] = 0;
3488 shapeDim[ TopAbs_SHAPE ] = 3;
3490 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3492 std::vector< std::string > compNames;
3493 switch ( geomAssocFields[ iF ]) {
3495 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3496 compNames.push_back( "dim" );
3499 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3502 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3505 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3509 compNames.push_back( "id" );
3510 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3511 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3513 fieldWriter.SetDtIt( -1, -1 );
3515 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3519 if ( compNames.size() == 2 ) // _vertices_
3520 while ( elemIt->more() )
3522 const SMDS_MeshElement* e = elemIt->next();
3523 const int shapeID = e->getshapeId();
3526 fieldWriter.AddValue( (double) -1 );
3527 fieldWriter.AddValue( (double) -1 );
3531 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3532 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3533 fieldWriter.AddValue( (double) shapeID );
3537 while ( elemIt->more() )
3539 const SMDS_MeshElement* e = elemIt->next();
3540 const int shapeID = e->getshapeId();
3542 fieldWriter.AddValue( (double) -1 );
3544 fieldWriter.AddValue( (double) shapeID );
3548 fieldWriter.Perform();
3549 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3550 if ( res && res->IsKO() )
3552 if ( res->myComment.empty() )
3553 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3555 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3558 } // loop on geomAssocFields
3563 //================================================================================
3565 * \brief Export a part of mesh to a DAT file
3567 //================================================================================
3569 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3571 throw (SALOME::SALOME_Exception)
3573 Unexpect aCatch(SALOME_SalomeException);
3575 _preMeshInfo->FullLoadFromFile();
3577 PrepareForWriting(file);
3579 SMESH_MeshPartDS partDS( meshPart );
3580 _impl->ExportDAT(file,&partDS);
3582 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3583 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3585 //================================================================================
3587 * \brief Export a part of mesh to an UNV file
3589 //================================================================================
3591 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3593 throw (SALOME::SALOME_Exception)
3595 Unexpect aCatch(SALOME_SalomeException);
3597 _preMeshInfo->FullLoadFromFile();
3599 PrepareForWriting(file);
3601 SMESH_MeshPartDS partDS( meshPart );
3602 _impl->ExportUNV(file, &partDS);
3604 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3605 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3607 //================================================================================
3609 * \brief Export a part of mesh to an STL file
3611 //================================================================================
3613 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3615 ::CORBA::Boolean isascii)
3616 throw (SALOME::SALOME_Exception)
3618 Unexpect aCatch(SALOME_SalomeException);
3620 _preMeshInfo->FullLoadFromFile();
3622 PrepareForWriting(file);
3624 CORBA::String_var name;
3625 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3626 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3627 if ( !so->_is_nil() )
3628 name = so->GetName();
3630 SMESH_MeshPartDS partDS( meshPart );
3631 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3633 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3634 << meshPart<< ", r'" << file << "', " << isascii << ")";
3637 //================================================================================
3639 * \brief Export a part of mesh to an STL file
3641 //================================================================================
3643 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3645 CORBA::Boolean overwrite,
3646 CORBA::Boolean groupElemsByType)
3647 throw (SALOME::SALOME_Exception)
3650 Unexpect aCatch(SALOME_SalomeException);
3652 _preMeshInfo->FullLoadFromFile();
3654 PrepareForWriting(file,overwrite);
3656 std::string meshName("");
3657 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3658 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3659 if ( !so->_is_nil() )
3661 CORBA::String_var name = so->GetName();
3662 meshName = name.in();
3666 SMESH_MeshPartDS partDS( meshPart );
3667 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3669 SMESH_CATCH( SMESH::throwCorbaException );
3671 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3672 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3674 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3678 //================================================================================
3680 * \brief Export a part of mesh to a GMF file
3682 //================================================================================
3684 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3686 bool withRequiredGroups)
3687 throw (SALOME::SALOME_Exception)
3689 Unexpect aCatch(SALOME_SalomeException);
3691 _preMeshInfo->FullLoadFromFile();
3693 PrepareForWriting(file,/*overwrite=*/true);
3695 SMESH_MeshPartDS partDS( meshPart );
3696 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3698 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3699 << meshPart<< ", r'"
3701 << withRequiredGroups << ")";
3704 //=============================================================================
3706 * Return computation progress [0.,1]
3708 //=============================================================================
3710 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3714 return _impl->GetComputeProgress();
3716 SMESH_CATCH( SMESH::doNothing );
3720 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3722 Unexpect aCatch(SALOME_SalomeException);
3724 return _preMeshInfo->NbNodes();
3726 return _impl->NbNodes();
3729 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3731 Unexpect aCatch(SALOME_SalomeException);
3733 return _preMeshInfo->NbElements();
3735 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3738 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3740 Unexpect aCatch(SALOME_SalomeException);
3742 return _preMeshInfo->Nb0DElements();
3744 return _impl->Nb0DElements();
3747 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3749 Unexpect aCatch(SALOME_SalomeException);
3751 return _preMeshInfo->NbBalls();
3753 return _impl->NbBalls();
3756 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3758 Unexpect aCatch(SALOME_SalomeException);
3760 return _preMeshInfo->NbEdges();
3762 return _impl->NbEdges();
3765 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3766 throw(SALOME::SALOME_Exception)
3768 Unexpect aCatch(SALOME_SalomeException);
3770 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3772 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3775 //=============================================================================
3777 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3779 Unexpect aCatch(SALOME_SalomeException);
3781 return _preMeshInfo->NbFaces();
3783 return _impl->NbFaces();
3786 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3788 Unexpect aCatch(SALOME_SalomeException);
3790 return _preMeshInfo->NbTriangles();
3792 return _impl->NbTriangles();
3795 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3797 Unexpect aCatch(SALOME_SalomeException);
3799 return _preMeshInfo->NbBiQuadTriangles();
3801 return _impl->NbBiQuadTriangles();
3804 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3806 Unexpect aCatch(SALOME_SalomeException);
3808 return _preMeshInfo->NbQuadrangles();
3810 return _impl->NbQuadrangles();
3813 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3815 Unexpect aCatch(SALOME_SalomeException);
3817 return _preMeshInfo->NbBiQuadQuadrangles();
3819 return _impl->NbBiQuadQuadrangles();
3822 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3824 Unexpect aCatch(SALOME_SalomeException);
3826 return _preMeshInfo->NbPolygons();
3828 return _impl->NbPolygons();
3831 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3833 Unexpect aCatch(SALOME_SalomeException);
3835 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3837 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3840 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3841 throw(SALOME::SALOME_Exception)
3843 Unexpect aCatch(SALOME_SalomeException);
3845 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3847 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3850 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3851 throw(SALOME::SALOME_Exception)
3853 Unexpect aCatch(SALOME_SalomeException);
3855 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3857 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3860 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3861 throw(SALOME::SALOME_Exception)
3863 Unexpect aCatch(SALOME_SalomeException);
3865 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3867 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3870 //=============================================================================
3872 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3874 Unexpect aCatch(SALOME_SalomeException);
3876 return _preMeshInfo->NbVolumes();
3878 return _impl->NbVolumes();
3881 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3883 Unexpect aCatch(SALOME_SalomeException);
3885 return _preMeshInfo->NbTetras();
3887 return _impl->NbTetras();
3890 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3892 Unexpect aCatch(SALOME_SalomeException);
3894 return _preMeshInfo->NbHexas();
3896 return _impl->NbHexas();
3899 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3901 Unexpect aCatch(SALOME_SalomeException);
3903 return _preMeshInfo->NbTriQuadHexas();
3905 return _impl->NbTriQuadraticHexas();
3908 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3910 Unexpect aCatch(SALOME_SalomeException);
3912 return _preMeshInfo->NbPyramids();
3914 return _impl->NbPyramids();
3917 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3919 Unexpect aCatch(SALOME_SalomeException);
3921 return _preMeshInfo->NbPrisms();
3923 return _impl->NbPrisms();
3926 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3928 Unexpect aCatch(SALOME_SalomeException);
3930 return _preMeshInfo->NbHexPrisms();
3932 return _impl->NbHexagonalPrisms();
3935 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3937 Unexpect aCatch(SALOME_SalomeException);
3939 return _preMeshInfo->NbPolyhedrons();
3941 return _impl->NbPolyhedrons();
3944 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3945 throw(SALOME::SALOME_Exception)
3947 Unexpect aCatch(SALOME_SalomeException);
3949 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3951 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3954 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3955 throw(SALOME::SALOME_Exception)
3957 Unexpect aCatch(SALOME_SalomeException);
3959 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3961 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3964 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3965 throw(SALOME::SALOME_Exception)
3967 Unexpect aCatch(SALOME_SalomeException);
3969 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3971 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3974 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3975 throw(SALOME::SALOME_Exception)
3977 Unexpect aCatch(SALOME_SalomeException);
3979 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3981 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3984 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3985 throw(SALOME::SALOME_Exception)
3987 Unexpect aCatch(SALOME_SalomeException);
3989 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3991 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3994 //=============================================================================
3996 * Returns nb of published sub-meshes
3998 //=============================================================================
4000 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4002 Unexpect aCatch(SALOME_SalomeException);
4003 return _mapSubMesh_i.size();
4006 //=============================================================================
4008 * Dumps mesh into a string
4010 //=============================================================================
4012 char* SMESH_Mesh_i::Dump()
4016 return CORBA::string_dup( os.str().c_str() );
4019 //=============================================================================
4021 * Method of SMESH_IDSource interface
4023 //=============================================================================
4025 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4027 return GetElementsId();
4030 //=============================================================================
4032 * Returns ids of all elements
4034 //=============================================================================
4036 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4037 throw (SALOME::SALOME_Exception)
4039 Unexpect aCatch(SALOME_SalomeException);
4041 _preMeshInfo->FullLoadFromFile();
4043 SMESH::long_array_var aResult = new SMESH::long_array();
4044 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4046 if ( aSMESHDS_Mesh == NULL )
4047 return aResult._retn();
4049 long nbElements = NbElements();
4050 aResult->length( nbElements );
4051 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4052 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4053 aResult[i] = anIt->next()->GetID();
4055 return aResult._retn();
4059 //=============================================================================
4061 * Returns ids of all elements of given type
4063 //=============================================================================
4065 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4066 throw (SALOME::SALOME_Exception)
4068 Unexpect aCatch(SALOME_SalomeException);
4070 _preMeshInfo->FullLoadFromFile();
4072 SMESH::long_array_var aResult = new SMESH::long_array();
4073 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4075 if ( aSMESHDS_Mesh == NULL )
4076 return aResult._retn();
4078 long nbElements = NbElements();
4080 // No sense in returning ids of elements along with ids of nodes:
4081 // when theElemType == SMESH::ALL, return node ids only if
4082 // there are no elements
4083 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4084 return GetNodesId();
4086 aResult->length( nbElements );
4090 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4091 while ( i < nbElements && anIt->more() )
4092 aResult[i++] = anIt->next()->GetID();
4094 aResult->length( i );
4096 return aResult._retn();
4099 //=============================================================================
4101 * Returns ids of all nodes
4103 //=============================================================================
4105 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4106 throw (SALOME::SALOME_Exception)
4108 Unexpect aCatch(SALOME_SalomeException);
4110 _preMeshInfo->FullLoadFromFile();
4112 SMESH::long_array_var aResult = new SMESH::long_array();
4113 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4115 if ( aMeshDS == NULL )
4116 return aResult._retn();
4118 long nbNodes = NbNodes();
4119 aResult->length( nbNodes );
4120 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4121 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4122 aResult[i] = anIt->next()->GetID();
4124 return aResult._retn();
4127 //=============================================================================
4131 //=============================================================================
4133 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4134 throw (SALOME::SALOME_Exception)
4136 SMESH::ElementType type = SMESH::ALL;
4140 _preMeshInfo->FullLoadFromFile();
4142 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4144 SMESH_CATCH( SMESH::throwCorbaException );
4149 //=============================================================================
4153 //=============================================================================
4155 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4156 throw (SALOME::SALOME_Exception)
4159 _preMeshInfo->FullLoadFromFile();
4161 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4163 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4165 return ( SMESH::EntityType ) e->GetEntityType();
4168 //=============================================================================
4172 //=============================================================================
4174 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4175 throw (SALOME::SALOME_Exception)
4178 _preMeshInfo->FullLoadFromFile();
4180 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4182 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4184 return ( SMESH::GeometryType ) e->GetGeomType();
4187 //=============================================================================
4189 * Returns ID of elements for given submesh
4191 //=============================================================================
4192 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4193 throw (SALOME::SALOME_Exception)
4195 SMESH::long_array_var aResult = new SMESH::long_array();
4199 _preMeshInfo->FullLoadFromFile();
4201 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4202 if(!SM) return aResult._retn();
4204 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4205 if(!SDSM) return aResult._retn();
4207 aResult->length(SDSM->NbElements());
4209 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4211 while ( eIt->more() ) {
4212 aResult[i++] = eIt->next()->GetID();
4215 SMESH_CATCH( SMESH::throwCorbaException );
4217 return aResult._retn();
4220 //=============================================================================
4222 * Returns ID of nodes for given submesh
4223 * If param all==true - returns all nodes, else -
4224 * returns only nodes on shapes.
4226 //=============================================================================
4228 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4230 throw (SALOME::SALOME_Exception)
4232 SMESH::long_array_var aResult = new SMESH::long_array();
4236 _preMeshInfo->FullLoadFromFile();
4238 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4239 if(!SM) return aResult._retn();
4241 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4242 if(!SDSM) return aResult._retn();
4245 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4246 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4247 while ( nIt->more() ) {
4248 const SMDS_MeshNode* elem = nIt->next();
4249 theElems.insert( elem->GetID() );
4252 else { // all nodes of submesh elements
4253 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4254 while ( eIt->more() ) {
4255 const SMDS_MeshElement* anElem = eIt->next();
4256 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4257 while ( nIt->more() ) {
4258 const SMDS_MeshElement* elem = nIt->next();
4259 theElems.insert( elem->GetID() );
4264 aResult->length(theElems.size());
4265 set<int>::iterator itElem;
4267 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4268 aResult[i++] = *itElem;
4270 SMESH_CATCH( SMESH::throwCorbaException );
4272 return aResult._retn();
4275 //=============================================================================
4277 * Returns type of elements for given submesh
4279 //=============================================================================
4281 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4282 throw (SALOME::SALOME_Exception)
4284 SMESH::ElementType type = SMESH::ALL;
4288 _preMeshInfo->FullLoadFromFile();
4290 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4291 if(!SM) return SMESH::ALL;
4293 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4294 if(!SDSM) return SMESH::ALL;
4296 if(SDSM->NbElements()==0)
4297 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4299 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4300 const SMDS_MeshElement* anElem = eIt->next();
4302 type = ( SMESH::ElementType ) anElem->GetType();
4304 SMESH_CATCH( SMESH::throwCorbaException );
4310 //=============================================================================
4312 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4314 //=============================================================================
4316 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4319 _preMeshInfo->FullLoadFromFile();
4321 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4322 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4327 //=============================================================================
4329 * Get XYZ coordinates of node as list of double
4330 * If there is not node for given ID - returns empty list
4332 //=============================================================================
4334 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4337 _preMeshInfo->FullLoadFromFile();
4339 SMESH::double_array_var aResult = new SMESH::double_array();
4340 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4341 if ( aMeshDS == NULL )
4342 return aResult._retn();
4345 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4347 return aResult._retn();
4351 aResult[0] = aNode->X();
4352 aResult[1] = aNode->Y();
4353 aResult[2] = aNode->Z();
4354 return aResult._retn();
4358 //=============================================================================
4360 * For given node returns list of IDs of inverse elements
4361 * If there is not node for given ID - returns empty list
4363 //=============================================================================
4365 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4368 _preMeshInfo->FullLoadFromFile();
4370 SMESH::long_array_var aResult = new SMESH::long_array();
4371 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4372 if ( aMeshDS == NULL )
4373 return aResult._retn();
4376 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4378 return aResult._retn();
4380 // find inverse elements
4381 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4382 aResult->length( aNode->NbInverseElements() );
4383 for( int i = 0; eIt->more(); ++i )
4385 const SMDS_MeshElement* elem = eIt->next();
4386 aResult[ i ] = elem->GetID();
4388 return aResult._retn();
4391 //=============================================================================
4393 * \brief Return position of a node on shape
4395 //=============================================================================
4397 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4400 _preMeshInfo->FullLoadFromFile();
4402 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4403 aNodePosition->shapeID = 0;
4404 aNodePosition->shapeType = GEOM::SHAPE;
4406 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4407 if ( !mesh ) return aNodePosition;
4409 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4411 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4413 aNodePosition->shapeID = aNode->getshapeId();
4414 switch ( pos->GetTypeOfPosition() ) {
4416 aNodePosition->shapeType = GEOM::EDGE;
4417 aNodePosition->params.length(1);
4418 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4420 case SMDS_TOP_FACE: {
4421 SMDS_FacePositionPtr fPos = pos;
4422 aNodePosition->shapeType = GEOM::FACE;
4423 aNodePosition->params.length(2);
4424 aNodePosition->params[0] = fPos->GetUParameter();
4425 aNodePosition->params[1] = fPos->GetVParameter();
4428 case SMDS_TOP_VERTEX:
4429 aNodePosition->shapeType = GEOM::VERTEX;
4431 case SMDS_TOP_3DSPACE:
4432 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4433 aNodePosition->shapeType = GEOM::SOLID;
4434 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4435 aNodePosition->shapeType = GEOM::SHELL;
4441 return aNodePosition;
4444 //=============================================================================
4446 * \brief Return position of an element on shape
4448 //=============================================================================
4450 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4453 _preMeshInfo->FullLoadFromFile();
4455 SMESH::ElementPosition anElementPosition;
4456 anElementPosition.shapeID = 0;
4457 anElementPosition.shapeType = GEOM::SHAPE;
4459 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4460 if ( !mesh ) return anElementPosition;
4462 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4464 anElementPosition.shapeID = anElem->getshapeId();
4465 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4466 if ( !aSp.IsNull() ) {
4467 switch ( aSp.ShapeType() ) {
4469 anElementPosition.shapeType = GEOM::EDGE;
4472 anElementPosition.shapeType = GEOM::FACE;
4475 anElementPosition.shapeType = GEOM::VERTEX;
4478 anElementPosition.shapeType = GEOM::SOLID;
4481 anElementPosition.shapeType = GEOM::SHELL;
4487 return anElementPosition;
4490 //=============================================================================
4492 * If given element is node returns IDs of shape from position
4493 * If there is not node for given ID - returns -1
4495 //=============================================================================
4497 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4500 _preMeshInfo->FullLoadFromFile();
4502 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4503 if ( aMeshDS == NULL )
4507 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4509 return aNode->getshapeId();
4516 //=============================================================================
4518 * For given element returns ID of result shape after
4519 * ::FindShape() from SMESH_MeshEditor
4520 * If there is not element for given ID - returns -1
4522 //=============================================================================
4524 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4527 _preMeshInfo->FullLoadFromFile();
4529 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4530 if ( aMeshDS == NULL )
4533 // try to find element
4534 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4538 ::SMESH_MeshEditor aMeshEditor(_impl);
4539 int index = aMeshEditor.FindShape( elem );
4547 //=============================================================================
4549 * Returns number of nodes for given element
4550 * If there is not element for given ID - returns -1
4552 //=============================================================================
4554 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4557 _preMeshInfo->FullLoadFromFile();
4559 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4560 if ( aMeshDS == NULL ) return -1;
4561 // try to find element
4562 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4563 if(!elem) return -1;
4564 return elem->NbNodes();
4568 //=============================================================================
4570 * Returns ID of node by given index for given element
4571 * If there is not element for given ID - returns -1
4572 * If there is not node for given index - returns -2
4574 //=============================================================================
4576 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4579 _preMeshInfo->FullLoadFromFile();
4581 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4582 if ( aMeshDS == NULL ) return -1;
4583 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4584 if(!elem) return -1;
4585 if( index>=elem->NbNodes() || index<0 ) return -1;
4586 return elem->GetNode(index)->GetID();
4589 //=============================================================================
4591 * Returns IDs of nodes of given element
4593 //=============================================================================
4595 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4598 _preMeshInfo->FullLoadFromFile();
4600 SMESH::long_array_var aResult = new SMESH::long_array();
4601 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4603 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4605 aResult->length( elem->NbNodes() );
4606 for ( int i = 0; i < elem->NbNodes(); ++i )
4607 aResult[ i ] = elem->GetNode( i )->GetID();
4610 return aResult._retn();
4613 //=============================================================================
4615 * Returns true if given node is medium node
4616 * in given quadratic element
4618 //=============================================================================
4620 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4623 _preMeshInfo->FullLoadFromFile();
4625 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4626 if ( aMeshDS == NULL ) return false;
4628 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4629 if(!aNode) return false;
4630 // try to find element
4631 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4632 if(!elem) return false;
4634 return elem->IsMediumNode(aNode);
4638 //=============================================================================
4640 * Returns true if given node is medium node
4641 * in one of quadratic elements
4643 //=============================================================================
4645 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4646 SMESH::ElementType theElemType)
4649 _preMeshInfo->FullLoadFromFile();
4651 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4652 if ( aMeshDS == NULL ) return false;
4655 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4656 if(!aNode) return false;
4658 SMESH_MesherHelper aHelper( *(_impl) );
4660 SMDSAbs_ElementType aType;
4661 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4662 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4663 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4664 else aType = SMDSAbs_All;
4666 return aHelper.IsMedium(aNode,aType);
4670 //=============================================================================
4672 * Returns number of edges for given element
4674 //=============================================================================
4676 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4679 _preMeshInfo->FullLoadFromFile();
4681 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4682 if ( aMeshDS == NULL ) return -1;
4683 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4684 if(!elem) return -1;
4685 return elem->NbEdges();
4689 //=============================================================================
4691 * Returns number of faces for given element
4693 //=============================================================================
4695 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4698 _preMeshInfo->FullLoadFromFile();
4700 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4701 if ( aMeshDS == NULL ) return -1;
4702 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4703 if(!elem) return -1;
4704 return elem->NbFaces();
4707 //=======================================================================
4708 //function : GetElemFaceNodes
4709 //purpose : Returns nodes of given face (counted from zero) for given element.
4710 //=======================================================================
4712 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4713 CORBA::Short faceIndex)
4716 _preMeshInfo->FullLoadFromFile();
4718 SMESH::long_array_var aResult = new SMESH::long_array();
4719 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4721 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4723 SMDS_VolumeTool vtool( elem );
4724 if ( faceIndex < vtool.NbFaces() )
4726 aResult->length( vtool.NbFaceNodes( faceIndex ));
4727 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4728 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4729 aResult[ i ] = nn[ i ]->GetID();
4733 return aResult._retn();
4736 //=======================================================================
4737 //function : GetElemFaceNodes
4738 //purpose : Returns three components of normal of given mesh face.
4739 //=======================================================================
4741 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4742 CORBA::Boolean normalized)
4745 _preMeshInfo->FullLoadFromFile();
4747 SMESH::double_array_var aResult = new SMESH::double_array();
4749 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4752 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4754 aResult->length( 3 );
4755 aResult[ 0 ] = normal.X();
4756 aResult[ 1 ] = normal.Y();
4757 aResult[ 2 ] = normal.Z();
4760 return aResult._retn();
4763 //=======================================================================
4764 //function : FindElementByNodes
4765 //purpose : Returns an element based on all given nodes.
4766 //=======================================================================
4768 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4771 _preMeshInfo->FullLoadFromFile();
4773 CORBA::Long elemID(0);
4774 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4776 vector< const SMDS_MeshNode * > nn( nodes.length() );
4777 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4778 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4781 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4782 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4783 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4784 _impl->NbVolumes( ORDER_QUADRATIC )))
4785 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4787 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4792 //================================================================================
4794 * \brief Return elements including all given nodes.
4796 //================================================================================
4798 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4799 SMESH::ElementType elemType)
4802 _preMeshInfo->FullLoadFromFile();
4804 SMESH::long_array_var result = new SMESH::long_array();
4806 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4808 vector< const SMDS_MeshNode * > nn( nodes.length() );
4809 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4810 nn[i] = mesh->FindNode( nodes[i] );
4812 std::vector<const SMDS_MeshElement *> elems;
4813 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4814 result->length( elems.size() );
4815 for ( size_t i = 0; i < elems.size(); ++i )
4816 result[i] = elems[i]->GetID();
4818 return result._retn();
4821 //=============================================================================
4823 * Returns true if given element is polygon
4825 //=============================================================================
4827 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4830 _preMeshInfo->FullLoadFromFile();
4832 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4833 if ( aMeshDS == NULL ) return false;
4834 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4835 if(!elem) return false;
4836 return elem->IsPoly();
4840 //=============================================================================
4842 * Returns true if given element is quadratic
4844 //=============================================================================
4846 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4849 _preMeshInfo->FullLoadFromFile();
4851 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4852 if ( aMeshDS == NULL ) return false;
4853 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4854 if(!elem) return false;
4855 return elem->IsQuadratic();
4858 //=============================================================================
4860 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4862 //=============================================================================
4864 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4867 _preMeshInfo->FullLoadFromFile();
4869 if ( const SMDS_BallElement* ball =
4870 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4871 return ball->GetDiameter();
4876 //=============================================================================
4878 * Returns bary center for given element
4880 //=============================================================================
4882 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4885 _preMeshInfo->FullLoadFromFile();
4887 SMESH::double_array_var aResult = new SMESH::double_array();
4888 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4889 if ( aMeshDS == NULL )
4890 return aResult._retn();
4892 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4894 return aResult._retn();
4896 if(elem->GetType()==SMDSAbs_Volume) {
4897 SMDS_VolumeTool aTool;
4898 if(aTool.Set(elem)) {
4900 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4905 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4907 double x=0., y=0., z=0.;
4908 for(; anIt->more(); ) {
4910 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4924 return aResult._retn();
4927 //================================================================================
4929 * \brief Create a group of elements preventing computation of a sub-shape
4931 //================================================================================
4933 SMESH::ListOfGroups*
4934 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4935 const char* theGroupName )
4936 throw ( SALOME::SALOME_Exception )
4938 Unexpect aCatch(SALOME_SalomeException);
4940 if ( !theGroupName || strlen( theGroupName) == 0 )
4941 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4943 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4944 ::SMESH_MeshEditor::ElemFeatures elemType;
4946 // submesh by subshape id
4947 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4948 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4951 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4952 if ( error && error->HasBadElems() )
4954 // sort bad elements by type
4955 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4956 const list<const SMDS_MeshElement*>& badElems =
4957 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
4958 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
4959 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
4960 for ( ; elemIt != elemEnd; ++elemIt )
4962 const SMDS_MeshElement* elem = *elemIt;
4963 if ( !elem ) continue;
4965 if ( elem->GetID() < 1 )
4967 // elem is a temporary element, make a real element
4968 vector< const SMDS_MeshNode* > nodes;
4969 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4970 while ( nIt->more() && elem )
4972 nodes.push_back( nIt->next() );
4973 if ( nodes.back()->GetID() < 1 )
4974 elem = 0; // a temporary element on temporary nodes
4978 ::SMESH_MeshEditor editor( _impl );
4979 elem = editor.AddElement( nodes, elemType.Init( elem ));
4983 elemsByType[ elem->GetType() ].push_back( elem );
4986 // how many groups to create?
4988 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4989 nbTypes += int( !elemsByType[ i ].empty() );
4990 groups->length( nbTypes );
4993 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4995 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4996 if ( elems.empty() ) continue;
4998 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4999 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5001 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
5002 SMESH::SMESH_Mesh_var mesh = _this();
5003 SALOMEDS::SObject_wrap aSO =
5004 _gen_i->PublishGroup( study, mesh, groups[ iG ],
5005 GEOM::GEOM_Object::_nil(), theGroupName);
5007 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5008 if ( !grp_i ) continue;
5010 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5011 for ( size_t iE = 0; iE < elems.size(); ++iE )
5012 grpDS->SMDSGroup().Add( elems[ iE ]);
5017 return groups._retn();
5020 //=============================================================================
5022 * Create and publish group servants if any groups were imported or created anyhow
5024 //=============================================================================
5026 void SMESH_Mesh_i::CreateGroupServants()
5028 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5029 SMESH::SMESH_Mesh_var aMesh = _this();
5032 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5033 while ( groupIt->more() )
5035 ::SMESH_Group* group = groupIt->next();
5036 int anId = group->GetGroupDS()->GetID();
5038 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5039 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5041 addedIDs.insert( anId );
5043 SMESH_GroupBase_i* aGroupImpl;
5045 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5046 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5048 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5049 shape = groupOnGeom->GetShape();
5052 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5055 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5056 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5057 aGroupImpl->Register();
5059 // register CORBA object for persistence
5060 int nextId = _gen_i->RegisterObject( groupVar );
5061 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5062 else { nextId = 0; } // avoid "unused variable" warning in release mode
5064 // publishing the groups in the study
5065 if ( !aStudy->_is_nil() ) {
5066 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5067 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
5070 if ( !addedIDs.empty() )
5073 set<int>::iterator id = addedIDs.begin();
5074 for ( ; id != addedIDs.end(); ++id )
5076 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5077 int i = std::distance( _mapGroups.begin(), it );
5078 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5083 //=============================================================================
5085 * \brief Return groups cantained in _mapGroups by their IDs
5087 //=============================================================================
5089 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5091 int nbGroups = groupIDs.size();
5092 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5093 aList->length( nbGroups );
5095 list<int>::const_iterator ids = groupIDs.begin();
5096 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5098 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5099 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5100 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5102 aList->length( nbGroups );
5103 return aList._retn();
5106 //=============================================================================
5108 * \brief Return information about imported file
5110 //=============================================================================
5112 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5114 SMESH::MedFileInfo_var res( _medFileInfo );
5115 if ( !res.operator->() ) {
5116 res = new SMESH::MedFileInfo;
5118 res->fileSize = res->major = res->minor = res->release = -1;
5123 //=============================================================================
5125 * \brief Pass names of mesh groups from study to mesh DS
5127 //=============================================================================
5129 void SMESH_Mesh_i::checkGroupNames()
5131 int nbGrp = NbGroups();
5135 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5136 if ( aStudy->_is_nil() )
5137 return; // nothing to do
5139 SMESH::ListOfGroups* grpList = 0;
5140 // avoid dump of "GetGroups"
5142 // store python dump into a local variable inside local scope
5143 SMESH::TPythonDump pDump; // do not delete this line of code
5144 grpList = GetGroups();
5147 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5148 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5151 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5152 if ( aGrpSO->_is_nil() )
5154 // correct name of the mesh group if necessary
5155 const char* guiName = aGrpSO->GetName();
5156 if ( strcmp(guiName, aGrp->GetName()) )
5157 aGrp->SetName( guiName );
5161 //=============================================================================
5163 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5165 //=============================================================================
5166 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5168 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5172 //=============================================================================
5174 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5176 //=============================================================================
5178 char* SMESH_Mesh_i::GetParameters()
5180 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5183 //=============================================================================
5185 * \brief Returns list of notebook variables used for last Mesh operation
5187 //=============================================================================
5188 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5190 SMESH::string_array_var aResult = new SMESH::string_array();
5191 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5193 CORBA::String_var aParameters = GetParameters();
5194 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5195 if ( !aStudy->_is_nil()) {
5196 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5197 if ( aSections->length() > 0 ) {
5198 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5199 aResult->length( aVars.length() );
5200 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5201 aResult[i] = CORBA::string_dup( aVars[i] );
5205 return aResult._retn();
5208 //=======================================================================
5209 //function : GetTypes
5210 //purpose : Returns types of elements it contains
5211 //=======================================================================
5213 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5216 return _preMeshInfo->GetTypes();
5218 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5222 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5223 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5224 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5225 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5226 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5227 if (_impl->NbNodes() &&
5228 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5229 types->length( nbTypes );
5231 return types._retn();
5234 //=======================================================================
5235 //function : GetMesh
5236 //purpose : Returns self
5237 //=======================================================================
5239 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5241 return SMESH::SMESH_Mesh::_duplicate( _this() );
5244 //=======================================================================
5245 //function : IsMeshInfoCorrect
5246 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5247 // * happen if mesh data is not yet fully loaded from the file of study.
5248 //=======================================================================
5250 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5252 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5255 //=============================================================================
5257 * \brief Returns number of mesh elements per each \a EntityType
5259 //=============================================================================
5261 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5264 return _preMeshInfo->GetMeshInfo();
5266 SMESH::long_array_var aRes = new SMESH::long_array();
5267 aRes->length(SMESH::Entity_Last);
5268 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5270 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5272 return aRes._retn();
5273 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5274 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5275 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5276 return aRes._retn();
5279 //=============================================================================
5281 * \brief Returns number of mesh elements per each \a ElementType
5283 //=============================================================================
5285 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5287 SMESH::long_array_var aRes = new SMESH::long_array();
5288 aRes->length(SMESH::NB_ELEMENT_TYPES);
5289 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5292 const SMDS_MeshInfo* meshInfo = 0;
5294 meshInfo = _preMeshInfo;
5295 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5296 meshInfo = & meshDS->GetMeshInfo();
5299 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5300 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5302 return aRes._retn();
5305 //=============================================================================
5307 * Collect statistic of mesh elements given by iterator
5309 //=============================================================================
5311 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5312 SMESH::long_array& theInfo)
5314 if (!theItr) return;
5315 while (theItr->more())
5316 theInfo[ theItr->next()->GetEntityType() ]++;
5318 //=============================================================================
5320 * Returns mesh unstructed grid information.
5322 //=============================================================================
5324 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5326 SALOMEDS::TMPFile_var SeqFile;
5327 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5328 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5330 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5331 aWriter->WriteToOutputStringOn();
5332 aWriter->SetInputData(aGrid);
5333 aWriter->SetFileTypeToBinary();
5335 char* str = aWriter->GetOutputString();
5336 int size = aWriter->GetOutputStringLength();
5338 //Allocate octect buffer of required size
5339 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5340 //Copy ostrstream content to the octect buffer
5341 memcpy(OctetBuf, str, size);
5342 //Create and return TMPFile
5343 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5347 return SeqFile._retn();
5350 //=============================================================================
5351 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5352 * SMESH::ElementType type) */
5354 using namespace SMESH::Controls;
5355 //-----------------------------------------------------------------------------
5356 struct PredicateIterator : public SMDS_ElemIterator
5358 SMDS_ElemIteratorPtr _elemIter;
5359 PredicatePtr _predicate;
5360 const SMDS_MeshElement* _elem;
5362 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5363 PredicatePtr predicate):
5364 _elemIter(iterator), _predicate(predicate)
5372 virtual const SMDS_MeshElement* next()
5374 const SMDS_MeshElement* res = _elem;
5376 while ( _elemIter->more() && !_elem )
5378 _elem = _elemIter->next();
5379 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5386 //-----------------------------------------------------------------------------
5387 struct IDSourceIterator : public SMDS_ElemIterator
5389 const CORBA::Long* _idPtr;
5390 const CORBA::Long* _idEndPtr;
5391 SMESH::long_array_var _idArray;
5392 const SMDS_Mesh* _mesh;
5393 const SMDSAbs_ElementType _type;
5394 const SMDS_MeshElement* _elem;
5396 IDSourceIterator( const SMDS_Mesh* mesh,
5397 const CORBA::Long* ids,
5399 SMDSAbs_ElementType type):
5400 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5402 if ( _idPtr && nbIds && _mesh )
5405 IDSourceIterator( const SMDS_Mesh* mesh,
5406 SMESH::long_array* idArray,
5407 SMDSAbs_ElementType type):
5408 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5410 if ( idArray && _mesh )
5412 _idPtr = &_idArray[0];
5413 _idEndPtr = _idPtr + _idArray->length();
5421 virtual const SMDS_MeshElement* next()
5423 const SMDS_MeshElement* res = _elem;
5425 while ( _idPtr < _idEndPtr && !_elem )
5427 if ( _type == SMDSAbs_Node )
5429 _elem = _mesh->FindNode( *_idPtr++ );
5431 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5432 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5440 //-----------------------------------------------------------------------------
5442 struct NodeOfElemIterator : public SMDS_ElemIterator
5444 TColStd_MapOfInteger _checkedNodeIDs;
5445 SMDS_ElemIteratorPtr _elemIter;
5446 SMDS_ElemIteratorPtr _nodeIter;
5447 const SMDS_MeshElement* _node;
5449 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5451 if ( _elemIter && _elemIter->more() )
5453 _nodeIter = _elemIter->next()->nodesIterator();
5461 virtual const SMDS_MeshElement* next()
5463 const SMDS_MeshElement* res = _node;
5465 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5467 if ( _nodeIter->more() )
5469 _node = _nodeIter->next();
5470 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5475 _nodeIter = _elemIter->next()->nodesIterator();
5483 //=============================================================================
5485 * Return iterator on elements of given type in given object
5487 //=============================================================================
5489 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5490 SMESH::ElementType theType)
5492 SMDS_ElemIteratorPtr elemIt;
5493 bool typeOK = ( theType == SMESH::ALL );
5494 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5496 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5497 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5498 if ( !mesh_i ) return elemIt;
5499 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5501 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5503 elemIt = meshDS->elementsIterator( elemType );
5506 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5508 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5511 elemIt = sm->GetElements();
5512 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5514 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5515 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5519 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5521 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5522 if ( groupDS && ( elemType == groupDS->GetType() ||
5523 elemType == SMDSAbs_Node ||
5524 elemType == SMDSAbs_All ))
5526 elemIt = groupDS->GetElements();
5527 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5530 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5532 if ( filter_i->GetElementType() == theType ||
5533 elemType == SMDSAbs_Node ||
5534 elemType == SMDSAbs_All)
5536 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5537 if ( pred_i && pred_i->GetPredicate() )
5539 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5540 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5541 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5542 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5548 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5549 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5550 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5552 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5555 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5556 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5560 SMESH::long_array_var ids = theObject->GetIDs();
5561 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5563 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5566 if ( elemIt && elemIt->more() && !typeOK )
5568 if ( elemType == SMDSAbs_Node )
5570 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5574 elemIt = SMDS_ElemIteratorPtr();
5580 //=============================================================================
5581 namespace // Finding concurrent hypotheses
5582 //=============================================================================
5586 * \brief mapping of mesh dimension into shape type
5588 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5590 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5592 case 0: aType = TopAbs_VERTEX; break;
5593 case 1: aType = TopAbs_EDGE; break;
5594 case 2: aType = TopAbs_FACE; break;
5596 default:aType = TopAbs_SOLID; break;
5601 //-----------------------------------------------------------------------------
5603 * \brief Internal structure used to find concurrent submeshes
5605 * It represents a pair < submesh, concurrent dimension >, where
5606 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5607 * with another submesh. In other words, it is dimension of a hypothesis assigned
5614 int _dim; //!< a dimension the algo can build (concurrent dimension)
5615 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5616 TopTools_MapOfShape _shapeMap;
5617 SMESH_subMesh* _subMesh;
5618 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5620 //-----------------------------------------------------------------------------
5621 // Return the algorithm
5622 const SMESH_Algo* GetAlgo() const
5623 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5625 //-----------------------------------------------------------------------------
5627 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5629 const TopoDS_Shape& theShape)
5631 _subMesh = (SMESH_subMesh*)theSubMesh;
5632 SetShape( theDim, theShape );
5635 //-----------------------------------------------------------------------------
5637 void SetShape(const int theDim,
5638 const TopoDS_Shape& theShape)
5641 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5642 if (_dim >= _ownDim)
5643 _shapeMap.Add( theShape );
5645 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5646 for( ; anExp.More(); anExp.Next() )
5647 _shapeMap.Add( anExp.Current() );
5651 //-----------------------------------------------------------------------------
5652 //! Check sharing of sub-shapes
5653 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5654 const TopTools_MapOfShape& theToFind,
5655 const TopAbs_ShapeEnum theType)
5657 bool isShared = false;
5658 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5659 for (; !isShared && anItr.More(); anItr.Next() )
5661 const TopoDS_Shape aSubSh = anItr.Key();
5662 // check for case when concurrent dimensions are same
5663 isShared = theToFind.Contains( aSubSh );
5664 // check for sub-shape with concurrent dimension
5665 TopExp_Explorer anExp( aSubSh, theType );
5666 for ( ; !isShared && anExp.More(); anExp.Next() )
5667 isShared = theToFind.Contains( anExp.Current() );
5672 //-----------------------------------------------------------------------------
5673 //! check algorithms
5674 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5675 const SMESHDS_Hypothesis* theA2)
5677 if ( !theA1 || !theA2 ||
5678 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5679 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5680 return false; // one of the hypothesis is not algorithm
5681 // check algorithm names (should be equal)
5682 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5686 //-----------------------------------------------------------------------------
5687 //! Check if sub-shape hypotheses are concurrent
5688 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5690 if ( _subMesh == theOther->_subMesh )
5691 return false; // same sub-shape - should not be
5693 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5694 // any of the two submeshes is not on COMPOUND shape )
5695 // -> no concurrency
5696 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5697 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5698 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5699 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5700 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5703 // bool checkSubShape = ( _dim >= theOther->_dim )
5704 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5705 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5706 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5707 if ( !checkSubShape )
5710 // check algorithms to be same
5711 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5712 return true; // different algorithms -> concurrency !
5714 // check hypothesises for concurrence (skip first as algorithm)
5716 // pointers should be same, because it is referened from mesh hypothesis partition
5717 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5718 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5719 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5720 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5722 // the submeshes are concurrent if their algorithms has different parameters
5723 return nbSame != (int)theOther->_hypotheses.size() - 1;
5726 // Return true if algorithm of this SMESH_DimHyp is used if no
5727 // sub-mesh order is imposed by the user
5728 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5730 // NeedDiscreteBoundary() algo has a higher priority
5731 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5732 theOther->GetAlgo()->NeedDiscreteBoundary() )
5733 return !this->GetAlgo()->NeedDiscreteBoundary();
5735 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5738 }; // end of SMESH_DimHyp
5739 //-----------------------------------------------------------------------------
5741 typedef list<const SMESH_DimHyp*> TDimHypList;
5743 //-----------------------------------------------------------------------------
5745 void addDimHypInstance(const int theDim,
5746 const TopoDS_Shape& theShape,
5747 const SMESH_Algo* theAlgo,
5748 const SMESH_subMesh* theSubMesh,
5749 const list <const SMESHDS_Hypothesis*>& theHypList,
5750 TDimHypList* theDimHypListArr )
5752 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5753 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5754 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5755 dimHyp->_hypotheses.push_front(theAlgo);
5756 listOfdimHyp.push_back( dimHyp );
5759 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5760 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5761 theHypList.begin(), theHypList.end() );
5764 //-----------------------------------------------------------------------------
5765 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5766 TDimHypList& theListOfConcurr)
5768 if ( theListOfConcurr.empty() )
5770 theListOfConcurr.push_back( theDimHyp );
5774 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5775 while ( hypIt != theListOfConcurr.end() &&
5776 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5778 theListOfConcurr.insert( hypIt, theDimHyp );
5782 //-----------------------------------------------------------------------------
5783 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5784 const TDimHypList& theListOfDimHyp,
5785 TDimHypList& theListOfConcurrHyp,
5786 set<int>& theSetOfConcurrId )
5788 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5789 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5791 const SMESH_DimHyp* curDimHyp = *rIt;
5792 if ( curDimHyp == theDimHyp )
5793 break; // meet own dimHyp pointer in same dimension
5795 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5796 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5798 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5803 //-----------------------------------------------------------------------------
5804 void unionLists(TListOfInt& theListOfId,
5805 TListOfListOfInt& theListOfListOfId,
5808 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5809 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5811 continue; //skip already treated lists
5812 // check if other list has any same submesh object
5813 TListOfInt& otherListOfId = *it;
5814 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5815 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5818 // union two lists (from source into target)
5819 TListOfInt::iterator it2 = otherListOfId.begin();
5820 for ( ; it2 != otherListOfId.end(); it2++ ) {
5821 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5822 theListOfId.push_back(*it2);
5824 // clear source list
5825 otherListOfId.clear();
5828 //-----------------------------------------------------------------------------
5830 //! free memory allocated for dimension-hypothesis objects
5831 void removeDimHyps( TDimHypList* theArrOfList )
5833 for (int i = 0; i < 4; i++ ) {
5834 TDimHypList& listOfdimHyp = theArrOfList[i];
5835 TDimHypList::const_iterator it = listOfdimHyp.begin();
5836 for ( ; it != listOfdimHyp.end(); it++ )
5841 //-----------------------------------------------------------------------------
5843 * \brief find common submeshes with given submesh
5844 * \param theSubMeshList list of already collected submesh to check
5845 * \param theSubMesh given submesh to intersect with other
5846 * \param theCommonSubMeshes collected common submeshes
5848 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5849 const SMESH_subMesh* theSubMesh,
5850 set<const SMESH_subMesh*>& theCommon )
5854 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5855 for ( ; it != theSubMeshList.end(); it++ )
5856 theSubMesh->FindIntersection( *it, theCommon );
5857 theSubMeshList.push_back( theSubMesh );
5858 //theCommon.insert( theSubMesh );
5861 //-----------------------------------------------------------------------------
5862 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5864 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5865 for ( ; listsIt != smLists.end(); ++listsIt )
5867 const TListOfInt& smIDs = *listsIt;
5868 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5876 //=============================================================================
5878 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5880 //=============================================================================
5882 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5884 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5885 if ( isSubMeshInList( submeshID, anOrder ))
5888 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5889 return isSubMeshInList( submeshID, allConurrent );
5892 //=============================================================================
5894 * \brief Return submesh objects list in meshing order
5896 //=============================================================================
5898 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5900 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5902 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5904 return aResult._retn();
5906 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5907 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5908 anOrder.splice( anOrder.end(), allConurrent );
5911 TListOfListOfInt::iterator listIt = anOrder.begin();
5912 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5913 unionLists( *listIt, anOrder, listIndx + 1 );
5915 // convert submesh ids into interface instances
5916 // and dump command into python
5917 convertMeshOrder( anOrder, aResult, false );
5919 return aResult._retn();
5922 //=============================================================================
5924 * \brief Finds concurrent sub-meshes
5926 //=============================================================================
5928 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5930 TListOfListOfInt anOrder;
5931 ::SMESH_Mesh& mesh = GetImpl();
5933 // collect submeshes and detect concurrent algorithms and hypothesises
5934 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5936 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5937 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5938 ::SMESH_subMesh* sm = (*i_sm).second;
5940 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5942 // list of assigned hypothesises
5943 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5944 // Find out dimensions where the submesh can be concurrent.
5945 // We define the dimensions by algo of each of hypotheses in hypList
5946 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5947 for( ; hypIt != hypList.end(); hypIt++ ) {
5948 SMESH_Algo* anAlgo = 0;
5949 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5950 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5951 // hyp it-self is algo
5952 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5954 // try to find algorithm with help of sub-shapes
5955 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5956 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5957 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5960 continue; // no algorithm assigned to a current submesh
5962 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5963 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5965 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5966 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5967 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5969 } // end iterations on submesh
5971 // iterate on created dimension-hypotheses and check for concurrents
5972 for ( int i = 0; i < 4; i++ ) {
5973 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5974 // check for concurrents in own and other dimensions (step-by-step)
5975 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5976 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5977 const SMESH_DimHyp* dimHyp = *dhIt;
5978 TDimHypList listOfConcurr;
5979 set<int> setOfConcurrIds;
5980 // looking for concurrents and collect into own list
5981 for ( int j = i; j < 4; j++ )
5982 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5983 // check if any concurrents found
5984 if ( listOfConcurr.size() > 0 ) {
5985 // add own submesh to list of concurrent
5986 addInOrderOfPriority( dimHyp, listOfConcurr );
5987 list<int> listOfConcurrIds;
5988 TDimHypList::iterator hypIt = listOfConcurr.begin();
5989 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5990 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5991 anOrder.push_back( listOfConcurrIds );
5996 removeDimHyps(dimHypListArr);
5998 // now, minimize the number of concurrent groups
5999 // Here we assume that lists of submeshes can have same submesh
6000 // in case of multi-dimension algorithms, as result
6001 // list with common submesh has to be united into one list
6003 TListOfListOfInt::iterator listIt = anOrder.begin();
6004 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6005 unionLists( *listIt, anOrder, listIndx + 1 );
6011 //=============================================================================
6013 * \brief Set submesh object order
6014 * \param theSubMeshArray submesh array order
6016 //=============================================================================
6018 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6021 _preMeshInfo->ForgetOrLoad();
6024 ::SMESH_Mesh& mesh = GetImpl();
6026 TPythonDump aPythonDump; // prevent dump of called methods
6027 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6029 TListOfListOfInt subMeshOrder;
6030 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6032 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6033 TListOfInt subMeshIds;
6035 aPythonDump << ", ";
6036 aPythonDump << "[ ";
6037 // Collect subMeshes which should be clear
6038 // do it list-by-list, because modification of submesh order
6039 // take effect between concurrent submeshes only
6040 set<const SMESH_subMesh*> subMeshToClear;
6041 list<const SMESH_subMesh*> subMeshList;
6042 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6044 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6046 aPythonDump << ", ";
6047 aPythonDump << subMesh;
6048 subMeshIds.push_back( subMesh->GetId() );
6049 // detect common parts of submeshes
6050 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6051 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6053 aPythonDump << " ]";
6054 subMeshOrder.push_back( subMeshIds );
6056 // clear collected submeshes
6057 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6058 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6059 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6060 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6062 aPythonDump << " ])";
6064 mesh.SetMeshOrder( subMeshOrder );
6070 //=============================================================================
6072 * \brief Convert submesh ids into submesh interfaces
6074 //=============================================================================
6076 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6077 SMESH::submesh_array_array& theResOrder,
6078 const bool theIsDump)
6080 int nbSet = theIdsOrder.size();
6081 TPythonDump aPythonDump; // prevent dump of called methods
6083 aPythonDump << "[ ";
6084 theResOrder.length(nbSet);
6085 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6087 for( ; it != theIdsOrder.end(); it++ ) {
6088 // translate submesh identificators into submesh objects
6089 // takeing into account real number of concurrent lists
6090 const TListOfInt& aSubOrder = (*it);
6091 if (!aSubOrder.size())
6094 aPythonDump << "[ ";
6095 // convert shape indices into interfaces
6096 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6097 aResSubSet->length(aSubOrder.size());
6098 TListOfInt::const_iterator subIt = aSubOrder.begin();
6100 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6101 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6103 SMESH::SMESH_subMesh_var subMesh =
6104 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6107 aPythonDump << ", ";
6108 aPythonDump << subMesh;
6110 aResSubSet[ j++ ] = subMesh;
6113 aPythonDump << " ]";
6115 theResOrder[ listIndx++ ] = aResSubSet;
6117 // correct number of lists
6118 theResOrder.length( listIndx );
6121 // finilise python dump
6122 aPythonDump << " ]";
6123 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6127 namespace // utils used by SMESH_MeshPartDS
6130 * \brief Class used to access to protected data of SMDS_MeshInfo
6132 struct TMeshInfo : public SMDS_MeshInfo
6134 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6137 * \brief Element holing its ID only
6139 struct TElemID : public SMDS_LinearEdge
6141 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6145 //================================================================================
6147 // Implementation of SMESH_MeshPartDS
6149 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6150 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6152 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6153 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6156 _meshDS = mesh_i->GetImpl().GetMeshDS();
6158 SetPersistentId( _meshDS->GetPersistentId() );
6160 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6162 // <meshPart> is the whole mesh
6163 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6165 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6166 myGroupSet = _meshDS->GetGroups();
6171 SMESH::long_array_var anIDs = meshPart->GetIDs();
6172 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6173 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6175 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6176 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6177 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6182 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6183 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6184 if ( _elements[ e->GetType() ].insert( e ).second )
6187 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6188 while ( nIt->more() )
6190 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6191 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6198 ShapeToMesh( _meshDS->ShapeToMesh() );
6200 _meshDS = 0; // to enforce iteration on _elements and _nodes
6203 // -------------------------------------------------------------------------------------
6204 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6205 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6208 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6209 for ( ; partIt != meshPart.end(); ++partIt )
6210 if ( const SMDS_MeshElement * e = *partIt )
6211 if ( _elements[ e->GetType() ].insert( e ).second )
6214 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6215 while ( nIt->more() )
6217 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6218 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6224 // -------------------------------------------------------------------------------------
6225 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6227 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6229 TElemID elem( IDelem );
6230 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6231 if ( !_elements[ iType ].empty() )
6233 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6234 if ( it != _elements[ iType ].end() )
6239 // -------------------------------------------------------------------------------------
6240 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6242 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6244 typedef SMDS_SetIterator
6245 <const SMDS_MeshElement*,
6246 TIDSortedElemSet::const_iterator,
6247 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6248 SMDS_MeshElement::GeomFilter
6251 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6253 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6254 _elements[type].end(),
6255 SMDS_MeshElement::GeomFilter( geomType )));
6257 // -------------------------------------------------------------------------------------
6258 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6260 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6262 typedef SMDS_SetIterator
6263 <const SMDS_MeshElement*,
6264 TIDSortedElemSet::const_iterator,
6265 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6266 SMDS_MeshElement::EntityFilter
6269 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6271 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6272 _elements[type].end(),
6273 SMDS_MeshElement::EntityFilter( entity )));
6275 // -------------------------------------------------------------------------------------
6276 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6278 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6279 if ( type == SMDSAbs_All && !_meshDS )
6281 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6283 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6284 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6286 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6288 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6289 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6291 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6292 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6294 // -------------------------------------------------------------------------------------
6295 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6296 iterType SMESH_MeshPartDS::methName() const \
6298 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6299 return _meshDS ? _meshDS->methName() : iterType \
6300 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6302 // -------------------------------------------------------------------------------------
6303 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6304 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6305 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6306 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6307 #undef _GET_ITER_DEFINE
6309 // END Implementation of SMESH_MeshPartDS
6311 //================================================================================