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 : SALOME::GenericObj_i( thePOA )
114 _id = _idGenerator++;
116 _previewEditor = NULL;
121 //=============================================================================
125 //=============================================================================
127 SMESH_Mesh_i::~SMESH_Mesh_i()
130 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
131 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
132 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
134 aGroup->UnRegister();
135 SMESH::SMESH_GroupBase_var( itGr->second );
140 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
141 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
142 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
144 aSubMesh->UnRegister();
145 SMESH::SMESH_subMesh_var( itSM->second );
147 _mapSubMeshIor.clear();
149 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
150 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
151 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
152 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
153 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
154 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
157 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
161 // clear cached shapes if no more meshes remain; (the cache is blame,
162 // together with publishing, of spent time increasing in issue 22874)
163 if ( _impl->NbMeshes() == 1 )
164 _gen_i->GetShapeReader()->ClearClientBuffer();
166 delete _editor; _editor = NULL;
167 delete _previewEditor; _previewEditor = NULL;
168 delete _impl; _impl = NULL;
169 delete _preMeshInfo; _preMeshInfo = NULL;
172 //=============================================================================
176 * Associates <this> mesh with <theShape> and puts a reference
177 * to <theShape> into the current study;
178 * the previous shape is substituted by the new one.
180 //=============================================================================
182 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
183 throw (SALOME::SALOME_Exception)
185 Unexpect aCatch(SALOME_SalomeException);
187 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
189 catch(SALOME_Exception & S_ex) {
190 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
192 // to track changes of GEOM groups
193 SMESH::SMESH_Mesh_var mesh = _this();
194 addGeomGroupData( theShapeObject, mesh );
195 if ( !CORBA::is_nil( theShapeObject ))
196 _mainShapeTick = theShapeObject->GetTick();
199 //================================================================================
201 * \brief return true if mesh has a shape to build a shape on
203 //================================================================================
205 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
206 throw (SALOME::SALOME_Exception)
208 Unexpect aCatch(SALOME_SalomeException);
211 res = _impl->HasShapeToMesh();
213 catch(SALOME_Exception & S_ex) {
214 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
219 //=======================================================================
220 //function : GetShapeToMesh
222 //=======================================================================
224 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
225 throw (SALOME::SALOME_Exception)
227 Unexpect aCatch(SALOME_SalomeException);
228 GEOM::GEOM_Object_var aShapeObj;
230 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
233 aShapeObj = _gen_i->ShapeToGeomObject( S );
234 if ( aShapeObj->_is_nil() )
236 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
237 // find GEOM_Object by entry (IPAL52735)
238 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
239 for ( ; data != _geomGroupData.end(); ++data )
240 if ( data->_smeshObject->_is_equivalent( _this() ))
242 SALOMEDS::SObject_wrap so = SMESH_Gen_i::getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
243 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
244 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
250 catch(SALOME_Exception & S_ex) {
251 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
253 return aShapeObj._retn();
256 //================================================================================
258 * \brief Return false if the mesh is not yet fully loaded from the study file
260 //================================================================================
262 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
264 Unexpect aCatch(SALOME_SalomeException);
265 return !_preMeshInfo;
268 //================================================================================
270 * \brief Load full mesh data from the study file
272 //================================================================================
274 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
276 Unexpect aCatch(SALOME_SalomeException);
278 _preMeshInfo->FullLoadFromFile();
281 //================================================================================
283 * \brief Remove all nodes and elements
285 //================================================================================
287 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
289 Unexpect aCatch(SALOME_SalomeException);
291 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
295 //CheckGeomGroupModif(); // issue 20145
297 catch(SALOME_Exception & S_ex) {
298 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
301 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
303 SMESH::SMESH_Mesh_var mesh = _this();
304 _gen_i->UpdateIcons( mesh );
307 //================================================================================
309 * \brief Remove all nodes and elements for indicated shape
311 //================================================================================
313 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
314 throw (SALOME::SALOME_Exception)
316 Unexpect aCatch(SALOME_SalomeException);
318 _preMeshInfo->FullLoadFromFile();
321 _impl->ClearSubMesh( ShapeID );
323 catch(SALOME_Exception & S_ex) {
324 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
326 _impl->GetMeshDS()->Modified();
328 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
331 //=============================================================================
333 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
335 //=============================================================================
337 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
339 SMESH::DriverMED_ReadStatus res;
342 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
343 res = SMESH::DRS_OK; break;
344 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
345 res = SMESH::DRS_EMPTY; break;
346 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
347 res = SMESH::DRS_WARN_RENUMBER; break;
348 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
349 res = SMESH::DRS_WARN_SKIP_ELEM; break;
350 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
351 res = SMESH::DRS_WARN_DESCENDING; break;
352 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
354 res = SMESH::DRS_FAIL; break;
359 //=============================================================================
361 * Convert ::SMESH_ComputeError to SMESH::ComputeError
363 //=============================================================================
365 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
367 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
368 errVar->subShapeID = -1;
369 errVar->hasBadMesh = false;
371 if ( !errorPtr || errorPtr->IsOK() )
373 errVar->code = SMESH::COMPERR_OK;
377 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
378 errVar->comment = errorPtr->myComment.c_str();
380 return errVar._retn();
383 //=============================================================================
387 * Imports mesh data from MED file
389 //=============================================================================
391 SMESH::DriverMED_ReadStatus
392 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
393 throw ( SALOME::SALOME_Exception )
395 Unexpect aCatch(SALOME_SalomeException);
398 status = _impl->MEDToMesh( theFileName, theMeshName );
400 catch( SALOME_Exception& S_ex ) {
401 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
404 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
407 CreateGroupServants();
409 int major, minor, release;
410 major = minor = release = 0;
411 MED::GetMEDVersion(theFileName, major, minor, release);
412 _medFileInfo = new SMESH::MedFileInfo();
413 _medFileInfo->fileName = theFileName;
414 _medFileInfo->fileSize = 0;
415 _medFileInfo->major = major;
416 _medFileInfo->minor = minor;
417 _medFileInfo->release = release;
418 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
420 return ConvertDriverMEDReadStatus(status);
423 //================================================================================
425 * \brief Imports mesh data from the CGNS file
427 //================================================================================
429 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
430 const int theMeshIndex,
431 std::string& theMeshName )
432 throw ( SALOME::SALOME_Exception )
434 Unexpect aCatch(SALOME_SalomeException);
437 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
439 catch( SALOME_Exception& S_ex ) {
440 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
443 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
446 CreateGroupServants();
448 _medFileInfo = new SMESH::MedFileInfo();
449 _medFileInfo->fileName = theFileName;
450 _medFileInfo->major = 0;
451 _medFileInfo->minor = 0;
452 _medFileInfo->release = 0;
453 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
455 return ConvertDriverMEDReadStatus(status);
458 //================================================================================
460 * \brief Return string representation of a MED file version comprising nbDigits
462 //================================================================================
464 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
466 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
468 return CORBA::string_dup( ver.c_str() );
471 //================================================================================
473 * Return the list of med versions compatibles for write/append,
474 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
476 //================================================================================
477 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
479 SMESH::long_array_var aResult = new SMESH::long_array();
480 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
481 long nbver = mvok.size();
482 aResult->length( nbver );
483 for ( int i = 0; i < nbver; i++ )
484 aResult[i] = mvok[i];
485 return aResult._retn();
488 //=============================================================================
492 * Imports mesh data from MED file
494 //=============================================================================
496 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
497 throw ( SALOME::SALOME_Exception )
501 // Read mesh with name = <theMeshName> into SMESH_Mesh
502 _impl->UNVToMesh( theFileName );
504 CreateGroupServants();
506 _medFileInfo = new SMESH::MedFileInfo();
507 _medFileInfo->fileName = theFileName;
508 _medFileInfo->major = 0;
509 _medFileInfo->minor = 0;
510 _medFileInfo->release = 0;
511 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
513 SMESH_CATCH( SMESH::throwCorbaException );
518 //=============================================================================
522 * Imports mesh data from STL file
524 //=============================================================================
525 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
526 throw ( SALOME::SALOME_Exception )
530 // Read mesh with name = <theMeshName> into SMESH_Mesh
531 std::string name = _impl->STLToMesh( theFileName );
534 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
535 _gen_i->SetName( meshSO, name.c_str() );
537 _medFileInfo = new SMESH::MedFileInfo();
538 _medFileInfo->fileName = theFileName;
539 _medFileInfo->major = 0;
540 _medFileInfo->minor = 0;
541 _medFileInfo->release = 0;
542 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
544 SMESH_CATCH( SMESH::throwCorbaException );
549 //================================================================================
551 * \brief Function used in SMESH_CATCH by ImportGMFFile()
553 //================================================================================
557 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
559 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
563 //================================================================================
565 * \brief Imports data from a GMF file and returns an error description
567 //================================================================================
569 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
570 bool theMakeRequiredGroups )
571 throw (SALOME::SALOME_Exception)
573 SMESH_ComputeErrorPtr error;
576 #define SMESH_CAUGHT error =
579 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
581 _medFileInfo = new SMESH::MedFileInfo();
582 _medFileInfo->fileName = theFileName;
583 _medFileInfo->major = 0;
584 _medFileInfo->minor = 0;
585 _medFileInfo->release = 0;
586 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
588 SMESH_CATCH( exceptionToComputeError );
592 CreateGroupServants();
594 return ConvertComputeError( error );
597 //=============================================================================
601 //=============================================================================
603 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
605 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
606 (SMESH_Hypothesis::Hypothesis_Status theStatus)
609 RETURNCASE( HYP_OK );
610 RETURNCASE( HYP_MISSING );
611 RETURNCASE( HYP_CONCURRENT );
612 RETURNCASE( HYP_BAD_PARAMETER );
613 RETURNCASE( HYP_HIDDEN_ALGO );
614 RETURNCASE( HYP_HIDING_ALGO );
615 RETURNCASE( HYP_UNKNOWN_FATAL );
616 RETURNCASE( HYP_INCOMPATIBLE );
617 RETURNCASE( HYP_NOTCONFORM );
618 RETURNCASE( HYP_ALREADY_EXIST );
619 RETURNCASE( HYP_BAD_DIM );
620 RETURNCASE( HYP_BAD_SUBSHAPE );
621 RETURNCASE( HYP_BAD_GEOMETRY );
622 RETURNCASE( HYP_NEED_SHAPE );
623 RETURNCASE( HYP_INCOMPAT_HYPS );
626 return SMESH::HYP_UNKNOWN_FATAL;
629 //=============================================================================
633 * calls internal addHypothesis() and then adds a reference to <anHyp> under
634 * the SObject actually having a reference to <aSubShape>.
635 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
637 //=============================================================================
639 SMESH::Hypothesis_Status
640 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
641 SMESH::SMESH_Hypothesis_ptr anHyp,
642 CORBA::String_out anErrorText)
643 throw(SALOME::SALOME_Exception)
645 Unexpect aCatch(SALOME_SalomeException);
647 _preMeshInfo->ForgetOrLoad();
650 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
651 anErrorText = error.c_str();
653 SMESH::SMESH_Mesh_var mesh( _this() );
654 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
656 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
657 _gen_i->UpdateIcons( mesh );
659 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
661 // Update Python script
662 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
663 << aSubShape << ", " << anHyp << " )";
665 return ConvertHypothesisStatus(status);
668 //=============================================================================
672 //=============================================================================
674 SMESH_Hypothesis::Hypothesis_Status
675 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
676 SMESH::SMESH_Hypothesis_ptr anHyp,
677 std::string* anErrorText)
679 if(MYDEBUG) MESSAGE("addHypothesis");
681 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
682 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
684 if (CORBA::is_nil( anHyp ))
685 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
687 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
690 TopoDS_Shape myLocSubShape;
691 //use PseudoShape in case if mesh has no shape
693 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
695 myLocSubShape = _impl->GetShapeToMesh();
697 const int hypId = anHyp->GetId();
699 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
700 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
702 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
704 // assure there is a corresponding submesh
705 if ( !_impl->IsMainShape( myLocSubShape )) {
706 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
707 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
708 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
711 else if ( anErrorText )
713 *anErrorText = error;
716 catch(SALOME_Exception & S_ex)
718 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
723 //=============================================================================
727 //=============================================================================
729 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
730 SMESH::SMESH_Hypothesis_ptr anHyp)
731 throw(SALOME::SALOME_Exception)
733 Unexpect aCatch(SALOME_SalomeException);
735 _preMeshInfo->ForgetOrLoad();
737 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
738 SMESH::SMESH_Mesh_var mesh = _this();
740 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
742 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
743 _gen_i->UpdateIcons( mesh );
745 // Update Python script
746 if(_impl->HasShapeToMesh())
747 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
748 << aSubShape << ", " << anHyp << " )";
750 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
753 return ConvertHypothesisStatus(status);
756 //=============================================================================
760 //=============================================================================
762 SMESH_Hypothesis::Hypothesis_Status
763 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
764 SMESH::SMESH_Hypothesis_ptr anHyp)
766 if(MYDEBUG) MESSAGE("removeHypothesis()");
768 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
769 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
771 if (CORBA::is_nil( anHyp ))
772 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
774 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
777 TopoDS_Shape myLocSubShape;
778 //use PseudoShape in case if mesh has no shape
779 if( _impl->HasShapeToMesh() )
780 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
782 myLocSubShape = _impl->GetShapeToMesh();
784 const int hypId = anHyp->GetId();
785 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
786 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
788 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
792 catch(SALOME_Exception & S_ex)
794 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
799 //=============================================================================
803 //=============================================================================
805 SMESH::ListOfHypothesis *
806 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
807 throw(SALOME::SALOME_Exception)
809 Unexpect aCatch(SALOME_SalomeException);
810 if (MYDEBUG) MESSAGE("GetHypothesisList");
811 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
812 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
814 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
817 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
818 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
819 myLocSubShape = _impl->GetShapeToMesh();
820 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
821 int i = 0, n = aLocalList.size();
824 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
825 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
826 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
828 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
829 if ( id_hypptr != _mapHypo.end() )
830 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
834 catch(SALOME_Exception & S_ex) {
835 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
838 return aList._retn();
841 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
843 Unexpect aCatch(SALOME_SalomeException);
844 if (MYDEBUG) MESSAGE("GetSubMeshes");
846 SMESH::submesh_array_var aList = new SMESH::submesh_array();
849 TPythonDump aPythonDump;
850 if ( !_mapSubMeshIor.empty() )
854 aList->length( _mapSubMeshIor.size() );
856 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
857 for ( ; it != _mapSubMeshIor.end(); it++ ) {
858 if ( CORBA::is_nil( it->second )) continue;
859 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
861 if (i > 1) aPythonDump << ", ";
862 aPythonDump << it->second;
866 catch(SALOME_Exception & S_ex) {
867 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
870 // Update Python script
871 if ( !_mapSubMeshIor.empty() )
872 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
874 return aList._retn();
877 //=============================================================================
881 //=============================================================================
883 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
884 const char* theName )
885 throw(SALOME::SALOME_Exception)
887 Unexpect aCatch(SALOME_SalomeException);
888 if (CORBA::is_nil(aSubShape))
889 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
891 SMESH::SMESH_subMesh_var subMesh;
892 SMESH::SMESH_Mesh_var aMesh = _this();
894 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
896 //Get or Create the SMESH_subMesh object implementation
898 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
900 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
902 TopoDS_Iterator it( myLocSubShape );
904 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
906 subMesh = getSubMesh( subMeshId );
908 // create a new subMesh object servant if there is none for the shape
909 if ( subMesh->_is_nil() )
910 subMesh = createSubMesh( aSubShape );
911 if ( _gen_i->CanPublishInStudy( subMesh ))
913 SALOMEDS::SObject_wrap aSO =
914 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
915 if ( !aSO->_is_nil()) {
916 // Update Python script
917 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
918 << aSubShape << ", '" << theName << "' )";
922 catch(SALOME_Exception & S_ex) {
923 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
925 return subMesh._retn();
928 //=============================================================================
932 //=============================================================================
934 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
935 throw (SALOME::SALOME_Exception)
939 if ( theSubMesh->_is_nil() )
942 GEOM::GEOM_Object_var aSubShape;
943 // Remove submesh's SObject
944 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
945 if ( !anSO->_is_nil() ) {
946 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
947 SALOMEDS::SObject_wrap anObj, aRef;
948 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
949 anObj->ReferencedObject( aRef.inout() ))
951 CORBA::Object_var obj = aRef->GetObject();
952 aSubShape = GEOM::GEOM_Object::_narrow( obj );
954 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
955 // aSubShape = theSubMesh->GetSubShape();
957 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
958 builder->RemoveObjectWithChildren( anSO );
960 // Update Python script
961 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
964 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
966 _preMeshInfo->ForgetOrLoad();
968 SMESH_CATCH( SMESH::throwCorbaException );
971 //=============================================================================
975 //=============================================================================
977 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
978 const char* theName )
979 throw(SALOME::SALOME_Exception)
981 Unexpect aCatch(SALOME_SalomeException);
983 _preMeshInfo->FullLoadFromFile();
985 SMESH::SMESH_Group_var aNewGroup =
986 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
988 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
990 SMESH::SMESH_Mesh_var mesh = _this();
991 SALOMEDS::SObject_wrap aSO =
992 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
993 if ( !aSO->_is_nil())
994 // Update Python script
995 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
996 << theElemType << ", '" << theName << "' )";
998 return aNewGroup._retn();
1001 //=============================================================================
1005 //=============================================================================
1006 SMESH::SMESH_GroupOnGeom_ptr
1007 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1008 const char* theName,
1009 GEOM::GEOM_Object_ptr theGeomObj)
1010 throw(SALOME::SALOME_Exception)
1012 Unexpect aCatch(SALOME_SalomeException);
1014 _preMeshInfo->FullLoadFromFile();
1016 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1018 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1019 if ( !aShape.IsNull() )
1022 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
1024 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1026 SMESH::SMESH_Mesh_var mesh = _this();
1027 SALOMEDS::SObject_wrap aSO =
1028 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1029 if ( !aSO->_is_nil())
1030 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1031 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1035 return aNewGroup._retn();
1038 //================================================================================
1040 * \brief Creates a group whose contents is defined by filter
1041 * \param theElemType - group type
1042 * \param theName - group name
1043 * \param theFilter - the filter
1044 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1046 //================================================================================
1048 SMESH::SMESH_GroupOnFilter_ptr
1049 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1050 const char* theName,
1051 SMESH::Filter_ptr theFilter )
1052 throw (SALOME::SALOME_Exception)
1054 Unexpect aCatch(SALOME_SalomeException);
1056 _preMeshInfo->FullLoadFromFile();
1058 if ( CORBA::is_nil( theFilter ))
1059 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1061 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1063 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1065 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1066 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1069 if ( !aNewGroup->_is_nil() )
1070 aNewGroup->SetFilter( theFilter );
1072 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1074 SMESH::SMESH_Mesh_var mesh = _this();
1075 SALOMEDS::SObject_wrap aSO =
1076 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1078 if ( !aSO->_is_nil())
1079 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1080 << theElemType << ", '" << theName << "', " << theFilter << " )";
1082 return aNewGroup._retn();
1085 //=============================================================================
1089 //=============================================================================
1091 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1092 throw (SALOME::SALOME_Exception)
1094 if ( theGroup->_is_nil() )
1099 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1103 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1104 if ( !aGroupSO->_is_nil() )
1106 // Update Python script
1107 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1109 // Remove group's SObject
1110 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1111 builder->RemoveObjectWithChildren( aGroupSO );
1113 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1115 // Remove the group from SMESH data structures
1116 removeGroup( aGroup->GetLocalID() );
1118 SMESH_CATCH( SMESH::throwCorbaException );
1121 //=============================================================================
1123 * Remove group with its contents
1125 //=============================================================================
1127 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1128 throw (SALOME::SALOME_Exception)
1132 _preMeshInfo->FullLoadFromFile();
1134 if ( theGroup->_is_nil() )
1137 vector<int> nodeIds; // to remove nodes becoming free
1138 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1139 if ( !isNodal && !theGroup->IsEmpty() )
1141 CORBA::Long elemID = theGroup->GetID( 1 );
1142 int nbElemNodes = GetElemNbNodes( elemID );
1143 if ( nbElemNodes > 0 )
1144 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1147 // Retrieve contents
1148 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1149 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1150 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1151 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1152 elems.assign( elemBeg, elemEnd );
1154 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1157 RemoveGroup( theGroup );
1160 for ( size_t i = 0; i < elems.size(); ++i )
1162 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1166 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1167 nodeIds.push_back( nIt->next()->GetID() );
1169 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1173 _impl->GetMeshDS()->RemoveElement( elems[i] );
1177 // Remove free nodes
1178 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1179 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1180 if ( n->NbInverseElements() == 0 )
1181 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1183 // Update Python script (theGroup must be alive for this)
1184 pyDump << SMESH::SMESH_Mesh_var(_this())
1185 << ".RemoveGroupWithContents( " << theGroup << " )";
1187 SMESH_CATCH( SMESH::throwCorbaException );
1190 //================================================================================
1192 * \brief Get the list of groups existing in the mesh
1193 * \retval SMESH::ListOfGroups * - list of groups
1195 //================================================================================
1197 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1199 Unexpect aCatch(SALOME_SalomeException);
1200 if (MYDEBUG) MESSAGE("GetGroups");
1202 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1205 TPythonDump aPythonDump;
1206 if ( !_mapGroups.empty() )
1208 aPythonDump << "[ ";
1210 aList->length( _mapGroups.size() );
1212 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1213 for ( ; it != _mapGroups.end(); it++ ) {
1214 if ( CORBA::is_nil( it->second )) continue;
1215 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1217 if (i > 1) aPythonDump << ", ";
1218 aPythonDump << it->second;
1222 catch(SALOME_Exception & S_ex) {
1223 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1225 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1227 return aList._retn();
1230 //=============================================================================
1232 * Get number of groups existing in the mesh
1234 //=============================================================================
1236 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1238 Unexpect aCatch(SALOME_SalomeException);
1239 return _mapGroups.size();
1242 //=============================================================================
1244 * New group including all mesh elements present in initial groups is created.
1246 //=============================================================================
1248 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1249 SMESH::SMESH_GroupBase_ptr theGroup2,
1250 const char* theName )
1251 throw (SALOME::SALOME_Exception)
1253 SMESH::SMESH_Group_var aResGrp;
1257 _preMeshInfo->FullLoadFromFile();
1259 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1260 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1262 if ( theGroup1->GetType() != theGroup2->GetType() )
1263 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1268 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1269 if ( aResGrp->_is_nil() )
1270 return SMESH::SMESH_Group::_nil();
1272 aResGrp->AddFrom( theGroup1 );
1273 aResGrp->AddFrom( theGroup2 );
1275 // Update Python script
1276 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1277 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1279 SMESH_CATCH( SMESH::throwCorbaException );
1281 return aResGrp._retn();
1284 //=============================================================================
1286 * \brief New group including all mesh elements present in initial groups is created.
1287 * \param theGroups list of groups
1288 * \param theName name of group to be created
1289 * \return pointer to the new group
1291 //=============================================================================
1293 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1294 const char* theName )
1295 throw (SALOME::SALOME_Exception)
1297 SMESH::SMESH_Group_var aResGrp;
1300 _preMeshInfo->FullLoadFromFile();
1303 return SMESH::SMESH_Group::_nil();
1308 SMESH::ElementType aType = SMESH::ALL;
1309 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1311 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1312 if ( CORBA::is_nil( aGrp ) )
1314 if ( aType == SMESH::ALL )
1315 aType = aGrp->GetType();
1316 else if ( aType != aGrp->GetType() )
1317 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1320 if ( aType == SMESH::ALL )
1321 return SMESH::SMESH_Group::_nil();
1326 aResGrp = CreateGroup( aType, theName );
1327 if ( aResGrp->_is_nil() )
1328 return SMESH::SMESH_Group::_nil();
1330 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1331 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1333 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1334 if ( !CORBA::is_nil( aGrp ) )
1336 aResGrp->AddFrom( aGrp );
1337 if ( g > 0 ) pyDump << ", ";
1341 pyDump << " ], '" << theName << "' )";
1343 SMESH_CATCH( SMESH::throwCorbaException );
1345 return aResGrp._retn();
1348 //=============================================================================
1350 * New group is created. All mesh elements that are
1351 * present in both initial groups are added to the new one.
1353 //=============================================================================
1355 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1356 SMESH::SMESH_GroupBase_ptr theGroup2,
1357 const char* theName )
1358 throw (SALOME::SALOME_Exception)
1360 SMESH::SMESH_Group_var aResGrp;
1365 _preMeshInfo->FullLoadFromFile();
1367 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1368 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1370 if ( theGroup1->GetType() != theGroup2->GetType() )
1371 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1375 // Create Intersection
1376 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1377 if ( aResGrp->_is_nil() )
1378 return aResGrp._retn();
1380 SMESHDS_GroupBase* groupDS1 = 0;
1381 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1382 groupDS1 = grp_i->GetGroupDS();
1384 SMESHDS_GroupBase* groupDS2 = 0;
1385 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1386 groupDS2 = grp_i->GetGroupDS();
1388 SMESHDS_Group* resGroupDS = 0;
1389 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1390 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1392 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1394 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1395 while ( elemIt1->more() )
1397 const SMDS_MeshElement* e = elemIt1->next();
1398 if ( groupDS2->Contains( e ))
1399 resGroupDS->SMDSGroup().Add( e );
1402 // Update Python script
1403 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1404 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1406 SMESH_CATCH( SMESH::throwCorbaException );
1408 return aResGrp._retn();
1411 //=============================================================================
1413 \brief Intersect list of groups. New group is created. All mesh elements that
1414 are present in all initial groups simultaneously are added to the new one.
1415 \param theGroups list of groups
1416 \param theName name of group to be created
1417 \return pointer on the group
1419 //=============================================================================
1420 SMESH::SMESH_Group_ptr
1421 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1422 const char* theName )
1423 throw (SALOME::SALOME_Exception)
1425 SMESH::SMESH_Group_var aResGrp;
1430 _preMeshInfo->FullLoadFromFile();
1433 return SMESH::SMESH_Group::_nil();
1435 // check types and get SMESHDS_GroupBase's
1436 SMESH::ElementType aType = SMESH::ALL;
1437 vector< SMESHDS_GroupBase* > groupVec;
1438 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1440 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1441 if ( CORBA::is_nil( aGrp ) )
1443 if ( aType == SMESH::ALL )
1444 aType = aGrp->GetType();
1445 else if ( aType != aGrp->GetType() )
1446 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1449 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1450 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1452 if ( grpDS->IsEmpty() )
1457 groupVec.push_back( grpDS );
1460 if ( aType == SMESH::ALL ) // all groups are nil
1461 return SMESH::SMESH_Group::_nil();
1466 aResGrp = CreateGroup( aType, theName );
1468 SMESHDS_Group* resGroupDS = 0;
1469 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1470 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1471 if ( !resGroupDS || groupVec.empty() )
1472 return aResGrp._retn();
1475 size_t i, nb = groupVec.size();
1476 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1477 while ( elemIt1->more() )
1479 const SMDS_MeshElement* e = elemIt1->next();
1481 for ( i = 1; ( i < nb && inAll ); ++i )
1482 inAll = groupVec[i]->Contains( e );
1485 resGroupDS->SMDSGroup().Add( e );
1488 // Update Python script
1489 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1490 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1492 SMESH_CATCH( SMESH::throwCorbaException );
1494 return aResGrp._retn();
1497 //=============================================================================
1499 * New group is created. All mesh elements that are present in
1500 * a main group but is not present in a tool group are added to the new one
1502 //=============================================================================
1504 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1505 SMESH::SMESH_GroupBase_ptr theGroup2,
1506 const char* theName )
1507 throw (SALOME::SALOME_Exception)
1509 SMESH::SMESH_Group_var aResGrp;
1514 _preMeshInfo->FullLoadFromFile();
1516 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1517 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1519 if ( theGroup1->GetType() != theGroup2->GetType() )
1520 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1524 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1525 if ( aResGrp->_is_nil() )
1526 return aResGrp._retn();
1528 SMESHDS_GroupBase* groupDS1 = 0;
1529 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1530 groupDS1 = grp_i->GetGroupDS();
1532 SMESHDS_GroupBase* groupDS2 = 0;
1533 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1534 groupDS2 = grp_i->GetGroupDS();
1536 SMESHDS_Group* resGroupDS = 0;
1537 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1538 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1540 if ( groupDS1 && groupDS2 && resGroupDS )
1542 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1543 while ( elemIt1->more() )
1545 const SMDS_MeshElement* e = elemIt1->next();
1546 if ( !groupDS2->Contains( e ))
1547 resGroupDS->SMDSGroup().Add( e );
1550 // Update Python script
1551 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1552 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1554 SMESH_CATCH( SMESH::throwCorbaException );
1556 return aResGrp._retn();
1559 //=============================================================================
1561 \brief Cut lists of groups. New group is created. All mesh elements that are
1562 present in main groups but do not present in tool groups are added to the new one
1563 \param theMainGroups list of main groups
1564 \param theToolGroups list of tool groups
1565 \param theName name of group to be created
1566 \return pointer on the group
1568 //=============================================================================
1569 SMESH::SMESH_Group_ptr
1570 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1571 const SMESH::ListOfGroups& theToolGroups,
1572 const char* theName )
1573 throw (SALOME::SALOME_Exception)
1575 SMESH::SMESH_Group_var aResGrp;
1580 _preMeshInfo->FullLoadFromFile();
1583 return SMESH::SMESH_Group::_nil();
1585 // check types and get SMESHDS_GroupBase's
1586 SMESH::ElementType aType = SMESH::ALL;
1587 vector< SMESHDS_GroupBase* > toolGroupVec;
1588 vector< SMDS_ElemIteratorPtr > mainIterVec;
1590 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1592 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1593 if ( CORBA::is_nil( aGrp ) )
1595 if ( aType == SMESH::ALL )
1596 aType = aGrp->GetType();
1597 else if ( aType != aGrp->GetType() )
1598 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1600 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1601 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1602 if ( !grpDS->IsEmpty() )
1603 mainIterVec.push_back( grpDS->GetElements() );
1605 if ( aType == SMESH::ALL ) // all main groups are nil
1606 return SMESH::SMESH_Group::_nil();
1607 if ( mainIterVec.empty() ) // all main groups are empty
1608 return aResGrp._retn();
1610 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1612 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1613 if ( CORBA::is_nil( aGrp ) )
1615 if ( aType != aGrp->GetType() )
1616 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1618 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1619 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1620 toolGroupVec.push_back( grpDS );
1626 aResGrp = CreateGroup( aType, theName );
1628 SMESHDS_Group* resGroupDS = 0;
1629 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1630 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1632 return aResGrp._retn();
1635 size_t i, nb = toolGroupVec.size();
1636 SMDS_ElemIteratorPtr mainElemIt
1637 ( new SMDS_IteratorOnIterators
1638 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1639 while ( mainElemIt->more() )
1641 const SMDS_MeshElement* e = mainElemIt->next();
1643 for ( i = 0; ( i < nb && !isIn ); ++i )
1644 isIn = toolGroupVec[i]->Contains( e );
1647 resGroupDS->SMDSGroup().Add( e );
1650 // Update Python script
1651 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1652 << ".CutListOfGroups( " << theMainGroups << ", "
1653 << theToolGroups << ", '" << theName << "' )";
1655 SMESH_CATCH( SMESH::throwCorbaException );
1657 return aResGrp._retn();
1660 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1662 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1663 bool & toStopChecking )
1665 toStopChecking = ( nbCommon < nbChecked );
1666 return nbCommon == nbNodes;
1668 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1669 bool & toStopChecking )
1671 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1672 return nbCommon == nbCorners;
1674 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1675 bool & toStopChecking )
1677 return nbCommon > 0;
1679 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1680 bool & toStopChecking )
1682 return nbCommon >= (nbNodes+1) / 2;
1686 //=============================================================================
1688 * Create a group of entities basing on nodes of other groups.
1689 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1690 * \param [in] anElemType - a type of elements to include to the new group.
1691 * \param [in] theName - a name of the new group.
1692 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1693 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1694 * new group provided that it is based on nodes of an element of \a aListOfGroups
1695 * \return SMESH_Group - the created group
1697 // IMP 19939, bug 22010, IMP 22635
1698 //=============================================================================
1700 SMESH::SMESH_Group_ptr
1701 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1702 SMESH::ElementType theElemType,
1703 const char* theName,
1704 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1705 CORBA::Boolean theUnderlyingOnly)
1706 throw (SALOME::SALOME_Exception)
1708 SMESH::SMESH_Group_var aResGrp;
1712 _preMeshInfo->FullLoadFromFile();
1714 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1716 if ( !theName || !aMeshDS )
1717 return SMESH::SMESH_Group::_nil();
1719 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1721 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1722 SMESH_Comment nbCoNoStr( "SMESH.");
1723 switch ( theNbCommonNodes ) {
1724 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1725 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1726 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1727 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1728 default: return aResGrp._retn();
1730 int nbChecked, nbCommon, nbNodes, nbCorners;
1736 aResGrp = CreateGroup( theElemType, theName );
1737 if ( aResGrp->_is_nil() )
1738 return SMESH::SMESH_Group::_nil();
1740 SMESHDS_GroupBase* groupBaseDS =
1741 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1742 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1744 vector<bool> isNodeInGroups;
1746 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1748 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1749 if ( CORBA::is_nil( aGrp ) )
1751 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1752 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1755 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1756 if ( !elIt ) continue;
1758 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1760 while ( elIt->more() ) {
1761 const SMDS_MeshElement* el = elIt->next();
1762 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1763 while ( nIt->more() )
1764 resGroupCore.Add( nIt->next() );
1767 // get elements of theElemType based on nodes of every element of group
1768 else if ( theUnderlyingOnly )
1770 while ( elIt->more() )
1772 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1773 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1774 TIDSortedElemSet checkedElems;
1775 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1776 while ( nIt->more() )
1778 const SMDS_MeshNode* n = nIt->next();
1779 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1780 // check nodes of elements of theElemType around el
1781 while ( elOfTypeIt->more() )
1783 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1784 if ( !checkedElems.insert( elOfType ).second ) continue;
1785 nbNodes = elOfType->NbNodes();
1786 nbCorners = elOfType->NbCornerNodes();
1788 bool toStopChecking = false;
1789 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1790 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1791 if ( elNodes.count( nIt2->next() ) &&
1792 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1794 resGroupCore.Add( elOfType );
1801 // get all nodes of elements of groups
1804 while ( elIt->more() )
1806 const SMDS_MeshElement* el = elIt->next(); // an element of group
1807 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1808 while ( nIt->more() )
1810 const SMDS_MeshNode* n = nIt->next();
1811 if ( n->GetID() >= (int) isNodeInGroups.size() )
1812 isNodeInGroups.resize( n->GetID() + 1, false );
1813 isNodeInGroups[ n->GetID() ] = true;
1819 // Get elements of theElemType based on a certain number of nodes of elements of groups
1820 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1822 const SMDS_MeshNode* n;
1823 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1824 const int isNodeInGroupsSize = isNodeInGroups.size();
1825 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1827 if ( !isNodeInGroups[ iN ] ||
1828 !( n = aMeshDS->FindNode( iN )))
1831 // check nodes of elements of theElemType around n
1832 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1833 while ( elOfTypeIt->more() )
1835 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1836 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1841 nbNodes = elOfType->NbNodes();
1842 nbCorners = elOfType->NbCornerNodes();
1844 bool toStopChecking = false;
1845 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1846 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1848 const int nID = nIt->next()->GetID();
1849 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1850 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1852 resGroupCore.Add( elOfType );
1860 // Update Python script
1861 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1862 << ".CreateDimGroup( "
1863 << theGroups << ", " << theElemType << ", '" << theName << "', "
1864 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1866 SMESH_CATCH( SMESH::throwCorbaException );
1868 return aResGrp._retn();
1871 //================================================================================
1873 * \brief Remember GEOM group data
1875 //================================================================================
1877 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1878 CORBA::Object_ptr theSmeshObj)
1880 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1883 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1884 if ( groupSO->_is_nil() )
1887 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1888 GEOM::GEOM_IGroupOperations_wrap groupOp =
1889 geomGen->GetIGroupOperations();
1890 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1893 _geomGroupData.push_back( TGeomGroupData() );
1894 TGeomGroupData & groupData = _geomGroupData.back();
1896 CORBA::String_var entry = groupSO->GetID();
1897 groupData._groupEntry = entry.in();
1899 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1900 groupData._indices.insert( ids[i] );
1902 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1903 // shape index in SMESHDS
1904 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1905 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1908 //================================================================================
1910 * Remove GEOM group data relating to removed smesh object
1912 //================================================================================
1914 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1916 list<TGeomGroupData>::iterator
1917 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1918 for ( ; data != dataEnd; ++data ) {
1919 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1920 _geomGroupData.erase( data );
1926 //================================================================================
1928 * \brief Return new group contents if it has been changed and update group data
1930 //================================================================================
1932 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1934 TopoDS_Shape newShape;
1937 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
1938 if ( !groupSO->_is_nil() )
1940 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1941 if ( CORBA::is_nil( groupObj )) return newShape;
1942 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1944 // get indices of group items
1945 set<int> curIndices;
1946 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1947 GEOM::GEOM_IGroupOperations_wrap groupOp =
1948 geomGen->GetIGroupOperations();
1949 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1950 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1951 curIndices.insert( ids[i] );
1953 if ( groupData._indices == curIndices )
1954 return newShape; // group not changed
1957 groupData._indices = curIndices;
1959 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1960 if ( !geomClient ) return newShape;
1961 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1962 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1963 newShape = _gen_i->GeomObjectToShape( geomGroup );
1966 if ( newShape.IsNull() ) {
1967 // geom group becomes empty - return empty compound
1968 TopoDS_Compound compound;
1969 BRep_Builder().MakeCompound(compound);
1970 newShape = compound;
1977 //-----------------------------------------------------------------------------
1979 * \brief Storage of shape and index used in CheckGeomGroupModif()
1981 struct TIndexedShape
1984 TopoDS_Shape _shape;
1985 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1987 //-----------------------------------------------------------------------------
1989 * \brief Data to re-create a group on geometry
1991 struct TGroupOnGeomData
1995 SMDSAbs_ElementType _type;
1997 Quantity_Color _color;
2001 //=============================================================================
2003 * \brief Update data if geometry changes
2007 //=============================================================================
2009 void SMESH_Mesh_i::CheckGeomModif()
2011 if ( !_impl->HasShapeToMesh() ) return;
2013 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
2014 //if ( mainGO->_is_nil() ) return;
2016 // Update after group modification
2018 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
2019 called by other mesh (IPAL52735) */
2020 mainGO->GetType() == GEOM_GROUP ||
2021 mainGO->GetTick() == _mainShapeTick )
2023 CheckGeomGroupModif();
2027 // Update after shape transformation like Translate
2029 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2030 if ( !geomClient ) return;
2031 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2032 if ( geomGen->_is_nil() ) return;
2034 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2035 geomClient->RemoveShapeFromBuffer( ior.in() );
2037 // Update data taking into account that
2038 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2041 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2042 if ( newShape.IsNull() )
2045 _mainShapeTick = mainGO->GetTick();
2047 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2049 // store data of groups on geometry
2050 vector< TGroupOnGeomData > groupsData;
2051 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2052 groupsData.reserve( groups.size() );
2053 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2054 for ( ; g != groups.end(); ++g )
2055 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2057 TGroupOnGeomData data;
2058 data._oldID = group->GetID();
2059 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2060 data._type = group->GetType();
2061 data._name = group->GetStoreName();
2062 data._color = group->GetColor();
2063 groupsData.push_back( data );
2065 // store assigned hypotheses
2066 vector< pair< int, THypList > > ids2Hyps;
2067 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2068 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2070 const TopoDS_Shape& s = s2hyps.Key();
2071 const THypList& hyps = s2hyps.ChangeValue();
2072 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2075 // change shape to mesh
2076 int oldNbSubShapes = meshDS->MaxShapeIndex();
2077 _impl->ShapeToMesh( TopoDS_Shape() );
2078 _impl->ShapeToMesh( newShape );
2080 // re-add shapes of geom groups
2081 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2082 for ( ; data != _geomGroupData.end(); ++data )
2084 TopoDS_Shape newShape = newGroupShape( *data );
2085 if ( !newShape.IsNull() )
2087 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2089 TopoDS_Compound compound;
2090 BRep_Builder().MakeCompound( compound );
2091 BRep_Builder().Add( compound, newShape );
2092 newShape = compound;
2094 _impl->GetSubMesh( newShape );
2097 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2098 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2099 SALOME::INTERNAL_ERROR );
2101 // re-assign hypotheses
2102 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2104 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2105 const THypList& hyps = ids2Hyps[i].second;
2106 THypList::const_iterator h = hyps.begin();
2107 for ( ; h != hyps.end(); ++h )
2108 _impl->AddHypothesis( s, (*h)->GetID() );
2112 for ( size_t i = 0; i < groupsData.size(); ++i )
2114 const TGroupOnGeomData& data = groupsData[i];
2116 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2117 if ( i2g == _mapGroups.end() ) continue;
2119 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2120 if ( !gr_i ) continue;
2123 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2124 meshDS->IndexToShape( data._shapeID ));
2127 _mapGroups.erase( i2g );
2131 g->GetGroupDS()->SetColor( data._color );
2132 gr_i->changeLocalId( id );
2133 _mapGroups[ id ] = i2g->second;
2134 if ( data._oldID != id )
2135 _mapGroups.erase( i2g );
2139 // update _mapSubMesh
2140 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2141 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2142 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2146 //=============================================================================
2148 * \brief Update objects depending on changed geom groups
2150 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2151 * issue 0020210: Update of a smesh group after modification of the associated geom group
2153 //=============================================================================
2155 void SMESH_Mesh_i::CheckGeomGroupModif()
2157 if ( !_impl->HasShapeToMesh() ) return;
2159 CORBA::Long nbEntities = NbNodes() + NbElements();
2161 // Check if group contents changed
2163 typedef map< string, TopoDS_Shape > TEntry2Geom;
2164 TEntry2Geom newGroupContents;
2166 list<TGeomGroupData>::iterator
2167 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2168 for ( ; data != dataEnd; ++data )
2170 pair< TEntry2Geom::iterator, bool > it_new =
2171 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2172 bool processedGroup = !it_new.second;
2173 TopoDS_Shape& newShape = it_new.first->second;
2174 if ( !processedGroup )
2175 newShape = newGroupShape( *data );
2176 if ( newShape.IsNull() )
2177 continue; // no changes
2180 _preMeshInfo->ForgetOrLoad();
2182 if ( processedGroup ) { // update group indices
2183 list<TGeomGroupData>::iterator data2 = data;
2184 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2185 data->_indices = data2->_indices;
2188 // Update SMESH objects according to new GEOM group contents
2190 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2191 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2193 int oldID = submesh->GetId();
2194 if ( !_mapSubMeshIor.count( oldID ))
2196 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2198 // update hypotheses
2199 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2200 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2201 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2203 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2204 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2206 // care of submeshes
2207 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2208 int newID = newSubmesh->GetId();
2209 if ( newID != oldID ) {
2210 _mapSubMesh [ newID ] = newSubmesh;
2211 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2212 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2213 _mapSubMesh. erase(oldID);
2214 _mapSubMesh_i. erase(oldID);
2215 _mapSubMeshIor.erase(oldID);
2216 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2221 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2222 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2223 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2225 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2227 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2228 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2229 ds->SetShape( newShape );
2234 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2235 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2237 // Remove groups and submeshes basing on removed sub-shapes
2239 TopTools_MapOfShape newShapeMap;
2240 TopoDS_Iterator shapeIt( newShape );
2241 for ( ; shapeIt.More(); shapeIt.Next() )
2242 newShapeMap.Add( shapeIt.Value() );
2244 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2245 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2247 if ( newShapeMap.Contains( shapeIt.Value() ))
2249 TopTools_IndexedMapOfShape oldShapeMap;
2250 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2251 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2253 const TopoDS_Shape& oldShape = oldShapeMap(i);
2254 int oldInd = meshDS->ShapeToIndex( oldShape );
2256 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2257 if ( i_smIor != _mapSubMeshIor.end() ) {
2258 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2261 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2262 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2264 // check if a group bases on oldInd shape
2265 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2266 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2267 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2268 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2270 RemoveGroup( i_grp->second ); // several groups can base on same shape
2271 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2276 // Reassign hypotheses and update groups after setting the new shape to mesh
2278 // collect anassigned hypotheses
2279 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2280 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2281 TShapeHypList assignedHyps;
2282 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2284 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2285 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2286 if ( !hyps.empty() ) {
2287 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2288 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2289 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2292 // collect shapes supporting groups
2293 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2294 TShapeTypeList groupData;
2295 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2296 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2297 for ( ; grIt != groups.end(); ++grIt )
2299 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2301 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2303 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2305 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2306 _impl->ShapeToMesh( newShape );
2308 // reassign hypotheses
2309 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2310 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2312 TIndexedShape& geom = indS_hyps->first;
2313 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2314 int oldID = geom._index;
2315 int newID = meshDS->ShapeToIndex( geom._shape );
2316 if ( oldID == 1 ) { // main shape
2318 geom._shape = newShape;
2322 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2323 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2324 // care of sub-meshes
2325 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2326 if ( newID != oldID ) {
2327 _mapSubMesh [ newID ] = newSubmesh;
2328 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2329 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2330 _mapSubMesh. erase(oldID);
2331 _mapSubMesh_i. erase(oldID);
2332 _mapSubMeshIor.erase(oldID);
2333 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2337 TShapeTypeList::iterator geomType = groupData.begin();
2338 for ( ; geomType != groupData.end(); ++geomType )
2340 const TIndexedShape& geom = geomType->first;
2341 int oldID = geom._index;
2342 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2345 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2346 CORBA::String_var name = groupSO->GetName();
2348 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2350 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2351 group_i->changeLocalId( newID );
2354 break; // everything has been updated
2357 } // loop on group data
2361 CORBA::Long newNbEntities = NbNodes() + NbElements();
2362 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2363 if ( newNbEntities != nbEntities )
2365 // Add all SObjects with icons to soToUpdateIcons
2366 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2368 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2369 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2370 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2372 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2373 i_gr != _mapGroups.end(); ++i_gr ) // groups
2374 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2377 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2378 for ( ; so != soToUpdateIcons.end(); ++so )
2379 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2382 //=============================================================================
2384 * \brief Create standalone group from a group on geometry or filter
2386 //=============================================================================
2388 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2389 throw (SALOME::SALOME_Exception)
2391 SMESH::SMESH_Group_var aGroup;
2396 _preMeshInfo->FullLoadFromFile();
2398 if ( theGroup->_is_nil() )
2399 return aGroup._retn();
2401 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2403 return aGroup._retn();
2405 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2407 const int anId = aGroupToRem->GetLocalID();
2408 if ( !_impl->ConvertToStandalone( anId ) )
2409 return aGroup._retn();
2410 removeGeomGroupData( theGroup );
2412 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2414 // remove old instance of group from own map
2415 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2416 _mapGroups.erase( anId );
2418 SALOMEDS::StudyBuilder_var builder;
2419 SALOMEDS::SObject_wrap aGroupSO;
2420 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2421 if ( !aStudy->_is_nil() ) {
2422 builder = aStudy->NewBuilder();
2423 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2424 if ( !aGroupSO->_is_nil() )
2426 // remove reference to geometry
2427 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2428 for ( ; chItr->More(); chItr->Next() )
2429 // Remove group's child SObject
2430 builder->RemoveObject( chItr->Value() );
2432 // Update Python script
2433 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2434 << ".ConvertToStandalone( " << aGroupSO << " )";
2436 // change icon of Group on Filter
2439 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2440 const int isEmpty = ( elemTypes->length() == 0 );
2443 SALOMEDS::GenericAttribute_wrap anAttr =
2444 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2445 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2446 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2452 // remember new group in own map
2453 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2454 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2456 // register CORBA object for persistence
2457 _gen_i->RegisterObject( aGroup );
2459 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2460 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2461 //aGroup->Register();
2462 aGroupToRem->UnRegister();
2464 SMESH_CATCH( SMESH::throwCorbaException );
2466 return aGroup._retn();
2469 //=============================================================================
2473 //=============================================================================
2475 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2477 if(MYDEBUG) MESSAGE( "createSubMesh" );
2478 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2479 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2482 SMESH_subMesh_i * subMeshServant;
2485 subMeshId = mySubMesh->GetId();
2486 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2488 else // "invalid sub-mesh"
2490 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2491 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2492 if ( _mapSubMesh.empty() )
2495 subMeshId = _mapSubMesh.begin()->first - 1;
2496 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2499 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2501 _mapSubMesh [subMeshId] = mySubMesh;
2502 _mapSubMesh_i [subMeshId] = subMeshServant;
2503 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2505 subMeshServant->Register();
2507 // register CORBA object for persistence
2508 int nextId = _gen_i->RegisterObject( subMesh );
2509 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2510 else { nextId = 0; } // avoid "unused variable" warning
2512 // to track changes of GEOM groups
2513 if ( subMeshId > 0 )
2514 addGeomGroupData( theSubShapeObject, subMesh );
2516 return subMesh._retn();
2519 //=======================================================================
2520 //function : getSubMesh
2522 //=======================================================================
2524 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2526 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2527 if ( it == _mapSubMeshIor.end() )
2528 return SMESH::SMESH_subMesh::_nil();
2530 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2533 //=============================================================================
2537 //=============================================================================
2539 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2540 GEOM::GEOM_Object_ptr theSubShapeObject )
2542 bool isHypChanged = false;
2543 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2544 return isHypChanged;
2546 const int subMeshId = theSubMesh->GetId();
2548 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2550 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end() &&
2551 _mapSubMesh[ subMeshId ])
2553 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2556 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2557 isHypChanged = !hyps.empty();
2558 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2559 for ( ; hyp != hyps.end(); ++hyp )
2560 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2567 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2568 isHypChanged = ( aHypList->length() > 0 );
2569 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2570 removeHypothesis( theSubShapeObject, aHypList[i] );
2573 catch( const SALOME::SALOME_Exception& ) {
2574 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2576 removeGeomGroupData( theSubShapeObject );
2580 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2581 if ( id_smi != _mapSubMesh_i.end() )
2582 id_smi->second->UnRegister();
2584 // remove a CORBA object
2585 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2586 if ( id_smptr != _mapSubMeshIor.end() )
2587 SMESH::SMESH_subMesh_var( id_smptr->second );
2589 _mapSubMesh.erase(subMeshId);
2590 _mapSubMesh_i.erase(subMeshId);
2591 _mapSubMeshIor.erase(subMeshId);
2593 return isHypChanged;
2596 //=============================================================================
2600 //=============================================================================
2602 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2603 const char* theName,
2604 const TopoDS_Shape& theShape,
2605 const SMESH_PredicatePtr& thePredicate )
2607 std::string newName;
2608 if ( !theName || !theName[0] )
2610 std::set< std::string > presentNames;
2611 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2612 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2614 CORBA::String_var name = i_gr->second->GetName();
2615 presentNames.insert( name.in() );
2618 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2619 } while ( !presentNames.insert( newName ).second );
2620 theName = newName.c_str();
2623 SMESH::SMESH_GroupBase_var aGroup;
2624 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2626 SMESH_GroupBase_i* aGroupImpl;
2627 if ( !theShape.IsNull() )
2628 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2629 else if ( thePredicate )
2630 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2632 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2634 aGroup = aGroupImpl->_this();
2635 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2636 aGroupImpl->Register();
2638 // register CORBA object for persistence
2639 int nextId = _gen_i->RegisterObject( aGroup );
2640 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2641 else { nextId = 0; } // avoid "unused variable" warning in release mode
2643 // to track changes of GEOM groups
2644 if ( !theShape.IsNull() ) {
2645 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2646 addGeomGroupData( geom, aGroup );
2649 return aGroup._retn();
2652 //=============================================================================
2654 * SMESH_Mesh_i::removeGroup
2656 * Should be called by ~SMESH_Group_i()
2658 //=============================================================================
2660 void SMESH_Mesh_i::removeGroup( const int theId )
2662 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2663 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2664 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2665 _mapGroups.erase( theId );
2666 removeGeomGroupData( group );
2667 if ( !_impl->RemoveGroup( theId ))
2669 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2670 RemoveGroup( group );
2672 group->UnRegister();
2676 //=============================================================================
2680 //=============================================================================
2682 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2683 throw(SALOME::SALOME_Exception)
2685 SMESH::log_array_var aLog;
2689 _preMeshInfo->FullLoadFromFile();
2691 list < SMESHDS_Command * >logDS = _impl->GetLog();
2692 aLog = new SMESH::log_array;
2694 int lg = logDS.size();
2697 list < SMESHDS_Command * >::iterator its = logDS.begin();
2698 while(its != logDS.end()){
2699 SMESHDS_Command *com = *its;
2700 int comType = com->GetType();
2702 int lgcom = com->GetNumber();
2704 const list < int >&intList = com->GetIndexes();
2705 int inum = intList.size();
2707 list < int >::const_iterator ii = intList.begin();
2708 const list < double >&coordList = com->GetCoords();
2709 int rnum = coordList.size();
2711 list < double >::const_iterator ir = coordList.begin();
2712 aLog[indexLog].commandType = comType;
2713 aLog[indexLog].number = lgcom;
2714 aLog[indexLog].coords.length(rnum);
2715 aLog[indexLog].indexes.length(inum);
2716 for(int i = 0; i < rnum; i++){
2717 aLog[indexLog].coords[i] = *ir;
2718 //MESSAGE(" "<<i<<" "<<ir.Value());
2721 for(int i = 0; i < inum; i++){
2722 aLog[indexLog].indexes[i] = *ii;
2723 //MESSAGE(" "<<i<<" "<<ii.Value());
2732 SMESH_CATCH( SMESH::throwCorbaException );
2734 return aLog._retn();
2738 //=============================================================================
2742 //=============================================================================
2744 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2748 SMESH_CATCH( SMESH::throwCorbaException );
2751 //=============================================================================
2755 //=============================================================================
2757 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2762 //=============================================================================
2765 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2766 // issue 0020918: groups removal is caused by hyp modification
2767 // issue 0021208: to forget not loaded mesh data at hyp modification
2768 struct TCallUp_i : public SMESH_Mesh::TCallUp
2770 SMESH_Mesh_i* _mesh;
2771 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2772 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2773 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
2774 virtual void Load () { _mesh->Load(); }
2778 //================================================================================
2780 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2782 //================================================================================
2784 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
2787 _preMeshInfo->ForgetOrLoad();
2789 SMESH::SMESH_Mesh_var mesh = _this();
2790 _gen_i->UpdateIcons( mesh );
2792 // mark a hypothesis as valid after edition
2793 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
2794 SALOMEDS::SObject_wrap hypRoot;
2795 if ( !smeshComp->_is_nil() &&
2796 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
2798 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
2799 for ( ; anIter->More(); anIter->Next() )
2801 SALOMEDS::SObject_wrap hypSO = anIter->Value();
2802 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
2803 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
2804 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
2805 _gen_i->HighLightInvalid( hyp, false );
2810 //=============================================================================
2814 //=============================================================================
2816 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2818 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2821 _impl->SetCallUp( new TCallUp_i(this));
2824 //=============================================================================
2828 //=============================================================================
2830 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2832 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2836 //=============================================================================
2838 * Return mesh editor
2840 //=============================================================================
2842 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2843 throw (SALOME::SALOME_Exception)
2845 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2849 _preMeshInfo->FullLoadFromFile();
2851 // Create MeshEditor
2853 _editor = new SMESH_MeshEditor_i( this, false );
2854 aMeshEdVar = _editor->_this();
2856 // Update Python script
2857 TPythonDump() << _editor << " = "
2858 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2860 SMESH_CATCH( SMESH::throwCorbaException );
2862 return aMeshEdVar._retn();
2865 //=============================================================================
2867 * Return mesh edition previewer
2869 //=============================================================================
2871 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2872 throw (SALOME::SALOME_Exception)
2874 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2878 _preMeshInfo->FullLoadFromFile();
2880 if ( !_previewEditor )
2881 _previewEditor = new SMESH_MeshEditor_i( this, true );
2882 aMeshEdVar = _previewEditor->_this();
2884 SMESH_CATCH( SMESH::throwCorbaException );
2886 return aMeshEdVar._retn();
2889 //================================================================================
2891 * \brief Return true if the mesh has been edited since a last total re-compute
2892 * and those modifications may prevent successful partial re-compute
2894 //================================================================================
2896 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2898 Unexpect aCatch(SALOME_SalomeException);
2899 return _impl->HasModificationsToDiscard();
2902 //================================================================================
2904 * \brief Returns a random unique color
2906 //================================================================================
2908 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2910 const int MAX_ATTEMPTS = 100;
2912 double tolerance = 0.5;
2913 SALOMEDS::Color col;
2917 // generate random color
2918 double red = (double)rand() / RAND_MAX;
2919 double green = (double)rand() / RAND_MAX;
2920 double blue = (double)rand() / RAND_MAX;
2921 // check existence in the list of the existing colors
2922 bool matched = false;
2923 std::list<SALOMEDS::Color>::const_iterator it;
2924 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2925 SALOMEDS::Color color = *it;
2926 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2927 matched = tol < tolerance;
2929 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2930 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2938 //=============================================================================
2940 * Sets auto-color mode. If it is on, groups get unique random colors
2942 //=============================================================================
2944 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2946 Unexpect aCatch(SALOME_SalomeException);
2947 _impl->SetAutoColor(theAutoColor);
2949 TPythonDump pyDump; // not to dump group->SetColor() from below code
2950 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2952 std::list<SALOMEDS::Color> aReservedColors;
2953 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2954 for ( ; it != _mapGroups.end(); it++ ) {
2955 if ( CORBA::is_nil( it->second )) continue;
2956 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2957 it->second->SetColor( aColor );
2958 aReservedColors.push_back( aColor );
2962 //=============================================================================
2964 * Returns true if auto-color mode is on
2966 //=============================================================================
2968 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2970 Unexpect aCatch(SALOME_SalomeException);
2971 return _impl->GetAutoColor();
2974 //=============================================================================
2976 * Checks if there are groups with equal names
2978 //=============================================================================
2980 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2982 return _impl->HasDuplicatedGroupNamesMED();
2985 //================================================================================
2987 * \brief Care of a file before exporting mesh into it
2989 //================================================================================
2991 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2993 SMESH_File aFile( file );
2995 if (aFile.exists()) {
2996 // existing filesystem node
2997 if ( !aFile.isDirectory() ) {
2998 if ( aFile.openForWriting() ) {
2999 if ( overwrite && ! aFile.remove()) {
3000 msg << "Can't replace " << aFile.getName();
3003 msg << "Can't write into " << aFile.getName();
3006 msg << "Location " << aFile.getName() << " is not a file";
3010 // nonexisting file; check if it can be created
3011 if ( !aFile.openForWriting() ) {
3012 msg << "You cannot create the file "
3014 << ". Check the directory existence and access rights";
3022 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3026 //================================================================================
3028 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3029 * \param file - file name
3030 * \param overwrite - to erase the file or not
3031 * \retval string - mesh name
3033 //================================================================================
3035 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3036 CORBA::Boolean overwrite)
3039 PrepareForWriting(file, overwrite);
3040 string aMeshName = "Mesh";
3041 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3042 if ( !aStudy->_is_nil() ) {
3043 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3044 if ( !aMeshSO->_is_nil() ) {
3045 CORBA::String_var name = aMeshSO->GetName();
3047 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3048 if ( !aStudy->GetProperties()->IsLocked() )
3050 SALOMEDS::GenericAttribute_wrap anAttr;
3051 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3052 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3053 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3054 ASSERT(!aFileName->_is_nil());
3055 aFileName->SetValue(file);
3056 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3057 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3058 ASSERT(!aFileType->_is_nil());
3059 aFileType->SetValue("FICHIERMED");
3063 // Update Python script
3064 // set name of mesh before export
3065 TPythonDump() << _gen_i << ".SetName("
3066 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3068 // check names of groups
3074 //================================================================================
3076 * \brief Export to MED file
3078 //================================================================================
3080 void SMESH_Mesh_i::ExportMED(const char* file,
3081 CORBA::Boolean auto_groups,
3082 CORBA::Long version,
3083 CORBA::Boolean overwrite,
3084 CORBA::Boolean autoDimension)
3085 throw(SALOME::SALOME_Exception)
3087 //MESSAGE("MED minor version: "<< minor);
3090 _preMeshInfo->FullLoadFromFile();
3092 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3093 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3095 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3097 << "auto_groups=" <<auto_groups << ", "
3098 << "minor=" << version << ", "
3099 << "overwrite=" << overwrite << ", "
3100 << "meshPart=None, "
3101 << "autoDimension=" << autoDimension << " )";
3103 SMESH_CATCH( SMESH::throwCorbaException );
3106 //================================================================================
3108 * \brief Export a mesh to a SAUV file
3110 //================================================================================
3112 void SMESH_Mesh_i::ExportSAUV (const char* file,
3113 CORBA::Boolean auto_groups)
3114 throw(SALOME::SALOME_Exception)
3116 Unexpect aCatch(SALOME_SalomeException);
3118 _preMeshInfo->FullLoadFromFile();
3120 string aMeshName = prepareMeshNameAndGroups(file, true);
3121 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3122 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3123 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3127 //================================================================================
3129 * \brief Export a mesh to a DAT file
3131 //================================================================================
3133 void SMESH_Mesh_i::ExportDAT (const char *file)
3134 throw(SALOME::SALOME_Exception)
3136 Unexpect aCatch(SALOME_SalomeException);
3138 _preMeshInfo->FullLoadFromFile();
3140 // Update Python script
3141 // check names of groups
3143 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3146 PrepareForWriting(file);
3147 _impl->ExportDAT(file);
3150 //================================================================================
3152 * \brief Export a mesh to an UNV file
3154 //================================================================================
3156 void SMESH_Mesh_i::ExportUNV (const char *file)
3157 throw(SALOME::SALOME_Exception)
3159 Unexpect aCatch(SALOME_SalomeException);
3161 _preMeshInfo->FullLoadFromFile();
3163 // Update Python script
3164 // check names of groups
3166 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3169 PrepareForWriting(file);
3170 _impl->ExportUNV(file);
3173 //================================================================================
3175 * \brief Export a mesh to an STL file
3177 //================================================================================
3179 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3180 throw(SALOME::SALOME_Exception)
3182 Unexpect aCatch(SALOME_SalomeException);
3184 _preMeshInfo->FullLoadFromFile();
3186 // Update Python script
3187 // check names of groups
3189 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3190 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3192 CORBA::String_var name;
3193 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3194 if ( !so->_is_nil() )
3195 name = so->GetName();
3198 PrepareForWriting( file );
3199 _impl->ExportSTL( file, isascii, name.in() );
3202 //================================================================================
3204 * \brief Export a part of mesh to a med file
3206 //================================================================================
3208 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3210 CORBA::Boolean auto_groups,
3211 CORBA::Long version,
3212 CORBA::Boolean overwrite,
3213 CORBA::Boolean autoDimension,
3214 const GEOM::ListOfFields& fields,
3215 const char* geomAssocFields,
3216 CORBA::Double ZTolerance)
3217 throw (SALOME::SALOME_Exception)
3219 MESSAGE("MED version: "<< version);
3222 _preMeshInfo->FullLoadFromFile();
3225 bool have0dField = false;
3226 if ( fields.length() > 0 )
3228 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3229 if ( shapeToMesh->_is_nil() )
3230 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3232 for ( size_t i = 0; i < fields.length(); ++i )
3234 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3235 THROW_SALOME_CORBA_EXCEPTION
3236 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3237 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3238 if ( fieldShape->_is_nil() )
3239 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3240 if ( !fieldShape->IsSame( shapeToMesh ) )
3241 THROW_SALOME_CORBA_EXCEPTION
3242 ( "Field defined not on shape", SALOME::BAD_PARAM);
3243 if ( fields[i]->GetDimension() == 0 )
3246 if ( geomAssocFields )
3247 for ( int i = 0; geomAssocFields[i]; ++i )
3248 switch ( geomAssocFields[i] ) {
3249 case 'v':case 'e':case 'f':case 's': break;
3250 case 'V':case 'E':case 'F':case 'S': break;
3251 default: THROW_SALOME_CORBA_EXCEPTION
3252 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3256 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3260 string aMeshName = "Mesh";
3261 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3262 if ( CORBA::is_nil( meshPart ) ||
3263 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3265 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3266 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3267 0, autoDimension, /*addODOnVertices=*/have0dField,
3269 meshDS = _impl->GetMeshDS();
3274 _preMeshInfo->FullLoadFromFile();
3276 PrepareForWriting(file, overwrite);
3278 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3279 if ( !SO->_is_nil() ) {
3280 CORBA::String_var name = SO->GetName();
3284 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3285 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3286 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3287 meshDS = tmpDSDeleter._obj = partDS;
3292 if ( _impl->HasShapeToMesh() )
3294 DriverMED_W_Field fieldWriter;
3295 fieldWriter.SetFile( file );
3296 fieldWriter.SetMeshName( aMeshName );
3297 fieldWriter.AddODOnVertices( have0dField );
3299 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3303 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3304 goList->length( fields.length() );
3305 for ( size_t i = 0; i < fields.length(); ++i )
3307 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3310 TPythonDump() << _this() << ".ExportPartToMED( "
3311 << meshPart << ", r'"
3313 << auto_groups << ", "
3315 << overwrite << ", "
3316 << autoDimension << ", "
3318 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3322 SMESH_CATCH( SMESH::throwCorbaException );
3325 //================================================================================
3327 * Write GEOM fields to MED file
3329 //================================================================================
3331 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3332 SMESHDS_Mesh* meshDS,
3333 const GEOM::ListOfFields& fields,
3334 const char* geomAssocFields)
3336 #define METH "SMESH_Mesh_i::exportMEDFields() "
3338 if (( fields.length() < 1 ) &&
3339 ( !geomAssocFields || !geomAssocFields[0] ))
3342 std::vector< std::vector< double > > dblVals;
3343 std::vector< std::vector< int > > intVals;
3344 std::vector< int > subIdsByDim[ 4 ];
3345 const double noneDblValue = 0.;
3346 const double noneIntValue = 0;
3348 for ( size_t iF = 0; iF < fields.length(); ++iF )
3352 int dim = fields[ iF ]->GetDimension();
3353 SMDSAbs_ElementType elemType;
3354 TopAbs_ShapeEnum shapeType;
3356 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3357 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3358 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3359 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3361 continue; // skip fields on whole shape
3363 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3364 if ( dataType == GEOM::FDT_String )
3366 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3367 if ( stepIDs->length() < 1 )
3369 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3370 if ( comps->length() < 1 )
3372 CORBA::String_var name = fields[ iF ]->GetName();
3374 if ( !fieldWriter.Set( meshDS,
3378 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3381 for ( size_t iC = 0; iC < comps->length(); ++iC )
3382 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3384 dblVals.resize( comps->length() );
3385 intVals.resize( comps->length() );
3387 // find sub-shape IDs
3389 std::vector< int >& subIds = subIdsByDim[ dim ];
3390 if ( subIds.empty() )
3391 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3392 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3393 subIds.push_back( id );
3397 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3401 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3403 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3404 if ( step->_is_nil() )
3407 CORBA::Long stamp = step->GetStamp();
3408 CORBA::Long id = step->GetID();
3409 fieldWriter.SetDtIt( int( stamp ), int( id ));
3411 // fill dblVals or intVals
3412 for ( size_t iC = 0; iC < comps->length(); ++iC )
3413 if ( dataType == GEOM::FDT_Double )
3415 dblVals[ iC ].clear();
3416 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3420 intVals[ iC ].clear();
3421 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3425 case GEOM::FDT_Double:
3427 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3428 if ( dblStep->_is_nil() ) continue;
3429 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3430 if ( vv->length() != subIds.size() * comps->length() )
3431 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3432 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3433 for ( size_t iC = 0; iC < comps->length(); ++iC )
3434 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3439 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3440 if ( intStep->_is_nil() ) continue;
3441 GEOM::ListOfLong_var vv = intStep->GetValues();
3442 if ( vv->length() != subIds.size() * comps->length() )
3443 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3444 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3445 for ( size_t iC = 0; iC < comps->length(); ++iC )
3446 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3449 case GEOM::FDT_Bool:
3451 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3452 if ( boolStep->_is_nil() ) continue;
3453 GEOM::short_array_var vv = boolStep->GetValues();
3454 if ( vv->length() != subIds.size() * comps->length() )
3455 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3456 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3457 for ( size_t iC = 0; iC < comps->length(); ++iC )
3458 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3464 // pass values to fieldWriter
3465 elemIt = fieldWriter.GetOrderedElems();
3466 if ( dataType == GEOM::FDT_Double )
3467 while ( elemIt->more() )
3469 const SMDS_MeshElement* e = elemIt->next();
3470 const int shapeID = e->getshapeId();
3471 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3472 for ( size_t iC = 0; iC < comps->length(); ++iC )
3473 fieldWriter.AddValue( noneDblValue );
3475 for ( size_t iC = 0; iC < comps->length(); ++iC )
3476 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3479 while ( elemIt->more() )
3481 const SMDS_MeshElement* e = elemIt->next();
3482 const int shapeID = e->getshapeId();
3483 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3484 for ( size_t iC = 0; iC < comps->length(); ++iC )
3485 fieldWriter.AddValue( (double) noneIntValue );
3487 for ( size_t iC = 0; iC < comps->length(); ++iC )
3488 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3492 fieldWriter.Perform();
3493 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3494 if ( res && res->IsKO() )
3496 if ( res->myComment.empty() )
3497 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3499 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3505 if ( !geomAssocFields || !geomAssocFields[0] )
3508 // write geomAssocFields
3510 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3511 shapeDim[ TopAbs_COMPOUND ] = 3;
3512 shapeDim[ TopAbs_COMPSOLID ] = 3;
3513 shapeDim[ TopAbs_SOLID ] = 3;
3514 shapeDim[ TopAbs_SHELL ] = 2;
3515 shapeDim[ TopAbs_FACE ] = 2;
3516 shapeDim[ TopAbs_WIRE ] = 1;
3517 shapeDim[ TopAbs_EDGE ] = 1;
3518 shapeDim[ TopAbs_VERTEX ] = 0;
3519 shapeDim[ TopAbs_SHAPE ] = 3;
3521 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3523 std::vector< std::string > compNames;
3524 switch ( geomAssocFields[ iF ]) {
3526 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3527 compNames.push_back( "dim" );
3530 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3533 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3536 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3540 compNames.push_back( "id" );
3541 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3542 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3544 fieldWriter.SetDtIt( -1, -1 );
3546 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3550 if ( compNames.size() == 2 ) // _vertices_
3551 while ( elemIt->more() )
3553 const SMDS_MeshElement* e = elemIt->next();
3554 const int shapeID = e->getshapeId();
3557 fieldWriter.AddValue( (double) -1 );
3558 fieldWriter.AddValue( (double) -1 );
3562 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3563 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3564 fieldWriter.AddValue( (double) shapeID );
3568 while ( elemIt->more() )
3570 const SMDS_MeshElement* e = elemIt->next();
3571 const int shapeID = e->getshapeId();
3573 fieldWriter.AddValue( (double) -1 );
3575 fieldWriter.AddValue( (double) shapeID );
3579 fieldWriter.Perform();
3580 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3581 if ( res && res->IsKO() )
3583 if ( res->myComment.empty() )
3584 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3586 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3589 } // loop on geomAssocFields
3594 //================================================================================
3596 * \brief Export a part of mesh to a DAT file
3598 //================================================================================
3600 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3602 throw (SALOME::SALOME_Exception)
3604 Unexpect aCatch(SALOME_SalomeException);
3606 _preMeshInfo->FullLoadFromFile();
3608 PrepareForWriting(file);
3610 SMESH_MeshPartDS partDS( meshPart );
3611 _impl->ExportDAT(file,&partDS);
3613 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3614 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3616 //================================================================================
3618 * \brief Export a part of mesh to an UNV file
3620 //================================================================================
3622 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3624 throw (SALOME::SALOME_Exception)
3626 Unexpect aCatch(SALOME_SalomeException);
3628 _preMeshInfo->FullLoadFromFile();
3630 PrepareForWriting(file);
3632 SMESH_MeshPartDS partDS( meshPart );
3633 _impl->ExportUNV(file, &partDS);
3635 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3636 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3638 //================================================================================
3640 * \brief Export a part of mesh to an STL file
3642 //================================================================================
3644 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3646 ::CORBA::Boolean isascii)
3647 throw (SALOME::SALOME_Exception)
3649 Unexpect aCatch(SALOME_SalomeException);
3651 _preMeshInfo->FullLoadFromFile();
3653 PrepareForWriting(file);
3655 CORBA::String_var name;
3656 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3657 if ( !so->_is_nil() )
3658 name = so->GetName();
3660 SMESH_MeshPartDS partDS( meshPart );
3661 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3663 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3664 << meshPart<< ", r'" << file << "', " << isascii << ")";
3667 //================================================================================
3669 * \brief Export a part of mesh to an STL file
3671 //================================================================================
3673 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3675 CORBA::Boolean overwrite,
3676 CORBA::Boolean groupElemsByType)
3677 throw (SALOME::SALOME_Exception)
3680 Unexpect aCatch(SALOME_SalomeException);
3682 _preMeshInfo->FullLoadFromFile();
3684 PrepareForWriting(file,overwrite);
3686 std::string meshName("");
3687 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3688 if ( !so->_is_nil() )
3690 CORBA::String_var name = so->GetName();
3691 meshName = name.in();
3695 SMESH_MeshPartDS partDS( meshPart );
3696 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3698 SMESH_CATCH( SMESH::throwCorbaException );
3700 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3701 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3703 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3707 //================================================================================
3709 * \brief Export a part of mesh to a GMF file
3711 //================================================================================
3713 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3715 bool withRequiredGroups)
3716 throw (SALOME::SALOME_Exception)
3718 Unexpect aCatch(SALOME_SalomeException);
3720 _preMeshInfo->FullLoadFromFile();
3722 PrepareForWriting(file,/*overwrite=*/true);
3724 SMESH_MeshPartDS partDS( meshPart );
3725 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3727 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3728 << meshPart<< ", r'"
3730 << withRequiredGroups << ")";
3733 //=============================================================================
3735 * Return computation progress [0.,1]
3737 //=============================================================================
3739 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3743 return _impl->GetComputeProgress();
3745 SMESH_CATCH( SMESH::doNothing );
3749 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3751 Unexpect aCatch(SALOME_SalomeException);
3753 return _preMeshInfo->NbNodes();
3755 return _impl->NbNodes();
3758 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3760 Unexpect aCatch(SALOME_SalomeException);
3762 return _preMeshInfo->NbElements();
3764 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3767 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3769 Unexpect aCatch(SALOME_SalomeException);
3771 return _preMeshInfo->Nb0DElements();
3773 return _impl->Nb0DElements();
3776 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3778 Unexpect aCatch(SALOME_SalomeException);
3780 return _preMeshInfo->NbBalls();
3782 return _impl->NbBalls();
3785 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3787 Unexpect aCatch(SALOME_SalomeException);
3789 return _preMeshInfo->NbEdges();
3791 return _impl->NbEdges();
3794 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3795 throw(SALOME::SALOME_Exception)
3797 Unexpect aCatch(SALOME_SalomeException);
3799 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3801 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3804 //=============================================================================
3806 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3808 Unexpect aCatch(SALOME_SalomeException);
3810 return _preMeshInfo->NbFaces();
3812 return _impl->NbFaces();
3815 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3817 Unexpect aCatch(SALOME_SalomeException);
3819 return _preMeshInfo->NbTriangles();
3821 return _impl->NbTriangles();
3824 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3826 Unexpect aCatch(SALOME_SalomeException);
3828 return _preMeshInfo->NbBiQuadTriangles();
3830 return _impl->NbBiQuadTriangles();
3833 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3835 Unexpect aCatch(SALOME_SalomeException);
3837 return _preMeshInfo->NbQuadrangles();
3839 return _impl->NbQuadrangles();
3842 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3844 Unexpect aCatch(SALOME_SalomeException);
3846 return _preMeshInfo->NbBiQuadQuadrangles();
3848 return _impl->NbBiQuadQuadrangles();
3851 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3853 Unexpect aCatch(SALOME_SalomeException);
3855 return _preMeshInfo->NbPolygons();
3857 return _impl->NbPolygons();
3860 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3862 Unexpect aCatch(SALOME_SalomeException);
3864 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3866 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3869 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3870 throw(SALOME::SALOME_Exception)
3872 Unexpect aCatch(SALOME_SalomeException);
3874 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3876 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3879 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3880 throw(SALOME::SALOME_Exception)
3882 Unexpect aCatch(SALOME_SalomeException);
3884 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3886 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3889 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3890 throw(SALOME::SALOME_Exception)
3892 Unexpect aCatch(SALOME_SalomeException);
3894 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3896 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3899 //=============================================================================
3901 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3903 Unexpect aCatch(SALOME_SalomeException);
3905 return _preMeshInfo->NbVolumes();
3907 return _impl->NbVolumes();
3910 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3912 Unexpect aCatch(SALOME_SalomeException);
3914 return _preMeshInfo->NbTetras();
3916 return _impl->NbTetras();
3919 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3921 Unexpect aCatch(SALOME_SalomeException);
3923 return _preMeshInfo->NbHexas();
3925 return _impl->NbHexas();
3928 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3930 Unexpect aCatch(SALOME_SalomeException);
3932 return _preMeshInfo->NbTriQuadHexas();
3934 return _impl->NbTriQuadraticHexas();
3937 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3939 Unexpect aCatch(SALOME_SalomeException);
3941 return _preMeshInfo->NbPyramids();
3943 return _impl->NbPyramids();
3946 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3948 Unexpect aCatch(SALOME_SalomeException);
3950 return _preMeshInfo->NbPrisms();
3952 return _impl->NbPrisms();
3955 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3957 Unexpect aCatch(SALOME_SalomeException);
3959 return _preMeshInfo->NbHexPrisms();
3961 return _impl->NbHexagonalPrisms();
3964 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3966 Unexpect aCatch(SALOME_SalomeException);
3968 return _preMeshInfo->NbPolyhedrons();
3970 return _impl->NbPolyhedrons();
3973 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3974 throw(SALOME::SALOME_Exception)
3976 Unexpect aCatch(SALOME_SalomeException);
3978 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3980 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3983 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3984 throw(SALOME::SALOME_Exception)
3986 Unexpect aCatch(SALOME_SalomeException);
3988 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3990 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3993 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3994 throw(SALOME::SALOME_Exception)
3996 Unexpect aCatch(SALOME_SalomeException);
3998 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4000 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4003 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4004 throw(SALOME::SALOME_Exception)
4006 Unexpect aCatch(SALOME_SalomeException);
4008 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4010 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4013 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4014 throw(SALOME::SALOME_Exception)
4016 Unexpect aCatch(SALOME_SalomeException);
4018 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4020 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4023 //=============================================================================
4025 * Returns nb of published sub-meshes
4027 //=============================================================================
4029 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4031 Unexpect aCatch(SALOME_SalomeException);
4032 return _mapSubMesh_i.size();
4035 //=============================================================================
4037 * Dumps mesh into a string
4039 //=============================================================================
4041 char* SMESH_Mesh_i::Dump()
4045 return CORBA::string_dup( os.str().c_str() );
4048 //=============================================================================
4050 * Method of SMESH_IDSource interface
4052 //=============================================================================
4054 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4056 return GetElementsId();
4059 //=============================================================================
4061 * Returns ids of all elements
4063 //=============================================================================
4065 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
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();
4079 aResult->length( nbElements );
4080 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4081 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4082 aResult[i] = anIt->next()->GetID();
4084 return aResult._retn();
4088 //=============================================================================
4090 * Returns ids of all elements of given type
4092 //=============================================================================
4094 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4095 throw (SALOME::SALOME_Exception)
4097 Unexpect aCatch(SALOME_SalomeException);
4099 _preMeshInfo->FullLoadFromFile();
4101 SMESH::long_array_var aResult = new SMESH::long_array();
4102 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4104 if ( aSMESHDS_Mesh == NULL )
4105 return aResult._retn();
4107 long nbElements = NbElements();
4109 // No sense in returning ids of elements along with ids of nodes:
4110 // when theElemType == SMESH::ALL, return node ids only if
4111 // there are no elements
4112 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4113 return GetNodesId();
4115 aResult->length( nbElements );
4119 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4120 while ( i < nbElements && anIt->more() )
4121 aResult[i++] = anIt->next()->GetID();
4123 aResult->length( i );
4125 return aResult._retn();
4128 //=============================================================================
4130 * Returns ids of all nodes
4132 //=============================================================================
4134 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4135 throw (SALOME::SALOME_Exception)
4137 Unexpect aCatch(SALOME_SalomeException);
4139 _preMeshInfo->FullLoadFromFile();
4141 SMESH::long_array_var aResult = new SMESH::long_array();
4142 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4144 if ( aMeshDS == NULL )
4145 return aResult._retn();
4147 long nbNodes = NbNodes();
4148 aResult->length( nbNodes );
4149 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4150 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4151 aResult[i] = anIt->next()->GetID();
4153 return aResult._retn();
4156 //=============================================================================
4160 //=============================================================================
4162 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4163 throw (SALOME::SALOME_Exception)
4165 SMESH::ElementType type = SMESH::ALL;
4169 _preMeshInfo->FullLoadFromFile();
4171 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4173 SMESH_CATCH( SMESH::throwCorbaException );
4178 //=============================================================================
4182 //=============================================================================
4184 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4185 throw (SALOME::SALOME_Exception)
4188 _preMeshInfo->FullLoadFromFile();
4190 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4192 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4194 return ( SMESH::EntityType ) e->GetEntityType();
4197 //=============================================================================
4201 //=============================================================================
4203 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4204 throw (SALOME::SALOME_Exception)
4207 _preMeshInfo->FullLoadFromFile();
4209 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4211 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4213 return ( SMESH::GeometryType ) e->GetGeomType();
4216 //=============================================================================
4218 * Returns ID of elements for given submesh
4220 //=============================================================================
4221 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4222 throw (SALOME::SALOME_Exception)
4224 SMESH::long_array_var aResult = new SMESH::long_array();
4228 _preMeshInfo->FullLoadFromFile();
4230 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4231 if(!SM) return aResult._retn();
4233 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4234 if(!SDSM) return aResult._retn();
4236 aResult->length(SDSM->NbElements());
4238 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4240 while ( eIt->more() ) {
4241 aResult[i++] = eIt->next()->GetID();
4244 SMESH_CATCH( SMESH::throwCorbaException );
4246 return aResult._retn();
4249 //=============================================================================
4251 * Returns ID of nodes for given submesh
4252 * If param all==true - returns all nodes, else -
4253 * returns only nodes on shapes.
4255 //=============================================================================
4257 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4259 throw (SALOME::SALOME_Exception)
4261 SMESH::long_array_var aResult = new SMESH::long_array();
4265 _preMeshInfo->FullLoadFromFile();
4267 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4268 if(!SM) return aResult._retn();
4270 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4271 if(!SDSM) return aResult._retn();
4274 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4275 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4276 while ( nIt->more() ) {
4277 const SMDS_MeshNode* elem = nIt->next();
4278 theElems.insert( elem->GetID() );
4281 else { // all nodes of submesh elements
4282 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4283 while ( eIt->more() ) {
4284 const SMDS_MeshElement* anElem = eIt->next();
4285 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4286 while ( nIt->more() ) {
4287 const SMDS_MeshElement* elem = nIt->next();
4288 theElems.insert( elem->GetID() );
4293 aResult->length(theElems.size());
4294 set<int>::iterator itElem;
4296 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4297 aResult[i++] = *itElem;
4299 SMESH_CATCH( SMESH::throwCorbaException );
4301 return aResult._retn();
4304 //=============================================================================
4306 * Returns type of elements for given submesh
4308 //=============================================================================
4310 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4311 throw (SALOME::SALOME_Exception)
4313 SMESH::ElementType type = SMESH::ALL;
4317 _preMeshInfo->FullLoadFromFile();
4319 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4320 if(!SM) return SMESH::ALL;
4322 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4323 if(!SDSM) return SMESH::ALL;
4325 if(SDSM->NbElements()==0)
4326 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4328 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4329 const SMDS_MeshElement* anElem = eIt->next();
4331 type = ( SMESH::ElementType ) anElem->GetType();
4333 SMESH_CATCH( SMESH::throwCorbaException );
4339 //=============================================================================
4341 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4343 //=============================================================================
4345 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4348 _preMeshInfo->FullLoadFromFile();
4350 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4351 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4356 //=============================================================================
4358 * Get XYZ coordinates of node as list of double
4359 * If there is not node for given ID - returns empty list
4361 //=============================================================================
4363 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4366 _preMeshInfo->FullLoadFromFile();
4368 SMESH::double_array_var aResult = new SMESH::double_array();
4369 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4370 if ( aMeshDS == NULL )
4371 return aResult._retn();
4374 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4376 return aResult._retn();
4380 aResult[0] = aNode->X();
4381 aResult[1] = aNode->Y();
4382 aResult[2] = aNode->Z();
4383 return aResult._retn();
4387 //=============================================================================
4389 * For given node returns list of IDs of inverse elements
4390 * If there is not node for given ID - returns empty list
4392 //=============================================================================
4394 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4397 _preMeshInfo->FullLoadFromFile();
4399 SMESH::long_array_var aResult = new SMESH::long_array();
4400 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4401 if ( aMeshDS == NULL )
4402 return aResult._retn();
4405 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4407 return aResult._retn();
4409 // find inverse elements
4410 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4411 aResult->length( aNode->NbInverseElements() );
4412 for( int i = 0; eIt->more(); ++i )
4414 const SMDS_MeshElement* elem = eIt->next();
4415 aResult[ i ] = elem->GetID();
4417 return aResult._retn();
4420 //=============================================================================
4422 * \brief Return position of a node on shape
4424 //=============================================================================
4426 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4429 _preMeshInfo->FullLoadFromFile();
4431 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4432 aNodePosition->shapeID = 0;
4433 aNodePosition->shapeType = GEOM::SHAPE;
4435 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4436 if ( !mesh ) return aNodePosition;
4438 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4440 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4442 aNodePosition->shapeID = aNode->getshapeId();
4443 switch ( pos->GetTypeOfPosition() ) {
4445 aNodePosition->shapeType = GEOM::EDGE;
4446 aNodePosition->params.length(1);
4447 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4449 case SMDS_TOP_FACE: {
4450 SMDS_FacePositionPtr fPos = pos;
4451 aNodePosition->shapeType = GEOM::FACE;
4452 aNodePosition->params.length(2);
4453 aNodePosition->params[0] = fPos->GetUParameter();
4454 aNodePosition->params[1] = fPos->GetVParameter();
4457 case SMDS_TOP_VERTEX:
4458 aNodePosition->shapeType = GEOM::VERTEX;
4460 case SMDS_TOP_3DSPACE:
4461 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4462 aNodePosition->shapeType = GEOM::SOLID;
4463 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4464 aNodePosition->shapeType = GEOM::SHELL;
4470 return aNodePosition;
4473 //=============================================================================
4475 * \brief Return position of an element on shape
4477 //=============================================================================
4479 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4482 _preMeshInfo->FullLoadFromFile();
4484 SMESH::ElementPosition anElementPosition;
4485 anElementPosition.shapeID = 0;
4486 anElementPosition.shapeType = GEOM::SHAPE;
4488 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4489 if ( !mesh ) return anElementPosition;
4491 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4493 anElementPosition.shapeID = anElem->getshapeId();
4494 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4495 if ( !aSp.IsNull() ) {
4496 switch ( aSp.ShapeType() ) {
4498 anElementPosition.shapeType = GEOM::EDGE;
4501 anElementPosition.shapeType = GEOM::FACE;
4504 anElementPosition.shapeType = GEOM::VERTEX;
4507 anElementPosition.shapeType = GEOM::SOLID;
4510 anElementPosition.shapeType = GEOM::SHELL;
4516 return anElementPosition;
4519 //=============================================================================
4521 * If given element is node returns IDs of shape from position
4522 * If there is not node for given ID - returns -1
4524 //=============================================================================
4526 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4529 _preMeshInfo->FullLoadFromFile();
4531 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4532 if ( aMeshDS == NULL )
4536 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4538 return aNode->getshapeId();
4545 //=============================================================================
4547 * For given element returns ID of result shape after
4548 * ::FindShape() from SMESH_MeshEditor
4549 * If there is not element for given ID - returns -1
4551 //=============================================================================
4553 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4556 _preMeshInfo->FullLoadFromFile();
4558 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4559 if ( aMeshDS == NULL )
4562 // try to find element
4563 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4567 ::SMESH_MeshEditor aMeshEditor(_impl);
4568 int index = aMeshEditor.FindShape( elem );
4576 //=============================================================================
4578 * Returns number of nodes for given element
4579 * If there is not element for given ID - returns -1
4581 //=============================================================================
4583 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4586 _preMeshInfo->FullLoadFromFile();
4588 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4589 if ( aMeshDS == NULL ) return -1;
4590 // try to find element
4591 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4592 if(!elem) return -1;
4593 return elem->NbNodes();
4597 //=============================================================================
4599 * Returns ID of node by given index for given element
4600 * If there is not element for given ID - returns -1
4601 * If there is not node for given index - returns -2
4603 //=============================================================================
4605 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4608 _preMeshInfo->FullLoadFromFile();
4610 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4611 if ( aMeshDS == NULL ) return -1;
4612 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4613 if(!elem) return -1;
4614 if( index>=elem->NbNodes() || index<0 ) return -1;
4615 return elem->GetNode(index)->GetID();
4618 //=============================================================================
4620 * Returns IDs of nodes of given element
4622 //=============================================================================
4624 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4627 _preMeshInfo->FullLoadFromFile();
4629 SMESH::long_array_var aResult = new SMESH::long_array();
4630 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4632 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4634 aResult->length( elem->NbNodes() );
4635 for ( int i = 0; i < elem->NbNodes(); ++i )
4636 aResult[ i ] = elem->GetNode( i )->GetID();
4639 return aResult._retn();
4642 //=============================================================================
4644 * Returns true if given node is medium node
4645 * in given quadratic element
4647 //=============================================================================
4649 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4652 _preMeshInfo->FullLoadFromFile();
4654 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4655 if ( aMeshDS == NULL ) return false;
4657 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4658 if(!aNode) return false;
4659 // try to find element
4660 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4661 if(!elem) return false;
4663 return elem->IsMediumNode(aNode);
4667 //=============================================================================
4669 * Returns true if given node is medium node
4670 * in one of quadratic elements
4672 //=============================================================================
4674 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4675 SMESH::ElementType theElemType)
4678 _preMeshInfo->FullLoadFromFile();
4680 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4681 if ( aMeshDS == NULL ) return false;
4684 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4685 if(!aNode) return false;
4687 SMESH_MesherHelper aHelper( *(_impl) );
4689 SMDSAbs_ElementType aType;
4690 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4691 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4692 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4693 else aType = SMDSAbs_All;
4695 return aHelper.IsMedium(aNode,aType);
4699 //=============================================================================
4701 * Returns number of edges for given element
4703 //=============================================================================
4705 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4708 _preMeshInfo->FullLoadFromFile();
4710 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4711 if ( aMeshDS == NULL ) return -1;
4712 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4713 if(!elem) return -1;
4714 return elem->NbEdges();
4718 //=============================================================================
4720 * Returns number of faces for given element
4722 //=============================================================================
4724 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4727 _preMeshInfo->FullLoadFromFile();
4729 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4730 if ( aMeshDS == NULL ) return -1;
4731 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4732 if(!elem) return -1;
4733 return elem->NbFaces();
4736 //=======================================================================
4737 //function : GetElemFaceNodes
4738 //purpose : Returns nodes of given face (counted from zero) for given element.
4739 //=======================================================================
4741 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4742 CORBA::Short faceIndex)
4745 _preMeshInfo->FullLoadFromFile();
4747 SMESH::long_array_var aResult = new SMESH::long_array();
4748 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4750 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4752 SMDS_VolumeTool vtool( elem );
4753 if ( faceIndex < vtool.NbFaces() )
4755 aResult->length( vtool.NbFaceNodes( faceIndex ));
4756 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4757 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4758 aResult[ i ] = nn[ i ]->GetID();
4762 return aResult._retn();
4765 //=======================================================================
4766 //function : GetElemFaceNodes
4767 //purpose : Returns three components of normal of given mesh face.
4768 //=======================================================================
4770 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4771 CORBA::Boolean normalized)
4774 _preMeshInfo->FullLoadFromFile();
4776 SMESH::double_array_var aResult = new SMESH::double_array();
4778 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4781 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4783 aResult->length( 3 );
4784 aResult[ 0 ] = normal.X();
4785 aResult[ 1 ] = normal.Y();
4786 aResult[ 2 ] = normal.Z();
4789 return aResult._retn();
4792 //=======================================================================
4793 //function : FindElementByNodes
4794 //purpose : Returns an element based on all given nodes.
4795 //=======================================================================
4797 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4800 _preMeshInfo->FullLoadFromFile();
4802 CORBA::Long elemID(0);
4803 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4805 vector< const SMDS_MeshNode * > nn( nodes.length() );
4806 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4807 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4810 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4811 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4812 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4813 _impl->NbVolumes( ORDER_QUADRATIC )))
4814 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4816 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4821 //================================================================================
4823 * \brief Return elements including all given nodes.
4825 //================================================================================
4827 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4828 SMESH::ElementType elemType)
4831 _preMeshInfo->FullLoadFromFile();
4833 SMESH::long_array_var result = new SMESH::long_array();
4835 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4837 vector< const SMDS_MeshNode * > nn( nodes.length() );
4838 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4839 nn[i] = mesh->FindNode( nodes[i] );
4841 std::vector<const SMDS_MeshElement *> elems;
4842 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4843 result->length( elems.size() );
4844 for ( size_t i = 0; i < elems.size(); ++i )
4845 result[i] = elems[i]->GetID();
4847 return result._retn();
4850 //=============================================================================
4852 * Returns true if given element is polygon
4854 //=============================================================================
4856 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4859 _preMeshInfo->FullLoadFromFile();
4861 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4862 if ( aMeshDS == NULL ) return false;
4863 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4864 if(!elem) return false;
4865 return elem->IsPoly();
4869 //=============================================================================
4871 * Returns true if given element is quadratic
4873 //=============================================================================
4875 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4878 _preMeshInfo->FullLoadFromFile();
4880 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4881 if ( aMeshDS == NULL ) return false;
4882 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4883 if(!elem) return false;
4884 return elem->IsQuadratic();
4887 //=============================================================================
4889 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4891 //=============================================================================
4893 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4896 _preMeshInfo->FullLoadFromFile();
4898 if ( const SMDS_BallElement* ball =
4899 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4900 return ball->GetDiameter();
4905 //=============================================================================
4907 * Returns bary center for given element
4909 //=============================================================================
4911 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4914 _preMeshInfo->FullLoadFromFile();
4916 SMESH::double_array_var aResult = new SMESH::double_array();
4917 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4918 if ( aMeshDS == NULL )
4919 return aResult._retn();
4921 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4923 return aResult._retn();
4925 if(elem->GetType()==SMDSAbs_Volume) {
4926 SMDS_VolumeTool aTool;
4927 if(aTool.Set(elem)) {
4929 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4934 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4936 double x=0., y=0., z=0.;
4937 for(; anIt->more(); ) {
4939 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4953 return aResult._retn();
4956 //================================================================================
4958 * \brief Create a group of elements preventing computation of a sub-shape
4960 //================================================================================
4962 SMESH::ListOfGroups*
4963 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4964 const char* theGroupName )
4965 throw ( SALOME::SALOME_Exception )
4967 Unexpect aCatch(SALOME_SalomeException);
4969 if ( !theGroupName || strlen( theGroupName) == 0 )
4970 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4972 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4973 ::SMESH_MeshEditor::ElemFeatures elemType;
4975 // submesh by subshape id
4976 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4977 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4980 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4981 if ( error && error->HasBadElems() )
4983 // sort bad elements by type
4984 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4985 const list<const SMDS_MeshElement*>& badElems =
4986 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
4987 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
4988 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
4989 for ( ; elemIt != elemEnd; ++elemIt )
4991 const SMDS_MeshElement* elem = *elemIt;
4992 if ( !elem ) continue;
4994 if ( elem->GetID() < 1 )
4996 // elem is a temporary element, make a real element
4997 vector< const SMDS_MeshNode* > nodes;
4998 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4999 while ( nIt->more() && elem )
5001 nodes.push_back( nIt->next() );
5002 if ( nodes.back()->GetID() < 1 )
5003 elem = 0; // a temporary element on temporary nodes
5007 ::SMESH_MeshEditor editor( _impl );
5008 elem = editor.AddElement( nodes, elemType.Init( elem ));
5012 elemsByType[ elem->GetType() ].push_back( elem );
5015 // how many groups to create?
5017 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5018 nbTypes += int( !elemsByType[ i ].empty() );
5019 groups->length( nbTypes );
5022 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5024 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5025 if ( elems.empty() ) continue;
5027 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5028 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5030 SMESH::SMESH_Mesh_var mesh = _this();
5031 SALOMEDS::SObject_wrap aSO =
5032 _gen_i->PublishGroup( mesh, groups[ iG ],
5033 GEOM::GEOM_Object::_nil(), theGroupName);
5035 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5036 if ( !grp_i ) continue;
5038 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5039 for ( size_t iE = 0; iE < elems.size(); ++iE )
5040 grpDS->SMDSGroup().Add( elems[ iE ]);
5045 return groups._retn();
5048 //=============================================================================
5050 * Create and publish group servants if any groups were imported or created anyhow
5052 //=============================================================================
5054 void SMESH_Mesh_i::CreateGroupServants()
5056 SMESH::SMESH_Mesh_var aMesh = _this();
5059 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5060 while ( groupIt->more() )
5062 ::SMESH_Group* group = groupIt->next();
5063 int anId = group->GetGroupDS()->GetID();
5065 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5066 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5068 addedIDs.insert( anId );
5070 SMESH_GroupBase_i* aGroupImpl;
5072 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5073 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5075 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5076 shape = groupOnGeom->GetShape();
5079 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5082 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5083 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5084 aGroupImpl->Register();
5086 // register CORBA object for persistence
5087 int nextId = _gen_i->RegisterObject( groupVar );
5088 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5089 else { nextId = 0; } // avoid "unused variable" warning in release mode
5091 // publishing the groups in the study
5092 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5093 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5095 if ( !addedIDs.empty() )
5098 set<int>::iterator id = addedIDs.begin();
5099 for ( ; id != addedIDs.end(); ++id )
5101 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5102 int i = std::distance( _mapGroups.begin(), it );
5103 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5108 //=============================================================================
5110 * \brief Return true if all sub-meshes are computed OK - to update an icon
5112 //=============================================================================
5114 bool SMESH_Mesh_i::IsComputedOK()
5116 return _impl->IsComputedOK();
5119 //=============================================================================
5121 * \brief Return groups cantained in _mapGroups by their IDs
5123 //=============================================================================
5125 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5127 int nbGroups = groupIDs.size();
5128 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5129 aList->length( nbGroups );
5131 list<int>::const_iterator ids = groupIDs.begin();
5132 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5134 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5135 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5136 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5138 aList->length( nbGroups );
5139 return aList._retn();
5142 //=============================================================================
5144 * \brief Return information about imported file
5146 //=============================================================================
5148 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5150 SMESH::MedFileInfo_var res( _medFileInfo );
5151 if ( !res.operator->() ) {
5152 res = new SMESH::MedFileInfo;
5154 res->fileSize = res->major = res->minor = res->release = -1;
5159 //=======================================================================
5160 //function : FileInfoToString
5161 //purpose : Persistence of file info
5162 //=======================================================================
5164 std::string SMESH_Mesh_i::FileInfoToString()
5167 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5169 s = SMESH_Comment( _medFileInfo->fileSize )
5170 << " " << _medFileInfo->major
5171 << " " << _medFileInfo->minor
5172 << " " << _medFileInfo->release
5173 << " " << _medFileInfo->fileName;
5178 //=======================================================================
5179 //function : FileInfoFromString
5180 //purpose : Persistence of file info
5181 //=======================================================================
5183 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5185 std::string size, major, minor, release, fileName;
5186 std::istringstream is(info);
5187 is >> size >> major >> minor >> release;
5188 fileName = info.data() + ( size.size() + 1 +
5191 release.size()+ 1 );
5193 _medFileInfo = new SMESH::MedFileInfo();
5194 _medFileInfo->fileName = fileName.c_str();
5195 _medFileInfo->fileSize = atoi( size.c_str() );
5196 _medFileInfo->major = atoi( major.c_str() );
5197 _medFileInfo->minor = atoi( minor.c_str() );
5198 _medFileInfo->release = atoi( release.c_str() );
5201 //=============================================================================
5203 * \brief Pass names of mesh groups from study to mesh DS
5205 //=============================================================================
5207 void SMESH_Mesh_i::checkGroupNames()
5209 int nbGrp = NbGroups();
5213 SMESH::ListOfGroups* grpList = 0;
5214 // avoid dump of "GetGroups"
5216 // store python dump into a local variable inside local scope
5217 SMESH::TPythonDump pDump; // do not delete this line of code
5218 grpList = GetGroups();
5221 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5222 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5225 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5226 if ( aGrpSO->_is_nil() )
5228 // correct name of the mesh group if necessary
5229 const char* guiName = aGrpSO->GetName();
5230 if ( strcmp(guiName, aGrp->GetName()) )
5231 aGrp->SetName( guiName );
5235 //=============================================================================
5237 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5239 //=============================================================================
5240 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5242 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5246 //=============================================================================
5248 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5250 //=============================================================================
5252 char* SMESH_Mesh_i::GetParameters()
5254 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5257 //=============================================================================
5259 * \brief Returns list of notebook variables used for last Mesh operation
5261 //=============================================================================
5262 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5264 SMESH::string_array_var aResult = new SMESH::string_array();
5265 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5267 CORBA::String_var aParameters = GetParameters();
5268 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5269 if ( aSections->length() > 0 ) {
5270 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5271 aResult->length( aVars.length() );
5272 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5273 aResult[i] = CORBA::string_dup( aVars[i] );
5276 return aResult._retn();
5279 //=======================================================================
5280 //function : GetTypes
5281 //purpose : Returns types of elements it contains
5282 //=======================================================================
5284 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5287 return _preMeshInfo->GetTypes();
5289 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5293 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5294 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5295 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5296 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5297 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5298 if (_impl->NbNodes() &&
5299 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5300 types->length( nbTypes );
5302 return types._retn();
5305 //=======================================================================
5306 //function : GetMesh
5307 //purpose : Returns self
5308 //=======================================================================
5310 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5312 return SMESH::SMESH_Mesh::_duplicate( _this() );
5315 //=======================================================================
5316 //function : IsMeshInfoCorrect
5317 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5318 // * happen if mesh data is not yet fully loaded from the file of study.
5319 //=======================================================================
5321 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5323 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5326 //=============================================================================
5328 * \brief Returns number of mesh elements per each \a EntityType
5330 //=============================================================================
5332 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5335 return _preMeshInfo->GetMeshInfo();
5337 SMESH::long_array_var aRes = new SMESH::long_array();
5338 aRes->length(SMESH::Entity_Last);
5339 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5341 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5343 return aRes._retn();
5344 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5345 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5346 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5347 return aRes._retn();
5350 //=============================================================================
5352 * \brief Returns number of mesh elements per each \a ElementType
5354 //=============================================================================
5356 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5358 SMESH::long_array_var aRes = new SMESH::long_array();
5359 aRes->length(SMESH::NB_ELEMENT_TYPES);
5360 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5363 const SMDS_MeshInfo* meshInfo = 0;
5365 meshInfo = _preMeshInfo;
5366 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5367 meshInfo = & meshDS->GetMeshInfo();
5370 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5371 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5373 return aRes._retn();
5376 //=============================================================================
5378 * Collect statistic of mesh elements given by iterator
5380 //=============================================================================
5382 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5383 SMESH::long_array& theInfo)
5385 if (!theItr) return;
5386 while (theItr->more())
5387 theInfo[ theItr->next()->GetEntityType() ]++;
5389 //=============================================================================
5391 * Returns mesh unstructed grid information.
5393 //=============================================================================
5395 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5397 SALOMEDS::TMPFile_var SeqFile;
5398 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5399 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5401 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5402 aWriter->WriteToOutputStringOn();
5403 aWriter->SetInputData(aGrid);
5404 aWriter->SetFileTypeToBinary();
5406 char* str = aWriter->GetOutputString();
5407 int size = aWriter->GetOutputStringLength();
5409 //Allocate octet buffer of required size
5410 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5411 //Copy ostrstream content to the octet buffer
5412 memcpy(OctetBuf, str, size);
5413 //Create and return TMPFile
5414 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5418 return SeqFile._retn();
5421 //=============================================================================
5422 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5423 * SMESH::ElementType type) */
5425 using namespace SMESH::Controls;
5426 //-----------------------------------------------------------------------------
5427 struct PredicateIterator : public SMDS_ElemIterator
5429 SMDS_ElemIteratorPtr _elemIter;
5430 PredicatePtr _predicate;
5431 const SMDS_MeshElement* _elem;
5433 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5434 PredicatePtr predicate):
5435 _elemIter(iterator), _predicate(predicate)
5443 virtual const SMDS_MeshElement* next()
5445 const SMDS_MeshElement* res = _elem;
5447 while ( _elemIter->more() && !_elem )
5449 _elem = _elemIter->next();
5450 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5457 //-----------------------------------------------------------------------------
5458 struct IDSourceIterator : public SMDS_ElemIterator
5460 const CORBA::Long* _idPtr;
5461 const CORBA::Long* _idEndPtr;
5462 SMESH::long_array_var _idArray;
5463 const SMDS_Mesh* _mesh;
5464 const SMDSAbs_ElementType _type;
5465 const SMDS_MeshElement* _elem;
5467 IDSourceIterator( const SMDS_Mesh* mesh,
5468 const CORBA::Long* ids,
5470 SMDSAbs_ElementType type):
5471 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5473 if ( _idPtr && nbIds && _mesh )
5476 IDSourceIterator( const SMDS_Mesh* mesh,
5477 SMESH::long_array* idArray,
5478 SMDSAbs_ElementType type):
5479 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5481 if ( idArray && _mesh )
5483 _idPtr = &_idArray[0];
5484 _idEndPtr = _idPtr + _idArray->length();
5492 virtual const SMDS_MeshElement* next()
5494 const SMDS_MeshElement* res = _elem;
5496 while ( _idPtr < _idEndPtr && !_elem )
5498 if ( _type == SMDSAbs_Node )
5500 _elem = _mesh->FindNode( *_idPtr++ );
5502 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5503 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5511 //-----------------------------------------------------------------------------
5513 struct NodeOfElemIterator : public SMDS_ElemIterator
5515 TColStd_MapOfInteger _checkedNodeIDs;
5516 SMDS_ElemIteratorPtr _elemIter;
5517 SMDS_ElemIteratorPtr _nodeIter;
5518 const SMDS_MeshElement* _node;
5520 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5522 if ( _elemIter && _elemIter->more() )
5524 _nodeIter = _elemIter->next()->nodesIterator();
5532 virtual const SMDS_MeshElement* next()
5534 const SMDS_MeshElement* res = _node;
5536 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5538 if ( _nodeIter->more() )
5540 _node = _nodeIter->next();
5541 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5546 _nodeIter = _elemIter->next()->nodesIterator();
5554 //=============================================================================
5556 * Return iterator on elements of given type in given object
5558 //=============================================================================
5560 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5561 SMESH::ElementType theType)
5563 SMDS_ElemIteratorPtr elemIt;
5564 bool typeOK = ( theType == SMESH::ALL );
5565 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5567 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5568 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5569 if ( !mesh_i ) return elemIt;
5570 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5572 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5574 elemIt = meshDS->elementsIterator( elemType );
5577 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5579 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5582 elemIt = sm->GetElements();
5583 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5585 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5586 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5590 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5592 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5593 if ( groupDS && ( elemType == groupDS->GetType() ||
5594 elemType == SMDSAbs_Node ||
5595 elemType == SMDSAbs_All ))
5597 elemIt = groupDS->GetElements();
5598 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5601 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5603 if ( filter_i->GetElementType() == theType ||
5604 elemType == SMDSAbs_Node ||
5605 elemType == SMDSAbs_All)
5607 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5608 if ( pred_i && pred_i->GetPredicate() )
5610 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5611 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5612 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5613 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5619 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5620 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5621 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5623 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5626 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5627 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5631 SMESH::long_array_var ids = theObject->GetIDs();
5632 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5634 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5637 if ( elemIt && elemIt->more() && !typeOK )
5639 if ( elemType == SMDSAbs_Node )
5641 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5645 elemIt = SMDS_ElemIteratorPtr();
5651 //=============================================================================
5652 namespace // Finding concurrent hypotheses
5653 //=============================================================================
5657 * \brief mapping of mesh dimension into shape type
5659 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5661 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5663 case 0: aType = TopAbs_VERTEX; break;
5664 case 1: aType = TopAbs_EDGE; break;
5665 case 2: aType = TopAbs_FACE; break;
5667 default:aType = TopAbs_SOLID; break;
5672 //-----------------------------------------------------------------------------
5674 * \brief Internal structure used to find concurrent submeshes
5676 * It represents a pair < submesh, concurrent dimension >, where
5677 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5678 * with another submesh. In other words, it is dimension of a hypothesis assigned
5685 int _dim; //!< a dimension the algo can build (concurrent dimension)
5686 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5687 TopTools_MapOfShape _shapeMap;
5688 SMESH_subMesh* _subMesh;
5689 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5691 //-----------------------------------------------------------------------------
5692 // Return the algorithm
5693 const SMESH_Algo* GetAlgo() const
5694 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5696 //-----------------------------------------------------------------------------
5698 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5700 const TopoDS_Shape& theShape)
5702 _subMesh = (SMESH_subMesh*)theSubMesh;
5703 SetShape( theDim, theShape );
5706 //-----------------------------------------------------------------------------
5708 void SetShape(const int theDim,
5709 const TopoDS_Shape& theShape)
5712 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5713 if (_dim >= _ownDim)
5714 _shapeMap.Add( theShape );
5716 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5717 for( ; anExp.More(); anExp.Next() )
5718 _shapeMap.Add( anExp.Current() );
5722 //-----------------------------------------------------------------------------
5723 //! Check sharing of sub-shapes
5724 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5725 const TopTools_MapOfShape& theToFind,
5726 const TopAbs_ShapeEnum theType)
5728 bool isShared = false;
5729 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5730 for (; !isShared && anItr.More(); anItr.Next() )
5732 const TopoDS_Shape aSubSh = anItr.Key();
5733 // check for case when concurrent dimensions are same
5734 isShared = theToFind.Contains( aSubSh );
5735 // check for sub-shape with concurrent dimension
5736 TopExp_Explorer anExp( aSubSh, theType );
5737 for ( ; !isShared && anExp.More(); anExp.Next() )
5738 isShared = theToFind.Contains( anExp.Current() );
5743 //-----------------------------------------------------------------------------
5744 //! check algorithms
5745 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5746 const SMESHDS_Hypothesis* theA2)
5748 if ( !theA1 || !theA2 ||
5749 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5750 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5751 return false; // one of the hypothesis is not algorithm
5752 // check algorithm names (should be equal)
5753 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5757 //-----------------------------------------------------------------------------
5758 //! Check if sub-shape hypotheses are concurrent
5759 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5761 if ( _subMesh == theOther->_subMesh )
5762 return false; // same sub-shape - should not be
5764 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5765 // any of the two submeshes is not on COMPOUND shape )
5766 // -> no concurrency
5767 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5768 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5769 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5770 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5771 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5774 // bool checkSubShape = ( _dim >= theOther->_dim )
5775 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5776 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5777 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5778 if ( !checkSubShape )
5781 // check algorithms to be same
5782 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5783 return true; // different algorithms -> concurrency !
5785 // check hypothesises for concurrence (skip first as algorithm)
5787 // pointers should be same, because it is referened from mesh hypothesis partition
5788 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5789 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5790 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5791 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5793 // the submeshes are concurrent if their algorithms has different parameters
5794 return nbSame != (int)theOther->_hypotheses.size() - 1;
5797 // Return true if algorithm of this SMESH_DimHyp is used if no
5798 // sub-mesh order is imposed by the user
5799 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5801 // NeedDiscreteBoundary() algo has a higher priority
5802 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5803 theOther->GetAlgo()->NeedDiscreteBoundary() )
5804 return !this->GetAlgo()->NeedDiscreteBoundary();
5806 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5809 }; // end of SMESH_DimHyp
5810 //-----------------------------------------------------------------------------
5812 typedef list<const SMESH_DimHyp*> TDimHypList;
5814 //-----------------------------------------------------------------------------
5816 void addDimHypInstance(const int theDim,
5817 const TopoDS_Shape& theShape,
5818 const SMESH_Algo* theAlgo,
5819 const SMESH_subMesh* theSubMesh,
5820 const list <const SMESHDS_Hypothesis*>& theHypList,
5821 TDimHypList* theDimHypListArr )
5823 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5824 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5825 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5826 dimHyp->_hypotheses.push_front(theAlgo);
5827 listOfdimHyp.push_back( dimHyp );
5830 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5831 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5832 theHypList.begin(), theHypList.end() );
5835 //-----------------------------------------------------------------------------
5836 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5837 TDimHypList& theListOfConcurr)
5839 if ( theListOfConcurr.empty() )
5841 theListOfConcurr.push_back( theDimHyp );
5845 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5846 while ( hypIt != theListOfConcurr.end() &&
5847 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5849 theListOfConcurr.insert( hypIt, theDimHyp );
5853 //-----------------------------------------------------------------------------
5854 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5855 const TDimHypList& theListOfDimHyp,
5856 TDimHypList& theListOfConcurrHyp,
5857 set<int>& theSetOfConcurrId )
5859 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5860 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5862 const SMESH_DimHyp* curDimHyp = *rIt;
5863 if ( curDimHyp == theDimHyp )
5864 break; // meet own dimHyp pointer in same dimension
5866 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5867 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5869 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5874 //-----------------------------------------------------------------------------
5875 void unionLists(TListOfInt& theListOfId,
5876 TListOfListOfInt& theListOfListOfId,
5879 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5880 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5882 continue; //skip already treated lists
5883 // check if other list has any same submesh object
5884 TListOfInt& otherListOfId = *it;
5885 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5886 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5889 // union two lists (from source into target)
5890 TListOfInt::iterator it2 = otherListOfId.begin();
5891 for ( ; it2 != otherListOfId.end(); it2++ ) {
5892 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5893 theListOfId.push_back(*it2);
5895 // clear source list
5896 otherListOfId.clear();
5899 //-----------------------------------------------------------------------------
5901 //! free memory allocated for dimension-hypothesis objects
5902 void removeDimHyps( TDimHypList* theArrOfList )
5904 for (int i = 0; i < 4; i++ ) {
5905 TDimHypList& listOfdimHyp = theArrOfList[i];
5906 TDimHypList::const_iterator it = listOfdimHyp.begin();
5907 for ( ; it != listOfdimHyp.end(); it++ )
5912 //-----------------------------------------------------------------------------
5914 * \brief find common submeshes with given submesh
5915 * \param theSubMeshList list of already collected submesh to check
5916 * \param theSubMesh given submesh to intersect with other
5917 * \param theCommonSubMeshes collected common submeshes
5919 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5920 const SMESH_subMesh* theSubMesh,
5921 set<const SMESH_subMesh*>& theCommon )
5925 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5926 for ( ; it != theSubMeshList.end(); it++ )
5927 theSubMesh->FindIntersection( *it, theCommon );
5928 theSubMeshList.push_back( theSubMesh );
5929 //theCommon.insert( theSubMesh );
5932 //-----------------------------------------------------------------------------
5933 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5935 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5936 for ( ; listsIt != smLists.end(); ++listsIt )
5938 const TListOfInt& smIDs = *listsIt;
5939 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5947 //=============================================================================
5949 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5951 //=============================================================================
5953 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5955 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5956 if ( isSubMeshInList( submeshID, anOrder ))
5959 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5960 return isSubMeshInList( submeshID, allConurrent );
5963 //=============================================================================
5965 * \brief Return submesh objects list in meshing order
5967 //=============================================================================
5969 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5971 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5973 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5975 return aResult._retn();
5977 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5978 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5979 anOrder.splice( anOrder.end(), allConurrent );
5982 TListOfListOfInt::iterator listIt = anOrder.begin();
5983 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5984 unionLists( *listIt, anOrder, listIndx + 1 );
5986 // convert submesh ids into interface instances
5987 // and dump command into python
5988 convertMeshOrder( anOrder, aResult, false );
5990 return aResult._retn();
5993 //=============================================================================
5995 * \brief Finds concurrent sub-meshes
5997 //=============================================================================
5999 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6001 TListOfListOfInt anOrder;
6002 ::SMESH_Mesh& mesh = GetImpl();
6004 // collect submeshes and detect concurrent algorithms and hypothesises
6005 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6007 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6008 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6009 ::SMESH_subMesh* sm = (*i_sm).second;
6011 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6013 // list of assigned hypothesises
6014 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6015 // Find out dimensions where the submesh can be concurrent.
6016 // We define the dimensions by algo of each of hypotheses in hypList
6017 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6018 for( ; hypIt != hypList.end(); hypIt++ ) {
6019 SMESH_Algo* anAlgo = 0;
6020 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6021 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6022 // hyp it-self is algo
6023 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6025 // try to find algorithm with help of sub-shapes
6026 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6027 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6028 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6031 continue; // no algorithm assigned to a current submesh
6033 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6034 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6036 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6037 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6038 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6040 } // end iterations on submesh
6042 // iterate on created dimension-hypotheses and check for concurrents
6043 for ( int i = 0; i < 4; i++ ) {
6044 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6045 // check for concurrents in own and other dimensions (step-by-step)
6046 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6047 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6048 const SMESH_DimHyp* dimHyp = *dhIt;
6049 TDimHypList listOfConcurr;
6050 set<int> setOfConcurrIds;
6051 // looking for concurrents and collect into own list
6052 for ( int j = i; j < 4; j++ )
6053 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6054 // check if any concurrents found
6055 if ( listOfConcurr.size() > 0 ) {
6056 // add own submesh to list of concurrent
6057 addInOrderOfPriority( dimHyp, listOfConcurr );
6058 list<int> listOfConcurrIds;
6059 TDimHypList::iterator hypIt = listOfConcurr.begin();
6060 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6061 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6062 anOrder.push_back( listOfConcurrIds );
6067 removeDimHyps(dimHypListArr);
6069 // now, minimize the number of concurrent groups
6070 // Here we assume that lists of submeshes can have same submesh
6071 // in case of multi-dimension algorithms, as result
6072 // list with common submesh has to be united into one list
6074 TListOfListOfInt::iterator listIt = anOrder.begin();
6075 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6076 unionLists( *listIt, anOrder, listIndx + 1 );
6082 //=============================================================================
6084 * \brief Set submesh object order
6085 * \param theSubMeshArray submesh array order
6087 //=============================================================================
6089 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6092 _preMeshInfo->ForgetOrLoad();
6095 ::SMESH_Mesh& mesh = GetImpl();
6097 TPythonDump aPythonDump; // prevent dump of called methods
6098 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6100 TListOfListOfInt subMeshOrder;
6101 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6103 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6104 TListOfInt subMeshIds;
6106 aPythonDump << ", ";
6107 aPythonDump << "[ ";
6108 // Collect subMeshes which should be clear
6109 // do it list-by-list, because modification of submesh order
6110 // take effect between concurrent submeshes only
6111 set<const SMESH_subMesh*> subMeshToClear;
6112 list<const SMESH_subMesh*> subMeshList;
6113 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6115 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6117 aPythonDump << ", ";
6118 aPythonDump << subMesh;
6119 subMeshIds.push_back( subMesh->GetId() );
6120 // detect common parts of submeshes
6121 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6122 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6124 aPythonDump << " ]";
6125 subMeshOrder.push_back( subMeshIds );
6127 // clear collected submeshes
6128 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6129 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6130 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6131 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6133 aPythonDump << " ])";
6135 mesh.SetMeshOrder( subMeshOrder );
6138 SMESH::SMESH_Mesh_var me = _this();
6139 _gen_i->UpdateIcons( me );
6144 //=============================================================================
6146 * \brief Convert submesh ids into submesh interfaces
6148 //=============================================================================
6150 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6151 SMESH::submesh_array_array& theResOrder,
6152 const bool theIsDump)
6154 int nbSet = theIdsOrder.size();
6155 TPythonDump aPythonDump; // prevent dump of called methods
6157 aPythonDump << "[ ";
6158 theResOrder.length(nbSet);
6159 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6161 for( ; it != theIdsOrder.end(); it++ ) {
6162 // translate submesh identificators into submesh objects
6163 // takeing into account real number of concurrent lists
6164 const TListOfInt& aSubOrder = (*it);
6165 if (!aSubOrder.size())
6168 aPythonDump << "[ ";
6169 // convert shape indices into interfaces
6170 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6171 aResSubSet->length(aSubOrder.size());
6172 TListOfInt::const_iterator subIt = aSubOrder.begin();
6174 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6175 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6177 SMESH::SMESH_subMesh_var subMesh =
6178 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6181 aPythonDump << ", ";
6182 aPythonDump << subMesh;
6184 aResSubSet[ j++ ] = subMesh;
6187 aPythonDump << " ]";
6189 theResOrder[ listIndx++ ] = aResSubSet;
6191 // correct number of lists
6192 theResOrder.length( listIndx );
6195 // finilise python dump
6196 aPythonDump << " ]";
6197 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6201 namespace // utils used by SMESH_MeshPartDS
6204 * \brief Class used to access to protected data of SMDS_MeshInfo
6206 struct TMeshInfo : public SMDS_MeshInfo
6208 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6211 * \brief Element holing its ID only
6213 struct TElemID : public SMDS_LinearEdge
6215 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6219 //================================================================================
6221 // Implementation of SMESH_MeshPartDS
6223 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6224 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6226 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6227 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6230 _meshDS = mesh_i->GetImpl().GetMeshDS();
6232 SetPersistentId( _meshDS->GetPersistentId() );
6234 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6236 // <meshPart> is the whole mesh
6237 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6239 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6240 myGroupSet = _meshDS->GetGroups();
6245 SMESH::long_array_var anIDs = meshPart->GetIDs();
6246 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6247 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6249 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6250 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6251 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6256 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6257 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6258 if ( _elements[ e->GetType() ].insert( e ).second )
6261 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6262 while ( nIt->more() )
6264 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6265 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6272 ShapeToMesh( _meshDS->ShapeToMesh() );
6274 _meshDS = 0; // to enforce iteration on _elements and _nodes
6277 // -------------------------------------------------------------------------------------
6278 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6279 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6282 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6283 for ( ; partIt != meshPart.end(); ++partIt )
6284 if ( const SMDS_MeshElement * e = *partIt )
6285 if ( _elements[ e->GetType() ].insert( e ).second )
6288 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6289 while ( nIt->more() )
6291 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6292 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6298 // -------------------------------------------------------------------------------------
6299 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6301 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6303 TElemID elem( IDelem );
6304 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6305 if ( !_elements[ iType ].empty() )
6307 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6308 if ( it != _elements[ iType ].end() )
6313 // -------------------------------------------------------------------------------------
6314 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6316 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6318 typedef SMDS_SetIterator
6319 <const SMDS_MeshElement*,
6320 TIDSortedElemSet::const_iterator,
6321 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6322 SMDS_MeshElement::GeomFilter
6325 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6327 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6328 _elements[type].end(),
6329 SMDS_MeshElement::GeomFilter( geomType )));
6331 // -------------------------------------------------------------------------------------
6332 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6334 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6336 typedef SMDS_SetIterator
6337 <const SMDS_MeshElement*,
6338 TIDSortedElemSet::const_iterator,
6339 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6340 SMDS_MeshElement::EntityFilter
6343 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6345 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6346 _elements[type].end(),
6347 SMDS_MeshElement::EntityFilter( entity )));
6349 // -------------------------------------------------------------------------------------
6350 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6352 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6353 if ( type == SMDSAbs_All && !_meshDS )
6355 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6357 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6358 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6360 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6362 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6363 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6365 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6366 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6368 // -------------------------------------------------------------------------------------
6369 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6370 iterType SMESH_MeshPartDS::methName() const \
6372 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6373 return _meshDS ? _meshDS->methName() : iterType \
6374 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6376 // -------------------------------------------------------------------------------------
6377 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6378 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6379 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6380 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6381 #undef _GET_ITER_DEFINE
6383 // END Implementation of SMESH_MeshPartDS
6385 //================================================================================