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 throw (SALOME::SALOME_Exception)
3218 MESSAGE("MED version: "<< version);
3221 _preMeshInfo->FullLoadFromFile();
3224 bool have0dField = false;
3225 if ( fields.length() > 0 )
3227 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3228 if ( shapeToMesh->_is_nil() )
3229 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3231 for ( size_t i = 0; i < fields.length(); ++i )
3233 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3234 THROW_SALOME_CORBA_EXCEPTION
3235 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3236 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3237 if ( fieldShape->_is_nil() )
3238 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3239 if ( !fieldShape->IsSame( shapeToMesh ) )
3240 THROW_SALOME_CORBA_EXCEPTION
3241 ( "Field defined not on shape", SALOME::BAD_PARAM);
3242 if ( fields[i]->GetDimension() == 0 )
3245 if ( geomAssocFields )
3246 for ( int i = 0; geomAssocFields[i]; ++i )
3247 switch ( geomAssocFields[i] ) {
3248 case 'v':case 'e':case 'f':case 's': break;
3249 case 'V':case 'E':case 'F':case 'S': break;
3250 default: THROW_SALOME_CORBA_EXCEPTION
3251 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3255 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3259 string aMeshName = "Mesh";
3260 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3261 if ( CORBA::is_nil( meshPart ) ||
3262 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3264 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3265 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3266 0, autoDimension, /*addODOnVertices=*/have0dField);
3267 meshDS = _impl->GetMeshDS();
3272 _preMeshInfo->FullLoadFromFile();
3274 PrepareForWriting(file, overwrite);
3276 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3277 if ( !SO->_is_nil() ) {
3278 CORBA::String_var name = SO->GetName();
3282 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3283 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3284 partDS, autoDimension, /*addODOnVertices=*/have0dField);
3285 meshDS = tmpDSDeleter._obj = partDS;
3290 if ( _impl->HasShapeToMesh() )
3292 DriverMED_W_Field fieldWriter;
3293 fieldWriter.SetFile( file );
3294 fieldWriter.SetMeshName( aMeshName );
3295 fieldWriter.AddODOnVertices( have0dField );
3297 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3301 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3302 goList->length( fields.length() );
3303 for ( size_t i = 0; i < fields.length(); ++i )
3305 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3308 TPythonDump() << _this() << ".ExportPartToMED( "
3309 << meshPart << ", r'"
3311 << auto_groups << ", "
3313 << overwrite << ", "
3314 << autoDimension << ", "
3316 << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3318 SMESH_CATCH( SMESH::throwCorbaException );
3321 //================================================================================
3323 * Write GEOM fields to MED file
3325 //================================================================================
3327 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3328 SMESHDS_Mesh* meshDS,
3329 const GEOM::ListOfFields& fields,
3330 const char* geomAssocFields)
3332 #define METH "SMESH_Mesh_i::exportMEDFields() "
3334 if (( fields.length() < 1 ) &&
3335 ( !geomAssocFields || !geomAssocFields[0] ))
3338 std::vector< std::vector< double > > dblVals;
3339 std::vector< std::vector< int > > intVals;
3340 std::vector< int > subIdsByDim[ 4 ];
3341 const double noneDblValue = 0.;
3342 const double noneIntValue = 0;
3344 for ( size_t iF = 0; iF < fields.length(); ++iF )
3348 int dim = fields[ iF ]->GetDimension();
3349 SMDSAbs_ElementType elemType;
3350 TopAbs_ShapeEnum shapeType;
3352 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3353 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3354 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3355 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3357 continue; // skip fields on whole shape
3359 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3360 if ( dataType == GEOM::FDT_String )
3362 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3363 if ( stepIDs->length() < 1 )
3365 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3366 if ( comps->length() < 1 )
3368 CORBA::String_var name = fields[ iF ]->GetName();
3370 if ( !fieldWriter.Set( meshDS,
3374 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3377 for ( size_t iC = 0; iC < comps->length(); ++iC )
3378 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3380 dblVals.resize( comps->length() );
3381 intVals.resize( comps->length() );
3383 // find sub-shape IDs
3385 std::vector< int >& subIds = subIdsByDim[ dim ];
3386 if ( subIds.empty() )
3387 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3388 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3389 subIds.push_back( id );
3393 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3397 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3399 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3400 if ( step->_is_nil() )
3403 CORBA::Long stamp = step->GetStamp();
3404 CORBA::Long id = step->GetID();
3405 fieldWriter.SetDtIt( int( stamp ), int( id ));
3407 // fill dblVals or intVals
3408 for ( size_t iC = 0; iC < comps->length(); ++iC )
3409 if ( dataType == GEOM::FDT_Double )
3411 dblVals[ iC ].clear();
3412 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3416 intVals[ iC ].clear();
3417 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3421 case GEOM::FDT_Double:
3423 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3424 if ( dblStep->_is_nil() ) continue;
3425 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3426 if ( vv->length() != subIds.size() * comps->length() )
3427 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3428 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3429 for ( size_t iC = 0; iC < comps->length(); ++iC )
3430 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3435 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3436 if ( intStep->_is_nil() ) continue;
3437 GEOM::ListOfLong_var vv = intStep->GetValues();
3438 if ( vv->length() != subIds.size() * comps->length() )
3439 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3440 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3441 for ( size_t iC = 0; iC < comps->length(); ++iC )
3442 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3445 case GEOM::FDT_Bool:
3447 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3448 if ( boolStep->_is_nil() ) continue;
3449 GEOM::short_array_var vv = boolStep->GetValues();
3450 if ( vv->length() != subIds.size() * comps->length() )
3451 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3452 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3453 for ( size_t iC = 0; iC < comps->length(); ++iC )
3454 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3460 // pass values to fieldWriter
3461 elemIt = fieldWriter.GetOrderedElems();
3462 if ( dataType == GEOM::FDT_Double )
3463 while ( elemIt->more() )
3465 const SMDS_MeshElement* e = elemIt->next();
3466 const int shapeID = e->getshapeId();
3467 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3468 for ( size_t iC = 0; iC < comps->length(); ++iC )
3469 fieldWriter.AddValue( noneDblValue );
3471 for ( size_t iC = 0; iC < comps->length(); ++iC )
3472 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3475 while ( elemIt->more() )
3477 const SMDS_MeshElement* e = elemIt->next();
3478 const int shapeID = e->getshapeId();
3479 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3480 for ( size_t iC = 0; iC < comps->length(); ++iC )
3481 fieldWriter.AddValue( (double) noneIntValue );
3483 for ( size_t iC = 0; iC < comps->length(); ++iC )
3484 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3488 fieldWriter.Perform();
3489 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3490 if ( res && res->IsKO() )
3492 if ( res->myComment.empty() )
3493 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3495 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3501 if ( !geomAssocFields || !geomAssocFields[0] )
3504 // write geomAssocFields
3506 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3507 shapeDim[ TopAbs_COMPOUND ] = 3;
3508 shapeDim[ TopAbs_COMPSOLID ] = 3;
3509 shapeDim[ TopAbs_SOLID ] = 3;
3510 shapeDim[ TopAbs_SHELL ] = 2;
3511 shapeDim[ TopAbs_FACE ] = 2;
3512 shapeDim[ TopAbs_WIRE ] = 1;
3513 shapeDim[ TopAbs_EDGE ] = 1;
3514 shapeDim[ TopAbs_VERTEX ] = 0;
3515 shapeDim[ TopAbs_SHAPE ] = 3;
3517 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3519 std::vector< std::string > compNames;
3520 switch ( geomAssocFields[ iF ]) {
3522 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3523 compNames.push_back( "dim" );
3526 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3529 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3532 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3536 compNames.push_back( "id" );
3537 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3538 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3540 fieldWriter.SetDtIt( -1, -1 );
3542 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3546 if ( compNames.size() == 2 ) // _vertices_
3547 while ( elemIt->more() )
3549 const SMDS_MeshElement* e = elemIt->next();
3550 const int shapeID = e->getshapeId();
3553 fieldWriter.AddValue( (double) -1 );
3554 fieldWriter.AddValue( (double) -1 );
3558 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3559 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3560 fieldWriter.AddValue( (double) shapeID );
3564 while ( elemIt->more() )
3566 const SMDS_MeshElement* e = elemIt->next();
3567 const int shapeID = e->getshapeId();
3569 fieldWriter.AddValue( (double) -1 );
3571 fieldWriter.AddValue( (double) shapeID );
3575 fieldWriter.Perform();
3576 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3577 if ( res && res->IsKO() )
3579 if ( res->myComment.empty() )
3580 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3582 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3585 } // loop on geomAssocFields
3590 //================================================================================
3592 * \brief Export a part of mesh to a DAT file
3594 //================================================================================
3596 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3598 throw (SALOME::SALOME_Exception)
3600 Unexpect aCatch(SALOME_SalomeException);
3602 _preMeshInfo->FullLoadFromFile();
3604 PrepareForWriting(file);
3606 SMESH_MeshPartDS partDS( meshPart );
3607 _impl->ExportDAT(file,&partDS);
3609 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3610 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3612 //================================================================================
3614 * \brief Export a part of mesh to an UNV file
3616 //================================================================================
3618 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3620 throw (SALOME::SALOME_Exception)
3622 Unexpect aCatch(SALOME_SalomeException);
3624 _preMeshInfo->FullLoadFromFile();
3626 PrepareForWriting(file);
3628 SMESH_MeshPartDS partDS( meshPart );
3629 _impl->ExportUNV(file, &partDS);
3631 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3632 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3634 //================================================================================
3636 * \brief Export a part of mesh to an STL file
3638 //================================================================================
3640 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3642 ::CORBA::Boolean isascii)
3643 throw (SALOME::SALOME_Exception)
3645 Unexpect aCatch(SALOME_SalomeException);
3647 _preMeshInfo->FullLoadFromFile();
3649 PrepareForWriting(file);
3651 CORBA::String_var name;
3652 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3653 if ( !so->_is_nil() )
3654 name = so->GetName();
3656 SMESH_MeshPartDS partDS( meshPart );
3657 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3659 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3660 << meshPart<< ", r'" << file << "', " << isascii << ")";
3663 //================================================================================
3665 * \brief Export a part of mesh to an STL file
3667 //================================================================================
3669 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3671 CORBA::Boolean overwrite,
3672 CORBA::Boolean groupElemsByType)
3673 throw (SALOME::SALOME_Exception)
3676 Unexpect aCatch(SALOME_SalomeException);
3678 _preMeshInfo->FullLoadFromFile();
3680 PrepareForWriting(file,overwrite);
3682 std::string meshName("");
3683 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3684 if ( !so->_is_nil() )
3686 CORBA::String_var name = so->GetName();
3687 meshName = name.in();
3691 SMESH_MeshPartDS partDS( meshPart );
3692 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3694 SMESH_CATCH( SMESH::throwCorbaException );
3696 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3697 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3699 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3703 //================================================================================
3705 * \brief Export a part of mesh to a GMF file
3707 //================================================================================
3709 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3711 bool withRequiredGroups)
3712 throw (SALOME::SALOME_Exception)
3714 Unexpect aCatch(SALOME_SalomeException);
3716 _preMeshInfo->FullLoadFromFile();
3718 PrepareForWriting(file,/*overwrite=*/true);
3720 SMESH_MeshPartDS partDS( meshPart );
3721 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3723 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3724 << meshPart<< ", r'"
3726 << withRequiredGroups << ")";
3729 //=============================================================================
3731 * Return computation progress [0.,1]
3733 //=============================================================================
3735 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3739 return _impl->GetComputeProgress();
3741 SMESH_CATCH( SMESH::doNothing );
3745 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3747 Unexpect aCatch(SALOME_SalomeException);
3749 return _preMeshInfo->NbNodes();
3751 return _impl->NbNodes();
3754 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3756 Unexpect aCatch(SALOME_SalomeException);
3758 return _preMeshInfo->NbElements();
3760 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3763 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3765 Unexpect aCatch(SALOME_SalomeException);
3767 return _preMeshInfo->Nb0DElements();
3769 return _impl->Nb0DElements();
3772 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3774 Unexpect aCatch(SALOME_SalomeException);
3776 return _preMeshInfo->NbBalls();
3778 return _impl->NbBalls();
3781 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3783 Unexpect aCatch(SALOME_SalomeException);
3785 return _preMeshInfo->NbEdges();
3787 return _impl->NbEdges();
3790 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3791 throw(SALOME::SALOME_Exception)
3793 Unexpect aCatch(SALOME_SalomeException);
3795 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3797 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3800 //=============================================================================
3802 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3804 Unexpect aCatch(SALOME_SalomeException);
3806 return _preMeshInfo->NbFaces();
3808 return _impl->NbFaces();
3811 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3813 Unexpect aCatch(SALOME_SalomeException);
3815 return _preMeshInfo->NbTriangles();
3817 return _impl->NbTriangles();
3820 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3822 Unexpect aCatch(SALOME_SalomeException);
3824 return _preMeshInfo->NbBiQuadTriangles();
3826 return _impl->NbBiQuadTriangles();
3829 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3831 Unexpect aCatch(SALOME_SalomeException);
3833 return _preMeshInfo->NbQuadrangles();
3835 return _impl->NbQuadrangles();
3838 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3840 Unexpect aCatch(SALOME_SalomeException);
3842 return _preMeshInfo->NbBiQuadQuadrangles();
3844 return _impl->NbBiQuadQuadrangles();
3847 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3849 Unexpect aCatch(SALOME_SalomeException);
3851 return _preMeshInfo->NbPolygons();
3853 return _impl->NbPolygons();
3856 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3858 Unexpect aCatch(SALOME_SalomeException);
3860 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3862 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3865 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3866 throw(SALOME::SALOME_Exception)
3868 Unexpect aCatch(SALOME_SalomeException);
3870 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3872 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3875 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3876 throw(SALOME::SALOME_Exception)
3878 Unexpect aCatch(SALOME_SalomeException);
3880 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3882 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3885 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3886 throw(SALOME::SALOME_Exception)
3888 Unexpect aCatch(SALOME_SalomeException);
3890 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3892 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3895 //=============================================================================
3897 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3899 Unexpect aCatch(SALOME_SalomeException);
3901 return _preMeshInfo->NbVolumes();
3903 return _impl->NbVolumes();
3906 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3908 Unexpect aCatch(SALOME_SalomeException);
3910 return _preMeshInfo->NbTetras();
3912 return _impl->NbTetras();
3915 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3917 Unexpect aCatch(SALOME_SalomeException);
3919 return _preMeshInfo->NbHexas();
3921 return _impl->NbHexas();
3924 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3926 Unexpect aCatch(SALOME_SalomeException);
3928 return _preMeshInfo->NbTriQuadHexas();
3930 return _impl->NbTriQuadraticHexas();
3933 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3935 Unexpect aCatch(SALOME_SalomeException);
3937 return _preMeshInfo->NbPyramids();
3939 return _impl->NbPyramids();
3942 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3944 Unexpect aCatch(SALOME_SalomeException);
3946 return _preMeshInfo->NbPrisms();
3948 return _impl->NbPrisms();
3951 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3953 Unexpect aCatch(SALOME_SalomeException);
3955 return _preMeshInfo->NbHexPrisms();
3957 return _impl->NbHexagonalPrisms();
3960 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3962 Unexpect aCatch(SALOME_SalomeException);
3964 return _preMeshInfo->NbPolyhedrons();
3966 return _impl->NbPolyhedrons();
3969 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3970 throw(SALOME::SALOME_Exception)
3972 Unexpect aCatch(SALOME_SalomeException);
3974 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3976 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3979 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3980 throw(SALOME::SALOME_Exception)
3982 Unexpect aCatch(SALOME_SalomeException);
3984 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3986 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3989 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3990 throw(SALOME::SALOME_Exception)
3992 Unexpect aCatch(SALOME_SalomeException);
3994 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3996 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3999 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4000 throw(SALOME::SALOME_Exception)
4002 Unexpect aCatch(SALOME_SalomeException);
4004 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4006 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4009 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4010 throw(SALOME::SALOME_Exception)
4012 Unexpect aCatch(SALOME_SalomeException);
4014 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4016 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4019 //=============================================================================
4021 * Returns nb of published sub-meshes
4023 //=============================================================================
4025 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4027 Unexpect aCatch(SALOME_SalomeException);
4028 return _mapSubMesh_i.size();
4031 //=============================================================================
4033 * Dumps mesh into a string
4035 //=============================================================================
4037 char* SMESH_Mesh_i::Dump()
4041 return CORBA::string_dup( os.str().c_str() );
4044 //=============================================================================
4046 * Method of SMESH_IDSource interface
4048 //=============================================================================
4050 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4052 return GetElementsId();
4055 //=============================================================================
4057 * Returns ids of all elements
4059 //=============================================================================
4061 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4062 throw (SALOME::SALOME_Exception)
4064 Unexpect aCatch(SALOME_SalomeException);
4066 _preMeshInfo->FullLoadFromFile();
4068 SMESH::long_array_var aResult = new SMESH::long_array();
4069 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4071 if ( aSMESHDS_Mesh == NULL )
4072 return aResult._retn();
4074 long nbElements = NbElements();
4075 aResult->length( nbElements );
4076 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4077 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4078 aResult[i] = anIt->next()->GetID();
4080 return aResult._retn();
4084 //=============================================================================
4086 * Returns ids of all elements of given type
4088 //=============================================================================
4090 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4091 throw (SALOME::SALOME_Exception)
4093 Unexpect aCatch(SALOME_SalomeException);
4095 _preMeshInfo->FullLoadFromFile();
4097 SMESH::long_array_var aResult = new SMESH::long_array();
4098 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4100 if ( aSMESHDS_Mesh == NULL )
4101 return aResult._retn();
4103 long nbElements = NbElements();
4105 // No sense in returning ids of elements along with ids of nodes:
4106 // when theElemType == SMESH::ALL, return node ids only if
4107 // there are no elements
4108 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4109 return GetNodesId();
4111 aResult->length( nbElements );
4115 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4116 while ( i < nbElements && anIt->more() )
4117 aResult[i++] = anIt->next()->GetID();
4119 aResult->length( i );
4121 return aResult._retn();
4124 //=============================================================================
4126 * Returns ids of all nodes
4128 //=============================================================================
4130 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4131 throw (SALOME::SALOME_Exception)
4133 Unexpect aCatch(SALOME_SalomeException);
4135 _preMeshInfo->FullLoadFromFile();
4137 SMESH::long_array_var aResult = new SMESH::long_array();
4138 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4140 if ( aMeshDS == NULL )
4141 return aResult._retn();
4143 long nbNodes = NbNodes();
4144 aResult->length( nbNodes );
4145 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4146 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4147 aResult[i] = anIt->next()->GetID();
4149 return aResult._retn();
4152 //=============================================================================
4156 //=============================================================================
4158 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4159 throw (SALOME::SALOME_Exception)
4161 SMESH::ElementType type = SMESH::ALL;
4165 _preMeshInfo->FullLoadFromFile();
4167 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4169 SMESH_CATCH( SMESH::throwCorbaException );
4174 //=============================================================================
4178 //=============================================================================
4180 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4181 throw (SALOME::SALOME_Exception)
4184 _preMeshInfo->FullLoadFromFile();
4186 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4188 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4190 return ( SMESH::EntityType ) e->GetEntityType();
4193 //=============================================================================
4197 //=============================================================================
4199 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4200 throw (SALOME::SALOME_Exception)
4203 _preMeshInfo->FullLoadFromFile();
4205 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4207 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4209 return ( SMESH::GeometryType ) e->GetGeomType();
4212 //=============================================================================
4214 * Returns ID of elements for given submesh
4216 //=============================================================================
4217 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4218 throw (SALOME::SALOME_Exception)
4220 SMESH::long_array_var aResult = new SMESH::long_array();
4224 _preMeshInfo->FullLoadFromFile();
4226 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4227 if(!SM) return aResult._retn();
4229 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4230 if(!SDSM) return aResult._retn();
4232 aResult->length(SDSM->NbElements());
4234 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4236 while ( eIt->more() ) {
4237 aResult[i++] = eIt->next()->GetID();
4240 SMESH_CATCH( SMESH::throwCorbaException );
4242 return aResult._retn();
4245 //=============================================================================
4247 * Returns ID of nodes for given submesh
4248 * If param all==true - returns all nodes, else -
4249 * returns only nodes on shapes.
4251 //=============================================================================
4253 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4255 throw (SALOME::SALOME_Exception)
4257 SMESH::long_array_var aResult = new SMESH::long_array();
4261 _preMeshInfo->FullLoadFromFile();
4263 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4264 if(!SM) return aResult._retn();
4266 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4267 if(!SDSM) return aResult._retn();
4270 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4271 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4272 while ( nIt->more() ) {
4273 const SMDS_MeshNode* elem = nIt->next();
4274 theElems.insert( elem->GetID() );
4277 else { // all nodes of submesh elements
4278 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4279 while ( eIt->more() ) {
4280 const SMDS_MeshElement* anElem = eIt->next();
4281 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4282 while ( nIt->more() ) {
4283 const SMDS_MeshElement* elem = nIt->next();
4284 theElems.insert( elem->GetID() );
4289 aResult->length(theElems.size());
4290 set<int>::iterator itElem;
4292 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4293 aResult[i++] = *itElem;
4295 SMESH_CATCH( SMESH::throwCorbaException );
4297 return aResult._retn();
4300 //=============================================================================
4302 * Returns type of elements for given submesh
4304 //=============================================================================
4306 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4307 throw (SALOME::SALOME_Exception)
4309 SMESH::ElementType type = SMESH::ALL;
4313 _preMeshInfo->FullLoadFromFile();
4315 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4316 if(!SM) return SMESH::ALL;
4318 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4319 if(!SDSM) return SMESH::ALL;
4321 if(SDSM->NbElements()==0)
4322 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4324 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4325 const SMDS_MeshElement* anElem = eIt->next();
4327 type = ( SMESH::ElementType ) anElem->GetType();
4329 SMESH_CATCH( SMESH::throwCorbaException );
4335 //=============================================================================
4337 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4339 //=============================================================================
4341 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4344 _preMeshInfo->FullLoadFromFile();
4346 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4347 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4352 //=============================================================================
4354 * Get XYZ coordinates of node as list of double
4355 * If there is not node for given ID - returns empty list
4357 //=============================================================================
4359 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4362 _preMeshInfo->FullLoadFromFile();
4364 SMESH::double_array_var aResult = new SMESH::double_array();
4365 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4366 if ( aMeshDS == NULL )
4367 return aResult._retn();
4370 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4372 return aResult._retn();
4376 aResult[0] = aNode->X();
4377 aResult[1] = aNode->Y();
4378 aResult[2] = aNode->Z();
4379 return aResult._retn();
4383 //=============================================================================
4385 * For given node returns list of IDs of inverse elements
4386 * If there is not node for given ID - returns empty list
4388 //=============================================================================
4390 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4393 _preMeshInfo->FullLoadFromFile();
4395 SMESH::long_array_var aResult = new SMESH::long_array();
4396 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4397 if ( aMeshDS == NULL )
4398 return aResult._retn();
4401 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4403 return aResult._retn();
4405 // find inverse elements
4406 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4407 aResult->length( aNode->NbInverseElements() );
4408 for( int i = 0; eIt->more(); ++i )
4410 const SMDS_MeshElement* elem = eIt->next();
4411 aResult[ i ] = elem->GetID();
4413 return aResult._retn();
4416 //=============================================================================
4418 * \brief Return position of a node on shape
4420 //=============================================================================
4422 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4425 _preMeshInfo->FullLoadFromFile();
4427 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4428 aNodePosition->shapeID = 0;
4429 aNodePosition->shapeType = GEOM::SHAPE;
4431 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4432 if ( !mesh ) return aNodePosition;
4434 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4436 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4438 aNodePosition->shapeID = aNode->getshapeId();
4439 switch ( pos->GetTypeOfPosition() ) {
4441 aNodePosition->shapeType = GEOM::EDGE;
4442 aNodePosition->params.length(1);
4443 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4445 case SMDS_TOP_FACE: {
4446 SMDS_FacePositionPtr fPos = pos;
4447 aNodePosition->shapeType = GEOM::FACE;
4448 aNodePosition->params.length(2);
4449 aNodePosition->params[0] = fPos->GetUParameter();
4450 aNodePosition->params[1] = fPos->GetVParameter();
4453 case SMDS_TOP_VERTEX:
4454 aNodePosition->shapeType = GEOM::VERTEX;
4456 case SMDS_TOP_3DSPACE:
4457 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4458 aNodePosition->shapeType = GEOM::SOLID;
4459 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4460 aNodePosition->shapeType = GEOM::SHELL;
4466 return aNodePosition;
4469 //=============================================================================
4471 * \brief Return position of an element on shape
4473 //=============================================================================
4475 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4478 _preMeshInfo->FullLoadFromFile();
4480 SMESH::ElementPosition anElementPosition;
4481 anElementPosition.shapeID = 0;
4482 anElementPosition.shapeType = GEOM::SHAPE;
4484 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4485 if ( !mesh ) return anElementPosition;
4487 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4489 anElementPosition.shapeID = anElem->getshapeId();
4490 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4491 if ( !aSp.IsNull() ) {
4492 switch ( aSp.ShapeType() ) {
4494 anElementPosition.shapeType = GEOM::EDGE;
4497 anElementPosition.shapeType = GEOM::FACE;
4500 anElementPosition.shapeType = GEOM::VERTEX;
4503 anElementPosition.shapeType = GEOM::SOLID;
4506 anElementPosition.shapeType = GEOM::SHELL;
4512 return anElementPosition;
4515 //=============================================================================
4517 * If given element is node returns IDs of shape from position
4518 * If there is not node for given ID - returns -1
4520 //=============================================================================
4522 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4525 _preMeshInfo->FullLoadFromFile();
4527 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4528 if ( aMeshDS == NULL )
4532 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4534 return aNode->getshapeId();
4541 //=============================================================================
4543 * For given element returns ID of result shape after
4544 * ::FindShape() from SMESH_MeshEditor
4545 * If there is not element for given ID - returns -1
4547 //=============================================================================
4549 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4552 _preMeshInfo->FullLoadFromFile();
4554 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4555 if ( aMeshDS == NULL )
4558 // try to find element
4559 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4563 ::SMESH_MeshEditor aMeshEditor(_impl);
4564 int index = aMeshEditor.FindShape( elem );
4572 //=============================================================================
4574 * Returns number of nodes for given element
4575 * If there is not element for given ID - returns -1
4577 //=============================================================================
4579 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4582 _preMeshInfo->FullLoadFromFile();
4584 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4585 if ( aMeshDS == NULL ) return -1;
4586 // try to find element
4587 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4588 if(!elem) return -1;
4589 return elem->NbNodes();
4593 //=============================================================================
4595 * Returns ID of node by given index for given element
4596 * If there is not element for given ID - returns -1
4597 * If there is not node for given index - returns -2
4599 //=============================================================================
4601 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4604 _preMeshInfo->FullLoadFromFile();
4606 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4607 if ( aMeshDS == NULL ) return -1;
4608 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4609 if(!elem) return -1;
4610 if( index>=elem->NbNodes() || index<0 ) return -1;
4611 return elem->GetNode(index)->GetID();
4614 //=============================================================================
4616 * Returns IDs of nodes of given element
4618 //=============================================================================
4620 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4623 _preMeshInfo->FullLoadFromFile();
4625 SMESH::long_array_var aResult = new SMESH::long_array();
4626 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4628 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4630 aResult->length( elem->NbNodes() );
4631 for ( int i = 0; i < elem->NbNodes(); ++i )
4632 aResult[ i ] = elem->GetNode( i )->GetID();
4635 return aResult._retn();
4638 //=============================================================================
4640 * Returns true if given node is medium node
4641 * in given quadratic element
4643 //=============================================================================
4645 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4648 _preMeshInfo->FullLoadFromFile();
4650 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4651 if ( aMeshDS == NULL ) return false;
4653 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4654 if(!aNode) return false;
4655 // try to find element
4656 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4657 if(!elem) return false;
4659 return elem->IsMediumNode(aNode);
4663 //=============================================================================
4665 * Returns true if given node is medium node
4666 * in one of quadratic elements
4668 //=============================================================================
4670 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4671 SMESH::ElementType theElemType)
4674 _preMeshInfo->FullLoadFromFile();
4676 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4677 if ( aMeshDS == NULL ) return false;
4680 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4681 if(!aNode) return false;
4683 SMESH_MesherHelper aHelper( *(_impl) );
4685 SMDSAbs_ElementType aType;
4686 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4687 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4688 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4689 else aType = SMDSAbs_All;
4691 return aHelper.IsMedium(aNode,aType);
4695 //=============================================================================
4697 * Returns number of edges for given element
4699 //=============================================================================
4701 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4704 _preMeshInfo->FullLoadFromFile();
4706 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4707 if ( aMeshDS == NULL ) return -1;
4708 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4709 if(!elem) return -1;
4710 return elem->NbEdges();
4714 //=============================================================================
4716 * Returns number of faces for given element
4718 //=============================================================================
4720 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4723 _preMeshInfo->FullLoadFromFile();
4725 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4726 if ( aMeshDS == NULL ) return -1;
4727 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4728 if(!elem) return -1;
4729 return elem->NbFaces();
4732 //=======================================================================
4733 //function : GetElemFaceNodes
4734 //purpose : Returns nodes of given face (counted from zero) for given element.
4735 //=======================================================================
4737 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4738 CORBA::Short faceIndex)
4741 _preMeshInfo->FullLoadFromFile();
4743 SMESH::long_array_var aResult = new SMESH::long_array();
4744 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4746 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4748 SMDS_VolumeTool vtool( elem );
4749 if ( faceIndex < vtool.NbFaces() )
4751 aResult->length( vtool.NbFaceNodes( faceIndex ));
4752 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4753 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4754 aResult[ i ] = nn[ i ]->GetID();
4758 return aResult._retn();
4761 //=======================================================================
4762 //function : GetElemFaceNodes
4763 //purpose : Returns three components of normal of given mesh face.
4764 //=======================================================================
4766 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4767 CORBA::Boolean normalized)
4770 _preMeshInfo->FullLoadFromFile();
4772 SMESH::double_array_var aResult = new SMESH::double_array();
4774 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4777 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4779 aResult->length( 3 );
4780 aResult[ 0 ] = normal.X();
4781 aResult[ 1 ] = normal.Y();
4782 aResult[ 2 ] = normal.Z();
4785 return aResult._retn();
4788 //=======================================================================
4789 //function : FindElementByNodes
4790 //purpose : Returns an element based on all given nodes.
4791 //=======================================================================
4793 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4796 _preMeshInfo->FullLoadFromFile();
4798 CORBA::Long elemID(0);
4799 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4801 vector< const SMDS_MeshNode * > nn( nodes.length() );
4802 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4803 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4806 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4807 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4808 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4809 _impl->NbVolumes( ORDER_QUADRATIC )))
4810 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4812 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4817 //================================================================================
4819 * \brief Return elements including all given nodes.
4821 //================================================================================
4823 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4824 SMESH::ElementType elemType)
4827 _preMeshInfo->FullLoadFromFile();
4829 SMESH::long_array_var result = new SMESH::long_array();
4831 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4833 vector< const SMDS_MeshNode * > nn( nodes.length() );
4834 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4835 nn[i] = mesh->FindNode( nodes[i] );
4837 std::vector<const SMDS_MeshElement *> elems;
4838 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4839 result->length( elems.size() );
4840 for ( size_t i = 0; i < elems.size(); ++i )
4841 result[i] = elems[i]->GetID();
4843 return result._retn();
4846 //=============================================================================
4848 * Returns true if given element is polygon
4850 //=============================================================================
4852 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4855 _preMeshInfo->FullLoadFromFile();
4857 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4858 if ( aMeshDS == NULL ) return false;
4859 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4860 if(!elem) return false;
4861 return elem->IsPoly();
4865 //=============================================================================
4867 * Returns true if given element is quadratic
4869 //=============================================================================
4871 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4874 _preMeshInfo->FullLoadFromFile();
4876 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4877 if ( aMeshDS == NULL ) return false;
4878 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4879 if(!elem) return false;
4880 return elem->IsQuadratic();
4883 //=============================================================================
4885 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4887 //=============================================================================
4889 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4892 _preMeshInfo->FullLoadFromFile();
4894 if ( const SMDS_BallElement* ball =
4895 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4896 return ball->GetDiameter();
4901 //=============================================================================
4903 * Returns bary center for given element
4905 //=============================================================================
4907 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4910 _preMeshInfo->FullLoadFromFile();
4912 SMESH::double_array_var aResult = new SMESH::double_array();
4913 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4914 if ( aMeshDS == NULL )
4915 return aResult._retn();
4917 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4919 return aResult._retn();
4921 if(elem->GetType()==SMDSAbs_Volume) {
4922 SMDS_VolumeTool aTool;
4923 if(aTool.Set(elem)) {
4925 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4930 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4932 double x=0., y=0., z=0.;
4933 for(; anIt->more(); ) {
4935 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4949 return aResult._retn();
4952 //================================================================================
4954 * \brief Create a group of elements preventing computation of a sub-shape
4956 //================================================================================
4958 SMESH::ListOfGroups*
4959 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4960 const char* theGroupName )
4961 throw ( SALOME::SALOME_Exception )
4963 Unexpect aCatch(SALOME_SalomeException);
4965 if ( !theGroupName || strlen( theGroupName) == 0 )
4966 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4968 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4969 ::SMESH_MeshEditor::ElemFeatures elemType;
4971 // submesh by subshape id
4972 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4973 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4976 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4977 if ( error && error->HasBadElems() )
4979 // sort bad elements by type
4980 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4981 const list<const SMDS_MeshElement*>& badElems =
4982 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
4983 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
4984 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
4985 for ( ; elemIt != elemEnd; ++elemIt )
4987 const SMDS_MeshElement* elem = *elemIt;
4988 if ( !elem ) continue;
4990 if ( elem->GetID() < 1 )
4992 // elem is a temporary element, make a real element
4993 vector< const SMDS_MeshNode* > nodes;
4994 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4995 while ( nIt->more() && elem )
4997 nodes.push_back( nIt->next() );
4998 if ( nodes.back()->GetID() < 1 )
4999 elem = 0; // a temporary element on temporary nodes
5003 ::SMESH_MeshEditor editor( _impl );
5004 elem = editor.AddElement( nodes, elemType.Init( elem ));
5008 elemsByType[ elem->GetType() ].push_back( elem );
5011 // how many groups to create?
5013 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5014 nbTypes += int( !elemsByType[ i ].empty() );
5015 groups->length( nbTypes );
5018 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5020 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5021 if ( elems.empty() ) continue;
5023 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5024 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5026 SMESH::SMESH_Mesh_var mesh = _this();
5027 SALOMEDS::SObject_wrap aSO =
5028 _gen_i->PublishGroup( mesh, groups[ iG ],
5029 GEOM::GEOM_Object::_nil(), theGroupName);
5031 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5032 if ( !grp_i ) continue;
5034 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5035 for ( size_t iE = 0; iE < elems.size(); ++iE )
5036 grpDS->SMDSGroup().Add( elems[ iE ]);
5041 return groups._retn();
5044 //=============================================================================
5046 * Create and publish group servants if any groups were imported or created anyhow
5048 //=============================================================================
5050 void SMESH_Mesh_i::CreateGroupServants()
5052 SMESH::SMESH_Mesh_var aMesh = _this();
5055 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5056 while ( groupIt->more() )
5058 ::SMESH_Group* group = groupIt->next();
5059 int anId = group->GetGroupDS()->GetID();
5061 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5062 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5064 addedIDs.insert( anId );
5066 SMESH_GroupBase_i* aGroupImpl;
5068 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5069 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5071 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5072 shape = groupOnGeom->GetShape();
5075 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5078 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5079 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5080 aGroupImpl->Register();
5082 // register CORBA object for persistence
5083 int nextId = _gen_i->RegisterObject( groupVar );
5084 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5085 else { nextId = 0; } // avoid "unused variable" warning in release mode
5087 // publishing the groups in the study
5088 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5089 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5091 if ( !addedIDs.empty() )
5094 set<int>::iterator id = addedIDs.begin();
5095 for ( ; id != addedIDs.end(); ++id )
5097 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5098 int i = std::distance( _mapGroups.begin(), it );
5099 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5104 //=============================================================================
5106 * \brief Return true if all sub-meshes are computed OK - to update an icon
5108 //=============================================================================
5110 bool SMESH_Mesh_i::IsComputedOK()
5112 return _impl->IsComputedOK();
5115 //=============================================================================
5117 * \brief Return groups cantained in _mapGroups by their IDs
5119 //=============================================================================
5121 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5123 int nbGroups = groupIDs.size();
5124 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5125 aList->length( nbGroups );
5127 list<int>::const_iterator ids = groupIDs.begin();
5128 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5130 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5131 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5132 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5134 aList->length( nbGroups );
5135 return aList._retn();
5138 //=============================================================================
5140 * \brief Return information about imported file
5142 //=============================================================================
5144 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5146 SMESH::MedFileInfo_var res( _medFileInfo );
5147 if ( !res.operator->() ) {
5148 res = new SMESH::MedFileInfo;
5150 res->fileSize = res->major = res->minor = res->release = -1;
5155 //=======================================================================
5156 //function : FileInfoToString
5157 //purpose : Persistence of file info
5158 //=======================================================================
5160 std::string SMESH_Mesh_i::FileInfoToString()
5163 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5165 s = SMESH_Comment( _medFileInfo->fileSize )
5166 << " " << _medFileInfo->major
5167 << " " << _medFileInfo->minor
5168 << " " << _medFileInfo->release
5169 << " " << _medFileInfo->fileName;
5174 //=======================================================================
5175 //function : FileInfoFromString
5176 //purpose : Persistence of file info
5177 //=======================================================================
5179 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5181 std::string size, major, minor, release, fileName;
5182 std::istringstream is(info);
5183 is >> size >> major >> minor >> release;
5184 fileName = info.data() + ( size.size() + 1 +
5187 release.size()+ 1 );
5189 _medFileInfo = new SMESH::MedFileInfo();
5190 _medFileInfo->fileName = fileName.c_str();
5191 _medFileInfo->fileSize = atoi( size.c_str() );
5192 _medFileInfo->major = atoi( major.c_str() );
5193 _medFileInfo->minor = atoi( minor.c_str() );
5194 _medFileInfo->release = atoi( release.c_str() );
5197 //=============================================================================
5199 * \brief Pass names of mesh groups from study to mesh DS
5201 //=============================================================================
5203 void SMESH_Mesh_i::checkGroupNames()
5205 int nbGrp = NbGroups();
5209 SMESH::ListOfGroups* grpList = 0;
5210 // avoid dump of "GetGroups"
5212 // store python dump into a local variable inside local scope
5213 SMESH::TPythonDump pDump; // do not delete this line of code
5214 grpList = GetGroups();
5217 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5218 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5221 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5222 if ( aGrpSO->_is_nil() )
5224 // correct name of the mesh group if necessary
5225 const char* guiName = aGrpSO->GetName();
5226 if ( strcmp(guiName, aGrp->GetName()) )
5227 aGrp->SetName( guiName );
5231 //=============================================================================
5233 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5235 //=============================================================================
5236 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5238 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5242 //=============================================================================
5244 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5246 //=============================================================================
5248 char* SMESH_Mesh_i::GetParameters()
5250 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5253 //=============================================================================
5255 * \brief Returns list of notebook variables used for last Mesh operation
5257 //=============================================================================
5258 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5260 SMESH::string_array_var aResult = new SMESH::string_array();
5261 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5263 CORBA::String_var aParameters = GetParameters();
5264 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5265 if ( aSections->length() > 0 ) {
5266 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5267 aResult->length( aVars.length() );
5268 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5269 aResult[i] = CORBA::string_dup( aVars[i] );
5272 return aResult._retn();
5275 //=======================================================================
5276 //function : GetTypes
5277 //purpose : Returns types of elements it contains
5278 //=======================================================================
5280 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5283 return _preMeshInfo->GetTypes();
5285 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5289 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5290 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5291 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5292 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5293 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5294 if (_impl->NbNodes() &&
5295 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5296 types->length( nbTypes );
5298 return types._retn();
5301 //=======================================================================
5302 //function : GetMesh
5303 //purpose : Returns self
5304 //=======================================================================
5306 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5308 return SMESH::SMESH_Mesh::_duplicate( _this() );
5311 //=======================================================================
5312 //function : IsMeshInfoCorrect
5313 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5314 // * happen if mesh data is not yet fully loaded from the file of study.
5315 //=======================================================================
5317 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5319 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5322 //=============================================================================
5324 * \brief Returns number of mesh elements per each \a EntityType
5326 //=============================================================================
5328 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5331 return _preMeshInfo->GetMeshInfo();
5333 SMESH::long_array_var aRes = new SMESH::long_array();
5334 aRes->length(SMESH::Entity_Last);
5335 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5337 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5339 return aRes._retn();
5340 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5341 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5342 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5343 return aRes._retn();
5346 //=============================================================================
5348 * \brief Returns number of mesh elements per each \a ElementType
5350 //=============================================================================
5352 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5354 SMESH::long_array_var aRes = new SMESH::long_array();
5355 aRes->length(SMESH::NB_ELEMENT_TYPES);
5356 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5359 const SMDS_MeshInfo* meshInfo = 0;
5361 meshInfo = _preMeshInfo;
5362 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5363 meshInfo = & meshDS->GetMeshInfo();
5366 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5367 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5369 return aRes._retn();
5372 //=============================================================================
5374 * Collect statistic of mesh elements given by iterator
5376 //=============================================================================
5378 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5379 SMESH::long_array& theInfo)
5381 if (!theItr) return;
5382 while (theItr->more())
5383 theInfo[ theItr->next()->GetEntityType() ]++;
5385 //=============================================================================
5387 * Returns mesh unstructed grid information.
5389 //=============================================================================
5391 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5393 SALOMEDS::TMPFile_var SeqFile;
5394 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5395 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5397 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5398 aWriter->WriteToOutputStringOn();
5399 aWriter->SetInputData(aGrid);
5400 aWriter->SetFileTypeToBinary();
5402 char* str = aWriter->GetOutputString();
5403 int size = aWriter->GetOutputStringLength();
5405 //Allocate octect buffer of required size
5406 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5407 //Copy ostrstream content to the octect buffer
5408 memcpy(OctetBuf, str, size);
5409 //Create and return TMPFile
5410 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5414 return SeqFile._retn();
5417 //=============================================================================
5418 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5419 * SMESH::ElementType type) */
5421 using namespace SMESH::Controls;
5422 //-----------------------------------------------------------------------------
5423 struct PredicateIterator : public SMDS_ElemIterator
5425 SMDS_ElemIteratorPtr _elemIter;
5426 PredicatePtr _predicate;
5427 const SMDS_MeshElement* _elem;
5429 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5430 PredicatePtr predicate):
5431 _elemIter(iterator), _predicate(predicate)
5439 virtual const SMDS_MeshElement* next()
5441 const SMDS_MeshElement* res = _elem;
5443 while ( _elemIter->more() && !_elem )
5445 _elem = _elemIter->next();
5446 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5453 //-----------------------------------------------------------------------------
5454 struct IDSourceIterator : public SMDS_ElemIterator
5456 const CORBA::Long* _idPtr;
5457 const CORBA::Long* _idEndPtr;
5458 SMESH::long_array_var _idArray;
5459 const SMDS_Mesh* _mesh;
5460 const SMDSAbs_ElementType _type;
5461 const SMDS_MeshElement* _elem;
5463 IDSourceIterator( const SMDS_Mesh* mesh,
5464 const CORBA::Long* ids,
5466 SMDSAbs_ElementType type):
5467 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5469 if ( _idPtr && nbIds && _mesh )
5472 IDSourceIterator( const SMDS_Mesh* mesh,
5473 SMESH::long_array* idArray,
5474 SMDSAbs_ElementType type):
5475 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5477 if ( idArray && _mesh )
5479 _idPtr = &_idArray[0];
5480 _idEndPtr = _idPtr + _idArray->length();
5488 virtual const SMDS_MeshElement* next()
5490 const SMDS_MeshElement* res = _elem;
5492 while ( _idPtr < _idEndPtr && !_elem )
5494 if ( _type == SMDSAbs_Node )
5496 _elem = _mesh->FindNode( *_idPtr++ );
5498 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5499 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5507 //-----------------------------------------------------------------------------
5509 struct NodeOfElemIterator : public SMDS_ElemIterator
5511 TColStd_MapOfInteger _checkedNodeIDs;
5512 SMDS_ElemIteratorPtr _elemIter;
5513 SMDS_ElemIteratorPtr _nodeIter;
5514 const SMDS_MeshElement* _node;
5516 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5518 if ( _elemIter && _elemIter->more() )
5520 _nodeIter = _elemIter->next()->nodesIterator();
5528 virtual const SMDS_MeshElement* next()
5530 const SMDS_MeshElement* res = _node;
5532 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5534 if ( _nodeIter->more() )
5536 _node = _nodeIter->next();
5537 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5542 _nodeIter = _elemIter->next()->nodesIterator();
5550 //=============================================================================
5552 * Return iterator on elements of given type in given object
5554 //=============================================================================
5556 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5557 SMESH::ElementType theType)
5559 SMDS_ElemIteratorPtr elemIt;
5560 bool typeOK = ( theType == SMESH::ALL );
5561 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5563 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5564 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5565 if ( !mesh_i ) return elemIt;
5566 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5568 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5570 elemIt = meshDS->elementsIterator( elemType );
5573 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5575 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5578 elemIt = sm->GetElements();
5579 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5581 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5582 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5586 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5588 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5589 if ( groupDS && ( elemType == groupDS->GetType() ||
5590 elemType == SMDSAbs_Node ||
5591 elemType == SMDSAbs_All ))
5593 elemIt = groupDS->GetElements();
5594 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5597 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5599 if ( filter_i->GetElementType() == theType ||
5600 elemType == SMDSAbs_Node ||
5601 elemType == SMDSAbs_All)
5603 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5604 if ( pred_i && pred_i->GetPredicate() )
5606 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5607 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5608 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5609 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5615 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5616 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5617 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5619 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5622 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5623 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5627 SMESH::long_array_var ids = theObject->GetIDs();
5628 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5630 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5633 if ( elemIt && elemIt->more() && !typeOK )
5635 if ( elemType == SMDSAbs_Node )
5637 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5641 elemIt = SMDS_ElemIteratorPtr();
5647 //=============================================================================
5648 namespace // Finding concurrent hypotheses
5649 //=============================================================================
5653 * \brief mapping of mesh dimension into shape type
5655 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5657 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5659 case 0: aType = TopAbs_VERTEX; break;
5660 case 1: aType = TopAbs_EDGE; break;
5661 case 2: aType = TopAbs_FACE; break;
5663 default:aType = TopAbs_SOLID; break;
5668 //-----------------------------------------------------------------------------
5670 * \brief Internal structure used to find concurrent submeshes
5672 * It represents a pair < submesh, concurrent dimension >, where
5673 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5674 * with another submesh. In other words, it is dimension of a hypothesis assigned
5681 int _dim; //!< a dimension the algo can build (concurrent dimension)
5682 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5683 TopTools_MapOfShape _shapeMap;
5684 SMESH_subMesh* _subMesh;
5685 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5687 //-----------------------------------------------------------------------------
5688 // Return the algorithm
5689 const SMESH_Algo* GetAlgo() const
5690 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5692 //-----------------------------------------------------------------------------
5694 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5696 const TopoDS_Shape& theShape)
5698 _subMesh = (SMESH_subMesh*)theSubMesh;
5699 SetShape( theDim, theShape );
5702 //-----------------------------------------------------------------------------
5704 void SetShape(const int theDim,
5705 const TopoDS_Shape& theShape)
5708 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5709 if (_dim >= _ownDim)
5710 _shapeMap.Add( theShape );
5712 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5713 for( ; anExp.More(); anExp.Next() )
5714 _shapeMap.Add( anExp.Current() );
5718 //-----------------------------------------------------------------------------
5719 //! Check sharing of sub-shapes
5720 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5721 const TopTools_MapOfShape& theToFind,
5722 const TopAbs_ShapeEnum theType)
5724 bool isShared = false;
5725 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5726 for (; !isShared && anItr.More(); anItr.Next() )
5728 const TopoDS_Shape aSubSh = anItr.Key();
5729 // check for case when concurrent dimensions are same
5730 isShared = theToFind.Contains( aSubSh );
5731 // check for sub-shape with concurrent dimension
5732 TopExp_Explorer anExp( aSubSh, theType );
5733 for ( ; !isShared && anExp.More(); anExp.Next() )
5734 isShared = theToFind.Contains( anExp.Current() );
5739 //-----------------------------------------------------------------------------
5740 //! check algorithms
5741 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5742 const SMESHDS_Hypothesis* theA2)
5744 if ( !theA1 || !theA2 ||
5745 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5746 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5747 return false; // one of the hypothesis is not algorithm
5748 // check algorithm names (should be equal)
5749 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5753 //-----------------------------------------------------------------------------
5754 //! Check if sub-shape hypotheses are concurrent
5755 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5757 if ( _subMesh == theOther->_subMesh )
5758 return false; // same sub-shape - should not be
5760 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5761 // any of the two submeshes is not on COMPOUND shape )
5762 // -> no concurrency
5763 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5764 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5765 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5766 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5767 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5770 // bool checkSubShape = ( _dim >= theOther->_dim )
5771 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5772 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5773 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5774 if ( !checkSubShape )
5777 // check algorithms to be same
5778 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5779 return true; // different algorithms -> concurrency !
5781 // check hypothesises for concurrence (skip first as algorithm)
5783 // pointers should be same, because it is referened from mesh hypothesis partition
5784 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5785 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5786 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5787 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5789 // the submeshes are concurrent if their algorithms has different parameters
5790 return nbSame != (int)theOther->_hypotheses.size() - 1;
5793 // Return true if algorithm of this SMESH_DimHyp is used if no
5794 // sub-mesh order is imposed by the user
5795 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5797 // NeedDiscreteBoundary() algo has a higher priority
5798 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5799 theOther->GetAlgo()->NeedDiscreteBoundary() )
5800 return !this->GetAlgo()->NeedDiscreteBoundary();
5802 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5805 }; // end of SMESH_DimHyp
5806 //-----------------------------------------------------------------------------
5808 typedef list<const SMESH_DimHyp*> TDimHypList;
5810 //-----------------------------------------------------------------------------
5812 void addDimHypInstance(const int theDim,
5813 const TopoDS_Shape& theShape,
5814 const SMESH_Algo* theAlgo,
5815 const SMESH_subMesh* theSubMesh,
5816 const list <const SMESHDS_Hypothesis*>& theHypList,
5817 TDimHypList* theDimHypListArr )
5819 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5820 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5821 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5822 dimHyp->_hypotheses.push_front(theAlgo);
5823 listOfdimHyp.push_back( dimHyp );
5826 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5827 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5828 theHypList.begin(), theHypList.end() );
5831 //-----------------------------------------------------------------------------
5832 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5833 TDimHypList& theListOfConcurr)
5835 if ( theListOfConcurr.empty() )
5837 theListOfConcurr.push_back( theDimHyp );
5841 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5842 while ( hypIt != theListOfConcurr.end() &&
5843 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5845 theListOfConcurr.insert( hypIt, theDimHyp );
5849 //-----------------------------------------------------------------------------
5850 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5851 const TDimHypList& theListOfDimHyp,
5852 TDimHypList& theListOfConcurrHyp,
5853 set<int>& theSetOfConcurrId )
5855 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5856 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5858 const SMESH_DimHyp* curDimHyp = *rIt;
5859 if ( curDimHyp == theDimHyp )
5860 break; // meet own dimHyp pointer in same dimension
5862 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5863 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5865 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5870 //-----------------------------------------------------------------------------
5871 void unionLists(TListOfInt& theListOfId,
5872 TListOfListOfInt& theListOfListOfId,
5875 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5876 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5878 continue; //skip already treated lists
5879 // check if other list has any same submesh object
5880 TListOfInt& otherListOfId = *it;
5881 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5882 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5885 // union two lists (from source into target)
5886 TListOfInt::iterator it2 = otherListOfId.begin();
5887 for ( ; it2 != otherListOfId.end(); it2++ ) {
5888 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5889 theListOfId.push_back(*it2);
5891 // clear source list
5892 otherListOfId.clear();
5895 //-----------------------------------------------------------------------------
5897 //! free memory allocated for dimension-hypothesis objects
5898 void removeDimHyps( TDimHypList* theArrOfList )
5900 for (int i = 0; i < 4; i++ ) {
5901 TDimHypList& listOfdimHyp = theArrOfList[i];
5902 TDimHypList::const_iterator it = listOfdimHyp.begin();
5903 for ( ; it != listOfdimHyp.end(); it++ )
5908 //-----------------------------------------------------------------------------
5910 * \brief find common submeshes with given submesh
5911 * \param theSubMeshList list of already collected submesh to check
5912 * \param theSubMesh given submesh to intersect with other
5913 * \param theCommonSubMeshes collected common submeshes
5915 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5916 const SMESH_subMesh* theSubMesh,
5917 set<const SMESH_subMesh*>& theCommon )
5921 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5922 for ( ; it != theSubMeshList.end(); it++ )
5923 theSubMesh->FindIntersection( *it, theCommon );
5924 theSubMeshList.push_back( theSubMesh );
5925 //theCommon.insert( theSubMesh );
5928 //-----------------------------------------------------------------------------
5929 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5931 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5932 for ( ; listsIt != smLists.end(); ++listsIt )
5934 const TListOfInt& smIDs = *listsIt;
5935 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5943 //=============================================================================
5945 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5947 //=============================================================================
5949 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5951 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5952 if ( isSubMeshInList( submeshID, anOrder ))
5955 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5956 return isSubMeshInList( submeshID, allConurrent );
5959 //=============================================================================
5961 * \brief Return submesh objects list in meshing order
5963 //=============================================================================
5965 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5967 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5969 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5971 return aResult._retn();
5973 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5974 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5975 anOrder.splice( anOrder.end(), allConurrent );
5978 TListOfListOfInt::iterator listIt = anOrder.begin();
5979 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5980 unionLists( *listIt, anOrder, listIndx + 1 );
5982 // convert submesh ids into interface instances
5983 // and dump command into python
5984 convertMeshOrder( anOrder, aResult, false );
5986 return aResult._retn();
5989 //=============================================================================
5991 * \brief Finds concurrent sub-meshes
5993 //=============================================================================
5995 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5997 TListOfListOfInt anOrder;
5998 ::SMESH_Mesh& mesh = GetImpl();
6000 // collect submeshes and detect concurrent algorithms and hypothesises
6001 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6003 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6004 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6005 ::SMESH_subMesh* sm = (*i_sm).second;
6007 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6009 // list of assigned hypothesises
6010 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6011 // Find out dimensions where the submesh can be concurrent.
6012 // We define the dimensions by algo of each of hypotheses in hypList
6013 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6014 for( ; hypIt != hypList.end(); hypIt++ ) {
6015 SMESH_Algo* anAlgo = 0;
6016 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6017 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6018 // hyp it-self is algo
6019 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6021 // try to find algorithm with help of sub-shapes
6022 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6023 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6024 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6027 continue; // no algorithm assigned to a current submesh
6029 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6030 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6032 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6033 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6034 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6036 } // end iterations on submesh
6038 // iterate on created dimension-hypotheses and check for concurrents
6039 for ( int i = 0; i < 4; i++ ) {
6040 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6041 // check for concurrents in own and other dimensions (step-by-step)
6042 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6043 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6044 const SMESH_DimHyp* dimHyp = *dhIt;
6045 TDimHypList listOfConcurr;
6046 set<int> setOfConcurrIds;
6047 // looking for concurrents and collect into own list
6048 for ( int j = i; j < 4; j++ )
6049 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6050 // check if any concurrents found
6051 if ( listOfConcurr.size() > 0 ) {
6052 // add own submesh to list of concurrent
6053 addInOrderOfPriority( dimHyp, listOfConcurr );
6054 list<int> listOfConcurrIds;
6055 TDimHypList::iterator hypIt = listOfConcurr.begin();
6056 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6057 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6058 anOrder.push_back( listOfConcurrIds );
6063 removeDimHyps(dimHypListArr);
6065 // now, minimize the number of concurrent groups
6066 // Here we assume that lists of submeshes can have same submesh
6067 // in case of multi-dimension algorithms, as result
6068 // list with common submesh has to be united into one list
6070 TListOfListOfInt::iterator listIt = anOrder.begin();
6071 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6072 unionLists( *listIt, anOrder, listIndx + 1 );
6078 //=============================================================================
6080 * \brief Set submesh object order
6081 * \param theSubMeshArray submesh array order
6083 //=============================================================================
6085 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6088 _preMeshInfo->ForgetOrLoad();
6091 ::SMESH_Mesh& mesh = GetImpl();
6093 TPythonDump aPythonDump; // prevent dump of called methods
6094 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6096 TListOfListOfInt subMeshOrder;
6097 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6099 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6100 TListOfInt subMeshIds;
6102 aPythonDump << ", ";
6103 aPythonDump << "[ ";
6104 // Collect subMeshes which should be clear
6105 // do it list-by-list, because modification of submesh order
6106 // take effect between concurrent submeshes only
6107 set<const SMESH_subMesh*> subMeshToClear;
6108 list<const SMESH_subMesh*> subMeshList;
6109 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6111 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6113 aPythonDump << ", ";
6114 aPythonDump << subMesh;
6115 subMeshIds.push_back( subMesh->GetId() );
6116 // detect common parts of submeshes
6117 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6118 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6120 aPythonDump << " ]";
6121 subMeshOrder.push_back( subMeshIds );
6123 // clear collected submeshes
6124 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6125 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6126 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6127 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6129 aPythonDump << " ])";
6131 mesh.SetMeshOrder( subMeshOrder );
6134 SMESH::SMESH_Mesh_var me = _this();
6135 _gen_i->UpdateIcons( me );
6140 //=============================================================================
6142 * \brief Convert submesh ids into submesh interfaces
6144 //=============================================================================
6146 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6147 SMESH::submesh_array_array& theResOrder,
6148 const bool theIsDump)
6150 int nbSet = theIdsOrder.size();
6151 TPythonDump aPythonDump; // prevent dump of called methods
6153 aPythonDump << "[ ";
6154 theResOrder.length(nbSet);
6155 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6157 for( ; it != theIdsOrder.end(); it++ ) {
6158 // translate submesh identificators into submesh objects
6159 // takeing into account real number of concurrent lists
6160 const TListOfInt& aSubOrder = (*it);
6161 if (!aSubOrder.size())
6164 aPythonDump << "[ ";
6165 // convert shape indices into interfaces
6166 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6167 aResSubSet->length(aSubOrder.size());
6168 TListOfInt::const_iterator subIt = aSubOrder.begin();
6170 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6171 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6173 SMESH::SMESH_subMesh_var subMesh =
6174 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6177 aPythonDump << ", ";
6178 aPythonDump << subMesh;
6180 aResSubSet[ j++ ] = subMesh;
6183 aPythonDump << " ]";
6185 theResOrder[ listIndx++ ] = aResSubSet;
6187 // correct number of lists
6188 theResOrder.length( listIndx );
6191 // finilise python dump
6192 aPythonDump << " ]";
6193 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6197 namespace // utils used by SMESH_MeshPartDS
6200 * \brief Class used to access to protected data of SMDS_MeshInfo
6202 struct TMeshInfo : public SMDS_MeshInfo
6204 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6207 * \brief Element holing its ID only
6209 struct TElemID : public SMDS_LinearEdge
6211 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6215 //================================================================================
6217 // Implementation of SMESH_MeshPartDS
6219 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6220 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6222 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6223 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6226 _meshDS = mesh_i->GetImpl().GetMeshDS();
6228 SetPersistentId( _meshDS->GetPersistentId() );
6230 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6232 // <meshPart> is the whole mesh
6233 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6235 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6236 myGroupSet = _meshDS->GetGroups();
6241 SMESH::long_array_var anIDs = meshPart->GetIDs();
6242 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6243 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6245 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6246 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6247 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6252 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6253 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6254 if ( _elements[ e->GetType() ].insert( e ).second )
6257 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6258 while ( nIt->more() )
6260 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6261 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6268 ShapeToMesh( _meshDS->ShapeToMesh() );
6270 _meshDS = 0; // to enforce iteration on _elements and _nodes
6273 // -------------------------------------------------------------------------------------
6274 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6275 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6278 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6279 for ( ; partIt != meshPart.end(); ++partIt )
6280 if ( const SMDS_MeshElement * e = *partIt )
6281 if ( _elements[ e->GetType() ].insert( e ).second )
6284 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6285 while ( nIt->more() )
6287 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6288 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6294 // -------------------------------------------------------------------------------------
6295 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6297 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6299 TElemID elem( IDelem );
6300 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6301 if ( !_elements[ iType ].empty() )
6303 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6304 if ( it != _elements[ iType ].end() )
6309 // -------------------------------------------------------------------------------------
6310 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6312 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6314 typedef SMDS_SetIterator
6315 <const SMDS_MeshElement*,
6316 TIDSortedElemSet::const_iterator,
6317 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6318 SMDS_MeshElement::GeomFilter
6321 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6323 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6324 _elements[type].end(),
6325 SMDS_MeshElement::GeomFilter( geomType )));
6327 // -------------------------------------------------------------------------------------
6328 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6330 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6332 typedef SMDS_SetIterator
6333 <const SMDS_MeshElement*,
6334 TIDSortedElemSet::const_iterator,
6335 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6336 SMDS_MeshElement::EntityFilter
6339 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6341 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6342 _elements[type].end(),
6343 SMDS_MeshElement::EntityFilter( entity )));
6345 // -------------------------------------------------------------------------------------
6346 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6348 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6349 if ( type == SMDSAbs_All && !_meshDS )
6351 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6353 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6354 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6356 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6358 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6359 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6361 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6362 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6364 // -------------------------------------------------------------------------------------
6365 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6366 iterType SMESH_MeshPartDS::methName() const \
6368 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6369 return _meshDS ? _meshDS->methName() : iterType \
6370 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6372 // -------------------------------------------------------------------------------------
6373 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6374 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6375 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6376 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6377 #undef _GET_ITER_DEFINE
6379 // END Implementation of SMESH_MeshPartDS
6381 //================================================================================