1 // Copyright (C) 2007-2019 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_DataMapOfShapeShape.hxx>
76 #include <TopTools_MapIteratorOfMapOfShape.hxx>
77 #include <TopTools_MapOfShape.hxx>
78 #include <TopoDS_Compound.hxx>
85 #include <vtkUnstructuredGridWriter.h>
87 // to pass CORBA exception through SMESH_TRY
88 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
90 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 static int MYDEBUG = 0;
95 static int MYDEBUG = 0;
99 using SMESH::TPythonDump;
102 int SMESH_Mesh_i::_idGenerator = 0;
104 //=============================================================================
108 //=============================================================================
110 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
112 : SALOME::GenericObj_i( thePOA )
116 _id = _idGenerator++;
118 _previewEditor = NULL;
123 //=============================================================================
127 //=============================================================================
129 SMESH_Mesh_i::~SMESH_Mesh_i()
132 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
133 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
134 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
136 aGroup->UnRegister();
137 SMESH::SMESH_GroupBase_var( itGr->second );
142 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
143 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
144 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
146 aSubMesh->UnRegister();
147 SMESH::SMESH_subMesh_var( itSM->second );
149 _mapSubMeshIor.clear();
151 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
152 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
153 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
154 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
155 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
156 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
159 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
163 // clear cached shapes if no more meshes remain; (the cache is blame,
164 // together with publishing, of spent time increasing in issue 22874)
165 if ( _impl->NbMeshes() == 1 )
166 _gen_i->GetShapeReader()->ClearClientBuffer();
168 delete _editor; _editor = NULL;
169 delete _previewEditor; _previewEditor = NULL;
170 delete _impl; _impl = NULL;
171 delete _preMeshInfo; _preMeshInfo = NULL;
174 //=============================================================================
178 * Associates <this> mesh with <theShape> and puts a reference
179 * to <theShape> into the current study;
180 * the previous shape is substituted by the new one.
182 //=============================================================================
184 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
185 throw (SALOME::SALOME_Exception)
187 Unexpect aCatch(SALOME_SalomeException);
189 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
191 catch(SALOME_Exception & S_ex) {
192 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
194 // to track changes of GEOM groups
195 SMESH::SMESH_Mesh_var mesh = _this();
196 addGeomGroupData( theShapeObject, mesh );
197 if ( !CORBA::is_nil( theShapeObject ))
198 _mainShapeTick = theShapeObject->GetTick();
201 //================================================================================
203 * \brief return true if mesh has a shape to build a shape on
205 //================================================================================
207 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
208 throw (SALOME::SALOME_Exception)
210 Unexpect aCatch(SALOME_SalomeException);
213 res = _impl->HasShapeToMesh();
215 catch(SALOME_Exception & S_ex) {
216 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
221 //=======================================================================
222 //function : GetShapeToMesh
224 //=======================================================================
226 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
227 throw (SALOME::SALOME_Exception)
229 Unexpect aCatch(SALOME_SalomeException);
230 GEOM::GEOM_Object_var aShapeObj;
232 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
236 if ( aShapeObj->_is_nil() )
238 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
239 // find GEOM_Object by entry (IPAL52735)
240 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
241 for ( ; data != _geomGroupData.end(); ++data )
242 if ( data->_smeshObject->_is_equivalent( _this() ))
244 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
245 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
246 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
252 catch(SALOME_Exception & S_ex) {
253 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
255 return aShapeObj._retn();
258 //================================================================================
260 * \brief Replaces a shape in the mesh
262 //================================================================================
263 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
264 throw (SALOME::SALOME_Exception)
266 TopoDS_Shape S = _impl->GetShapeToMesh();
267 GEOM_Client* geomClient = _gen_i->GetShapeReader();
268 TCollection_AsciiString aIOR;
269 if (geomClient->Find(S, aIOR)) {
270 geomClient->RemoveShapeFromBuffer(aIOR);
273 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
274 SMESH::SMESH_Mesh_var me = _this();
275 SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
276 CORBA::String_var entry = theNewGeom->GetStudyEntry();
277 if ( !aSO->_is_nil() )
279 SALOMEDS::SObject_wrap aShapeRefSO;
280 if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
282 SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
283 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
284 builder->Addreference( aShapeRefSO, aShapeSO );
288 // re-assign global hypotheses to the new shape
290 CheckGeomModif( true );
292 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
293 << me <<".GetMesh()), " << entry.in() << ")";
295 TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )";
299 //================================================================================
301 * \brief Return false if the mesh is not yet fully loaded from the study file
303 //================================================================================
305 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
307 Unexpect aCatch(SALOME_SalomeException);
308 return !_preMeshInfo;
311 //================================================================================
313 * \brief Load full mesh data from the study file
315 //================================================================================
317 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
319 Unexpect aCatch(SALOME_SalomeException);
321 _preMeshInfo->FullLoadFromFile();
324 //================================================================================
326 * \brief Remove all nodes and elements
328 //================================================================================
330 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
332 Unexpect aCatch(SALOME_SalomeException);
334 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
338 //CheckGeomGroupModif(); // issue 20145
340 catch(SALOME_Exception & S_ex) {
341 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
344 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
346 SMESH::SMESH_Mesh_var mesh = _this();
347 _gen_i->UpdateIcons( mesh );
350 //================================================================================
352 * \brief Remove all nodes and elements for indicated shape
354 //================================================================================
356 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
357 throw (SALOME::SALOME_Exception)
359 Unexpect aCatch(SALOME_SalomeException);
361 _preMeshInfo->FullLoadFromFile();
364 _impl->ClearSubMesh( ShapeID );
366 catch(SALOME_Exception & S_ex) {
367 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
369 _impl->GetMeshDS()->Modified();
371 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
374 //=============================================================================
376 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
378 //=============================================================================
380 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
382 SMESH::DriverMED_ReadStatus res;
385 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
386 res = SMESH::DRS_OK; break;
387 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
388 res = SMESH::DRS_EMPTY; break;
389 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
390 res = SMESH::DRS_WARN_RENUMBER; break;
391 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
392 res = SMESH::DRS_WARN_SKIP_ELEM; break;
393 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
394 res = SMESH::DRS_WARN_DESCENDING; break;
395 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
397 res = SMESH::DRS_FAIL; break;
402 //=============================================================================
404 * Convert ::SMESH_ComputeError to SMESH::ComputeError
406 //=============================================================================
408 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
410 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
411 errVar->subShapeID = -1;
412 errVar->hasBadMesh = false;
414 if ( !errorPtr || errorPtr->IsOK() )
416 errVar->code = SMESH::COMPERR_OK;
420 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
421 errVar->comment = errorPtr->myComment.c_str();
423 return errVar._retn();
426 //=============================================================================
430 * Imports mesh data from MED file
432 //=============================================================================
434 SMESH::DriverMED_ReadStatus
435 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
436 throw ( SALOME::SALOME_Exception )
438 Unexpect aCatch(SALOME_SalomeException);
441 status = _impl->MEDToMesh( theFileName, theMeshName );
443 catch( SALOME_Exception& S_ex ) {
444 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
447 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
450 CreateGroupServants();
452 int major, minor, release;
453 major = minor = release = 0;
454 MED::GetMEDVersion(theFileName, major, minor, release);
455 _medFileInfo = new SMESH::MedFileInfo();
456 _medFileInfo->fileName = theFileName;
457 _medFileInfo->fileSize = 0;
458 _medFileInfo->major = major;
459 _medFileInfo->minor = minor;
460 _medFileInfo->release = release;
461 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
463 return ConvertDriverMEDReadStatus(status);
466 //================================================================================
468 * \brief Imports mesh data from the CGNS file
470 //================================================================================
472 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
473 const int theMeshIndex,
474 std::string& theMeshName )
475 throw ( SALOME::SALOME_Exception )
477 Unexpect aCatch(SALOME_SalomeException);
480 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
482 catch( SALOME_Exception& S_ex ) {
483 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
486 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
489 CreateGroupServants();
491 _medFileInfo = new SMESH::MedFileInfo();
492 _medFileInfo->fileName = theFileName;
493 _medFileInfo->major = 0;
494 _medFileInfo->minor = 0;
495 _medFileInfo->release = 0;
496 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
498 return ConvertDriverMEDReadStatus(status);
501 //================================================================================
503 * \brief Return string representation of a MED file version comprising nbDigits
505 //================================================================================
507 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
509 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
511 return CORBA::string_dup( ver.c_str() );
514 //================================================================================
516 * Return the list of med versions compatibles for write/append,
517 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
519 //================================================================================
520 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
522 SMESH::long_array_var aResult = new SMESH::long_array();
523 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
524 long nbver = mvok.size();
525 aResult->length( nbver );
526 for ( int i = 0; i < nbver; i++ )
527 aResult[i] = mvok[i];
528 return aResult._retn();
531 //=============================================================================
535 * Imports mesh data from MED file
537 //=============================================================================
539 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
540 throw ( SALOME::SALOME_Exception )
544 // Read mesh with name = <theMeshName> into SMESH_Mesh
545 _impl->UNVToMesh( theFileName );
547 CreateGroupServants();
549 _medFileInfo = new SMESH::MedFileInfo();
550 _medFileInfo->fileName = theFileName;
551 _medFileInfo->major = 0;
552 _medFileInfo->minor = 0;
553 _medFileInfo->release = 0;
554 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
556 SMESH_CATCH( SMESH::throwCorbaException );
561 //=============================================================================
565 * Imports mesh data from STL file
567 //=============================================================================
568 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
569 throw ( SALOME::SALOME_Exception )
573 // Read mesh with name = <theMeshName> into SMESH_Mesh
574 std::string name = _impl->STLToMesh( theFileName );
577 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
578 _gen_i->SetName( meshSO, name.c_str() );
580 _medFileInfo = new SMESH::MedFileInfo();
581 _medFileInfo->fileName = theFileName;
582 _medFileInfo->major = 0;
583 _medFileInfo->minor = 0;
584 _medFileInfo->release = 0;
585 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
587 SMESH_CATCH( SMESH::throwCorbaException );
592 //================================================================================
594 * \brief Function used in SMESH_CATCH by ImportGMFFile()
596 //================================================================================
600 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
602 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
606 //================================================================================
608 * \brief Imports data from a GMF file and returns an error description
610 //================================================================================
612 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
613 bool theMakeRequiredGroups )
614 throw (SALOME::SALOME_Exception)
616 SMESH_ComputeErrorPtr error;
619 #define SMESH_CAUGHT error =
622 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
624 _medFileInfo = new SMESH::MedFileInfo();
625 _medFileInfo->fileName = theFileName;
626 _medFileInfo->major = 0;
627 _medFileInfo->minor = 0;
628 _medFileInfo->release = 0;
629 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
631 SMESH_CATCH( exceptionToComputeError );
635 CreateGroupServants();
637 return ConvertComputeError( error );
640 //=============================================================================
644 //=============================================================================
646 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
648 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
649 (SMESH_Hypothesis::Hypothesis_Status theStatus)
652 RETURNCASE( HYP_OK );
653 RETURNCASE( HYP_MISSING );
654 RETURNCASE( HYP_CONCURRENT );
655 RETURNCASE( HYP_BAD_PARAMETER );
656 RETURNCASE( HYP_HIDDEN_ALGO );
657 RETURNCASE( HYP_HIDING_ALGO );
658 RETURNCASE( HYP_UNKNOWN_FATAL );
659 RETURNCASE( HYP_INCOMPATIBLE );
660 RETURNCASE( HYP_NOTCONFORM );
661 RETURNCASE( HYP_ALREADY_EXIST );
662 RETURNCASE( HYP_BAD_DIM );
663 RETURNCASE( HYP_BAD_SUBSHAPE );
664 RETURNCASE( HYP_BAD_GEOMETRY );
665 RETURNCASE( HYP_NEED_SHAPE );
666 RETURNCASE( HYP_INCOMPAT_HYPS );
669 return SMESH::HYP_UNKNOWN_FATAL;
672 //=============================================================================
676 * calls internal addHypothesis() and then adds a reference to <anHyp> under
677 * the SObject actually having a reference to <aSubShape>.
678 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
680 //=============================================================================
682 SMESH::Hypothesis_Status
683 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
684 SMESH::SMESH_Hypothesis_ptr anHyp,
685 CORBA::String_out anErrorText)
686 throw(SALOME::SALOME_Exception)
688 Unexpect aCatch(SALOME_SalomeException);
690 _preMeshInfo->ForgetOrLoad();
693 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
694 anErrorText = error.c_str();
696 SMESH::SMESH_Mesh_var mesh( _this() );
697 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
699 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
700 _gen_i->UpdateIcons( mesh );
702 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
704 // Update Python script
705 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
706 << aSubShape << ", " << anHyp << " )";
708 return ConvertHypothesisStatus(status);
711 //=============================================================================
715 //=============================================================================
717 SMESH_Hypothesis::Hypothesis_Status
718 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
719 SMESH::SMESH_Hypothesis_ptr anHyp,
720 std::string* anErrorText)
722 if(MYDEBUG) MESSAGE("addHypothesis");
724 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
725 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
727 if (CORBA::is_nil( anHyp ))
728 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
730 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
733 TopoDS_Shape myLocSubShape;
734 //use PseudoShape in case if mesh has no shape
736 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
738 myLocSubShape = _impl->GetShapeToMesh();
740 const int hypId = anHyp->GetId();
742 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
743 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
745 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
747 // assure there is a corresponding submesh
748 if ( !_impl->IsMainShape( myLocSubShape )) {
749 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
750 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
751 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
754 else if ( anErrorText )
756 *anErrorText = error;
759 catch(SALOME_Exception & S_ex)
761 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
766 //=============================================================================
770 //=============================================================================
772 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
773 SMESH::SMESH_Hypothesis_ptr anHyp)
774 throw(SALOME::SALOME_Exception)
776 Unexpect aCatch(SALOME_SalomeException);
778 _preMeshInfo->ForgetOrLoad();
780 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
781 SMESH::SMESH_Mesh_var mesh = _this();
783 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
785 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
786 _gen_i->UpdateIcons( mesh );
788 // Update Python script
789 if(_impl->HasShapeToMesh())
790 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
791 << aSubShape << ", " << anHyp << " )";
793 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
796 return ConvertHypothesisStatus(status);
799 //=============================================================================
803 //=============================================================================
805 SMESH_Hypothesis::Hypothesis_Status
806 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
807 SMESH::SMESH_Hypothesis_ptr anHyp)
809 if(MYDEBUG) MESSAGE("removeHypothesis()");
811 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
812 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
814 if (CORBA::is_nil( anHyp ))
815 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
818 _preMeshInfo->ForgetOrLoad();
820 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
823 TopoDS_Shape myLocSubShape;
824 //use PseudoShape in case if mesh has no shape
825 if( _impl->HasShapeToMesh() )
826 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
828 myLocSubShape = _impl->GetShapeToMesh();
830 const int hypId = anHyp->GetId();
831 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
832 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
834 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
838 catch(SALOME_Exception & S_ex)
840 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
845 //=============================================================================
849 //=============================================================================
851 SMESH::ListOfHypothesis *
852 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
853 throw(SALOME::SALOME_Exception)
855 Unexpect aCatch(SALOME_SalomeException);
856 if (MYDEBUG) MESSAGE("GetHypothesisList");
857 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
858 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
860 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
863 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
864 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
865 myLocSubShape = _impl->GetShapeToMesh();
866 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
867 int i = 0, n = aLocalList.size();
870 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
871 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
872 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
874 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
875 if ( id_hypptr != _mapHypo.end() )
876 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
880 catch(SALOME_Exception & S_ex) {
881 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
884 return aList._retn();
887 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
889 Unexpect aCatch(SALOME_SalomeException);
890 if (MYDEBUG) MESSAGE("GetSubMeshes");
892 SMESH::submesh_array_var aList = new SMESH::submesh_array();
895 TPythonDump aPythonDump;
896 if ( !_mapSubMeshIor.empty() )
900 aList->length( _mapSubMeshIor.size() );
902 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
903 for ( ; it != _mapSubMeshIor.end(); it++ ) {
904 if ( CORBA::is_nil( it->second )) continue;
905 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
907 if (i > 1) aPythonDump << ", ";
908 aPythonDump << it->second;
912 catch(SALOME_Exception & S_ex) {
913 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
916 // Update Python script
917 if ( !_mapSubMeshIor.empty() )
918 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
920 return aList._retn();
923 //=============================================================================
927 //=============================================================================
929 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
930 const char* theName )
931 throw(SALOME::SALOME_Exception)
933 Unexpect aCatch(SALOME_SalomeException);
934 if (CORBA::is_nil(aSubShape))
935 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
937 SMESH::SMESH_subMesh_var subMesh;
938 SMESH::SMESH_Mesh_var aMesh = _this();
940 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
942 //Get or Create the SMESH_subMesh object implementation
944 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
946 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
948 TopoDS_Iterator it( myLocSubShape );
950 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
952 subMesh = getSubMesh( subMeshId );
954 // create a new subMesh object servant if there is none for the shape
955 if ( subMesh->_is_nil() )
956 subMesh = createSubMesh( aSubShape );
957 if ( _gen_i->CanPublishInStudy( subMesh ))
959 SALOMEDS::SObject_wrap aSO =
960 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
961 if ( !aSO->_is_nil()) {
962 // Update Python script
963 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
964 << aSubShape << ", '" << theName << "' )";
968 catch(SALOME_Exception & S_ex) {
969 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
971 return subMesh._retn();
974 //=============================================================================
978 //=============================================================================
980 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
981 throw (SALOME::SALOME_Exception)
985 if ( theSubMesh->_is_nil() )
988 GEOM::GEOM_Object_var aSubShape;
989 // Remove submesh's SObject
990 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
991 if ( !anSO->_is_nil() ) {
992 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
993 SALOMEDS::SObject_wrap anObj, aRef;
994 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
995 anObj->ReferencedObject( aRef.inout() ))
997 CORBA::Object_var obj = aRef->GetObject();
998 aSubShape = GEOM::GEOM_Object::_narrow( obj );
1000 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
1001 // aSubShape = theSubMesh->GetSubShape();
1003 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
1004 builder->RemoveObjectWithChildren( anSO );
1006 // Update Python script
1007 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
1010 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
1012 _preMeshInfo->ForgetOrLoad();
1014 SMESH_CATCH( SMESH::throwCorbaException );
1017 //=============================================================================
1021 //=============================================================================
1023 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1024 const char* theName )
1025 throw(SALOME::SALOME_Exception)
1027 Unexpect aCatch(SALOME_SalomeException);
1029 _preMeshInfo->FullLoadFromFile();
1031 SMESH::SMESH_Group_var aNewGroup =
1032 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1034 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1036 SMESH::SMESH_Mesh_var mesh = _this();
1037 SALOMEDS::SObject_wrap aSO =
1038 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1039 if ( !aSO->_is_nil())
1040 // Update Python script
1041 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1042 << theElemType << ", '" << theName << "' )";
1044 return aNewGroup._retn();
1047 //=============================================================================
1051 //=============================================================================
1052 SMESH::SMESH_GroupOnGeom_ptr
1053 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1054 const char* theName,
1055 GEOM::GEOM_Object_ptr theGeomObj)
1056 throw(SALOME::SALOME_Exception)
1058 Unexpect aCatch(SALOME_SalomeException);
1060 _preMeshInfo->FullLoadFromFile();
1062 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1064 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1065 if ( !aShape.IsNull() )
1068 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1070 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1072 SMESH::SMESH_Mesh_var mesh = _this();
1073 SALOMEDS::SObject_wrap aSO =
1074 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1075 if ( !aSO->_is_nil())
1076 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1077 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1081 return aNewGroup._retn();
1084 //================================================================================
1086 * \brief Creates a group whose contents is defined by filter
1087 * \param theElemType - group type
1088 * \param theName - group name
1089 * \param theFilter - the filter
1090 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1092 //================================================================================
1094 SMESH::SMESH_GroupOnFilter_ptr
1095 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1096 const char* theName,
1097 SMESH::Filter_ptr theFilter )
1098 throw (SALOME::SALOME_Exception)
1100 Unexpect aCatch(SALOME_SalomeException);
1102 _preMeshInfo->FullLoadFromFile();
1104 if ( CORBA::is_nil( theFilter ))
1105 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1107 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1109 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1111 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1112 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1115 if ( !aNewGroup->_is_nil() )
1116 aNewGroup->SetFilter( theFilter );
1118 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1120 SMESH::SMESH_Mesh_var mesh = _this();
1121 SALOMEDS::SObject_wrap aSO =
1122 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1124 if ( !aSO->_is_nil())
1125 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1126 << theElemType << ", '" << theName << "', " << theFilter << " )";
1128 return aNewGroup._retn();
1131 //=============================================================================
1135 //=============================================================================
1137 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1138 throw (SALOME::SALOME_Exception)
1140 if ( theGroup->_is_nil() )
1145 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1149 if ( aGroup->GetMeshServant() != this )
1150 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1151 SALOME::BAD_PARAM );
1153 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1154 if ( !aGroupSO->_is_nil() )
1156 // Update Python script
1157 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1159 // Remove group's SObject
1160 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1161 builder->RemoveObjectWithChildren( aGroupSO );
1163 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1165 // Remove the group from SMESH data structures
1166 removeGroup( aGroup->GetLocalID() );
1168 SMESH_CATCH( SMESH::throwCorbaException );
1171 //=============================================================================
1173 * Remove group with its contents
1175 //=============================================================================
1177 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1178 throw (SALOME::SALOME_Exception)
1182 _preMeshInfo->FullLoadFromFile();
1184 if ( theGroup->_is_nil() )
1187 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1188 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1189 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1192 vector<int> nodeIds; // to remove nodes becoming free
1193 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1194 if ( !isNodal && !theGroup->IsEmpty() )
1196 CORBA::Long elemID = theGroup->GetID( 1 );
1197 int nbElemNodes = GetElemNbNodes( elemID );
1198 if ( nbElemNodes > 0 )
1199 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1202 // Retrieve contents
1203 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1204 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1205 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1206 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1207 elems.assign( elemBeg, elemEnd );
1209 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1212 RemoveGroup( theGroup );
1215 for ( size_t i = 0; i < elems.size(); ++i )
1217 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1221 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1222 nodeIds.push_back( nIt->next()->GetID() );
1224 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1228 _impl->GetMeshDS()->RemoveElement( elems[i] );
1232 // Remove free nodes
1233 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1234 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1235 if ( n->NbInverseElements() == 0 )
1236 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1238 // Update Python script (theGroup must be alive for this)
1239 pyDump << SMESH::SMESH_Mesh_var(_this())
1240 << ".RemoveGroupWithContents( " << theGroup << " )";
1242 SMESH_CATCH( SMESH::throwCorbaException );
1245 //================================================================================
1247 * \brief Get the list of groups existing in the mesh
1248 * \retval SMESH::ListOfGroups * - list of groups
1250 //================================================================================
1252 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1254 Unexpect aCatch(SALOME_SalomeException);
1255 if (MYDEBUG) MESSAGE("GetGroups");
1257 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1260 TPythonDump aPythonDump;
1261 if ( !_mapGroups.empty() )
1263 aPythonDump << "[ ";
1265 aList->length( _mapGroups.size() );
1267 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1268 for ( ; it != _mapGroups.end(); it++ ) {
1269 if ( CORBA::is_nil( it->second )) continue;
1270 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1272 if (i > 1) aPythonDump << ", ";
1273 aPythonDump << it->second;
1277 catch(SALOME_Exception & S_ex) {
1278 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1280 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1282 return aList._retn();
1285 //=============================================================================
1287 * Get number of groups existing in the mesh
1289 //=============================================================================
1291 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1293 Unexpect aCatch(SALOME_SalomeException);
1294 return _mapGroups.size();
1297 //=============================================================================
1299 * New group including all mesh elements present in initial groups is created.
1301 //=============================================================================
1303 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1304 SMESH::SMESH_GroupBase_ptr theGroup2,
1305 const char* theName )
1306 throw (SALOME::SALOME_Exception)
1308 SMESH::SMESH_Group_var aResGrp;
1312 _preMeshInfo->FullLoadFromFile();
1314 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1315 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1317 if ( theGroup1->GetType() != theGroup2->GetType() )
1318 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1323 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1324 if ( aResGrp->_is_nil() )
1325 return SMESH::SMESH_Group::_nil();
1327 aResGrp->AddFrom( theGroup1 );
1328 aResGrp->AddFrom( theGroup2 );
1330 // Update Python script
1331 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1332 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1334 SMESH_CATCH( SMESH::throwCorbaException );
1336 return aResGrp._retn();
1339 //=============================================================================
1341 * \brief New group including all mesh elements present in initial groups is created.
1342 * \param theGroups list of groups
1343 * \param theName name of group to be created
1344 * \return pointer to the new group
1346 //=============================================================================
1348 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1349 const char* theName )
1350 throw (SALOME::SALOME_Exception)
1352 SMESH::SMESH_Group_var aResGrp;
1355 _preMeshInfo->FullLoadFromFile();
1358 return SMESH::SMESH_Group::_nil();
1363 SMESH::ElementType aType = SMESH::ALL;
1364 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1366 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1367 if ( CORBA::is_nil( aGrp ) )
1369 if ( aType == SMESH::ALL )
1370 aType = aGrp->GetType();
1371 else if ( aType != aGrp->GetType() )
1372 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1375 if ( aType == SMESH::ALL )
1376 return SMESH::SMESH_Group::_nil();
1381 aResGrp = CreateGroup( aType, theName );
1382 if ( aResGrp->_is_nil() )
1383 return SMESH::SMESH_Group::_nil();
1385 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1386 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1388 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1389 if ( !CORBA::is_nil( aGrp ) )
1391 aResGrp->AddFrom( aGrp );
1392 if ( g > 0 ) pyDump << ", ";
1396 pyDump << " ], '" << theName << "' )";
1398 SMESH_CATCH( SMESH::throwCorbaException );
1400 return aResGrp._retn();
1403 //=============================================================================
1405 * New group is created. All mesh elements that are
1406 * present in both initial groups are added to the new one.
1408 //=============================================================================
1410 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1411 SMESH::SMESH_GroupBase_ptr theGroup2,
1412 const char* theName )
1413 throw (SALOME::SALOME_Exception)
1415 SMESH::SMESH_Group_var aResGrp;
1420 _preMeshInfo->FullLoadFromFile();
1422 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1423 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1425 if ( theGroup1->GetType() != theGroup2->GetType() )
1426 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1430 // Create Intersection
1431 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1432 if ( aResGrp->_is_nil() )
1433 return aResGrp._retn();
1435 SMESHDS_GroupBase* groupDS1 = 0;
1436 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1437 groupDS1 = grp_i->GetGroupDS();
1439 SMESHDS_GroupBase* groupDS2 = 0;
1440 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1441 groupDS2 = grp_i->GetGroupDS();
1443 SMESHDS_Group* resGroupDS = 0;
1444 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1445 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1447 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1449 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1450 while ( elemIt1->more() )
1452 const SMDS_MeshElement* e = elemIt1->next();
1453 if ( groupDS2->Contains( e ))
1454 resGroupDS->SMDSGroup().Add( e );
1457 // Update Python script
1458 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1459 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1461 SMESH_CATCH( SMESH::throwCorbaException );
1463 return aResGrp._retn();
1466 //=============================================================================
1468 \brief Intersect list of groups. New group is created. All mesh elements that
1469 are present in all initial groups simultaneously are added to the new one.
1470 \param theGroups list of groups
1471 \param theName name of group to be created
1472 \return pointer on the group
1474 //=============================================================================
1475 SMESH::SMESH_Group_ptr
1476 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1477 const char* theName )
1478 throw (SALOME::SALOME_Exception)
1480 SMESH::SMESH_Group_var aResGrp;
1485 _preMeshInfo->FullLoadFromFile();
1488 return SMESH::SMESH_Group::_nil();
1490 // check types and get SMESHDS_GroupBase's
1491 SMESH::ElementType aType = SMESH::ALL;
1492 vector< SMESHDS_GroupBase* > groupVec;
1493 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1495 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1496 if ( CORBA::is_nil( aGrp ) )
1498 if ( aType == SMESH::ALL )
1499 aType = aGrp->GetType();
1500 else if ( aType != aGrp->GetType() )
1501 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1504 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1505 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1507 if ( grpDS->IsEmpty() )
1512 groupVec.push_back( grpDS );
1515 if ( aType == SMESH::ALL ) // all groups are nil
1516 return SMESH::SMESH_Group::_nil();
1521 aResGrp = CreateGroup( aType, theName );
1523 SMESHDS_Group* resGroupDS = 0;
1524 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1525 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1526 if ( !resGroupDS || groupVec.empty() )
1527 return aResGrp._retn();
1530 size_t i, nb = groupVec.size();
1531 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1532 while ( elemIt1->more() )
1534 const SMDS_MeshElement* e = elemIt1->next();
1536 for ( i = 1; ( i < nb && inAll ); ++i )
1537 inAll = groupVec[i]->Contains( e );
1540 resGroupDS->SMDSGroup().Add( e );
1543 // Update Python script
1544 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1545 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1547 SMESH_CATCH( SMESH::throwCorbaException );
1549 return aResGrp._retn();
1552 //=============================================================================
1554 * New group is created. All mesh elements that are present in
1555 * a main group but is not present in a tool group are added to the new one
1557 //=============================================================================
1559 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1560 SMESH::SMESH_GroupBase_ptr theGroup2,
1561 const char* theName )
1562 throw (SALOME::SALOME_Exception)
1564 SMESH::SMESH_Group_var aResGrp;
1569 _preMeshInfo->FullLoadFromFile();
1571 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1572 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1574 if ( theGroup1->GetType() != theGroup2->GetType() )
1575 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1579 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1580 if ( aResGrp->_is_nil() )
1581 return aResGrp._retn();
1583 SMESHDS_GroupBase* groupDS1 = 0;
1584 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1585 groupDS1 = grp_i->GetGroupDS();
1587 SMESHDS_GroupBase* groupDS2 = 0;
1588 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1589 groupDS2 = grp_i->GetGroupDS();
1591 SMESHDS_Group* resGroupDS = 0;
1592 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1593 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1595 if ( groupDS1 && groupDS2 && resGroupDS )
1597 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1598 while ( elemIt1->more() )
1600 const SMDS_MeshElement* e = elemIt1->next();
1601 if ( !groupDS2->Contains( e ))
1602 resGroupDS->SMDSGroup().Add( e );
1605 // Update Python script
1606 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1607 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1609 SMESH_CATCH( SMESH::throwCorbaException );
1611 return aResGrp._retn();
1614 //=============================================================================
1616 \brief Cut lists of groups. New group is created. All mesh elements that are
1617 present in main groups but do not present in tool groups are added to the new one
1618 \param theMainGroups list of main groups
1619 \param theToolGroups list of tool groups
1620 \param theName name of group to be created
1621 \return pointer on the group
1623 //=============================================================================
1624 SMESH::SMESH_Group_ptr
1625 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1626 const SMESH::ListOfGroups& theToolGroups,
1627 const char* theName )
1628 throw (SALOME::SALOME_Exception)
1630 SMESH::SMESH_Group_var aResGrp;
1635 _preMeshInfo->FullLoadFromFile();
1638 return SMESH::SMESH_Group::_nil();
1640 // check types and get SMESHDS_GroupBase's
1641 SMESH::ElementType aType = SMESH::ALL;
1642 vector< SMESHDS_GroupBase* > toolGroupVec;
1643 vector< SMDS_ElemIteratorPtr > mainIterVec;
1645 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1647 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1648 if ( CORBA::is_nil( aGrp ) )
1650 if ( aType == SMESH::ALL )
1651 aType = aGrp->GetType();
1652 else if ( aType != aGrp->GetType() )
1653 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1655 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1656 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1657 if ( !grpDS->IsEmpty() )
1658 mainIterVec.push_back( grpDS->GetElements() );
1660 if ( aType == SMESH::ALL ) // all main groups are nil
1661 return SMESH::SMESH_Group::_nil();
1662 if ( mainIterVec.empty() ) // all main groups are empty
1663 return aResGrp._retn();
1665 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1667 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1668 if ( CORBA::is_nil( aGrp ) )
1670 if ( aType != aGrp->GetType() )
1671 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1673 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1674 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1675 toolGroupVec.push_back( grpDS );
1681 aResGrp = CreateGroup( aType, theName );
1683 SMESHDS_Group* resGroupDS = 0;
1684 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1685 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1687 return aResGrp._retn();
1690 size_t i, nb = toolGroupVec.size();
1691 SMDS_ElemIteratorPtr mainElemIt
1692 ( new SMDS_IteratorOnIterators
1693 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1694 while ( mainElemIt->more() )
1696 const SMDS_MeshElement* e = mainElemIt->next();
1698 for ( i = 0; ( i < nb && !isIn ); ++i )
1699 isIn = toolGroupVec[i]->Contains( e );
1702 resGroupDS->SMDSGroup().Add( e );
1705 // Update Python script
1706 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1707 << ".CutListOfGroups( " << theMainGroups << ", "
1708 << theToolGroups << ", '" << theName << "' )";
1710 SMESH_CATCH( SMESH::throwCorbaException );
1712 return aResGrp._retn();
1715 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1717 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1718 bool & toStopChecking )
1720 toStopChecking = ( nbCommon < nbChecked );
1721 return nbCommon == nbNodes;
1723 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1724 bool & toStopChecking )
1726 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1727 return nbCommon == nbCorners;
1729 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1730 bool & toStopChecking )
1732 return nbCommon > 0;
1734 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1735 bool & toStopChecking )
1737 return nbCommon >= (nbNodes+1) / 2;
1741 //=============================================================================
1743 * Create a group of entities basing on nodes of other groups.
1744 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1745 * \param [in] anElemType - a type of elements to include to the new group.
1746 * \param [in] theName - a name of the new group.
1747 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1748 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1749 * new group provided that it is based on nodes of an element of \a aListOfGroups
1750 * \return SMESH_Group - the created group
1752 // IMP 19939, bug 22010, IMP 22635
1753 //=============================================================================
1755 SMESH::SMESH_Group_ptr
1756 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1757 SMESH::ElementType theElemType,
1758 const char* theName,
1759 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1760 CORBA::Boolean theUnderlyingOnly)
1761 throw (SALOME::SALOME_Exception)
1763 SMESH::SMESH_Group_var aResGrp;
1767 _preMeshInfo->FullLoadFromFile();
1769 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1771 if ( !theName || !aMeshDS )
1772 return SMESH::SMESH_Group::_nil();
1774 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1776 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1777 SMESH_Comment nbCoNoStr( "SMESH.");
1778 switch ( theNbCommonNodes ) {
1779 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1780 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1781 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1782 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1783 default: return aResGrp._retn();
1785 int nbChecked, nbCommon, nbNodes, nbCorners;
1791 aResGrp = CreateGroup( theElemType, theName );
1792 if ( aResGrp->_is_nil() )
1793 return SMESH::SMESH_Group::_nil();
1795 SMESHDS_GroupBase* groupBaseDS =
1796 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1797 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1799 vector<bool> isNodeInGroups;
1801 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1803 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1804 if ( CORBA::is_nil( aGrp ) )
1806 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1807 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1810 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1811 if ( !elIt ) continue;
1813 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1815 while ( elIt->more() ) {
1816 const SMDS_MeshElement* el = elIt->next();
1817 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1818 while ( nIt->more() )
1819 resGroupCore.Add( nIt->next() );
1822 // get elements of theElemType based on nodes of every element of group
1823 else if ( theUnderlyingOnly )
1825 while ( elIt->more() )
1827 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1828 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1829 TIDSortedElemSet checkedElems;
1830 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1831 while ( nIt->more() )
1833 const SMDS_MeshNode* n = nIt->next();
1834 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1835 // check nodes of elements of theElemType around el
1836 while ( elOfTypeIt->more() )
1838 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1839 if ( !checkedElems.insert( elOfType ).second ) continue;
1840 nbNodes = elOfType->NbNodes();
1841 nbCorners = elOfType->NbCornerNodes();
1843 bool toStopChecking = false;
1844 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1845 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1846 if ( elNodes.count( nIt2->next() ) &&
1847 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1849 resGroupCore.Add( elOfType );
1856 // get all nodes of elements of groups
1859 while ( elIt->more() )
1861 const SMDS_MeshElement* el = elIt->next(); // an element of group
1862 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1863 while ( nIt->more() )
1865 const SMDS_MeshNode* n = nIt->next();
1866 if ( n->GetID() >= (int) isNodeInGroups.size() )
1867 isNodeInGroups.resize( n->GetID() + 1, false );
1868 isNodeInGroups[ n->GetID() ] = true;
1874 // Get elements of theElemType based on a certain number of nodes of elements of groups
1875 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1877 const SMDS_MeshNode* n;
1878 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1879 const int isNodeInGroupsSize = isNodeInGroups.size();
1880 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1882 if ( !isNodeInGroups[ iN ] ||
1883 !( n = aMeshDS->FindNode( iN )))
1886 // check nodes of elements of theElemType around n
1887 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1888 while ( elOfTypeIt->more() )
1890 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1891 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1896 nbNodes = elOfType->NbNodes();
1897 nbCorners = elOfType->NbCornerNodes();
1899 bool toStopChecking = false;
1900 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1901 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1903 const int nID = nIt->next()->GetID();
1904 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1905 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1907 resGroupCore.Add( elOfType );
1915 // Update Python script
1916 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1917 << ".CreateDimGroup( "
1918 << theGroups << ", " << theElemType << ", '" << theName << "', "
1919 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1921 SMESH_CATCH( SMESH::throwCorbaException );
1923 return aResGrp._retn();
1926 //================================================================================
1928 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1929 * existing 1D elements as group boundaries.
1930 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1931 * adjacent faces is more than \a sharpAngle in degrees.
1932 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1933 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1934 * \return ListOfGroups - the created groups
1936 //================================================================================
1938 SMESH::ListOfGroups*
1939 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1940 CORBA::Boolean theCreateEdges,
1941 CORBA::Boolean theUseExistingEdges )
1942 throw (SALOME::SALOME_Exception)
1944 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1945 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1948 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1954 _preMeshInfo->FullLoadFromFile();
1956 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1958 std::vector< SMESH_MeshAlgos::Edge > edges =
1959 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1961 if ( theCreateEdges )
1963 std::vector<const SMDS_MeshNode *> nodes(2);
1964 for ( size_t i = 0; i < edges.size(); ++i )
1966 nodes[0] = edges[i]._node1;
1967 nodes[1] = edges[i]._node2;
1968 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1970 if ( edges[i]._medium )
1971 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1973 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1977 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1978 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1980 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1982 resultGroups->length( faceGroups.size() );
1983 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1985 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1986 _editor->GenerateGroupName("Group").c_str());
1987 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1989 SMESHDS_GroupBase* groupBaseDS =
1990 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1991 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1993 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1994 for ( size_t i = 0; i < faces.size(); ++i )
1995 groupCore.Add( faces[i] );
1998 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1999 << ".FaceGroupsSeparatedByEdges( "
2000 << TVar( theSharpAngle ) << ", "
2001 << theCreateEdges << ", "
2002 << theUseExistingEdges << " )";
2004 SMESH_CATCH( SMESH::throwCorbaException );
2005 return resultGroups._retn();
2009 //================================================================================
2011 * \brief Remember GEOM group data
2013 //================================================================================
2015 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
2016 CORBA::Object_ptr theSmeshObj)
2018 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2021 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2022 if ( groupSO->_is_nil() )
2025 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2026 GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
2027 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2030 _geomGroupData.push_back( TGeomGroupData() );
2031 TGeomGroupData & groupData = _geomGroupData.back();
2033 CORBA::String_var entry = groupSO->GetID();
2034 groupData._groupEntry = entry.in();
2036 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2037 groupData._indices.insert( ids[i] );
2039 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2040 // shape index in SMESHDS
2041 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2042 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2045 //================================================================================
2047 * Remove GEOM group data relating to removed smesh object
2049 //================================================================================
2051 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2053 list<TGeomGroupData>::iterator
2054 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2055 for ( ; data != dataEnd; ++data ) {
2056 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2057 _geomGroupData.erase( data );
2063 //================================================================================
2065 * \brief Return new group contents if it has been changed and update group data
2067 //================================================================================
2068 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2070 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2072 TopoDS_Shape newShape;
2074 if ( how == IS_BREAK_LINK )
2076 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2077 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2078 if ( !meshSO->_is_nil() &&
2079 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2080 geomRefSO->ReferencedObject( geomSO.inout() ))
2082 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2083 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2084 newShape = _gen_i->GeomObjectToShape( geom );
2085 CORBA::String_var entry = geom->GetStudyEntry();
2086 groupData._groupEntry = entry.in();
2092 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2093 if ( !groupSO->_is_nil() )
2095 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2096 if ( CORBA::is_nil( groupObj )) return newShape;
2097 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2099 // get indices of group items
2100 set<int> curIndices;
2101 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2102 GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
2103 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2104 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2105 curIndices.insert( ids[i] );
2107 if ( how == ONLY_IF_CHANGED && groupData._indices == curIndices )
2108 return newShape; // group not changed
2111 groupData._indices = curIndices;
2113 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2114 if ( !geomClient ) return newShape;
2115 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2116 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2117 newShape = _gen_i->GeomObjectToShape( geomGroup );
2120 if ( newShape.IsNull() ) {
2121 // geom group becomes empty - return empty compound
2122 TopoDS_Compound compound;
2123 BRep_Builder().MakeCompound(compound);
2124 newShape = compound;
2131 //-----------------------------------------------------------------------------
2133 * \brief Storage of shape and index used in CheckGeomGroupModif()
2135 struct TIndexedShape
2138 TopoDS_Shape _shape;
2139 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2141 //-----------------------------------------------------------------------------
2143 * \brief Data to re-create a group on geometry
2145 struct TGroupOnGeomData
2148 TopoDS_Shape _shape;
2149 SMDSAbs_ElementType _type;
2151 Quantity_Color _color;
2153 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2155 _oldID = group->GetID();
2156 _type = group->GetType();
2157 _name = group->GetStoreName();
2158 _color = group->GetColor();
2162 //-----------------------------------------------------------------------------
2164 * \brief Check if a filter is still valid after geometry removal
2166 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2168 if ( theFilter->_is_nil() )
2170 SMESH::Filter::Criteria_var criteria;
2171 theFilter->GetCriteria( criteria.out() );
2173 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2175 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2177 switch ( criteria[ iCr ].Type )
2179 case SMESH::FT_BelongToGeom:
2180 case SMESH::FT_BelongToPlane:
2181 case SMESH::FT_BelongToCylinder:
2182 case SMESH::FT_BelongToGenSurface:
2183 case SMESH::FT_LyingOnGeom:
2184 entry = thresholdID;
2186 case SMESH::FT_ConnectedElements:
2189 entry = thresholdID;
2195 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2196 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2197 if ( so->_is_nil() )
2199 CORBA::Object_var obj = so->GetObject();
2200 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2201 if ( gen->GeomObjectToShape( geom ).IsNull() )
2204 } // loop on criteria
2210 //=============================================================================
2212 * \brief Update data if geometry changes
2216 //=============================================================================
2218 void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
2220 SMESH::SMESH_Mesh_var me = _this();
2221 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2223 TPythonDump dumpNothing; // prevent any dump
2225 //bool removedFromClient = false;
2227 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2229 //removedFromClient = _impl->HasShapeToMesh();
2231 // try to find geometry by study reference
2232 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2233 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2234 if ( !meshSO->_is_nil() &&
2235 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2236 geomRefSO->ReferencedObject( geomSO.inout() ))
2238 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2239 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2242 if ( mainGO->_is_nil() && // geometry removed ==>
2243 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2245 // convert geom dependent groups into standalone ones
2246 CheckGeomGroupModif();
2248 _impl->ShapeToMesh( TopoDS_Shape() );
2250 // remove sub-meshes
2251 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2252 while ( i_sm != _mapSubMeshIor.end() )
2254 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2256 RemoveSubMesh( sm );
2258 // remove all children except groups in the study
2259 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2260 SALOMEDS::SObject_wrap so;
2261 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2262 if ( meshSO->FindSubObject( tag, so.inout() ))
2263 builder->RemoveObjectWithChildren( so );
2265 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2271 if ( !_impl->HasShapeToMesh() ) return;
2274 // Update after group modification
2276 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2277 mainGO->GetTick() == _mainShapeTick )
2279 int nb = NbNodes() + NbElements();
2280 CheckGeomGroupModif();
2281 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2282 _gen_i->UpdateIcons( me );
2286 // Update after shape modification
2288 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2289 if ( !geomClient ) return;
2290 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2291 if ( geomGen->_is_nil() ) return;
2293 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2294 geomClient->RemoveShapeFromBuffer( ior.in() );
2296 // Update data taking into account that if topology doesn't change
2297 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2300 _preMeshInfo->ForgetAllData();
2305 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2306 if ( newShape.IsNull() )
2309 _mainShapeTick = mainGO->GetTick();
2311 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2313 // store data of groups on geometry
2314 std::vector< TGroupOnGeomData > groupsData;
2315 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2316 groupsData.reserve( groups.size() );
2317 TopTools_DataMapOfShapeShape old2newShapeMap;
2318 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2319 for ( ; g != groups.end(); ++g )
2321 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2323 groupsData.push_back( TGroupOnGeomData( group ));
2326 SMESH::SMESH_GroupOnGeom_var gog;
2327 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2328 if ( i_grp != _mapGroups.end() )
2329 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2331 GEOM::GEOM_Object_var geom;
2332 if ( !gog->_is_nil() )
2336 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2337 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2338 if ( !grpSO->_is_nil() &&
2339 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2340 geomRefSO->ReferencedObject( geomSO.inout() ))
2342 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2343 geom = GEOM::GEOM_Object::_narrow( geomObj );
2348 geom = gog->GetShape();
2351 if ( !geom->_is_nil() )
2353 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2354 geomClient->RemoveShapeFromBuffer( ior.in() );
2355 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2356 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2358 else if ( old2newShapeMap.IsBound( group->GetShape() ))
2360 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2364 // store assigned hypotheses
2365 std::vector< pair< int, THypList > > ids2Hyps;
2366 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2367 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2369 const TopoDS_Shape& s = s2hyps.Key();
2370 const THypList& hyps = s2hyps.ChangeValue();
2371 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2374 std::map< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2376 // count shapes excluding compounds corresponding to geom groups
2377 int oldNbSubShapes = meshDS->MaxShapeIndex();
2378 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2380 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2381 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2384 std::set<int> subIds;
2385 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2386 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2387 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2390 // check if shape topology changes - save shape type per shape ID
2391 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2392 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2393 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2395 // change shape to mesh
2396 _impl->ShapeToMesh( TopoDS_Shape() );
2397 _impl->ShapeToMesh( newShape );
2399 // check if shape topology changes - check new shape types
2400 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2401 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2403 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2404 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2407 // re-add shapes (compounds) of geom groups
2408 std::map< int, int > old2newIDs; // group IDs
2409 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2410 for ( ; data != _geomGroupData.end(); ++data )
2413 std::map< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2414 if ( ii2i != ii2iMap.end() )
2415 oldID = ii2i->second;
2417 TopoDS_Shape newShape = newGroupShape( *data, isBreakLink ? IS_BREAK_LINK : MAIN_TRANSFORMED );
2418 if ( !newShape.IsNull() )
2420 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2422 TopoDS_Compound compound;
2423 BRep_Builder().MakeCompound( compound );
2424 BRep_Builder().Add( compound, newShape );
2425 newShape = compound;
2427 int newID = _impl->GetSubMesh( newShape )->GetId();
2428 if ( oldID && oldID != newID )
2429 old2newIDs.insert( std::make_pair( oldID, newID ));
2433 // re-assign hypotheses
2434 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2436 if ( !sameTopology && ids2Hyps[i].first != 1 )
2437 continue; // assign only global hypos
2438 int sID = ids2Hyps[i].first;
2439 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2440 if ( o2n != old2newIDs.end() )
2442 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2443 const THypList& hyps = ids2Hyps[i].second;
2444 THypList::const_iterator h = hyps.begin();
2445 for ( ; h != hyps.end(); ++h )
2446 _impl->AddHypothesis( s, (*h)->GetID() );
2449 if ( !sameTopology )
2451 // remove invalid study sub-objects
2452 CheckGeomGroupModif();
2456 // restore groups on geometry
2457 for ( size_t i = 0; i < groupsData.size(); ++i )
2459 const TGroupOnGeomData& data = groupsData[i];
2460 if ( data._shape.IsNull() )
2463 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2464 if ( i2g == _mapGroups.end() ) continue;
2466 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2467 if ( !gr_i ) continue;
2469 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2471 _mapGroups.erase( i2g );
2473 g->GetGroupDS()->SetColor( data._color );
2476 std::map< int, int >::iterator o2n = old2newIDs.begin();
2477 for ( ; o2n != old2newIDs.end(); ++o2n )
2479 int newID = o2n->second, oldID = o2n->first;
2480 if ( !_mapSubMesh.count( oldID ))
2484 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2485 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2486 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2488 _mapSubMesh. erase(oldID);
2489 _mapSubMesh_i. erase(oldID);
2490 _mapSubMeshIor.erase(oldID);
2492 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2495 // update _mapSubMesh
2496 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2497 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2498 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2501 _gen_i->UpdateIcons( me );
2505 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2506 if ( !meshSO->_is_nil() )
2507 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2511 //=============================================================================
2513 * \brief Update objects depending on changed geom groups
2515 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2516 * issue 0020210: Update of a smesh group after modification of the associated geom group
2518 //=============================================================================
2520 void SMESH_Mesh_i::CheckGeomGroupModif()
2522 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2523 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2524 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2525 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2526 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2528 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2529 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2530 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2532 int nbValid = 0, nbRemoved = 0;
2533 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2534 for ( ; chItr->More(); chItr->Next() )
2536 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2537 if ( !smSO->_is_nil() &&
2538 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2539 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2541 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2542 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2543 if ( !geom->_non_existent() )
2546 continue; // keep the sub-mesh
2549 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2550 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2551 if ( !sm->_is_nil() && !sm->_non_existent() )
2553 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2554 if ( smGeom->_is_nil() )
2556 RemoveSubMesh( sm );
2563 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2564 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2568 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2569 builder->RemoveObjectWithChildren( rootSO );
2573 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2574 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2575 while ( i_gr != _mapGroups.end())
2577 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2579 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2580 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2581 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2582 bool isValidGeom = false;
2583 if ( !onGeom->_is_nil() )
2585 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2587 else if ( !onFilt->_is_nil() )
2589 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2593 isValidGeom = ( !groupSO->_is_nil() &&
2594 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2598 if ( !IsLoaded() || group->IsEmpty() )
2600 RemoveGroup( group );
2602 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2604 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2606 else // is it possible?
2608 builder->RemoveObjectWithChildren( refSO );
2614 if ( !_impl->HasShapeToMesh() ) return;
2616 CORBA::Long nbEntities = NbNodes() + NbElements();
2618 // Check if group contents changed
2620 typedef map< string, TopoDS_Shape > TEntry2Geom;
2621 TEntry2Geom newGroupContents;
2623 list<TGeomGroupData>::iterator
2624 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2625 for ( ; data != dataEnd; ++data )
2627 pair< TEntry2Geom::iterator, bool > it_new =
2628 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2629 bool processedGroup = !it_new.second;
2630 TopoDS_Shape& newShape = it_new.first->second;
2631 if ( !processedGroup )
2632 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2633 if ( newShape.IsNull() )
2634 continue; // no changes
2637 _preMeshInfo->ForgetOrLoad();
2639 if ( processedGroup ) { // update group indices
2640 list<TGeomGroupData>::iterator data2 = data;
2641 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2642 data->_indices = data2->_indices;
2645 // Update SMESH objects according to new GEOM group contents
2647 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2648 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2650 int oldID = submesh->GetId();
2651 if ( !_mapSubMeshIor.count( oldID ))
2653 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2655 // update hypotheses
2656 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2657 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2658 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2660 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2661 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2663 // care of submeshes
2664 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2665 int newID = newSubmesh->GetId();
2666 if ( newID != oldID ) {
2667 _mapSubMesh [ newID ] = newSubmesh;
2668 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2669 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2670 _mapSubMesh. erase(oldID);
2671 _mapSubMesh_i. erase(oldID);
2672 _mapSubMeshIor.erase(oldID);
2673 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2678 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2679 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2680 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2682 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2684 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2685 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2686 ds->SetShape( newShape );
2691 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2692 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2694 // Remove groups and submeshes basing on removed sub-shapes
2696 TopTools_MapOfShape newShapeMap;
2697 TopoDS_Iterator shapeIt( newShape );
2698 for ( ; shapeIt.More(); shapeIt.Next() )
2699 newShapeMap.Add( shapeIt.Value() );
2701 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2702 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2704 if ( newShapeMap.Contains( shapeIt.Value() ))
2706 TopTools_IndexedMapOfShape oldShapeMap;
2707 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2708 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2710 const TopoDS_Shape& oldShape = oldShapeMap(i);
2711 int oldInd = meshDS->ShapeToIndex( oldShape );
2713 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2714 if ( i_smIor != _mapSubMeshIor.end() ) {
2715 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2718 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2719 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2721 // check if a group bases on oldInd shape
2722 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2723 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2724 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2725 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2727 RemoveGroup( i_grp->second ); // several groups can base on same shape
2728 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2733 // Reassign hypotheses and update groups after setting the new shape to mesh
2735 // collect anassigned hypotheses
2736 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2737 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2738 TShapeHypList assignedHyps;
2739 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2741 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2742 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2743 if ( !hyps.empty() ) {
2744 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2745 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2746 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2749 // collect shapes supporting groups
2750 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2751 TShapeTypeList groupData;
2752 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2753 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2754 for ( ; grIt != groups.end(); ++grIt )
2756 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2758 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2760 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2762 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2763 _impl->ShapeToMesh( newShape );
2765 // reassign hypotheses
2766 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2767 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2769 TIndexedShape& geom = indS_hyps->first;
2770 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2771 int oldID = geom._index;
2772 int newID = meshDS->ShapeToIndex( geom._shape );
2773 if ( oldID == 1 ) { // main shape
2775 geom._shape = newShape;
2779 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2780 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2781 // care of sub-meshes
2782 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2783 if ( newID != oldID ) {
2784 _mapSubMesh [ newID ] = newSubmesh;
2785 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2786 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2787 _mapSubMesh. erase(oldID);
2788 _mapSubMesh_i. erase(oldID);
2789 _mapSubMeshIor.erase(oldID);
2790 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2794 TShapeTypeList::iterator geomType = groupData.begin();
2795 for ( ; geomType != groupData.end(); ++geomType )
2797 const TIndexedShape& geom = geomType->first;
2798 int oldID = geom._index;
2799 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2802 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2803 CORBA::String_var name = groupSO->GetName();
2805 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2806 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2807 /*id=*/-1, geom._shape ))
2808 group_i->changeLocalId( group->GetID() );
2811 break; // everything has been updated
2814 } // loop on group data
2818 CORBA::Long newNbEntities = NbNodes() + NbElements();
2819 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2820 if ( newNbEntities != nbEntities )
2822 // Add all SObjects with icons to soToUpdateIcons
2823 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2825 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2826 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2827 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2829 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2830 i_gr != _mapGroups.end(); ++i_gr ) // groups
2831 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2834 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2835 for ( ; so != soToUpdateIcons.end(); ++so )
2836 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2839 //=============================================================================
2841 * \brief Create standalone group from a group on geometry or filter
2843 //=============================================================================
2845 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2846 throw (SALOME::SALOME_Exception)
2848 SMESH::SMESH_Group_var aGroup;
2853 _preMeshInfo->FullLoadFromFile();
2855 if ( theGroup->_is_nil() )
2856 return aGroup._retn();
2858 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2860 return aGroup._retn();
2862 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2864 const int anId = aGroupToRem->GetLocalID();
2865 if ( !_impl->ConvertToStandalone( anId ) )
2866 return aGroup._retn();
2867 removeGeomGroupData( theGroup );
2869 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2871 // remove old instance of group from own map
2872 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2873 _mapGroups.erase( anId );
2875 SALOMEDS::StudyBuilder_var builder;
2876 SALOMEDS::SObject_wrap aGroupSO;
2877 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2878 if ( !aStudy->_is_nil() ) {
2879 builder = aStudy->NewBuilder();
2880 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2881 if ( !aGroupSO->_is_nil() )
2883 // remove reference to geometry
2884 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2885 for ( ; chItr->More(); chItr->Next() )
2887 // Remove group's child SObject
2888 SALOMEDS::SObject_wrap so = chItr->Value();
2889 builder->RemoveObject( so );
2891 // Update Python script
2892 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2893 << ".ConvertToStandalone( " << aGroupSO << " )";
2895 // change icon of Group on Filter
2898 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2899 // const int isEmpty = ( elemTypes->length() == 0 );
2902 SALOMEDS::GenericAttribute_wrap anAttr =
2903 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2904 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2905 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2911 // remember new group in own map
2912 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2913 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2915 // register CORBA object for persistence
2916 _gen_i->RegisterObject( aGroup );
2918 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2919 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2920 //aGroup->Register();
2921 aGroupToRem->UnRegister();
2923 SMESH_CATCH( SMESH::throwCorbaException );
2925 return aGroup._retn();
2928 //=============================================================================
2932 //=============================================================================
2934 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2936 if(MYDEBUG) MESSAGE( "createSubMesh" );
2937 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2938 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2941 SMESH_subMesh_i * subMeshServant;
2944 subMeshId = mySubMesh->GetId();
2945 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2947 else // "invalid sub-mesh"
2949 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2950 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2951 if ( _mapSubMesh.empty() )
2954 subMeshId = _mapSubMesh.begin()->first - 1;
2955 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2958 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2960 _mapSubMesh [subMeshId] = mySubMesh;
2961 _mapSubMesh_i [subMeshId] = subMeshServant;
2962 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2964 subMeshServant->Register();
2966 // register CORBA object for persistence
2967 int nextId = _gen_i->RegisterObject( subMesh );
2968 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2969 else { nextId = 0; } // avoid "unused variable" warning
2971 // to track changes of GEOM groups
2972 if ( subMeshId > 0 )
2973 addGeomGroupData( theSubShapeObject, subMesh );
2975 return subMesh._retn();
2978 //=======================================================================
2979 //function : getSubMesh
2981 //=======================================================================
2983 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2985 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2986 if ( it == _mapSubMeshIor.end() )
2987 return SMESH::SMESH_subMesh::_nil();
2989 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2992 //=============================================================================
2996 //=============================================================================
2998 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2999 GEOM::GEOM_Object_ptr theSubShapeObject )
3001 bool isHypChanged = false;
3002 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3003 return isHypChanged;
3005 const int subMeshId = theSubMesh->GetId();
3007 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3010 if (( _mapSubMesh.count( subMeshId )) &&
3011 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3013 TopoDS_Shape S = sm->GetSubShape();
3016 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3017 isHypChanged = !hyps.empty();
3018 if ( isHypChanged && _preMeshInfo )
3019 _preMeshInfo->ForgetOrLoad();
3020 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3021 for ( ; hyp != hyps.end(); ++hyp )
3022 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3029 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3030 isHypChanged = ( aHypList->length() > 0 );
3031 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3032 removeHypothesis( theSubShapeObject, aHypList[i] );
3035 catch( const SALOME::SALOME_Exception& ) {
3036 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3038 removeGeomGroupData( theSubShapeObject );
3042 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3043 if ( id_smi != _mapSubMesh_i.end() )
3044 id_smi->second->UnRegister();
3046 // remove a CORBA object
3047 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3048 if ( id_smptr != _mapSubMeshIor.end() )
3049 SMESH::SMESH_subMesh_var( id_smptr->second );
3051 _mapSubMesh.erase(subMeshId);
3052 _mapSubMesh_i.erase(subMeshId);
3053 _mapSubMeshIor.erase(subMeshId);
3055 return isHypChanged;
3058 //=============================================================================
3062 //=============================================================================
3064 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3065 const char* theName,
3067 const TopoDS_Shape& theShape,
3068 const SMESH_PredicatePtr& thePredicate )
3070 std::string newName;
3071 if ( !theName || !theName[0] )
3073 std::set< std::string > presentNames;
3074 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3075 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3077 CORBA::String_var name = i_gr->second->GetName();
3078 presentNames.insert( name.in() );
3081 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3082 } while ( !presentNames.insert( newName ).second );
3083 theName = newName.c_str();
3085 SMESH::SMESH_GroupBase_var aGroup;
3086 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3087 theID, theShape, thePredicate ))
3089 int anId = g->GetID();
3090 SMESH_GroupBase_i* aGroupImpl;
3091 if ( !theShape.IsNull() )
3092 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3093 else if ( thePredicate )
3094 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3096 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3098 aGroup = aGroupImpl->_this();
3099 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3100 aGroupImpl->Register();
3102 // register CORBA object for persistence
3103 int nextId = _gen_i->RegisterObject( aGroup );
3104 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3105 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3107 // to track changes of GEOM groups
3108 if ( !theShape.IsNull() ) {
3109 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3110 addGeomGroupData( geom, aGroup );
3113 return aGroup._retn();
3116 //=============================================================================
3118 * SMESH_Mesh_i::removeGroup
3120 * Should be called by ~SMESH_Group_i()
3122 //=============================================================================
3124 void SMESH_Mesh_i::removeGroup( const int theId )
3126 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3127 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3128 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3129 _mapGroups.erase( theId );
3130 removeGeomGroupData( group );
3131 if ( !_impl->RemoveGroup( theId ))
3133 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3134 RemoveGroup( group );
3136 group->UnRegister();
3140 //=============================================================================
3144 //=============================================================================
3146 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3147 throw(SALOME::SALOME_Exception)
3149 SMESH::log_array_var aLog;
3153 _preMeshInfo->FullLoadFromFile();
3155 list < SMESHDS_Command * >logDS = _impl->GetLog();
3156 aLog = new SMESH::log_array;
3158 int lg = logDS.size();
3161 list < SMESHDS_Command * >::iterator its = logDS.begin();
3162 while(its != logDS.end()){
3163 SMESHDS_Command *com = *its;
3164 int comType = com->GetType();
3166 int lgcom = com->GetNumber();
3168 const list < int >&intList = com->GetIndexes();
3169 int inum = intList.size();
3171 list < int >::const_iterator ii = intList.begin();
3172 const list < double >&coordList = com->GetCoords();
3173 int rnum = coordList.size();
3175 list < double >::const_iterator ir = coordList.begin();
3176 aLog[indexLog].commandType = comType;
3177 aLog[indexLog].number = lgcom;
3178 aLog[indexLog].coords.length(rnum);
3179 aLog[indexLog].indexes.length(inum);
3180 for(int i = 0; i < rnum; i++){
3181 aLog[indexLog].coords[i] = *ir;
3182 //MESSAGE(" "<<i<<" "<<ir.Value());
3185 for(int i = 0; i < inum; i++){
3186 aLog[indexLog].indexes[i] = *ii;
3187 //MESSAGE(" "<<i<<" "<<ii.Value());
3196 SMESH_CATCH( SMESH::throwCorbaException );
3198 return aLog._retn();
3202 //=============================================================================
3206 //=============================================================================
3208 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3212 SMESH_CATCH( SMESH::throwCorbaException );
3215 //=============================================================================
3219 //=============================================================================
3221 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3226 //=============================================================================
3229 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3230 // issue 0020918: groups removal is caused by hyp modification
3231 // issue 0021208: to forget not loaded mesh data at hyp modification
3232 struct TCallUp_i : public SMESH_Mesh::TCallUp
3234 SMESH_Mesh_i* _mesh;
3235 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3236 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3237 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3238 virtual void Load () { _mesh->Load(); }
3242 //================================================================================
3244 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3246 //================================================================================
3248 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3251 _preMeshInfo->ForgetOrLoad();
3253 SMESH::SMESH_Mesh_var mesh = _this();
3254 _gen_i->UpdateIcons( mesh );
3256 // mark a hypothesis as valid after edition
3257 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3258 SALOMEDS::SObject_wrap hypRoot;
3259 if ( !smeshComp->_is_nil() &&
3260 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3262 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3263 for ( ; anIter->More(); anIter->Next() )
3265 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3266 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3267 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3268 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3269 _gen_i->HighLightInvalid( hyp, false );
3274 //=============================================================================
3278 //=============================================================================
3280 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3282 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3285 _impl->SetCallUp( new TCallUp_i(this));
3288 //=============================================================================
3292 //=============================================================================
3294 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3296 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3300 //=============================================================================
3302 * Return mesh editor
3304 //=============================================================================
3306 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3307 throw (SALOME::SALOME_Exception)
3309 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3313 _preMeshInfo->FullLoadFromFile();
3315 // Create MeshEditor
3317 _editor = new SMESH_MeshEditor_i( this, false );
3318 aMeshEdVar = _editor->_this();
3320 // Update Python script
3321 TPythonDump() << _editor << " = "
3322 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3324 SMESH_CATCH( SMESH::throwCorbaException );
3326 return aMeshEdVar._retn();
3329 //=============================================================================
3331 * Return mesh edition previewer
3333 //=============================================================================
3335 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3336 throw (SALOME::SALOME_Exception)
3338 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3342 _preMeshInfo->FullLoadFromFile();
3344 if ( !_previewEditor )
3345 _previewEditor = new SMESH_MeshEditor_i( this, true );
3346 aMeshEdVar = _previewEditor->_this();
3348 SMESH_CATCH( SMESH::throwCorbaException );
3350 return aMeshEdVar._retn();
3353 //================================================================================
3355 * \brief Return true if the mesh has been edited since a last total re-compute
3356 * and those modifications may prevent successful partial re-compute
3358 //================================================================================
3360 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3362 Unexpect aCatch(SALOME_SalomeException);
3363 return _impl->HasModificationsToDiscard();
3366 //================================================================================
3368 * \brief Returns a random unique color
3370 //================================================================================
3372 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3374 const int MAX_ATTEMPTS = 100;
3376 double tolerance = 0.5;
3377 SALOMEDS::Color col;
3381 // generate random color
3382 double red = (double)rand() / RAND_MAX;
3383 double green = (double)rand() / RAND_MAX;
3384 double blue = (double)rand() / RAND_MAX;
3385 // check existence in the list of the existing colors
3386 bool matched = false;
3387 std::list<SALOMEDS::Color>::const_iterator it;
3388 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3389 SALOMEDS::Color color = *it;
3390 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3391 matched = tol < tolerance;
3393 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3394 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3402 //=============================================================================
3404 * Sets auto-color mode. If it is on, groups get unique random colors
3406 //=============================================================================
3408 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3410 Unexpect aCatch(SALOME_SalomeException);
3411 _impl->SetAutoColor(theAutoColor);
3413 TPythonDump pyDump; // not to dump group->SetColor() from below code
3414 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3416 std::list<SALOMEDS::Color> aReservedColors;
3417 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3418 for ( ; it != _mapGroups.end(); it++ ) {
3419 if ( CORBA::is_nil( it->second )) continue;
3420 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3421 it->second->SetColor( aColor );
3422 aReservedColors.push_back( aColor );
3426 //=============================================================================
3428 * Returns true if auto-color mode is on
3430 //=============================================================================
3432 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3434 Unexpect aCatch(SALOME_SalomeException);
3435 return _impl->GetAutoColor();
3438 //=============================================================================
3440 * Checks if there are groups with equal names
3442 //=============================================================================
3444 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3446 return _impl->HasDuplicatedGroupNamesMED();
3449 //================================================================================
3451 * \brief Care of a file before exporting mesh into it
3453 //================================================================================
3455 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3457 SMESH_File aFile( file, false );
3459 if ( aFile.exists() ) {
3460 // existing filesystem node
3461 if ( !aFile.isDirectory() ) {
3462 if ( aFile.openForWriting() ) {
3463 if ( overwrite && ! aFile.remove()) {
3464 msg << "Can't replace " << aFile.getName();
3467 msg << "Can't write into " << aFile.getName();
3470 msg << "Location " << aFile.getName() << " is not a file";
3474 // nonexisting file; check if it can be created
3475 if ( !aFile.openForWriting() ) {
3476 msg << "You cannot create the file "
3478 << ". Check the directory existence and access rights";
3486 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3490 //================================================================================
3492 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3493 * \param file - file name
3494 * \param overwrite - to erase the file or not
3495 * \retval string - mesh name
3497 //================================================================================
3499 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3500 CORBA::Boolean overwrite)
3503 PrepareForWriting(file, overwrite);
3504 string aMeshName = "Mesh";
3505 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3506 if ( !aStudy->_is_nil() ) {
3507 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3508 if ( !aMeshSO->_is_nil() ) {
3509 CORBA::String_var name = aMeshSO->GetName();
3511 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3512 if ( !aStudy->GetProperties()->IsLocked() )
3514 SALOMEDS::GenericAttribute_wrap anAttr;
3515 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3516 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3517 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3518 ASSERT(!aFileName->_is_nil());
3519 aFileName->SetValue(file);
3520 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3521 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3522 ASSERT(!aFileType->_is_nil());
3523 aFileType->SetValue("FICHIERMED");
3527 // Update Python script
3528 // set name of mesh before export
3529 TPythonDump() << _gen_i << ".SetName("
3530 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3532 // check names of groups
3538 //================================================================================
3540 * \brief Export to MED file
3542 //================================================================================
3544 void SMESH_Mesh_i::ExportMED(const char* file,
3545 CORBA::Boolean auto_groups,
3546 CORBA::Long version,
3547 CORBA::Boolean overwrite,
3548 CORBA::Boolean autoDimension)
3549 throw(SALOME::SALOME_Exception)
3551 //MESSAGE("MED minor version: "<< minor);
3554 _preMeshInfo->FullLoadFromFile();
3556 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3557 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3559 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3561 << "auto_groups=" <<auto_groups << ", "
3562 << "minor=" << version << ", "
3563 << "overwrite=" << overwrite << ", "
3564 << "meshPart=None, "
3565 << "autoDimension=" << autoDimension << " )";
3567 SMESH_CATCH( SMESH::throwCorbaException );
3570 //================================================================================
3572 * \brief Export a mesh to a SAUV file
3574 //================================================================================
3576 void SMESH_Mesh_i::ExportSAUV (const char* file,
3577 CORBA::Boolean auto_groups)
3578 throw(SALOME::SALOME_Exception)
3580 Unexpect aCatch(SALOME_SalomeException);
3582 _preMeshInfo->FullLoadFromFile();
3584 string aMeshName = prepareMeshNameAndGroups(file, true);
3585 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3586 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3587 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3591 //================================================================================
3593 * \brief Export a mesh to a DAT file
3595 //================================================================================
3597 void SMESH_Mesh_i::ExportDAT (const char *file)
3598 throw(SALOME::SALOME_Exception)
3600 Unexpect aCatch(SALOME_SalomeException);
3602 _preMeshInfo->FullLoadFromFile();
3604 // Update Python script
3605 // check names of groups
3607 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3610 PrepareForWriting(file);
3611 _impl->ExportDAT(file);
3614 //================================================================================
3616 * \brief Export a mesh to an UNV file
3618 //================================================================================
3620 void SMESH_Mesh_i::ExportUNV (const char *file)
3621 throw(SALOME::SALOME_Exception)
3623 Unexpect aCatch(SALOME_SalomeException);
3625 _preMeshInfo->FullLoadFromFile();
3627 // Update Python script
3628 // check names of groups
3630 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3633 PrepareForWriting(file);
3634 _impl->ExportUNV(file);
3637 //================================================================================
3639 * \brief Export a mesh to an STL file
3641 //================================================================================
3643 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3644 throw(SALOME::SALOME_Exception)
3646 Unexpect aCatch(SALOME_SalomeException);
3648 _preMeshInfo->FullLoadFromFile();
3650 // Update Python script
3651 // check names of groups
3653 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3654 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3656 CORBA::String_var name;
3657 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3658 if ( !so->_is_nil() )
3659 name = so->GetName();
3662 PrepareForWriting( file );
3663 _impl->ExportSTL( file, isascii, name.in() );
3666 //================================================================================
3668 * \brief Export a part of mesh to a med file
3670 //================================================================================
3672 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3674 CORBA::Boolean auto_groups,
3675 CORBA::Long version,
3676 CORBA::Boolean overwrite,
3677 CORBA::Boolean autoDimension,
3678 const GEOM::ListOfFields& fields,
3679 const char* geomAssocFields,
3680 CORBA::Double ZTolerance)
3681 throw (SALOME::SALOME_Exception)
3683 MESSAGE("MED version: "<< version);
3686 _preMeshInfo->FullLoadFromFile();
3689 bool have0dField = false;
3690 if ( fields.length() > 0 )
3692 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3693 if ( shapeToMesh->_is_nil() )
3694 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3696 for ( size_t i = 0; i < fields.length(); ++i )
3698 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3699 THROW_SALOME_CORBA_EXCEPTION
3700 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3701 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3702 if ( fieldShape->_is_nil() )
3703 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3704 if ( !fieldShape->IsSame( shapeToMesh ) )
3705 THROW_SALOME_CORBA_EXCEPTION
3706 ( "Field defined not on shape", SALOME::BAD_PARAM);
3707 if ( fields[i]->GetDimension() == 0 )
3710 if ( geomAssocFields )
3711 for ( int i = 0; geomAssocFields[i]; ++i )
3712 switch ( geomAssocFields[i] ) {
3713 case 'v':case 'e':case 'f':case 's': break;
3714 case 'V':case 'E':case 'F':case 'S': break;
3715 default: THROW_SALOME_CORBA_EXCEPTION
3716 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3720 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3724 string aMeshName = "Mesh";
3725 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3726 if ( CORBA::is_nil( meshPart ) ||
3727 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3729 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3730 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3731 0, autoDimension, /*addODOnVertices=*/have0dField,
3733 meshDS = _impl->GetMeshDS();
3738 _preMeshInfo->FullLoadFromFile();
3740 PrepareForWriting(file, overwrite);
3742 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3743 if ( !SO->_is_nil() ) {
3744 CORBA::String_var name = SO->GetName();
3748 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3749 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3750 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3751 meshDS = tmpDSDeleter._obj = partDS;
3756 if ( _impl->HasShapeToMesh() )
3758 DriverMED_W_Field fieldWriter;
3759 fieldWriter.SetFile( file );
3760 fieldWriter.SetMeshName( aMeshName );
3761 fieldWriter.AddODOnVertices( have0dField );
3763 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3767 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3768 goList->length( fields.length() );
3769 for ( size_t i = 0; i < fields.length(); ++i )
3771 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3774 TPythonDump() << _this() << ".ExportPartToMED( "
3775 << meshPart << ", r'"
3777 << auto_groups << ", "
3779 << overwrite << ", "
3780 << autoDimension << ", "
3782 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3783 << TVar( ZTolerance )
3786 SMESH_CATCH( SMESH::throwCorbaException );
3789 //================================================================================
3791 * Write GEOM fields to MED file
3793 //================================================================================
3795 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3796 SMESHDS_Mesh* meshDS,
3797 const GEOM::ListOfFields& fields,
3798 const char* geomAssocFields)
3800 #define METH "SMESH_Mesh_i::exportMEDFields() "
3802 if (( fields.length() < 1 ) &&
3803 ( !geomAssocFields || !geomAssocFields[0] ))
3806 std::vector< std::vector< double > > dblVals;
3807 std::vector< std::vector< int > > intVals;
3808 std::vector< int > subIdsByDim[ 4 ];
3809 const double noneDblValue = 0.;
3810 const double noneIntValue = 0;
3812 for ( size_t iF = 0; iF < fields.length(); ++iF )
3816 int dim = fields[ iF ]->GetDimension();
3817 SMDSAbs_ElementType elemType;
3818 TopAbs_ShapeEnum shapeType;
3820 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3821 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3822 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3823 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3825 continue; // skip fields on whole shape
3827 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3828 if ( dataType == GEOM::FDT_String )
3830 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3831 if ( stepIDs->length() < 1 )
3833 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3834 if ( comps->length() < 1 )
3836 CORBA::String_var name = fields[ iF ]->GetName();
3838 if ( !fieldWriter.Set( meshDS,
3842 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3845 for ( size_t iC = 0; iC < comps->length(); ++iC )
3846 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3848 dblVals.resize( comps->length() );
3849 intVals.resize( comps->length() );
3851 // find sub-shape IDs
3853 std::vector< int >& subIds = subIdsByDim[ dim ];
3854 if ( subIds.empty() )
3855 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3856 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3857 subIds.push_back( id );
3861 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3865 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3867 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3868 if ( step->_is_nil() )
3871 CORBA::Long stamp = step->GetStamp();
3872 CORBA::Long id = step->GetID();
3873 fieldWriter.SetDtIt( int( stamp ), int( id ));
3875 // fill dblVals or intVals
3876 for ( size_t iC = 0; iC < comps->length(); ++iC )
3877 if ( dataType == GEOM::FDT_Double )
3879 dblVals[ iC ].clear();
3880 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3884 intVals[ iC ].clear();
3885 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3889 case GEOM::FDT_Double:
3891 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3892 if ( dblStep->_is_nil() ) continue;
3893 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3894 if ( vv->length() != subIds.size() * comps->length() )
3895 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3896 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3897 for ( size_t iC = 0; iC < comps->length(); ++iC )
3898 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3903 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3904 if ( intStep->_is_nil() ) continue;
3905 GEOM::ListOfLong_var vv = intStep->GetValues();
3906 if ( vv->length() != subIds.size() * comps->length() )
3907 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3908 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3909 for ( size_t iC = 0; iC < comps->length(); ++iC )
3910 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3913 case GEOM::FDT_Bool:
3915 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3916 if ( boolStep->_is_nil() ) continue;
3917 GEOM::short_array_var vv = boolStep->GetValues();
3918 if ( vv->length() != subIds.size() * comps->length() )
3919 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3920 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3921 for ( size_t iC = 0; iC < comps->length(); ++iC )
3922 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3928 // pass values to fieldWriter
3929 elemIt = fieldWriter.GetOrderedElems();
3930 if ( dataType == GEOM::FDT_Double )
3931 while ( elemIt->more() )
3933 const SMDS_MeshElement* e = elemIt->next();
3934 const int shapeID = e->getshapeId();
3935 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3936 for ( size_t iC = 0; iC < comps->length(); ++iC )
3937 fieldWriter.AddValue( noneDblValue );
3939 for ( size_t iC = 0; iC < comps->length(); ++iC )
3940 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3943 while ( elemIt->more() )
3945 const SMDS_MeshElement* e = elemIt->next();
3946 const int shapeID = e->getshapeId();
3947 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3948 for ( size_t iC = 0; iC < comps->length(); ++iC )
3949 fieldWriter.AddValue( (double) noneIntValue );
3951 for ( size_t iC = 0; iC < comps->length(); ++iC )
3952 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3956 fieldWriter.Perform();
3957 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3958 if ( res && res->IsKO() )
3960 if ( res->myComment.empty() )
3961 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3963 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3969 if ( !geomAssocFields || !geomAssocFields[0] )
3972 // write geomAssocFields
3974 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3975 shapeDim[ TopAbs_COMPOUND ] = 3;
3976 shapeDim[ TopAbs_COMPSOLID ] = 3;
3977 shapeDim[ TopAbs_SOLID ] = 3;
3978 shapeDim[ TopAbs_SHELL ] = 2;
3979 shapeDim[ TopAbs_FACE ] = 2;
3980 shapeDim[ TopAbs_WIRE ] = 1;
3981 shapeDim[ TopAbs_EDGE ] = 1;
3982 shapeDim[ TopAbs_VERTEX ] = 0;
3983 shapeDim[ TopAbs_SHAPE ] = 3;
3985 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3987 std::vector< std::string > compNames;
3988 switch ( geomAssocFields[ iF ]) {
3990 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3991 compNames.push_back( "dim" );
3994 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3997 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4000 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4004 compNames.push_back( "id" );
4005 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4006 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4008 fieldWriter.SetDtIt( -1, -1 );
4010 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4014 if ( compNames.size() == 2 ) // _vertices_
4015 while ( elemIt->more() )
4017 const SMDS_MeshElement* e = elemIt->next();
4018 const int shapeID = e->getshapeId();
4021 fieldWriter.AddValue( (double) -1 );
4022 fieldWriter.AddValue( (double) -1 );
4026 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4027 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4028 fieldWriter.AddValue( (double) shapeID );
4032 while ( elemIt->more() )
4034 const SMDS_MeshElement* e = elemIt->next();
4035 const int shapeID = e->getshapeId();
4037 fieldWriter.AddValue( (double) -1 );
4039 fieldWriter.AddValue( (double) shapeID );
4043 fieldWriter.Perform();
4044 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4045 if ( res && res->IsKO() )
4047 if ( res->myComment.empty() )
4048 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4050 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4053 } // loop on geomAssocFields
4058 //================================================================================
4060 * \brief Export a part of mesh to a DAT file
4062 //================================================================================
4064 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4066 throw (SALOME::SALOME_Exception)
4068 Unexpect aCatch(SALOME_SalomeException);
4070 _preMeshInfo->FullLoadFromFile();
4072 PrepareForWriting(file);
4074 SMESH_MeshPartDS partDS( meshPart );
4075 _impl->ExportDAT(file,&partDS);
4077 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4078 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4080 //================================================================================
4082 * \brief Export a part of mesh to an UNV file
4084 //================================================================================
4086 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4088 throw (SALOME::SALOME_Exception)
4090 Unexpect aCatch(SALOME_SalomeException);
4092 _preMeshInfo->FullLoadFromFile();
4094 PrepareForWriting(file);
4096 SMESH_MeshPartDS partDS( meshPart );
4097 _impl->ExportUNV(file, &partDS);
4099 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4100 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4102 //================================================================================
4104 * \brief Export a part of mesh to an STL file
4106 //================================================================================
4108 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4110 ::CORBA::Boolean isascii)
4111 throw (SALOME::SALOME_Exception)
4113 Unexpect aCatch(SALOME_SalomeException);
4115 _preMeshInfo->FullLoadFromFile();
4117 PrepareForWriting(file);
4119 CORBA::String_var name;
4120 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4121 if ( !so->_is_nil() )
4122 name = so->GetName();
4124 SMESH_MeshPartDS partDS( meshPart );
4125 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4127 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4128 << meshPart<< ", r'" << file << "', " << isascii << ")";
4131 //================================================================================
4133 * \brief Export a part of mesh to an STL file
4135 //================================================================================
4137 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4139 CORBA::Boolean overwrite,
4140 CORBA::Boolean groupElemsByType)
4141 throw (SALOME::SALOME_Exception)
4144 Unexpect aCatch(SALOME_SalomeException);
4146 _preMeshInfo->FullLoadFromFile();
4148 PrepareForWriting(file,overwrite);
4150 std::string meshName("");
4151 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4152 if ( !so->_is_nil() )
4154 CORBA::String_var name = so->GetName();
4155 meshName = name.in();
4159 SMESH_MeshPartDS partDS( meshPart );
4160 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4162 SMESH_CATCH( SMESH::throwCorbaException );
4164 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4165 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4167 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4171 //================================================================================
4173 * \brief Export a part of mesh to a GMF file
4175 //================================================================================
4177 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4179 bool withRequiredGroups)
4180 throw (SALOME::SALOME_Exception)
4182 Unexpect aCatch(SALOME_SalomeException);
4184 _preMeshInfo->FullLoadFromFile();
4186 PrepareForWriting(file,/*overwrite=*/true);
4188 SMESH_MeshPartDS partDS( meshPart );
4189 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4191 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4192 << meshPart<< ", r'"
4194 << withRequiredGroups << ")";
4197 //=============================================================================
4199 * Return computation progress [0.,1]
4201 //=============================================================================
4203 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4207 return _impl->GetComputeProgress();
4209 SMESH_CATCH( SMESH::doNothing );
4213 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4215 Unexpect aCatch(SALOME_SalomeException);
4217 return _preMeshInfo->NbNodes();
4219 return _impl->NbNodes();
4222 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4224 Unexpect aCatch(SALOME_SalomeException);
4226 return _preMeshInfo->NbElements();
4228 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4231 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4233 Unexpect aCatch(SALOME_SalomeException);
4235 return _preMeshInfo->Nb0DElements();
4237 return _impl->Nb0DElements();
4240 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4242 Unexpect aCatch(SALOME_SalomeException);
4244 return _preMeshInfo->NbBalls();
4246 return _impl->NbBalls();
4249 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4251 Unexpect aCatch(SALOME_SalomeException);
4253 return _preMeshInfo->NbEdges();
4255 return _impl->NbEdges();
4258 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4259 throw(SALOME::SALOME_Exception)
4261 Unexpect aCatch(SALOME_SalomeException);
4263 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4265 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4268 //=============================================================================
4270 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4272 Unexpect aCatch(SALOME_SalomeException);
4274 return _preMeshInfo->NbFaces();
4276 return _impl->NbFaces();
4279 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4281 Unexpect aCatch(SALOME_SalomeException);
4283 return _preMeshInfo->NbTriangles();
4285 return _impl->NbTriangles();
4288 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4290 Unexpect aCatch(SALOME_SalomeException);
4292 return _preMeshInfo->NbBiQuadTriangles();
4294 return _impl->NbBiQuadTriangles();
4297 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4299 Unexpect aCatch(SALOME_SalomeException);
4301 return _preMeshInfo->NbQuadrangles();
4303 return _impl->NbQuadrangles();
4306 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4308 Unexpect aCatch(SALOME_SalomeException);
4310 return _preMeshInfo->NbBiQuadQuadrangles();
4312 return _impl->NbBiQuadQuadrangles();
4315 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4317 Unexpect aCatch(SALOME_SalomeException);
4319 return _preMeshInfo->NbPolygons();
4321 return _impl->NbPolygons();
4324 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4326 Unexpect aCatch(SALOME_SalomeException);
4328 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4330 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4333 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4334 throw(SALOME::SALOME_Exception)
4336 Unexpect aCatch(SALOME_SalomeException);
4338 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4340 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4343 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4344 throw(SALOME::SALOME_Exception)
4346 Unexpect aCatch(SALOME_SalomeException);
4348 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4350 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4353 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4354 throw(SALOME::SALOME_Exception)
4356 Unexpect aCatch(SALOME_SalomeException);
4358 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4360 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4363 //=============================================================================
4365 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4367 Unexpect aCatch(SALOME_SalomeException);
4369 return _preMeshInfo->NbVolumes();
4371 return _impl->NbVolumes();
4374 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4376 Unexpect aCatch(SALOME_SalomeException);
4378 return _preMeshInfo->NbTetras();
4380 return _impl->NbTetras();
4383 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4385 Unexpect aCatch(SALOME_SalomeException);
4387 return _preMeshInfo->NbHexas();
4389 return _impl->NbHexas();
4392 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4394 Unexpect aCatch(SALOME_SalomeException);
4396 return _preMeshInfo->NbTriQuadHexas();
4398 return _impl->NbTriQuadraticHexas();
4401 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4403 Unexpect aCatch(SALOME_SalomeException);
4405 return _preMeshInfo->NbPyramids();
4407 return _impl->NbPyramids();
4410 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4412 Unexpect aCatch(SALOME_SalomeException);
4414 return _preMeshInfo->NbPrisms();
4416 return _impl->NbPrisms();
4419 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4421 Unexpect aCatch(SALOME_SalomeException);
4423 return _preMeshInfo->NbHexPrisms();
4425 return _impl->NbHexagonalPrisms();
4428 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4430 Unexpect aCatch(SALOME_SalomeException);
4432 return _preMeshInfo->NbPolyhedrons();
4434 return _impl->NbPolyhedrons();
4437 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4438 throw(SALOME::SALOME_Exception)
4440 Unexpect aCatch(SALOME_SalomeException);
4442 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4444 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4447 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4448 throw(SALOME::SALOME_Exception)
4450 Unexpect aCatch(SALOME_SalomeException);
4452 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4454 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4457 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4458 throw(SALOME::SALOME_Exception)
4460 Unexpect aCatch(SALOME_SalomeException);
4462 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4464 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4467 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4468 throw(SALOME::SALOME_Exception)
4470 Unexpect aCatch(SALOME_SalomeException);
4472 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4474 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4477 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4478 throw(SALOME::SALOME_Exception)
4480 Unexpect aCatch(SALOME_SalomeException);
4482 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4484 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4487 //=============================================================================
4489 * Returns nb of published sub-meshes
4491 //=============================================================================
4493 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4495 Unexpect aCatch(SALOME_SalomeException);
4496 return _mapSubMesh_i.size();
4499 //=============================================================================
4501 * Dumps mesh into a string
4503 //=============================================================================
4505 char* SMESH_Mesh_i::Dump()
4509 return CORBA::string_dup( os.str().c_str() );
4512 //=============================================================================
4514 * Method of SMESH_IDSource interface
4516 //=============================================================================
4518 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4520 return GetElementsId();
4523 //=============================================================================
4525 * Returns ids of all elements
4527 //=============================================================================
4529 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4530 throw (SALOME::SALOME_Exception)
4532 Unexpect aCatch(SALOME_SalomeException);
4534 _preMeshInfo->FullLoadFromFile();
4536 SMESH::long_array_var aResult = new SMESH::long_array();
4537 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4539 if ( aSMESHDS_Mesh == NULL )
4540 return aResult._retn();
4542 long nbElements = NbElements();
4543 aResult->length( nbElements );
4544 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4545 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4546 aResult[i] = anIt->next()->GetID();
4548 return aResult._retn();
4552 //=============================================================================
4554 * Returns ids of all elements of given type
4556 //=============================================================================
4558 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4559 throw (SALOME::SALOME_Exception)
4561 Unexpect aCatch(SALOME_SalomeException);
4563 _preMeshInfo->FullLoadFromFile();
4565 SMESH::long_array_var aResult = new SMESH::long_array();
4566 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4568 if ( aSMESHDS_Mesh == NULL )
4569 return aResult._retn();
4571 long nbElements = NbElements();
4573 // No sense in returning ids of elements along with ids of nodes:
4574 // when theElemType == SMESH::ALL, return node ids only if
4575 // there are no elements
4576 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4577 return GetNodesId();
4579 aResult->length( nbElements );
4583 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4584 while ( i < nbElements && anIt->more() )
4585 aResult[i++] = anIt->next()->GetID();
4587 aResult->length( i );
4589 return aResult._retn();
4592 //=============================================================================
4594 * Returns ids of all nodes
4596 //=============================================================================
4598 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4599 throw (SALOME::SALOME_Exception)
4601 Unexpect aCatch(SALOME_SalomeException);
4603 _preMeshInfo->FullLoadFromFile();
4605 SMESH::long_array_var aResult = new SMESH::long_array();
4606 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4608 if ( aMeshDS == NULL )
4609 return aResult._retn();
4611 long nbNodes = NbNodes();
4612 aResult->length( nbNodes );
4613 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4614 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4615 aResult[i] = anIt->next()->GetID();
4617 return aResult._retn();
4620 //=============================================================================
4624 //=============================================================================
4626 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4627 throw (SALOME::SALOME_Exception)
4629 SMESH::ElementType type = SMESH::ALL;
4633 _preMeshInfo->FullLoadFromFile();
4635 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4637 SMESH_CATCH( SMESH::throwCorbaException );
4642 //=============================================================================
4646 //=============================================================================
4648 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4649 throw (SALOME::SALOME_Exception)
4652 _preMeshInfo->FullLoadFromFile();
4654 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4656 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4658 return ( SMESH::EntityType ) e->GetEntityType();
4661 //=============================================================================
4665 //=============================================================================
4667 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4668 throw (SALOME::SALOME_Exception)
4671 _preMeshInfo->FullLoadFromFile();
4673 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4675 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4677 return ( SMESH::GeometryType ) e->GetGeomType();
4680 //=============================================================================
4682 * Returns ID of elements for given submesh
4684 //=============================================================================
4685 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4686 throw (SALOME::SALOME_Exception)
4688 SMESH::long_array_var aResult = new SMESH::long_array();
4692 _preMeshInfo->FullLoadFromFile();
4694 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4695 if(!SM) return aResult._retn();
4697 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4698 if(!SDSM) return aResult._retn();
4700 aResult->length(SDSM->NbElements());
4702 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4704 while ( eIt->more() ) {
4705 aResult[i++] = eIt->next()->GetID();
4708 SMESH_CATCH( SMESH::throwCorbaException );
4710 return aResult._retn();
4713 //=============================================================================
4715 * Returns ID of nodes for given submesh
4716 * If param all==true - returns all nodes, else -
4717 * returns only nodes on shapes.
4719 //=============================================================================
4721 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4723 throw (SALOME::SALOME_Exception)
4725 SMESH::long_array_var aResult = new SMESH::long_array();
4729 _preMeshInfo->FullLoadFromFile();
4731 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4732 if(!SM) return aResult._retn();
4734 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4735 if(!SDSM) return aResult._retn();
4738 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4739 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4740 while ( nIt->more() ) {
4741 const SMDS_MeshNode* elem = nIt->next();
4742 theElems.insert( elem->GetID() );
4745 else { // all nodes of submesh elements
4746 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4747 while ( eIt->more() ) {
4748 const SMDS_MeshElement* anElem = eIt->next();
4749 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4750 while ( nIt->more() ) {
4751 const SMDS_MeshElement* elem = nIt->next();
4752 theElems.insert( elem->GetID() );
4757 aResult->length(theElems.size());
4758 set<int>::iterator itElem;
4760 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4761 aResult[i++] = *itElem;
4763 SMESH_CATCH( SMESH::throwCorbaException );
4765 return aResult._retn();
4768 //=============================================================================
4770 * Returns type of elements for given submesh
4772 //=============================================================================
4774 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4775 throw (SALOME::SALOME_Exception)
4777 SMESH::ElementType type = SMESH::ALL;
4781 _preMeshInfo->FullLoadFromFile();
4783 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4784 if(!SM) return SMESH::ALL;
4786 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4787 if(!SDSM) return SMESH::ALL;
4789 if(SDSM->NbElements()==0)
4790 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4792 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4793 const SMDS_MeshElement* anElem = eIt->next();
4795 type = ( SMESH::ElementType ) anElem->GetType();
4797 SMESH_CATCH( SMESH::throwCorbaException );
4803 //=============================================================================
4805 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4807 //=============================================================================
4809 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4812 _preMeshInfo->FullLoadFromFile();
4814 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4815 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4820 //=============================================================================
4822 * Get XYZ coordinates of node as list of double
4823 * If there is not node for given ID - returns empty list
4825 //=============================================================================
4827 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4830 _preMeshInfo->FullLoadFromFile();
4832 SMESH::double_array_var aResult = new SMESH::double_array();
4833 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4834 if ( aMeshDS == NULL )
4835 return aResult._retn();
4838 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4840 return aResult._retn();
4844 aResult[0] = aNode->X();
4845 aResult[1] = aNode->Y();
4846 aResult[2] = aNode->Z();
4847 return aResult._retn();
4851 //=============================================================================
4853 * For given node returns list of IDs of inverse elements
4854 * If there is not node for given ID - returns empty list
4856 //=============================================================================
4858 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4859 SMESH::ElementType elemType)
4862 _preMeshInfo->FullLoadFromFile();
4864 SMESH::long_array_var aResult = new SMESH::long_array();
4865 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4866 if ( aMeshDS == NULL )
4867 return aResult._retn();
4870 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4872 return aResult._retn();
4874 // find inverse elements
4875 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4876 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4877 aResult->length( aNode->NbInverseElements( type ));
4878 for( int i = 0; eIt->more(); ++i )
4880 const SMDS_MeshElement* elem = eIt->next();
4881 aResult[ i ] = elem->GetID();
4883 return aResult._retn();
4886 //=============================================================================
4888 * \brief Return position of a node on shape
4890 //=============================================================================
4892 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4895 _preMeshInfo->FullLoadFromFile();
4897 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4898 aNodePosition->shapeID = 0;
4899 aNodePosition->shapeType = GEOM::SHAPE;
4901 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4902 if ( !mesh ) return aNodePosition;
4904 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4906 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4908 aNodePosition->shapeID = aNode->getshapeId();
4909 switch ( pos->GetTypeOfPosition() ) {
4911 aNodePosition->shapeType = GEOM::EDGE;
4912 aNodePosition->params.length(1);
4913 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4915 case SMDS_TOP_FACE: {
4916 SMDS_FacePositionPtr fPos = pos;
4917 aNodePosition->shapeType = GEOM::FACE;
4918 aNodePosition->params.length(2);
4919 aNodePosition->params[0] = fPos->GetUParameter();
4920 aNodePosition->params[1] = fPos->GetVParameter();
4923 case SMDS_TOP_VERTEX:
4924 aNodePosition->shapeType = GEOM::VERTEX;
4926 case SMDS_TOP_3DSPACE:
4927 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4928 aNodePosition->shapeType = GEOM::SOLID;
4929 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4930 aNodePosition->shapeType = GEOM::SHELL;
4936 return aNodePosition;
4939 //=============================================================================
4941 * \brief Return position of an element on shape
4943 //=============================================================================
4945 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4948 _preMeshInfo->FullLoadFromFile();
4950 SMESH::ElementPosition anElementPosition;
4951 anElementPosition.shapeID = 0;
4952 anElementPosition.shapeType = GEOM::SHAPE;
4954 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4955 if ( !mesh ) return anElementPosition;
4957 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4959 anElementPosition.shapeID = anElem->getshapeId();
4960 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4961 if ( !aSp.IsNull() ) {
4962 switch ( aSp.ShapeType() ) {
4964 anElementPosition.shapeType = GEOM::EDGE;
4967 anElementPosition.shapeType = GEOM::FACE;
4970 anElementPosition.shapeType = GEOM::VERTEX;
4973 anElementPosition.shapeType = GEOM::SOLID;
4976 anElementPosition.shapeType = GEOM::SHELL;
4982 return anElementPosition;
4985 //=============================================================================
4987 * If given element is node returns IDs of shape from position
4988 * If there is not node for given ID - returns -1
4990 //=============================================================================
4992 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4995 _preMeshInfo->FullLoadFromFile();
4997 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4998 if ( aMeshDS == NULL )
5002 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5004 return aNode->getshapeId();
5011 //=============================================================================
5013 * For given element returns ID of result shape after
5014 * ::FindShape() from SMESH_MeshEditor
5015 * If there is not element for given ID - returns -1
5017 //=============================================================================
5019 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5022 _preMeshInfo->FullLoadFromFile();
5024 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5025 if ( aMeshDS == NULL )
5028 // try to find element
5029 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5033 ::SMESH_MeshEditor aMeshEditor(_impl);
5034 int index = aMeshEditor.FindShape( elem );
5042 //=============================================================================
5044 * Returns number of nodes for given element
5045 * If there is not element for given ID - returns -1
5047 //=============================================================================
5049 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5052 _preMeshInfo->FullLoadFromFile();
5054 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5055 if ( aMeshDS == NULL ) return -1;
5056 // try to find element
5057 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5058 if(!elem) return -1;
5059 return elem->NbNodes();
5063 //=============================================================================
5065 * Returns ID of node by given index for given element
5066 * If there is not element for given ID - returns -1
5067 * If there is not node for given index - returns -2
5069 //=============================================================================
5071 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5074 _preMeshInfo->FullLoadFromFile();
5076 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5077 if ( aMeshDS == NULL ) return -1;
5078 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5079 if(!elem) return -1;
5080 if( index>=elem->NbNodes() || index<0 ) return -1;
5081 return elem->GetNode(index)->GetID();
5084 //=============================================================================
5086 * Returns IDs of nodes of given element
5088 //=============================================================================
5090 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5093 _preMeshInfo->FullLoadFromFile();
5095 SMESH::long_array_var aResult = new SMESH::long_array();
5096 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5098 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5100 aResult->length( elem->NbNodes() );
5101 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5102 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5103 aResult[ i ] = n->GetID();
5106 return aResult._retn();
5109 //=============================================================================
5111 * Returns true if given node is medium node
5112 * in given quadratic element
5114 //=============================================================================
5116 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5119 _preMeshInfo->FullLoadFromFile();
5121 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5122 if ( aMeshDS == NULL ) return false;
5124 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5125 if(!aNode) return false;
5126 // try to find element
5127 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5128 if(!elem) return false;
5130 return elem->IsMediumNode(aNode);
5134 //=============================================================================
5136 * Returns true if given node is medium node
5137 * in one of quadratic elements
5139 //=============================================================================
5141 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5142 SMESH::ElementType theElemType)
5145 _preMeshInfo->FullLoadFromFile();
5147 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5148 if ( aMeshDS == NULL ) return false;
5151 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5152 if(!aNode) return false;
5154 SMESH_MesherHelper aHelper( *(_impl) );
5156 SMDSAbs_ElementType aType;
5157 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5158 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5159 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5160 else aType = SMDSAbs_All;
5162 return aHelper.IsMedium(aNode,aType);
5166 //=============================================================================
5168 * Returns number of edges for given element
5170 //=============================================================================
5172 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5175 _preMeshInfo->FullLoadFromFile();
5177 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5178 if ( aMeshDS == NULL ) return -1;
5179 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5180 if(!elem) return -1;
5181 return elem->NbEdges();
5185 //=============================================================================
5187 * Returns number of faces for given element
5189 //=============================================================================
5191 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5194 _preMeshInfo->FullLoadFromFile();
5196 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5197 if ( aMeshDS == NULL ) return -1;
5198 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5199 if(!elem) return -1;
5200 return elem->NbFaces();
5203 //=======================================================================
5204 //function : GetElemFaceNodes
5205 //purpose : Returns nodes of given face (counted from zero) for given element.
5206 //=======================================================================
5208 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5209 CORBA::Short faceIndex)
5212 _preMeshInfo->FullLoadFromFile();
5214 SMESH::long_array_var aResult = new SMESH::long_array();
5215 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5217 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5219 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5220 if ( faceIndex < vtool.NbFaces() )
5222 aResult->length( vtool.NbFaceNodes( faceIndex ));
5223 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5224 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5225 aResult[ i ] = nn[ i ]->GetID();
5229 return aResult._retn();
5232 //=======================================================================
5233 //function : GetFaceNormal
5234 //purpose : Returns three components of normal of given mesh face.
5235 //=======================================================================
5237 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5238 CORBA::Boolean normalized)
5241 _preMeshInfo->FullLoadFromFile();
5243 SMESH::double_array_var aResult = new SMESH::double_array();
5245 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5248 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5250 aResult->length( 3 );
5251 aResult[ 0 ] = normal.X();
5252 aResult[ 1 ] = normal.Y();
5253 aResult[ 2 ] = normal.Z();
5256 return aResult._retn();
5259 //=======================================================================
5260 //function : FindElementByNodes
5261 //purpose : Returns an element based on all given nodes.
5262 //=======================================================================
5264 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5267 _preMeshInfo->FullLoadFromFile();
5269 CORBA::Long elemID(0);
5270 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5272 vector< const SMDS_MeshNode * > nn( nodes.length() );
5273 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5274 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5277 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5278 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5279 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5280 _impl->NbVolumes( ORDER_QUADRATIC )))
5281 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5283 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5288 //================================================================================
5290 * \brief Return elements including all given nodes.
5292 //================================================================================
5294 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5295 SMESH::ElementType elemType)
5298 _preMeshInfo->FullLoadFromFile();
5300 SMESH::long_array_var result = new SMESH::long_array();
5302 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5304 vector< const SMDS_MeshNode * > nn( nodes.length() );
5305 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5306 nn[i] = mesh->FindNode( nodes[i] );
5308 std::vector<const SMDS_MeshElement *> elems;
5309 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5310 result->length( elems.size() );
5311 for ( size_t i = 0; i < elems.size(); ++i )
5312 result[i] = elems[i]->GetID();
5314 return result._retn();
5317 //=============================================================================
5319 * Returns true if given element is polygon
5321 //=============================================================================
5323 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5326 _preMeshInfo->FullLoadFromFile();
5328 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5329 if ( aMeshDS == NULL ) return false;
5330 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5331 if(!elem) return false;
5332 return elem->IsPoly();
5336 //=============================================================================
5338 * Returns true if given element is quadratic
5340 //=============================================================================
5342 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5345 _preMeshInfo->FullLoadFromFile();
5347 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5348 if ( aMeshDS == NULL ) return false;
5349 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5350 if(!elem) return false;
5351 return elem->IsQuadratic();
5354 //=============================================================================
5356 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5358 //=============================================================================
5360 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5363 _preMeshInfo->FullLoadFromFile();
5365 if ( const SMDS_BallElement* ball =
5366 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5367 return ball->GetDiameter();
5372 //=============================================================================
5374 * Returns bary center for given element
5376 //=============================================================================
5378 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5381 _preMeshInfo->FullLoadFromFile();
5383 SMESH::double_array_var aResult = new SMESH::double_array();
5384 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5385 if ( aMeshDS == NULL )
5386 return aResult._retn();
5388 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5390 return aResult._retn();
5392 if(elem->GetType()==SMDSAbs_Volume) {
5393 SMDS_VolumeTool aTool;
5394 if(aTool.Set(elem)) {
5396 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5401 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5403 double x=0., y=0., z=0.;
5404 for(; anIt->more(); ) {
5406 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5420 return aResult._retn();
5423 //================================================================================
5425 * \brief Create a group of elements preventing computation of a sub-shape
5427 //================================================================================
5429 SMESH::ListOfGroups*
5430 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5431 const char* theGroupName )
5432 throw ( SALOME::SALOME_Exception )
5434 Unexpect aCatch(SALOME_SalomeException);
5436 if ( !theGroupName || strlen( theGroupName) == 0 )
5437 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5439 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5440 ::SMESH_MeshEditor::ElemFeatures elemType;
5442 // submesh by subshape id
5443 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5444 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5447 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5448 if ( error && error->HasBadElems() )
5450 // sort bad elements by type
5451 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5452 const list<const SMDS_MeshElement*>& badElems =
5453 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5454 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5455 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5456 for ( ; elemIt != elemEnd; ++elemIt )
5458 const SMDS_MeshElement* elem = *elemIt;
5459 if ( !elem ) continue;
5461 if ( elem->GetID() < 1 )
5463 // elem is a temporary element, make a real element
5464 vector< const SMDS_MeshNode* > nodes;
5465 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5466 while ( nIt->more() && elem )
5468 nodes.push_back( nIt->next() );
5469 if ( nodes.back()->GetID() < 1 )
5470 elem = 0; // a temporary element on temporary nodes
5474 ::SMESH_MeshEditor editor( _impl );
5475 elem = editor.AddElement( nodes, elemType.Init( elem ));
5479 elemsByType[ elem->GetType() ].push_back( elem );
5482 // how many groups to create?
5484 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5485 nbTypes += int( !elemsByType[ i ].empty() );
5486 groups->length( nbTypes );
5489 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5491 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5492 if ( elems.empty() ) continue;
5494 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5495 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5497 SMESH::SMESH_Mesh_var mesh = _this();
5498 SALOMEDS::SObject_wrap aSO =
5499 _gen_i->PublishGroup( mesh, groups[ iG ],
5500 GEOM::GEOM_Object::_nil(), theGroupName);
5502 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5503 if ( !grp_i ) continue;
5505 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5506 for ( size_t iE = 0; iE < elems.size(); ++iE )
5507 grpDS->SMDSGroup().Add( elems[ iE ]);
5512 return groups._retn();
5515 //=============================================================================
5517 * Create and publish group servants if any groups were imported or created anyhow
5519 //=============================================================================
5521 void SMESH_Mesh_i::CreateGroupServants()
5523 SMESH::SMESH_Mesh_var aMesh = _this();
5526 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5527 while ( groupIt->more() )
5529 ::SMESH_Group* group = groupIt->next();
5530 int anId = group->GetID();
5532 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5533 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5535 addedIDs.insert( anId );
5537 SMESH_GroupBase_i* aGroupImpl;
5539 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5540 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5542 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5543 shape = groupOnGeom->GetShape();
5546 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5549 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5550 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5551 aGroupImpl->Register();
5553 // register CORBA object for persistence
5554 int nextId = _gen_i->RegisterObject( groupVar );
5555 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5556 else { nextId = 0; } // avoid "unused variable" warning in release mode
5558 // publishing the groups in the study
5559 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5560 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5562 if ( !addedIDs.empty() )
5565 set<int>::iterator id = addedIDs.begin();
5566 for ( ; id != addedIDs.end(); ++id )
5568 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5569 int i = std::distance( _mapGroups.begin(), it );
5570 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5575 //=============================================================================
5577 * \brief Return true if all sub-meshes are computed OK - to update an icon
5579 //=============================================================================
5581 bool SMESH_Mesh_i::IsComputedOK()
5583 return _impl->IsComputedOK();
5586 //=============================================================================
5588 * \brief Return groups cantained in _mapGroups by their IDs
5590 //=============================================================================
5592 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5594 int nbGroups = groupIDs.size();
5595 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5596 aList->length( nbGroups );
5598 list<int>::const_iterator ids = groupIDs.begin();
5599 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5601 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5602 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5603 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5605 aList->length( nbGroups );
5606 return aList._retn();
5609 //=============================================================================
5611 * \brief Return information about imported file
5613 //=============================================================================
5615 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5617 SMESH::MedFileInfo_var res( _medFileInfo );
5618 if ( !res.operator->() ) {
5619 res = new SMESH::MedFileInfo;
5621 res->fileSize = res->major = res->minor = res->release = -1;
5626 //=======================================================================
5627 //function : FileInfoToString
5628 //purpose : Persistence of file info
5629 //=======================================================================
5631 std::string SMESH_Mesh_i::FileInfoToString()
5634 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5636 s = SMESH_Comment( _medFileInfo->fileSize )
5637 << " " << _medFileInfo->major
5638 << " " << _medFileInfo->minor
5639 << " " << _medFileInfo->release
5640 << " " << _medFileInfo->fileName;
5645 //=======================================================================
5646 //function : FileInfoFromString
5647 //purpose : Persistence of file info
5648 //=======================================================================
5650 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5652 std::string size, major, minor, release, fileName;
5653 std::istringstream is(info);
5654 is >> size >> major >> minor >> release;
5655 fileName = info.data() + ( size.size() + 1 +
5658 release.size()+ 1 );
5660 _medFileInfo = new SMESH::MedFileInfo();
5661 _medFileInfo->fileName = fileName.c_str();
5662 _medFileInfo->fileSize = atoi( size.c_str() );
5663 _medFileInfo->major = atoi( major.c_str() );
5664 _medFileInfo->minor = atoi( minor.c_str() );
5665 _medFileInfo->release = atoi( release.c_str() );
5668 //=============================================================================
5670 * \brief Pass names of mesh groups from study to mesh DS
5672 //=============================================================================
5674 void SMESH_Mesh_i::checkGroupNames()
5676 int nbGrp = NbGroups();
5680 SMESH::ListOfGroups* grpList = 0;
5681 // avoid dump of "GetGroups"
5683 // store python dump into a local variable inside local scope
5684 SMESH::TPythonDump pDump; // do not delete this line of code
5685 grpList = GetGroups();
5688 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5689 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5692 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5693 if ( aGrpSO->_is_nil() )
5695 // correct name of the mesh group if necessary
5696 const char* guiName = aGrpSO->GetName();
5697 if ( strcmp(guiName, aGrp->GetName()) )
5698 aGrp->SetName( guiName );
5702 //=============================================================================
5704 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5706 //=============================================================================
5707 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5709 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5713 //=============================================================================
5715 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5717 //=============================================================================
5719 char* SMESH_Mesh_i::GetParameters()
5721 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5724 //=============================================================================
5726 * \brief Returns list of notebook variables used for last Mesh operation
5728 //=============================================================================
5729 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5731 SMESH::string_array_var aResult = new SMESH::string_array();
5732 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5734 CORBA::String_var aParameters = GetParameters();
5735 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5736 if ( aSections->length() > 0 ) {
5737 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5738 aResult->length( aVars.length() );
5739 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5740 aResult[i] = CORBA::string_dup( aVars[i] );
5743 return aResult._retn();
5746 //=======================================================================
5747 //function : GetTypes
5748 //purpose : Returns types of elements it contains
5749 //=======================================================================
5751 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5754 return _preMeshInfo->GetTypes();
5756 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5760 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5761 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5762 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5763 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5764 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5765 if (_impl->NbNodes() &&
5766 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5767 types->length( nbTypes );
5769 return types._retn();
5772 //=======================================================================
5773 //function : GetMesh
5774 //purpose : Returns self
5775 //=======================================================================
5777 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5779 return SMESH::SMESH_Mesh::_duplicate( _this() );
5782 //=======================================================================
5783 //function : IsMeshInfoCorrect
5784 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5785 // * happen if mesh data is not yet fully loaded from the file of study.
5786 //=======================================================================
5788 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5790 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5793 //=============================================================================
5795 * \brief Returns number of mesh elements per each \a EntityType
5797 //=============================================================================
5799 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5802 return _preMeshInfo->GetMeshInfo();
5804 SMESH::long_array_var aRes = new SMESH::long_array();
5805 aRes->length(SMESH::Entity_Last);
5806 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5808 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5810 return aRes._retn();
5811 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5812 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5813 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5814 return aRes._retn();
5817 //=============================================================================
5819 * \brief Returns number of mesh elements per each \a ElementType
5821 //=============================================================================
5823 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5825 SMESH::long_array_var aRes = new SMESH::long_array();
5826 aRes->length(SMESH::NB_ELEMENT_TYPES);
5827 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5830 const SMDS_MeshInfo* meshInfo = 0;
5832 meshInfo = _preMeshInfo;
5833 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5834 meshInfo = & meshDS->GetMeshInfo();
5837 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5838 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5840 return aRes._retn();
5843 //=============================================================================
5845 * Collect statistic of mesh elements given by iterator
5847 //=============================================================================
5849 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5850 SMESH::long_array& theInfo)
5852 if (!theItr) return;
5853 while (theItr->more())
5854 theInfo[ theItr->next()->GetEntityType() ]++;
5856 //=============================================================================
5858 * Returns mesh unstructed grid information.
5860 //=============================================================================
5862 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5864 SALOMEDS::TMPFile_var SeqFile;
5865 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5866 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5868 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5869 aWriter->WriteToOutputStringOn();
5870 aWriter->SetInputData(aGrid);
5871 aWriter->SetFileTypeToBinary();
5873 char* str = aWriter->GetOutputString();
5874 int size = aWriter->GetOutputStringLength();
5876 //Allocate octet buffer of required size
5877 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5878 //Copy ostrstream content to the octet buffer
5879 memcpy(OctetBuf, str, size);
5880 //Create and return TMPFile
5881 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5885 return SeqFile._retn();
5888 //=============================================================================
5889 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5890 * SMESH::ElementType type) */
5892 using namespace SMESH::Controls;
5893 //-----------------------------------------------------------------------------
5894 struct PredicateIterator : public SMDS_ElemIterator
5896 SMDS_ElemIteratorPtr _elemIter;
5897 PredicatePtr _predicate;
5898 const SMDS_MeshElement* _elem;
5899 SMDSAbs_ElementType _type;
5901 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5902 PredicatePtr predicate,
5903 SMDSAbs_ElementType type):
5904 _elemIter(iterator), _predicate(predicate), _type(type)
5912 virtual const SMDS_MeshElement* next()
5914 const SMDS_MeshElement* res = _elem;
5916 while ( _elemIter->more() && !_elem )
5918 if ((_elem = _elemIter->next()) &&
5919 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5920 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5927 //-----------------------------------------------------------------------------
5928 struct IDSourceIterator : public SMDS_ElemIterator
5930 const CORBA::Long* _idPtr;
5931 const CORBA::Long* _idEndPtr;
5932 SMESH::long_array_var _idArray;
5933 const SMDS_Mesh* _mesh;
5934 const SMDSAbs_ElementType _type;
5935 const SMDS_MeshElement* _elem;
5937 IDSourceIterator( const SMDS_Mesh* mesh,
5938 const CORBA::Long* ids,
5940 SMDSAbs_ElementType type):
5941 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5943 if ( _idPtr && nbIds && _mesh )
5946 IDSourceIterator( const SMDS_Mesh* mesh,
5947 SMESH::long_array* idArray,
5948 SMDSAbs_ElementType type):
5949 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5951 if ( idArray && _mesh )
5953 _idPtr = &_idArray[0];
5954 _idEndPtr = _idPtr + _idArray->length();
5962 virtual const SMDS_MeshElement* next()
5964 const SMDS_MeshElement* res = _elem;
5966 while ( _idPtr < _idEndPtr && !_elem )
5968 if ( _type == SMDSAbs_Node )
5970 _elem = _mesh->FindNode( *_idPtr++ );
5972 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5973 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5981 //-----------------------------------------------------------------------------
5983 struct NodeOfElemIterator : public SMDS_ElemIterator
5985 TColStd_MapOfInteger _checkedNodeIDs;
5986 SMDS_ElemIteratorPtr _elemIter;
5987 SMDS_ElemIteratorPtr _nodeIter;
5988 const SMDS_MeshElement* _node;
5990 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5992 if ( _elemIter && _elemIter->more() )
5994 _nodeIter = _elemIter->next()->nodesIterator();
6002 virtual const SMDS_MeshElement* next()
6004 const SMDS_MeshElement* res = _node;
6006 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6008 if ( _nodeIter->more() )
6010 _node = _nodeIter->next();
6011 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6016 _nodeIter = _elemIter->next()->nodesIterator();
6024 //=============================================================================
6026 * Return iterator on elements of given type in given object
6028 //=============================================================================
6030 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6031 SMESH::ElementType theType)
6033 SMDS_ElemIteratorPtr elemIt;
6034 bool typeOK = ( theType == SMESH::ALL );
6035 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6037 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6038 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6039 if ( !mesh_i ) return elemIt;
6040 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6042 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6044 elemIt = meshDS->elementsIterator( elemType );
6047 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6049 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6052 elemIt = sm->GetElements();
6053 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6055 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6056 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6060 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6062 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6063 if ( groupDS && ( elemType == groupDS->GetType() ||
6064 elemType == SMDSAbs_Node ||
6065 elemType == SMDSAbs_All ))
6067 elemIt = groupDS->GetElements();
6068 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6071 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6073 if ( filter_i->GetElementType() == theType ||
6074 filter_i->GetElementType() == SMESH::ALL ||
6075 elemType == SMDSAbs_Node ||
6076 elemType == SMDSAbs_All)
6078 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6079 if ( pred_i && pred_i->GetPredicate() )
6081 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6082 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6083 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6084 elemIt = SMDS_ElemIteratorPtr
6085 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6086 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6092 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6093 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6094 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6096 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6097 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6100 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6101 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6105 SMESH::long_array_var ids = theObject->GetIDs();
6106 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6108 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6111 if ( elemIt && elemIt->more() && !typeOK )
6113 if ( elemType == SMDSAbs_Node )
6115 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6119 elemIt = SMDS_ElemIteratorPtr();
6125 //=============================================================================
6126 namespace // Finding concurrent hypotheses
6127 //=============================================================================
6131 * \brief mapping of mesh dimension into shape type
6133 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6135 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6137 case 0: aType = TopAbs_VERTEX; break;
6138 case 1: aType = TopAbs_EDGE; break;
6139 case 2: aType = TopAbs_FACE; break;
6141 default:aType = TopAbs_SOLID; break;
6146 //-----------------------------------------------------------------------------
6148 * \brief Internal structure used to find concurrent submeshes
6150 * It represents a pair < submesh, concurrent dimension >, where
6151 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6152 * with another submesh. In other words, it is dimension of a hypothesis assigned
6159 int _dim; //!< a dimension the algo can build (concurrent dimension)
6160 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6161 TopTools_MapOfShape _shapeMap;
6162 SMESH_subMesh* _subMesh;
6163 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6165 //-----------------------------------------------------------------------------
6166 // Return the algorithm
6167 const SMESH_Algo* GetAlgo() const
6168 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6170 //-----------------------------------------------------------------------------
6172 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6174 const TopoDS_Shape& theShape)
6176 _subMesh = (SMESH_subMesh*)theSubMesh;
6177 SetShape( theDim, theShape );
6180 //-----------------------------------------------------------------------------
6182 void SetShape(const int theDim,
6183 const TopoDS_Shape& theShape)
6186 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6187 if (_dim >= _ownDim)
6188 _shapeMap.Add( theShape );
6190 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6191 for( ; anExp.More(); anExp.Next() )
6192 _shapeMap.Add( anExp.Current() );
6196 //-----------------------------------------------------------------------------
6197 //! Check sharing of sub-shapes
6198 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6199 const TopTools_MapOfShape& theToFind,
6200 const TopAbs_ShapeEnum theType)
6202 bool isShared = false;
6203 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6204 for (; !isShared && anItr.More(); anItr.Next() )
6206 const TopoDS_Shape aSubSh = anItr.Key();
6207 // check for case when concurrent dimensions are same
6208 isShared = theToFind.Contains( aSubSh );
6209 // check for sub-shape with concurrent dimension
6210 TopExp_Explorer anExp( aSubSh, theType );
6211 for ( ; !isShared && anExp.More(); anExp.Next() )
6212 isShared = theToFind.Contains( anExp.Current() );
6217 //-----------------------------------------------------------------------------
6218 //! check algorithms
6219 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6220 const SMESHDS_Hypothesis* theA2)
6222 if ( !theA1 || !theA2 ||
6223 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6224 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6225 return false; // one of the hypothesis is not algorithm
6226 // check algorithm names (should be equal)
6227 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6231 //-----------------------------------------------------------------------------
6232 //! Check if sub-shape hypotheses are concurrent
6233 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6235 if ( _subMesh == theOther->_subMesh )
6236 return false; // same sub-shape - should not be
6238 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6239 // any of the two submeshes is not on COMPOUND shape )
6240 // -> no concurrency
6241 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6242 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6243 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6244 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6245 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6248 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6249 if ( !checkSubShape )
6252 // check algorithms to be same
6253 const SMESH_Algo* a1 = this->GetAlgo();
6254 const SMESH_Algo* a2 = theOther->GetAlgo();
6255 bool isSame = checkAlgo( a1, a2 );
6259 return false; // pb?
6260 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6263 // check hypothesises for concurrence (skip first as algorithm)
6265 // pointers should be same, because it is referened from mesh hypothesis partition
6266 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6267 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6268 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6269 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6271 // the submeshes are concurrent if their algorithms has different parameters
6272 return nbSame != theOther->_hypotheses.size() - 1;
6275 // Return true if algorithm of this SMESH_DimHyp is used if no
6276 // sub-mesh order is imposed by the user
6277 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6279 // NeedDiscreteBoundary() algo has a higher priority
6280 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6281 theOther->GetAlgo()->NeedDiscreteBoundary() )
6282 return !this->GetAlgo()->NeedDiscreteBoundary();
6284 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6287 }; // end of SMESH_DimHyp
6288 //-----------------------------------------------------------------------------
6290 typedef list<const SMESH_DimHyp*> TDimHypList;
6292 //-----------------------------------------------------------------------------
6294 void addDimHypInstance(const int theDim,
6295 const TopoDS_Shape& theShape,
6296 const SMESH_Algo* theAlgo,
6297 const SMESH_subMesh* theSubMesh,
6298 const list <const SMESHDS_Hypothesis*>& theHypList,
6299 TDimHypList* theDimHypListArr )
6301 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6302 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6303 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6304 dimHyp->_hypotheses.push_front(theAlgo);
6305 listOfdimHyp.push_back( dimHyp );
6308 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6309 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6310 theHypList.begin(), theHypList.end() );
6313 //-----------------------------------------------------------------------------
6314 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6315 TDimHypList& theListOfConcurr)
6317 if ( theListOfConcurr.empty() )
6319 theListOfConcurr.push_back( theDimHyp );
6323 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6324 while ( hypIt != theListOfConcurr.end() &&
6325 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6327 theListOfConcurr.insert( hypIt, theDimHyp );
6331 //-----------------------------------------------------------------------------
6332 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6333 const TDimHypList& theListOfDimHyp,
6334 TDimHypList& theListOfConcurrHyp,
6335 set<int>& theSetOfConcurrId )
6337 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6338 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6340 const SMESH_DimHyp* curDimHyp = *rIt;
6341 if ( curDimHyp == theDimHyp )
6342 break; // meet own dimHyp pointer in same dimension
6344 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6345 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6347 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6352 //-----------------------------------------------------------------------------
6353 void unionLists(TListOfInt& theListOfId,
6354 TListOfListOfInt& theListOfListOfId,
6357 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6358 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6360 continue; //skip already treated lists
6361 // check if other list has any same submesh object
6362 TListOfInt& otherListOfId = *it;
6363 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6364 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6367 // union two lists (from source into target)
6368 TListOfInt::iterator it2 = otherListOfId.begin();
6369 for ( ; it2 != otherListOfId.end(); it2++ ) {
6370 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6371 theListOfId.push_back(*it2);
6373 // clear source list
6374 otherListOfId.clear();
6377 //-----------------------------------------------------------------------------
6379 //! free memory allocated for dimension-hypothesis objects
6380 void removeDimHyps( TDimHypList* theArrOfList )
6382 for (int i = 0; i < 4; i++ ) {
6383 TDimHypList& listOfdimHyp = theArrOfList[i];
6384 TDimHypList::const_iterator it = listOfdimHyp.begin();
6385 for ( ; it != listOfdimHyp.end(); it++ )
6390 //-----------------------------------------------------------------------------
6392 * \brief find common submeshes with given submesh
6393 * \param theSubMeshList list of already collected submesh to check
6394 * \param theSubMesh given submesh to intersect with other
6395 * \param theCommonSubMeshes collected common submeshes
6397 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6398 const SMESH_subMesh* theSubMesh,
6399 set<const SMESH_subMesh*>& theCommon )
6403 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6404 for ( ; it != theSubMeshList.end(); it++ )
6405 theSubMesh->FindIntersection( *it, theCommon );
6406 theSubMeshList.push_back( theSubMesh );
6407 //theCommon.insert( theSubMesh );
6410 //-----------------------------------------------------------------------------
6411 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6413 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6414 for ( ; listsIt != smLists.end(); ++listsIt )
6416 const TListOfInt& smIDs = *listsIt;
6417 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6425 //=============================================================================
6427 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6429 //=============================================================================
6431 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6433 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6434 if ( isSubMeshInList( submeshID, anOrder ))
6437 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6438 return isSubMeshInList( submeshID, allConurrent );
6441 //=============================================================================
6443 * \brief Return submesh objects list in meshing order
6445 //=============================================================================
6447 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6449 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6451 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6453 return aResult._retn();
6455 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6456 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6457 anOrder.splice( anOrder.end(), allConurrent );
6460 TListOfListOfInt::iterator listIt = anOrder.begin();
6461 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6462 unionLists( *listIt, anOrder, listIndx + 1 );
6464 // convert submesh ids into interface instances
6465 // and dump command into python
6466 convertMeshOrder( anOrder, aResult, false );
6468 return aResult._retn();
6471 //=============================================================================
6473 * \brief Finds concurrent sub-meshes
6475 //=============================================================================
6477 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6479 TListOfListOfInt anOrder;
6480 ::SMESH_Mesh& mesh = GetImpl();
6482 // collect submeshes and detect concurrent algorithms and hypothesises
6483 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6485 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6486 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6487 ::SMESH_subMesh* sm = (*i_sm).second;
6489 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6491 // list of assigned hypothesises
6492 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6493 // Find out dimensions where the submesh can be concurrent.
6494 // We define the dimensions by algo of each of hypotheses in hypList
6495 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6496 for( ; hypIt != hypList.end(); hypIt++ ) {
6497 SMESH_Algo* anAlgo = 0;
6498 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6499 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6500 // hyp it-self is algo
6501 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6503 // try to find algorithm with help of sub-shapes
6504 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6505 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6506 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6509 continue; // no algorithm assigned to a current submesh
6511 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6512 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6514 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6515 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6516 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6518 } // end iterations on submesh
6520 // iterate on created dimension-hypotheses and check for concurrents
6521 for ( int i = 0; i < 4; i++ ) {
6522 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6523 // check for concurrents in own and other dimensions (step-by-step)
6524 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6525 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6526 const SMESH_DimHyp* dimHyp = *dhIt;
6527 TDimHypList listOfConcurr;
6528 set<int> setOfConcurrIds;
6529 // looking for concurrents and collect into own list
6530 for ( int j = i; j < 4; j++ )
6531 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6532 // check if any concurrents found
6533 if ( listOfConcurr.size() > 0 ) {
6534 // add own submesh to list of concurrent
6535 addInOrderOfPriority( dimHyp, listOfConcurr );
6536 list<int> listOfConcurrIds;
6537 TDimHypList::iterator hypIt = listOfConcurr.begin();
6538 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6539 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6540 anOrder.push_back( listOfConcurrIds );
6545 removeDimHyps(dimHypListArr);
6547 // now, minimize the number of concurrent groups
6548 // Here we assume that lists of submeshes can have same submesh
6549 // in case of multi-dimension algorithms, as result
6550 // list with common submesh has to be united into one list
6552 TListOfListOfInt::iterator listIt = anOrder.begin();
6553 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6554 unionLists( *listIt, anOrder, listIndx + 1 );
6560 //=============================================================================
6562 * \brief Set submesh object order
6563 * \param theSubMeshArray submesh array order
6565 //=============================================================================
6567 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6570 _preMeshInfo->ForgetOrLoad();
6573 ::SMESH_Mesh& mesh = GetImpl();
6575 TPythonDump aPythonDump; // prevent dump of called methods
6576 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6578 TListOfListOfInt subMeshOrder;
6579 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6581 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6582 TListOfInt subMeshIds;
6584 aPythonDump << ", ";
6585 aPythonDump << "[ ";
6586 // Collect subMeshes which should be clear
6587 // do it list-by-list, because modification of submesh order
6588 // take effect between concurrent submeshes only
6589 set<const SMESH_subMesh*> subMeshToClear;
6590 list<const SMESH_subMesh*> subMeshList;
6591 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6593 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6595 aPythonDump << ", ";
6596 aPythonDump << subMesh;
6597 subMeshIds.push_back( subMesh->GetId() );
6598 // detect common parts of submeshes
6599 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6600 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6602 aPythonDump << " ]";
6603 subMeshOrder.push_back( subMeshIds );
6605 // clear collected sub-meshes
6606 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6607 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6608 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6610 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6611 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6612 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6615 aPythonDump << " ])";
6617 mesh.SetMeshOrder( subMeshOrder );
6620 SMESH::SMESH_Mesh_var me = _this();
6621 _gen_i->UpdateIcons( me );
6626 //=============================================================================
6628 * \brief Convert submesh ids into submesh interfaces
6630 //=============================================================================
6632 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6633 SMESH::submesh_array_array& theResOrder,
6634 const bool theIsDump)
6636 int nbSet = theIdsOrder.size();
6637 TPythonDump aPythonDump; // prevent dump of called methods
6639 aPythonDump << "[ ";
6640 theResOrder.length(nbSet);
6641 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6643 for( ; it != theIdsOrder.end(); it++ ) {
6644 // translate submesh identificators into submesh objects
6645 // takeing into account real number of concurrent lists
6646 const TListOfInt& aSubOrder = (*it);
6647 if (!aSubOrder.size())
6650 aPythonDump << "[ ";
6651 // convert shape indices into interfaces
6652 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6653 aResSubSet->length(aSubOrder.size());
6654 TListOfInt::const_iterator subIt = aSubOrder.begin();
6656 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6657 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6659 SMESH::SMESH_subMesh_var subMesh =
6660 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6663 aPythonDump << ", ";
6664 aPythonDump << subMesh;
6666 aResSubSet[ j++ ] = subMesh;
6669 aPythonDump << " ]";
6671 theResOrder[ listIndx++ ] = aResSubSet;
6673 // correct number of lists
6674 theResOrder.length( listIndx );
6677 // finilise python dump
6678 aPythonDump << " ]";
6679 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6683 namespace // utils used by SMESH_MeshPartDS
6686 * \brief Class used to access to protected data of SMDS_MeshInfo
6688 struct TMeshInfo : public SMDS_MeshInfo
6690 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6693 * \brief Element holing its ID only
6695 struct TElemID : public SMDS_LinearEdge
6697 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6701 //================================================================================
6703 // Implementation of SMESH_MeshPartDS
6705 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6706 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6708 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6709 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6712 _meshDS = mesh_i->GetImpl().GetMeshDS();
6714 SetPersistentId( _meshDS->GetPersistentId() );
6716 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6718 // <meshPart> is the whole mesh
6719 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6721 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6722 myGroupSet = _meshDS->GetGroups();
6727 SMESH::long_array_var anIDs = meshPart->GetIDs();
6728 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6729 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6731 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6732 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6733 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6738 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6739 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6740 if ( _elements[ e->GetType() ].insert( e ).second )
6743 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6744 while ( nIt->more() )
6746 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6747 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6754 ShapeToMesh( _meshDS->ShapeToMesh() );
6756 _meshDS = 0; // to enforce iteration on _elements and _nodes
6759 // -------------------------------------------------------------------------------------
6760 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6761 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6764 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6765 for ( ; partIt != meshPart.end(); ++partIt )
6766 if ( const SMDS_MeshElement * e = *partIt )
6767 if ( _elements[ e->GetType() ].insert( e ).second )
6770 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6771 while ( nIt->more() )
6773 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6774 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6780 // -------------------------------------------------------------------------------------
6781 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6783 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6785 TElemID elem( IDelem );
6786 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6787 if ( !_elements[ iType ].empty() )
6789 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6790 if ( it != _elements[ iType ].end() )
6795 // -------------------------------------------------------------------------------------
6796 bool SMESH_MeshPartDS::HasNumerationHoles()
6798 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6800 return ( MinNodeID() != 1 ||
6801 MaxNodeID() != NbNodes() ||
6802 MinElementID() != 1 ||
6803 MaxElementID() != NbElements() );
6805 // -------------------------------------------------------------------------------------
6806 int SMESH_MeshPartDS::MaxNodeID() const
6808 if ( _meshDS ) return _meshDS->MaxNodeID();
6809 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6811 // -------------------------------------------------------------------------------------
6812 int SMESH_MeshPartDS::MinNodeID() const
6814 if ( _meshDS ) return _meshDS->MinNodeID();
6815 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6817 // -------------------------------------------------------------------------------------
6818 int SMESH_MeshPartDS::MaxElementID() const
6820 if ( _meshDS ) return _meshDS->MaxElementID();
6822 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6823 if ( !_elements[ iType ].empty() )
6824 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6827 // -------------------------------------------------------------------------------------
6828 int SMESH_MeshPartDS::MinElementID() const
6830 if ( _meshDS ) return _meshDS->MinElementID();
6832 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6833 if ( !_elements[ iType ].empty() )
6834 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6837 // -------------------------------------------------------------------------------------
6838 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6840 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6842 typedef SMDS_SetIterator
6843 <const SMDS_MeshElement*,
6844 TIDSortedElemSet::const_iterator,
6845 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6846 SMDS_MeshElement::GeomFilter
6849 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6851 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6852 _elements[type].end(),
6853 SMDS_MeshElement::GeomFilter( geomType )));
6855 // -------------------------------------------------------------------------------------
6856 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6858 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6860 typedef SMDS_SetIterator
6861 <const SMDS_MeshElement*,
6862 TIDSortedElemSet::const_iterator,
6863 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6864 SMDS_MeshElement::EntityFilter
6867 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6869 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6870 _elements[type].end(),
6871 SMDS_MeshElement::EntityFilter( entity )));
6873 // -------------------------------------------------------------------------------------
6874 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6876 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6877 if ( type == SMDSAbs_All && !_meshDS )
6879 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6881 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6882 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6884 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6886 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6887 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6889 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6890 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6892 // -------------------------------------------------------------------------------------
6893 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6894 iterType SMESH_MeshPartDS::methName() const \
6896 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6897 return _meshDS ? _meshDS->methName() : iterType \
6898 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6900 // -------------------------------------------------------------------------------------
6901 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6902 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6903 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6904 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6905 #undef _GET_ITER_DEFINE
6907 // END Implementation of SMESH_MeshPartDS
6909 //================================================================================