1 // Copyright (C) 2007-2020 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++;
119 _previewEditor = NULL;
124 //=============================================================================
128 //=============================================================================
130 SMESH_Mesh_i::~SMESH_Mesh_i()
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 aGroup->UnRegister();
138 SMESH::SMESH_GroupBase_var( itGr->second );
143 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
144 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
145 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
147 aSubMesh->UnRegister();
148 SMESH::SMESH_subMesh_var( itSM->second );
150 _mapSubMeshIor.clear();
152 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
156 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
157 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
160 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
164 // clear cached shapes if no more meshes remain; (the cache is blame,
165 // together with publishing, of spent time increasing in issue 22874)
166 if ( _impl->NbMeshes() == 1 )
167 _gen_i->GetShapeReader()->ClearClientBuffer();
169 delete _editor; _editor = NULL;
170 delete _previewEditor; _previewEditor = NULL;
171 delete _impl; _impl = NULL;
172 delete _preMeshInfo; _preMeshInfo = NULL;
175 //=============================================================================
179 * Associate <this> mesh with <theShape> and put a reference
180 * to <theShape> into the current study;
181 * the previous shape is substituted by the new one.
183 //=============================================================================
185 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
186 throw (SALOME::SALOME_Exception)
188 Unexpect aCatch(SALOME_SalomeException);
190 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
192 catch(SALOME_Exception & S_ex) {
193 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
195 // to track changes of GEOM groups
196 SMESH::SMESH_Mesh_var mesh = _this();
197 addGeomGroupData( theShapeObject, mesh );
198 if ( !CORBA::is_nil( theShapeObject ))
199 _mainShapeTick = theShapeObject->GetTick();
202 //================================================================================
204 * \brief Return true if mesh has a shape to build a shape on
206 //================================================================================
208 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
209 throw (SALOME::SALOME_Exception)
211 Unexpect aCatch(SALOME_SalomeException);
214 res = _impl->HasShapeToMesh();
216 catch(SALOME_Exception & S_ex) {
217 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
222 //================================================================================
224 * \brief Return the shape to mesh
226 //================================================================================
228 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
229 throw (SALOME::SALOME_Exception)
231 Unexpect aCatch(SALOME_SalomeException);
232 GEOM::GEOM_Object_var aShapeObj;
234 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
237 aShapeObj = _gen_i->ShapeToGeomObject( S );
238 if ( aShapeObj->_is_nil() )
240 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
241 // find GEOM_Object by entry (IPAL52735)
242 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
243 for ( ; data != _geomGroupData.end(); ++data )
244 if ( data->_smeshObject->_is_equivalent( _this() ))
246 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
247 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
248 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
254 catch(SALOME_Exception & S_ex) {
255 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
257 return aShapeObj._retn();
260 //================================================================================
262 * \brief Return false if the mesh is not yet fully loaded from the study file
264 //================================================================================
266 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
268 Unexpect aCatch(SALOME_SalomeException);
269 return !_preMeshInfo;
272 //================================================================================
274 * \brief Load full mesh data from the study file
276 //================================================================================
278 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
280 Unexpect aCatch(SALOME_SalomeException);
282 _preMeshInfo->FullLoadFromFile();
285 //================================================================================
287 * \brief Remove all nodes and elements
289 //================================================================================
291 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
293 Unexpect aCatch(SALOME_SalomeException);
295 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
299 //CheckGeomGroupModif(); // issue 20145
301 catch(SALOME_Exception & S_ex) {
302 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
305 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
307 SMESH::SMESH_Mesh_var mesh = _this();
308 _gen_i->UpdateIcons( mesh );
311 //================================================================================
313 * \brief Remove all nodes and elements for indicated shape
315 //================================================================================
317 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
318 throw (SALOME::SALOME_Exception)
320 Unexpect aCatch(SALOME_SalomeException);
322 _preMeshInfo->FullLoadFromFile();
325 _impl->ClearSubMesh( ShapeID );
327 catch(SALOME_Exception & S_ex) {
328 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
330 _impl->GetMeshDS()->Modified();
332 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
335 //=============================================================================
337 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
339 //=============================================================================
341 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
343 SMESH::DriverMED_ReadStatus res;
346 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
347 res = SMESH::DRS_OK; break;
348 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
349 res = SMESH::DRS_EMPTY; break;
350 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
351 res = SMESH::DRS_WARN_RENUMBER; break;
352 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
353 res = SMESH::DRS_WARN_SKIP_ELEM; break;
354 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
355 res = SMESH::DRS_WARN_DESCENDING; break;
356 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
358 res = SMESH::DRS_FAIL; break;
363 //=============================================================================
365 * Convert ::SMESH_ComputeError to SMESH::ComputeError
367 //=============================================================================
369 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
371 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
372 errVar->subShapeID = -1;
373 errVar->hasBadMesh = false;
375 if ( !errorPtr || errorPtr->IsOK() )
377 errVar->code = SMESH::COMPERR_OK;
381 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
382 errVar->comment = errorPtr->myComment.c_str();
384 return errVar._retn();
387 //=============================================================================
391 * Import mesh data from MED file
393 //=============================================================================
395 SMESH::DriverMED_ReadStatus
396 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
397 throw ( SALOME::SALOME_Exception )
399 Unexpect aCatch(SALOME_SalomeException);
402 status = _impl->MEDToMesh( theFileName, theMeshName );
404 catch( SALOME_Exception& S_ex ) {
405 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
408 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
411 CreateGroupServants();
413 int major, minor, release;
414 major = minor = release = 0;
415 MED::GetMEDVersion(theFileName, major, minor, release);
416 _medFileInfo = new SMESH::MedFileInfo();
417 _medFileInfo->fileName = theFileName;
418 _medFileInfo->fileSize = 0;
419 _medFileInfo->major = major;
420 _medFileInfo->minor = minor;
421 _medFileInfo->release = release;
422 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
424 return ConvertDriverMEDReadStatus(status);
427 //================================================================================
429 * \brief Import mesh data from the CGNS file
431 //================================================================================
433 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
434 const int theMeshIndex,
435 std::string& theMeshName )
436 throw ( SALOME::SALOME_Exception )
438 Unexpect aCatch(SALOME_SalomeException);
441 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
443 catch( SALOME_Exception& S_ex ) {
444 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
447 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
450 CreateGroupServants();
452 _medFileInfo = new SMESH::MedFileInfo();
453 _medFileInfo->fileName = theFileName;
454 _medFileInfo->major = 0;
455 _medFileInfo->minor = 0;
456 _medFileInfo->release = 0;
457 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
459 return ConvertDriverMEDReadStatus(status);
462 //================================================================================
464 * \brief Return string representation of a MED file version comprising nbDigits
466 //================================================================================
468 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
470 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
472 return CORBA::string_dup( ver.c_str() );
475 //================================================================================
477 * Return the list of med versions compatibles for write/append,
478 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
480 //================================================================================
482 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
484 SMESH::long_array_var aResult = new SMESH::long_array();
485 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
486 long nbver = mvok.size();
487 aResult->length( nbver );
488 for ( int i = 0; i < nbver; i++ )
489 aResult[i] = mvok[i];
490 return aResult._retn();
493 //=============================================================================
497 * Import mesh data from MED file
499 //=============================================================================
501 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
502 throw ( SALOME::SALOME_Exception )
506 // Read mesh with name = <theMeshName> into SMESH_Mesh
507 _impl->UNVToMesh( theFileName );
509 CreateGroupServants();
511 _medFileInfo = new SMESH::MedFileInfo();
512 _medFileInfo->fileName = theFileName;
513 _medFileInfo->major = 0;
514 _medFileInfo->minor = 0;
515 _medFileInfo->release = 0;
516 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
518 SMESH_CATCH( SMESH::throwCorbaException );
523 //=============================================================================
527 * Import mesh data from STL file
529 //=============================================================================
531 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
532 throw ( SALOME::SALOME_Exception )
536 // Read mesh with name = <theMeshName> into SMESH_Mesh
537 std::string name = _impl->STLToMesh( theFileName );
540 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
541 _gen_i->SetName( meshSO, name.c_str() );
543 _medFileInfo = new SMESH::MedFileInfo();
544 _medFileInfo->fileName = theFileName;
545 _medFileInfo->major = 0;
546 _medFileInfo->minor = 0;
547 _medFileInfo->release = 0;
548 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
550 SMESH_CATCH( SMESH::throwCorbaException );
555 //================================================================================
557 * \brief Function used in SMESH_CATCH by ImportGMFFile()
559 //================================================================================
563 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
565 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
569 //================================================================================
571 * \brief Import data from a GMF file and return an error description
573 //================================================================================
575 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
576 bool theMakeRequiredGroups )
577 throw (SALOME::SALOME_Exception)
579 SMESH_ComputeErrorPtr error;
582 #define SMESH_CAUGHT error =
585 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
587 _medFileInfo = new SMESH::MedFileInfo();
588 _medFileInfo->fileName = theFileName;
589 _medFileInfo->major = 0;
590 _medFileInfo->minor = 0;
591 _medFileInfo->release = 0;
592 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
594 SMESH_CATCH( exceptionToComputeError );
598 CreateGroupServants();
600 return ConvertComputeError( error );
603 //=============================================================================
605 * \brief Convert SMESH_Hypothesis::Hypothesis_Status into SMESH::Hypothesis_Status
607 //=============================================================================
609 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
611 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
612 (SMESH_Hypothesis::Hypothesis_Status theStatus)
615 RETURNCASE( HYP_OK );
616 RETURNCASE( HYP_MISSING );
617 RETURNCASE( HYP_CONCURRENT );
618 RETURNCASE( HYP_BAD_PARAMETER );
619 RETURNCASE( HYP_HIDDEN_ALGO );
620 RETURNCASE( HYP_HIDING_ALGO );
621 RETURNCASE( HYP_UNKNOWN_FATAL );
622 RETURNCASE( HYP_INCOMPATIBLE );
623 RETURNCASE( HYP_NOTCONFORM );
624 RETURNCASE( HYP_ALREADY_EXIST );
625 RETURNCASE( HYP_BAD_DIM );
626 RETURNCASE( HYP_BAD_SUBSHAPE );
627 RETURNCASE( HYP_BAD_GEOMETRY );
628 RETURNCASE( HYP_NEED_SHAPE );
629 RETURNCASE( HYP_INCOMPAT_HYPS );
632 return SMESH::HYP_UNKNOWN_FATAL;
635 //=============================================================================
639 * Call internal addHypothesis() and then add a reference to <anHyp> under
640 * the SObject actually having a reference to <aSubShape>.
641 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
643 //=============================================================================
645 SMESH::Hypothesis_Status
646 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
647 SMESH::SMESH_Hypothesis_ptr anHyp,
648 CORBA::String_out anErrorText)
649 throw(SALOME::SALOME_Exception)
651 Unexpect aCatch(SALOME_SalomeException);
653 _preMeshInfo->ForgetOrLoad();
655 const int prevNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
658 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
659 anErrorText = error.c_str();
661 SMESH::SMESH_Mesh_var mesh( _this() );
662 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
664 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
666 //int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
667 if ( prevNbMeshEnt > 0 /*newNbMeshEnt != prevNbMeshEnt*/ )
668 _gen_i->UpdateIcons( mesh );
670 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
672 // Update Python script
673 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
674 << aSubShape << ", " << anHyp << " )";
676 return ConvertHypothesisStatus(status);
679 //================================================================================
681 * \brief Create a sub-mesh and add a hypothesis to it
683 //================================================================================
685 SMESH_Hypothesis::Hypothesis_Status
686 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
687 SMESH::SMESH_Hypothesis_ptr anHyp,
688 std::string* anErrorText)
690 if(MYDEBUG) MESSAGE("addHypothesis");
692 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
693 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
695 if (CORBA::is_nil( anHyp ))
696 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
698 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
701 TopoDS_Shape myLocSubShape;
702 //use PseudoShape in case if mesh has no shape
704 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
706 myLocSubShape = _impl->GetShapeToMesh();
708 const int hypId = anHyp->GetId();
710 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
711 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
713 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
715 // assure there is a corresponding submesh
716 if ( !_impl->IsMainShape( myLocSubShape )) {
717 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
718 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
719 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
722 else if ( anErrorText )
724 *anErrorText = error;
727 catch(SALOME_Exception & S_ex)
729 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
734 //================================================================================
736 * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape
738 //================================================================================
740 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
741 SMESH::SMESH_Hypothesis_ptr anHyp)
742 throw(SALOME::SALOME_Exception)
744 Unexpect aCatch(SALOME_SalomeException);
746 _preMeshInfo->ForgetOrLoad();
748 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
749 SMESH::SMESH_Mesh_var mesh = _this();
751 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
753 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
754 _gen_i->UpdateIcons( mesh );
756 // Update Python script
757 if(_impl->HasShapeToMesh())
758 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
759 << aSubShape << ", " << anHyp << " )";
761 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
764 return ConvertHypothesisStatus(status);
767 //=============================================================================
769 * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape
771 //=============================================================================
773 SMESH_Hypothesis::Hypothesis_Status
774 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
775 SMESH::SMESH_Hypothesis_ptr anHyp)
777 if(MYDEBUG) MESSAGE("removeHypothesis()");
779 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
780 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
782 if (CORBA::is_nil( anHyp ))
783 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
786 _preMeshInfo->ForgetOrLoad();
788 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
791 TopoDS_Shape myLocSubShape;
792 //use PseudoShape in case if mesh has no shape
793 if( _impl->HasShapeToMesh() )
794 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
796 myLocSubShape = _impl->GetShapeToMesh();
798 const int hypId = anHyp->GetId();
799 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
800 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
802 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
806 catch(SALOME_Exception & S_ex)
808 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
813 //================================================================================
815 * \brief Return hypotheses assigned to a given sub-shape
817 //================================================================================
819 SMESH::ListOfHypothesis *
820 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
821 throw(SALOME::SALOME_Exception)
823 Unexpect aCatch(SALOME_SalomeException);
824 if (MYDEBUG) MESSAGE("GetHypothesisList");
825 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
826 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
828 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
831 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
832 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
833 myLocSubShape = _impl->GetShapeToMesh();
834 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
835 int i = 0, n = aLocalList.size();
838 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
839 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
840 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
842 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
843 if ( id_hypptr != _mapHypo.end() )
844 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
848 catch(SALOME_Exception & S_ex) {
849 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
852 return aList._retn();
855 //================================================================================
857 * \brief Return sub-meshes
859 //================================================================================
861 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
863 Unexpect aCatch(SALOME_SalomeException);
864 if (MYDEBUG) MESSAGE("GetSubMeshes");
866 SMESH::submesh_array_var aList = new SMESH::submesh_array();
869 TPythonDump aPythonDump;
870 if ( !_mapSubMeshIor.empty() )
874 aList->length( _mapSubMeshIor.size() );
876 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
877 for ( ; it != _mapSubMeshIor.end(); it++ ) {
878 if ( CORBA::is_nil( it->second )) continue;
879 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
881 if (i > 1) aPythonDump << ", ";
882 aPythonDump << it->second;
886 catch(SALOME_Exception & S_ex) {
887 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
890 // Update Python script
891 if ( !_mapSubMeshIor.empty() )
892 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
894 return aList._retn();
897 //================================================================================
899 * \brief Create and return a sub-mesh on the given sub-shape
901 //================================================================================
903 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
904 const char* theName )
905 throw(SALOME::SALOME_Exception)
907 Unexpect aCatch(SALOME_SalomeException);
908 if (CORBA::is_nil(aSubShape))
909 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
911 SMESH::SMESH_subMesh_var subMesh;
912 SMESH::SMESH_Mesh_var aMesh = _this();
914 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
916 //Get or Create the SMESH_subMesh object implementation
918 TopoDS_Iterator it( myLocSubShape );
919 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
920 bool isValidSub = ( subMeshId || _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ));
921 if ( isValidSub && myLocSubShape.ShapeType() == TopAbs_COMPOUND )
922 isValidSub = !it.Value().IsSame( _impl->GetShapeToMesh() );
926 THROW_SALOME_CORBA_EXCEPTION("Not a sub-shape of the main shape", SALOME::BAD_PARAM);
928 subMesh = getSubMesh( subMeshId );
930 // create a new subMesh object servant if there is none for the shape
931 if ( subMesh->_is_nil() )
932 subMesh = createSubMesh( aSubShape );
933 if ( _gen_i->CanPublishInStudy( subMesh ))
935 SALOMEDS::SObject_wrap aSO =
936 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
937 if ( !aSO->_is_nil()) {
938 // Update Python script
939 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
940 << aSubShape << ", '" << theName << "' )";
944 catch(SALOME_Exception & S_ex) {
945 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
947 return subMesh._retn();
950 //================================================================================
952 * \brief Remove a sub-mesh
954 //================================================================================
956 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
957 throw (SALOME::SALOME_Exception)
961 if ( theSubMesh->_is_nil() )
964 GEOM::GEOM_Object_var aSubShape;
965 // Remove submesh's SObject
966 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
967 if ( !anSO->_is_nil() ) {
968 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
969 SALOMEDS::SObject_wrap anObj, aRef;
970 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
971 anObj->ReferencedObject( aRef.inout() ))
973 CORBA::Object_var obj = aRef->GetObject();
974 aSubShape = GEOM::GEOM_Object::_narrow( obj );
976 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
977 // aSubShape = theSubMesh->GetSubShape();
979 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
980 builder->RemoveObjectWithChildren( anSO );
982 // Update Python script
983 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
986 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
988 _preMeshInfo->ForgetOrLoad();
990 SMESH_CATCH( SMESH::throwCorbaException );
993 //================================================================================
995 * \brief Create a standalone group
997 //================================================================================
999 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1000 const char* theName )
1001 throw(SALOME::SALOME_Exception)
1003 Unexpect aCatch(SALOME_SalomeException);
1005 _preMeshInfo->FullLoadFromFile();
1007 SMESH::SMESH_Group_var aNewGroup =
1008 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1010 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1012 SMESH::SMESH_Mesh_var mesh = _this();
1013 SALOMEDS::SObject_wrap aSO =
1014 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1015 if ( !aSO->_is_nil())
1016 // Update Python script
1017 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1018 << theElemType << ", '" << theName << "' )";
1020 return aNewGroup._retn();
1023 //================================================================================
1025 * \brief Create a group based on the given geometry
1027 //================================================================================
1029 SMESH::SMESH_GroupOnGeom_ptr
1030 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1031 const char* theName,
1032 GEOM::GEOM_Object_ptr theGeomObj)
1033 throw(SALOME::SALOME_Exception)
1035 Unexpect aCatch(SALOME_SalomeException);
1037 _preMeshInfo->FullLoadFromFile();
1039 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1041 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1042 if ( !aShape.IsNull() )
1045 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1047 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1049 SMESH::SMESH_Mesh_var mesh = _this();
1050 SALOMEDS::SObject_wrap aSO =
1051 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1052 if ( !aSO->_is_nil())
1053 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1054 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1058 return aNewGroup._retn();
1061 //================================================================================
1063 * \brief Creates a group whose contents is defined by filter
1064 * \param theElemType - group type
1065 * \param theName - group name
1066 * \param theFilter - the filter
1067 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1069 //================================================================================
1071 SMESH::SMESH_GroupOnFilter_ptr
1072 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1073 const char* theName,
1074 SMESH::Filter_ptr theFilter )
1075 throw (SALOME::SALOME_Exception)
1077 Unexpect aCatch(SALOME_SalomeException);
1079 _preMeshInfo->FullLoadFromFile();
1081 if ( CORBA::is_nil( theFilter ))
1082 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1084 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1086 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1088 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1089 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1092 if ( !aNewGroup->_is_nil() )
1093 aNewGroup->SetFilter( theFilter );
1095 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1097 SMESH::SMESH_Mesh_var mesh = _this();
1098 SALOMEDS::SObject_wrap aSO =
1099 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1101 if ( !aSO->_is_nil())
1102 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1103 << theElemType << ", '" << theName << "', " << theFilter << " )";
1105 return aNewGroup._retn();
1108 //================================================================================
1110 * \brief Remove a group
1112 //================================================================================
1114 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1115 throw (SALOME::SALOME_Exception)
1117 if ( theGroup->_is_nil() )
1122 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1126 if ( aGroup->GetMeshServant() != this )
1127 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1128 SALOME::BAD_PARAM );
1130 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1131 if ( !aGroupSO->_is_nil() )
1133 // Update Python script
1134 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1136 // Remove group's SObject
1137 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1138 builder->RemoveObjectWithChildren( aGroupSO );
1140 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1142 // Remove the group from SMESH data structures
1143 removeGroup( aGroup->GetLocalID() );
1145 SMESH_CATCH( SMESH::throwCorbaException );
1148 //=============================================================================
1150 * Remove group with its contents
1152 //=============================================================================
1154 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1155 throw (SALOME::SALOME_Exception)
1159 _preMeshInfo->FullLoadFromFile();
1161 if ( theGroup->_is_nil() )
1164 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1165 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1166 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1169 vector<int> nodeIds; // to remove nodes becoming free
1170 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1171 if ( !isNodal && !theGroup->IsEmpty() )
1173 CORBA::Long elemID = theGroup->GetID( 1 );
1174 int nbElemNodes = GetElemNbNodes( elemID );
1175 if ( nbElemNodes > 0 )
1176 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1179 // Retrieve contents
1180 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1181 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1182 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1183 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1184 elems.assign( elemBeg, elemEnd );
1186 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1189 RemoveGroup( theGroup );
1192 for ( size_t i = 0; i < elems.size(); ++i )
1194 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1198 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1199 nodeIds.push_back( nIt->next()->GetID() );
1201 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1205 _impl->GetMeshDS()->RemoveElement( elems[i] );
1209 // Remove free nodes
1210 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1211 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1212 if ( n->NbInverseElements() == 0 )
1213 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1215 // Update Python script (theGroup must be alive for this)
1216 pyDump << SMESH::SMESH_Mesh_var(_this())
1217 << ".RemoveGroupWithContents( " << theGroup << " )";
1219 SMESH_CATCH( SMESH::throwCorbaException );
1222 //================================================================================
1224 * \brief Get the list of groups existing in the mesh
1225 * \retval SMESH::ListOfGroups * - list of groups
1227 //================================================================================
1229 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1231 Unexpect aCatch(SALOME_SalomeException);
1232 if (MYDEBUG) MESSAGE("GetGroups");
1234 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1237 TPythonDump aPythonDump;
1238 if ( !_mapGroups.empty() )
1240 aPythonDump << "[ ";
1242 aList->length( _mapGroups.size() );
1244 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1245 for ( ; it != _mapGroups.end(); it++ ) {
1246 if ( CORBA::is_nil( it->second )) continue;
1247 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1249 if (i > 1) aPythonDump << ", ";
1250 aPythonDump << it->second;
1254 catch(SALOME_Exception & S_ex) {
1255 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1257 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1259 return aList._retn();
1262 //=============================================================================
1264 * Get number of groups existing in the mesh
1266 //=============================================================================
1268 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1270 Unexpect aCatch(SALOME_SalomeException);
1271 return _mapGroups.size();
1274 //=============================================================================
1276 * New group including all mesh elements present in initial groups is created.
1278 //=============================================================================
1280 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1281 SMESH::SMESH_GroupBase_ptr theGroup2,
1282 const char* theName )
1283 throw (SALOME::SALOME_Exception)
1285 SMESH::SMESH_Group_var aResGrp;
1289 _preMeshInfo->FullLoadFromFile();
1291 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1292 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1294 if ( theGroup1->GetType() != theGroup2->GetType() )
1295 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1300 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1301 if ( aResGrp->_is_nil() )
1302 return SMESH::SMESH_Group::_nil();
1304 aResGrp->AddFrom( theGroup1 );
1305 aResGrp->AddFrom( theGroup2 );
1307 // Update Python script
1308 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1309 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1311 SMESH_CATCH( SMESH::throwCorbaException );
1313 return aResGrp._retn();
1316 //=============================================================================
1318 * \brief New group including all mesh elements present in initial groups is created.
1319 * \param theGroups list of groups
1320 * \param theName name of group to be created
1321 * \return pointer to the new group
1323 //=============================================================================
1325 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1326 const char* theName )
1327 throw (SALOME::SALOME_Exception)
1329 SMESH::SMESH_Group_var aResGrp;
1332 _preMeshInfo->FullLoadFromFile();
1335 return SMESH::SMESH_Group::_nil();
1340 SMESH::ElementType aType = SMESH::ALL;
1341 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1343 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1344 if ( CORBA::is_nil( aGrp ) )
1346 if ( aType == SMESH::ALL )
1347 aType = aGrp->GetType();
1348 else if ( aType != aGrp->GetType() )
1349 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1352 if ( aType == SMESH::ALL )
1353 return SMESH::SMESH_Group::_nil();
1358 aResGrp = CreateGroup( aType, theName );
1359 if ( aResGrp->_is_nil() )
1360 return SMESH::SMESH_Group::_nil();
1362 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1363 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1365 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1366 if ( !CORBA::is_nil( aGrp ) )
1368 aResGrp->AddFrom( aGrp );
1369 if ( g > 0 ) pyDump << ", ";
1373 pyDump << " ], '" << theName << "' )";
1375 SMESH_CATCH( SMESH::throwCorbaException );
1377 return aResGrp._retn();
1380 //=============================================================================
1382 * New group is created. All mesh elements that are
1383 * present in both initial groups are added to the new one.
1385 //=============================================================================
1387 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1388 SMESH::SMESH_GroupBase_ptr theGroup2,
1389 const char* theName )
1390 throw (SALOME::SALOME_Exception)
1392 SMESH::SMESH_Group_var aResGrp;
1397 _preMeshInfo->FullLoadFromFile();
1399 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1400 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1402 if ( theGroup1->GetType() != theGroup2->GetType() )
1403 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1407 // Create Intersection
1408 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1409 if ( aResGrp->_is_nil() )
1410 return aResGrp._retn();
1412 SMESHDS_GroupBase* groupDS1 = 0;
1413 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1414 groupDS1 = grp_i->GetGroupDS();
1416 SMESHDS_GroupBase* groupDS2 = 0;
1417 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1418 groupDS2 = grp_i->GetGroupDS();
1420 SMESHDS_Group* resGroupDS = 0;
1421 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1422 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1424 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1426 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1427 while ( elemIt1->more() )
1429 const SMDS_MeshElement* e = elemIt1->next();
1430 if ( groupDS2->Contains( e ))
1431 resGroupDS->SMDSGroup().Add( e );
1434 // Update Python script
1435 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1436 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1438 SMESH_CATCH( SMESH::throwCorbaException );
1440 return aResGrp._retn();
1443 //=============================================================================
1445 \brief Intersect list of groups. New group is created. All mesh elements that
1446 are present in all initial groups simultaneously are added to the new one.
1447 \param theGroups list of groups
1448 \param theName name of group to be created
1449 \return pointer on the group
1451 //=============================================================================
1453 SMESH::SMESH_Group_ptr
1454 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1455 const char* theName )
1456 throw (SALOME::SALOME_Exception)
1458 SMESH::SMESH_Group_var aResGrp;
1463 _preMeshInfo->FullLoadFromFile();
1466 return SMESH::SMESH_Group::_nil();
1468 // check types and get SMESHDS_GroupBase's
1469 SMESH::ElementType aType = SMESH::ALL;
1470 vector< SMESHDS_GroupBase* > groupVec;
1471 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1473 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1474 if ( CORBA::is_nil( aGrp ) )
1476 if ( aType == SMESH::ALL )
1477 aType = aGrp->GetType();
1478 else if ( aType != aGrp->GetType() )
1479 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1482 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1483 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1485 if ( grpDS->IsEmpty() )
1490 groupVec.push_back( grpDS );
1493 if ( aType == SMESH::ALL ) // all groups are nil
1494 return SMESH::SMESH_Group::_nil();
1499 aResGrp = CreateGroup( aType, theName );
1501 SMESHDS_Group* resGroupDS = 0;
1502 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1503 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1504 if ( !resGroupDS || groupVec.empty() )
1505 return aResGrp._retn();
1508 size_t i, nb = groupVec.size();
1509 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1510 while ( elemIt1->more() )
1512 const SMDS_MeshElement* e = elemIt1->next();
1514 for ( i = 1; ( i < nb && inAll ); ++i )
1515 inAll = groupVec[i]->Contains( e );
1518 resGroupDS->SMDSGroup().Add( e );
1521 // Update Python script
1522 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1523 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1525 SMESH_CATCH( SMESH::throwCorbaException );
1527 return aResGrp._retn();
1530 //=============================================================================
1532 * New group is created. All mesh elements that are present in
1533 * a main group but is not present in a tool group are added to the new one
1535 //=============================================================================
1537 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1538 SMESH::SMESH_GroupBase_ptr theGroup2,
1539 const char* theName )
1540 throw (SALOME::SALOME_Exception)
1542 SMESH::SMESH_Group_var aResGrp;
1547 _preMeshInfo->FullLoadFromFile();
1549 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1550 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1552 if ( theGroup1->GetType() != theGroup2->GetType() )
1553 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1557 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1558 if ( aResGrp->_is_nil() )
1559 return aResGrp._retn();
1561 SMESHDS_GroupBase* groupDS1 = 0;
1562 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1563 groupDS1 = grp_i->GetGroupDS();
1565 SMESHDS_GroupBase* groupDS2 = 0;
1566 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1567 groupDS2 = grp_i->GetGroupDS();
1569 SMESHDS_Group* resGroupDS = 0;
1570 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1571 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1573 if ( groupDS1 && groupDS2 && resGroupDS )
1575 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1576 while ( elemIt1->more() )
1578 const SMDS_MeshElement* e = elemIt1->next();
1579 if ( !groupDS2->Contains( e ))
1580 resGroupDS->SMDSGroup().Add( e );
1583 // Update Python script
1584 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1585 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1587 SMESH_CATCH( SMESH::throwCorbaException );
1589 return aResGrp._retn();
1592 //=============================================================================
1594 \brief Cut lists of groups. New group is created. All mesh elements that are
1595 present in main groups but do not present in tool groups are added to the new one
1596 \param theMainGroups list of main groups
1597 \param theToolGroups list of tool groups
1598 \param theName name of group to be created
1599 \return pointer on the group
1601 //=============================================================================
1603 SMESH::SMESH_Group_ptr
1604 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1605 const SMESH::ListOfGroups& theToolGroups,
1606 const char* theName )
1607 throw (SALOME::SALOME_Exception)
1609 SMESH::SMESH_Group_var aResGrp;
1614 _preMeshInfo->FullLoadFromFile();
1617 return SMESH::SMESH_Group::_nil();
1619 // check types and get SMESHDS_GroupBase's
1620 SMESH::ElementType aType = SMESH::ALL;
1621 vector< SMESHDS_GroupBase* > toolGroupVec;
1622 vector< SMDS_ElemIteratorPtr > mainIterVec;
1624 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1626 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1627 if ( CORBA::is_nil( aGrp ) )
1629 if ( aType == SMESH::ALL )
1630 aType = aGrp->GetType();
1631 else if ( aType != aGrp->GetType() )
1632 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1634 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1635 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1636 if ( !grpDS->IsEmpty() )
1637 mainIterVec.push_back( grpDS->GetElements() );
1639 if ( aType == SMESH::ALL ) // all main groups are nil
1640 return SMESH::SMESH_Group::_nil();
1641 if ( mainIterVec.empty() ) // all main groups are empty
1642 return aResGrp._retn();
1644 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1646 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1647 if ( CORBA::is_nil( aGrp ) )
1649 if ( aType != aGrp->GetType() )
1650 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1652 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1653 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1654 toolGroupVec.push_back( grpDS );
1660 aResGrp = CreateGroup( aType, theName );
1662 SMESHDS_Group* resGroupDS = 0;
1663 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1664 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1666 return aResGrp._retn();
1669 size_t i, nb = toolGroupVec.size();
1670 SMDS_ElemIteratorPtr mainElemIt
1671 ( new SMDS_IteratorOnIterators
1672 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1673 while ( mainElemIt->more() )
1675 const SMDS_MeshElement* e = mainElemIt->next();
1677 for ( i = 0; ( i < nb && !isIn ); ++i )
1678 isIn = toolGroupVec[i]->Contains( e );
1681 resGroupDS->SMDSGroup().Add( e );
1684 // Update Python script
1685 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1686 << ".CutListOfGroups( " << theMainGroups << ", "
1687 << theToolGroups << ", '" << theName << "' )";
1689 SMESH_CATCH( SMESH::throwCorbaException );
1691 return aResGrp._retn();
1694 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1696 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1697 bool & toStopChecking )
1699 toStopChecking = ( nbCommon < nbChecked );
1700 return nbCommon == nbNodes;
1702 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1703 bool & toStopChecking )
1705 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1706 return nbCommon == nbCorners;
1708 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1709 bool & toStopChecking )
1711 return nbCommon > 0;
1713 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1714 bool & toStopChecking )
1716 return nbCommon >= (nbNodes+1) / 2;
1720 //=============================================================================
1722 * Create a group of entities basing on nodes of other groups.
1723 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1724 * \param [in] anElemType - a type of elements to include to the new group.
1725 * \param [in] theName - a name of the new group.
1726 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1727 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1728 * new group provided that it is based on nodes of an element of \a aListOfGroups
1729 * \return SMESH_Group - the created group
1731 // IMP 19939, bug 22010, IMP 22635
1732 //=============================================================================
1734 SMESH::SMESH_Group_ptr
1735 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1736 SMESH::ElementType theElemType,
1737 const char* theName,
1738 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1739 CORBA::Boolean theUnderlyingOnly)
1740 throw (SALOME::SALOME_Exception)
1742 SMESH::SMESH_Group_var aResGrp;
1746 _preMeshInfo->FullLoadFromFile();
1748 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1750 if ( !theName || !aMeshDS )
1751 return SMESH::SMESH_Group::_nil();
1753 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1755 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1756 SMESH_Comment nbCoNoStr( "SMESH.");
1757 switch ( theNbCommonNodes ) {
1758 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1759 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1760 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1761 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1762 default: return aResGrp._retn();
1764 int nbChecked, nbCommon, nbNodes, nbCorners;
1770 aResGrp = CreateGroup( theElemType, theName );
1771 if ( aResGrp->_is_nil() )
1772 return SMESH::SMESH_Group::_nil();
1774 SMESHDS_GroupBase* groupBaseDS =
1775 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1776 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1778 vector<bool> isNodeInGroups;
1780 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1782 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1783 if ( CORBA::is_nil( aGrp ) )
1785 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1786 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1789 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1790 if ( !elIt ) continue;
1792 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1794 while ( elIt->more() ) {
1795 const SMDS_MeshElement* el = elIt->next();
1796 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1797 while ( nIt->more() )
1798 resGroupCore.Add( nIt->next() );
1801 // get elements of theElemType based on nodes of every element of group
1802 else if ( theUnderlyingOnly )
1804 while ( elIt->more() )
1806 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1807 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1808 TIDSortedElemSet checkedElems;
1809 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1810 while ( nIt->more() )
1812 const SMDS_MeshNode* n = nIt->next();
1813 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1814 // check nodes of elements of theElemType around el
1815 while ( elOfTypeIt->more() )
1817 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1818 if ( !checkedElems.insert( elOfType ).second ) continue;
1819 nbNodes = elOfType->NbNodes();
1820 nbCorners = elOfType->NbCornerNodes();
1822 bool toStopChecking = false;
1823 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1824 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1825 if ( elNodes.count( nIt2->next() ) &&
1826 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1828 resGroupCore.Add( elOfType );
1835 // get all nodes of elements of groups
1838 while ( elIt->more() )
1840 const SMDS_MeshElement* el = elIt->next(); // an element of group
1841 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1842 while ( nIt->more() )
1844 const SMDS_MeshNode* n = nIt->next();
1845 if ( n->GetID() >= (int) isNodeInGroups.size() )
1846 isNodeInGroups.resize( n->GetID() + 1, false );
1847 isNodeInGroups[ n->GetID() ] = true;
1853 // Get elements of theElemType based on a certain number of nodes of elements of groups
1854 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1856 const SMDS_MeshNode* n;
1857 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1858 const int isNodeInGroupsSize = isNodeInGroups.size();
1859 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1861 if ( !isNodeInGroups[ iN ] ||
1862 !( n = aMeshDS->FindNode( iN )))
1865 // check nodes of elements of theElemType around n
1866 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1867 while ( elOfTypeIt->more() )
1869 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1870 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1875 nbNodes = elOfType->NbNodes();
1876 nbCorners = elOfType->NbCornerNodes();
1878 bool toStopChecking = false;
1879 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1880 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1882 const int nID = nIt->next()->GetID();
1883 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1884 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1886 resGroupCore.Add( elOfType );
1894 // Update Python script
1895 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1896 << ".CreateDimGroup( "
1897 << theGroups << ", " << theElemType << ", '" << theName << "', "
1898 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1900 SMESH_CATCH( SMESH::throwCorbaException );
1902 return aResGrp._retn();
1905 //================================================================================
1907 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1908 * existing 1D elements as group boundaries.
1909 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1910 * adjacent faces is more than \a sharpAngle in degrees.
1911 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1912 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1913 * \return ListOfGroups - the created groups
1915 //================================================================================
1917 SMESH::ListOfGroups*
1918 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1919 CORBA::Boolean theCreateEdges,
1920 CORBA::Boolean theUseExistingEdges )
1921 throw (SALOME::SALOME_Exception)
1923 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1924 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1927 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1933 _preMeshInfo->FullLoadFromFile();
1935 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1937 std::vector< SMESH_MeshAlgos::Edge > edges =
1938 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1940 if ( theCreateEdges )
1942 std::vector<const SMDS_MeshNode *> nodes(2);
1943 for ( size_t i = 0; i < edges.size(); ++i )
1945 nodes[0] = edges[i]._node1;
1946 nodes[1] = edges[i]._node2;
1947 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1949 if ( edges[i]._medium )
1950 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1952 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1956 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1957 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1959 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1961 resultGroups->length( faceGroups.size() );
1962 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1964 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1965 _editor->GenerateGroupName("Group").c_str());
1966 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1968 SMESHDS_GroupBase* groupBaseDS =
1969 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1970 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1972 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1973 for ( size_t i = 0; i < faces.size(); ++i )
1974 groupCore.Add( faces[i] );
1977 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1978 << ".FaceGroupsSeparatedByEdges( "
1979 << TVar( theSharpAngle ) << ", "
1980 << theCreateEdges << ", "
1981 << theUseExistingEdges << " )";
1983 SMESH_CATCH( SMESH::throwCorbaException );
1984 return resultGroups._retn();
1988 //================================================================================
1990 * \brief Remember GEOM group data
1992 //================================================================================
1994 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1995 CORBA::Object_ptr theSmeshObj)
1997 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2000 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2001 if ( groupSO->_is_nil() )
2004 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2005 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2006 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2009 _geomGroupData.push_back( TGeomGroupData() );
2010 TGeomGroupData & groupData = _geomGroupData.back();
2012 CORBA::String_var entry = groupSO->GetID();
2013 groupData._groupEntry = entry.in();
2015 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2016 groupData._indices.insert( ids[i] );
2018 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2019 // shape index in SMESHDS
2020 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2021 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2024 //================================================================================
2026 * Remove GEOM group data relating to removed smesh object
2028 //================================================================================
2030 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2032 list<TGeomGroupData>::iterator
2033 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2034 for ( ; data != dataEnd; ++data ) {
2035 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2036 _geomGroupData.erase( data );
2042 //================================================================================
2044 * \brief Replace a shape in the mesh upon Break Link
2046 //================================================================================
2048 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
2049 throw (SALOME::SALOME_Exception)
2051 // check if geometry changed
2052 bool geomChanged = true;
2053 GEOM::GEOM_Object_var oldGeom = GetShapeToMesh();
2054 if ( !theNewGeom->_is_nil() && !oldGeom->_is_nil() )
2055 geomChanged = ( oldGeom->GetTick() != theNewGeom->GetTick() );
2057 TopoDS_Shape S = _impl->GetShapeToMesh();
2058 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2059 TCollection_AsciiString aIOR;
2060 if ( geomClient->Find( S, aIOR ))
2061 geomClient->RemoveShapeFromBuffer( aIOR );
2063 // clear buffer also for sub-groups
2064 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2065 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2066 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2067 for (; g != groups.end(); ++g)
2068 if (const SMESHDS_GroupOnGeom* group = dynamic_cast<SMESHDS_GroupOnGeom*>(*g))
2070 const TopoDS_Shape& s = group->GetShape();
2071 if ( geomClient->Find( s, aIOR ))
2072 geomClient->RemoveShapeFromBuffer( aIOR );
2075 // clear buffer also for sub-meshes
2076 std::map<int, SMESH_subMesh_i*>::const_iterator aSubMeshIter = _mapSubMesh_i.cbegin();
2077 for(; aSubMeshIter != _mapSubMesh_i.cend(); aSubMeshIter++) {
2078 int aShapeID = aSubMeshIter->first;
2079 const TopoDS_Shape& aSubShape = meshDS->IndexToShape(aShapeID);
2080 TCollection_AsciiString aShapeIOR;
2081 if ( geomClient->Find( aSubShape, aShapeIOR ))
2082 geomClient->RemoveShapeFromBuffer( aShapeIOR );
2086 int shapeID, fromID, toID; // indices of elements of a sub-mesh
2088 std::vector< TRange > elemRanges, nodeRanges; // elements of sub-meshes
2089 std::vector< SMDS_PositionPtr > positions; // node positions
2092 // store positions of elements on geometry
2094 if ( meshDS->MaxNodeID() > meshDS->NbNodes() ||
2095 meshDS->MaxElementID() > meshDS->NbElements() )
2098 meshDS->CompactMesh();
2100 positions.resize( meshDS->NbNodes() + 1 );
2101 for ( SMDS_NodeIteratorPtr nodeIt = meshDS->nodesIterator(); nodeIt->more(); )
2103 const SMDS_MeshNode* n = nodeIt->next();
2104 positions[ n->GetID() ] = n->GetPosition();
2107 // remove elements from sub-meshes to avoid their removal at hypotheses addition
2108 for ( int isNode = 0; isNode < 2; ++isNode )
2110 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2111 ranges.reserve( meshDS->MaxShapeIndex() + 10 );
2112 ranges.push_back( TRange{ 0,0,0 });
2113 SMDS_ElemIteratorPtr elemIt = meshDS->elementsIterator( isNode ? SMDSAbs_Node : SMDSAbs_All );
2114 while ( elemIt->more() )
2116 const SMDS_MeshElement* e = elemIt->next();
2117 const int elemID = e->GetID();
2118 const int shapeID = e->GetShapeID();
2119 TRange & lastRange = ranges.back();
2120 if ( lastRange.shapeID != shapeID ||
2121 lastRange.toID != elemID )
2122 ranges.push_back( TRange{ shapeID, elemID, elemID + 1 });
2124 lastRange.toID = elemID + 1;
2126 if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( shapeID ))
2128 if ( isNode ) sm->RemoveNode( static_cast< const SMDS_MeshNode *>( e ));
2129 else sm->RemoveElement( e );
2136 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
2137 SMESH::SMESH_Mesh_var me = _this();
2138 SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
2139 CORBA::String_var entry = theNewGeom->GetStudyEntry();
2140 if ( !aSO->_is_nil() )
2142 SALOMEDS::SObject_wrap aShapeRefSO;
2143 if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
2145 SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
2146 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2147 builder->Addreference( aShapeRefSO, aShapeSO );
2151 // re-assign global hypotheses to the new shape
2152 _mainShapeTick = geomChanged ? -1 : theNewGeom->GetTick();
2153 CheckGeomModif( true );
2157 // restore positions of elements on geometry
2158 for ( int isNode = 0; isNode < 2; ++isNode )
2160 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2161 for ( size_t i = 1; i < ranges.size(); ++i )
2163 int elemID = ranges[ i ].fromID;
2164 int toID = ranges[ i ].toID;
2165 SMESHDS_SubMesh * smDS = meshDS->NewSubMesh( ranges[ i ].shapeID );
2167 for ( ; elemID < toID; ++elemID )
2168 smDS->AddNode( meshDS->FindNode( elemID ));
2170 for ( ; elemID < toID; ++elemID )
2171 smDS->AddElement( meshDS->FindElement( elemID ));
2173 if ( SMESH_subMesh* sm = _impl->GetSubMeshContaining( ranges[ i ].shapeID ))
2174 sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
2177 for ( unsigned int nodeID = 1; nodeID < positions.size(); ++nodeID )
2178 if ( positions[ nodeID ])
2179 if ( SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( meshDS->FindNode( nodeID )))
2180 n->SetPosition( positions[ nodeID ], n->GetShapeID() );
2183 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
2186 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
2187 << me <<".GetMesh()), " << entry.in() << ")";
2189 TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )";
2193 //================================================================================
2195 * \brief Return new group contents if it has been changed and update group data
2197 //================================================================================
2199 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2201 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2203 TopoDS_Shape newShape;
2204 SALOMEDS::SObject_wrap groupSO;
2206 if ( how == IS_BREAK_LINK )
2208 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2209 SALOMEDS::SObject_wrap geomRefSO;
2210 if ( !meshSO->_is_nil() &&
2211 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ))
2213 geomRefSO->ReferencedObject( groupSO.inout() );
2219 groupSO = _gen_i->getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2222 if ( groupSO->_is_nil() )
2225 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2226 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2227 if ( geomGroup->_is_nil() )
2230 // get indices of group items
2231 set<int> curIndices;
2232 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2233 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2234 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2235 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2236 curIndices.insert( ids[i] );
2238 bool sameIndices = ( groupData._indices == curIndices );
2239 if ( how == ONLY_IF_CHANGED && sameIndices )
2240 return newShape; // group not changed
2243 CORBA::String_var entry = geomGroup->GetStudyEntry();
2244 groupData._groupEntry = entry.in();
2245 groupData._indices = curIndices;
2247 newShape = _gen_i->GeomObjectToShape( geomGroup );
2249 // check if newShape is up-to-date
2250 if ( !newShape.IsNull() && ids->length() > 0 )
2252 bool toUpdate = ! _impl->GetMeshDS()->IsGroupOfSubShapes( newShape );
2255 TopExp_Explorer exp( newShape, (TopAbs_ShapeEnum)( groupOp->GetType( geomGroup )));
2256 for ( ; exp.More() && !toUpdate; exp.Next() )
2258 int ind = _impl->GetMeshDS()->ShapeToIndex( exp.Current() );
2259 toUpdate = ( curIndices.erase( ind ) == 0 );
2261 if ( !curIndices.empty() )
2266 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2267 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2268 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2269 newShape = _gen_i->GeomObjectToShape( geomGroup );
2274 // geom group becomes empty - return empty compound
2275 TopoDS_Compound compound;
2276 BRep_Builder().MakeCompound(compound);
2277 newShape = compound;
2285 //-----------------------------------------------------------------------------
2287 * \brief Storage of shape and index used in CheckGeomGroupModif()
2289 struct TIndexedShape
2292 TopoDS_Shape _shape;
2293 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2295 //-----------------------------------------------------------------------------
2297 * \brief Data to re-create a group on geometry
2299 struct TGroupOnGeomData
2302 TopoDS_Shape _shape;
2303 SMDSAbs_ElementType _type;
2305 Quantity_Color _color;
2307 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2309 _oldID = group->GetID();
2310 _type = group->GetType();
2311 _name = group->GetStoreName();
2312 _color = group->GetColor();
2316 //-----------------------------------------------------------------------------
2318 * \brief Check if a filter is still valid after geometry removal
2320 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2322 if ( theFilter->_is_nil() )
2324 SMESH::Filter::Criteria_var criteria;
2325 theFilter->GetCriteria( criteria.out() );
2327 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2329 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2331 switch ( criteria[ iCr ].Type )
2333 case SMESH::FT_BelongToGeom:
2334 case SMESH::FT_BelongToPlane:
2335 case SMESH::FT_BelongToCylinder:
2336 case SMESH::FT_BelongToGenSurface:
2337 case SMESH::FT_LyingOnGeom:
2338 entry = thresholdID;
2340 case SMESH::FT_ConnectedElements:
2343 entry = thresholdID;
2349 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2350 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2351 if ( so->_is_nil() )
2353 CORBA::Object_var obj = so->GetObject();
2354 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2355 if ( gen->GeomObjectToShape( geom ).IsNull() )
2358 } // loop on criteria
2364 //=============================================================================
2366 * \brief Update data if geometry changes
2370 //=============================================================================
2372 void SMESH_Mesh_i::CheckGeomModif( bool theIsBreakLink )
2374 SMESH::SMESH_Mesh_var me = _this();
2375 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2377 TPythonDump dumpNothing; // prevent any dump
2379 //bool removedFromClient = false;
2381 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2383 //removedFromClient = _impl->HasShapeToMesh();
2385 // try to find geometry by study reference
2386 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2387 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2388 if ( !meshSO->_is_nil() &&
2389 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2390 geomRefSO->ReferencedObject( geomSO.inout() ))
2392 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2393 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2396 if ( mainGO->_is_nil() && // geometry removed ==>
2397 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2399 // convert geom dependent groups into standalone ones
2400 CheckGeomGroupModif();
2402 _impl->ShapeToMesh( TopoDS_Shape() );
2404 // remove sub-meshes
2405 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2406 while ( i_sm != _mapSubMeshIor.end() )
2408 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2410 RemoveSubMesh( sm );
2412 // remove all children except groups in the study
2413 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2414 SALOMEDS::SObject_wrap so;
2415 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2416 if ( meshSO->FindSubObject( tag, so.inout() ))
2417 builder->RemoveObjectWithChildren( so );
2419 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2425 if ( !_impl->HasShapeToMesh() ) return;
2428 // Update after group modification
2430 const bool geomChanged = ( mainGO->GetTick() != _mainShapeTick );
2431 if ( !theIsBreakLink )
2432 if ( mainGO->GetType() == GEOM_GROUP || !geomChanged ) // is group or not modified
2434 int nb = NbNodes() + NbElements();
2435 CheckGeomGroupModif();
2436 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2437 _gen_i->UpdateIcons( me );
2441 // Update after shape modification or breakLink w/o geometry change
2443 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2444 if ( !geomClient ) return;
2445 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2446 if ( geomGen->_is_nil() ) return;
2447 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2448 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2450 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2452 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2453 if ( meshDS->ShapeToIndex( newShape ) == 1 ) // not yet updated
2455 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2456 geomClient->RemoveShapeFromBuffer( ior.in() );
2457 newShape = _gen_i->GeomObjectToShape( mainGO );
2460 // Update data taking into account that if topology doesn't change
2461 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2464 _preMeshInfo->ForgetAllData();
2466 if ( geomChanged || !isShaper )
2468 if ( newShape.IsNull() )
2471 _mainShapeTick = mainGO->GetTick();
2473 // store data of groups on geometry including new TopoDS_Shape's
2474 std::vector< TGroupOnGeomData > groupsData;
2475 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2476 groupsData.reserve( groups.size() );
2477 TopTools_DataMapOfShapeShape old2newShapeMap;
2478 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2479 for ( ; g != groups.end(); ++g )
2481 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2483 groupsData.push_back( TGroupOnGeomData( group ));
2486 SMESH::SMESH_GroupOnGeom_var gog;
2487 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2488 if ( i_grp != _mapGroups.end() )
2489 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2491 GEOM::GEOM_Object_var geom;
2492 if ( !gog->_is_nil() )
2494 if ( !theIsBreakLink )
2495 geom = gog->GetShape();
2497 if ( theIsBreakLink || geom->_is_nil() )
2499 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2500 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2501 if ( !grpSO->_is_nil() &&
2502 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2503 geomRefSO->ReferencedObject( geomSO.inout() ))
2505 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2506 geom = GEOM::GEOM_Object::_narrow( geomObj );
2510 if ( old2newShapeMap.IsBound( group->GetShape() ))
2512 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2514 else if ( !geom->_is_nil() )
2516 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2517 if ( meshDS->IsGroupOfSubShapes( groupsData.back()._shape ))
2519 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2520 geomClient->RemoveShapeFromBuffer( ior.in() );
2521 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2523 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2528 // store assigned hypotheses
2529 std::vector< pair< int, THypList > > ids2Hyps;
2530 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2531 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2533 const TopoDS_Shape& s = s2hyps.Key();
2534 const THypList& hyps = s2hyps.ChangeValue();
2535 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2538 std::multimap< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2540 // count shapes excluding compounds corresponding to geom groups
2541 int oldNbSubShapes = meshDS->MaxShapeIndex();
2542 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2544 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2545 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2548 std::set<int> subIds;
2549 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2550 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2551 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2554 // check if shape topology changes - save shape type per shape ID
2555 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2556 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2557 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2559 // change shape to mesh
2560 _impl->ShapeToMesh( TopoDS_Shape() );
2561 _impl->ShapeToMesh( newShape );
2563 // check if shape topology changes - check new shape types
2564 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2565 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2567 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2568 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2571 // re-add shapes (compounds) of geom groups
2572 typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData;
2573 TIndices2GroupData ii2grData;
2574 std::vector< int > ii;
2575 std::map< int, int > old2newIDs; // group IDs
2576 std::list<TGeomGroupData>::iterator dataIt = _geomGroupData.begin();
2577 for ( ; dataIt != _geomGroupData.end(); ++dataIt )
2579 TGeomGroupData* data = &(*dataIt);
2580 ii.reserve( data->_indices.size() );
2581 ii.assign( data->_indices.begin(), data->_indices.end() );
2582 TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first;
2583 if ( ii2gd->second != data )
2585 data->_groupEntry = ii2gd->second->_groupEntry;
2586 data->_indices = ii2gd->second->_indices;
2589 const int oldNbSub = data->_indices.size();
2590 const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0;
2592 std::multimap< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2593 if ( ii2i != ii2iMap.end() )
2595 oldID = ii2i->second;
2596 ii2iMap.erase( ii2i );
2598 if ( !oldID && oldNbSub == 1 )
2600 if ( old2newIDs.count( oldID ))
2603 int how = ( theIsBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2604 newShape = newGroupShape( *data, how );
2606 if ( !newShape.IsNull() )
2608 if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape
2610 TopoDS_Compound compound;
2611 BRep_Builder().MakeCompound( compound );
2612 BRep_Builder().Add( compound, newShape );
2613 newShape = compound;
2615 int newID = _impl->GetSubMesh( newShape )->GetId();
2616 if ( oldID /*&& oldID != newID*/ )
2617 old2newIDs.insert( std::make_pair( oldID, newID ));
2618 if ( oldNbSub == 1 )
2619 old2newIDs.insert( std::make_pair( soleOldID, newID ));
2623 // re-assign hypotheses
2624 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2626 int sID = ids2Hyps[i].first;
2629 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2630 if ( o2n != old2newIDs.end() )
2632 else if ( !sameTopology )
2635 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2638 const THypList& hyps = ids2Hyps[i].second;
2639 THypList::const_iterator h = hyps.begin();
2640 for ( ; h != hyps.end(); ++h )
2641 _impl->AddHypothesis( s, (*h)->GetID() );
2645 // restore groups on geometry
2646 for ( size_t i = 0; i < groupsData.size(); ++i )
2648 const TGroupOnGeomData& data = groupsData[i];
2649 if ( data._shape.IsNull() )
2652 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2653 if ( i2g == _mapGroups.end() ) continue;
2655 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2656 if ( !gr_i ) continue;
2658 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2660 _mapGroups.erase( i2g );
2662 g->GetGroupDS()->SetColor( data._color );
2665 if ( !sameTopology )
2667 std::map< int, int >::iterator o2n = old2newIDs.begin();
2668 for ( ; o2n != old2newIDs.end(); ++o2n )
2670 int newID = o2n->second, oldID = o2n->first;
2671 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2675 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2676 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2677 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2679 _mapSubMesh. erase(oldID);
2680 _mapSubMesh_i. erase(oldID);
2681 _mapSubMeshIor.erase(oldID);
2683 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2687 // update _mapSubMesh
2688 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2689 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2690 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2693 if ( !sameTopology )
2695 // remove invalid study sub-objects
2696 CheckGeomGroupModif();
2699 _gen_i->UpdateIcons( me );
2701 if ( !theIsBreakLink && isShaper )
2703 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2704 if ( !meshSO->_is_nil() )
2705 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2709 //=============================================================================
2711 * \brief Update objects depending on changed geom groups
2713 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2714 * issue 0020210: Update of a smesh group after modification of the associated geom group
2716 //=============================================================================
2718 void SMESH_Mesh_i::CheckGeomGroupModif()
2720 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2721 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2722 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2723 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2724 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2726 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2727 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2728 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2730 int nbValid = 0, nbRemoved = 0;
2731 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2732 for ( ; chItr->More(); chItr->Next() )
2734 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2735 if ( !smSO->_is_nil() &&
2736 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2737 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2739 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2740 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2741 if ( !geom->_non_existent() )
2744 continue; // keep the sub-mesh
2747 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2748 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2749 if ( !sm->_is_nil() && !sm->_non_existent() )
2751 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2752 if ( smGeom->_is_nil() )
2754 RemoveSubMesh( sm );
2761 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2762 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2766 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2767 builder->RemoveObjectWithChildren( rootSO );
2771 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2772 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2773 while ( i_gr != _mapGroups.end())
2775 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2777 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO;
2778 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2779 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2780 bool isValidGeom = false;
2781 if ( !onGeom->_is_nil() )
2783 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); // check TopoDS
2784 if ( !isValidGeom ) // check reference
2786 isValidGeom = ( ! groupSO->_is_nil() &&
2787 groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) &&
2788 refSO->ReferencedObject( geomSO.inout() ) &&
2789 ! geomSO->_is_nil() &&
2790 !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() )));
2793 else if ( !onFilt->_is_nil() )
2795 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2799 isValidGeom = ( !groupSO->_is_nil() &&
2800 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2804 if ( !IsLoaded() || group->IsEmpty() )
2806 RemoveGroup( group );
2808 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2810 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2812 else // is it possible?
2814 builder->RemoveObjectWithChildren( refSO );
2820 if ( !_impl->HasShapeToMesh() ) return;
2822 CORBA::Long nbEntities = NbNodes() + NbElements();
2824 // Check if group contents changed
2826 typedef map< string, TopoDS_Shape > TEntry2Geom;
2827 TEntry2Geom newGroupContents;
2829 list<TGeomGroupData>::iterator
2830 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2831 for ( ; data != dataEnd; ++data )
2833 pair< TEntry2Geom::iterator, bool > it_new =
2834 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2835 bool processedGroup = !it_new.second;
2836 TopoDS_Shape& newShape = it_new.first->second;
2837 if ( !processedGroup )
2838 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2839 if ( newShape.IsNull() )
2840 continue; // no changes
2843 _preMeshInfo->ForgetOrLoad();
2845 if ( processedGroup ) { // update group indices
2846 list<TGeomGroupData>::iterator data2 = data;
2847 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2848 data->_indices = data2->_indices;
2851 // Update SMESH objects according to new GEOM group contents
2853 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2854 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2856 int oldID = submesh->GetId();
2857 if ( !_mapSubMeshIor.count( oldID ))
2859 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2861 // update hypotheses
2862 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2863 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2864 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2866 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2867 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2869 // care of submeshes
2870 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2871 int newID = newSubmesh->GetId();
2872 if ( newID != oldID ) {
2873 _mapSubMesh [ newID ] = newSubmesh;
2874 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2875 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2876 _mapSubMesh. erase(oldID);
2877 _mapSubMesh_i. erase(oldID);
2878 _mapSubMeshIor.erase(oldID);
2879 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2884 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2885 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2886 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2888 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2890 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2891 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2892 ds->SetShape( newShape );
2897 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2898 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2900 // Remove groups and submeshes basing on removed sub-shapes
2902 TopTools_MapOfShape newShapeMap;
2903 TopoDS_Iterator shapeIt( newShape );
2904 for ( ; shapeIt.More(); shapeIt.Next() )
2905 newShapeMap.Add( shapeIt.Value() );
2907 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2908 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2910 if ( newShapeMap.Contains( shapeIt.Value() ))
2912 TopTools_IndexedMapOfShape oldShapeMap;
2913 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2914 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2916 const TopoDS_Shape& oldShape = oldShapeMap(i);
2917 int oldInd = meshDS->ShapeToIndex( oldShape );
2919 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2920 if ( i_smIor != _mapSubMeshIor.end() ) {
2921 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2924 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2925 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2927 // check if a group bases on oldInd shape
2928 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2929 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2930 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2931 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2933 RemoveGroup( i_grp->second ); // several groups can base on same shape
2934 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2939 // Reassign hypotheses and update groups after setting the new shape to mesh
2941 // collect anassigned hypotheses
2942 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2943 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2944 TShapeHypList assignedHyps;
2945 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2947 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2948 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2949 if ( !hyps.empty() ) {
2950 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2951 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2952 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2955 // collect shapes supporting groups
2956 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2957 TShapeTypeList groupData;
2958 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2959 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2960 for ( ; grIt != groups.end(); ++grIt )
2962 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2964 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2966 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2968 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2969 _impl->ShapeToMesh( newShape );
2971 // reassign hypotheses
2972 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2973 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2975 TIndexedShape& geom = indS_hyps->first;
2976 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2977 int oldID = geom._index;
2978 int newID = meshDS->ShapeToIndex( geom._shape );
2979 if ( oldID == 1 ) { // main shape
2981 geom._shape = newShape;
2985 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2986 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2987 // care of sub-meshes
2988 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2989 if ( newID != oldID ) {
2990 _mapSubMesh [ newID ] = newSubmesh;
2991 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2992 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2993 _mapSubMesh. erase(oldID);
2994 _mapSubMesh_i. erase(oldID);
2995 _mapSubMeshIor.erase(oldID);
2996 _mapSubMesh_i [ newID ]->changeLocalId( newID );
3000 TShapeTypeList::iterator geomType = groupData.begin();
3001 for ( ; geomType != groupData.end(); ++geomType )
3003 const TIndexedShape& geom = geomType->first;
3004 int oldID = geom._index;
3005 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
3008 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
3009 CORBA::String_var name = groupSO->GetName();
3011 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
3012 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
3013 /*id=*/-1, geom._shape ))
3014 group_i->changeLocalId( group->GetID() );
3017 break; // everything has been updated
3020 } // loop on group data
3024 CORBA::Long newNbEntities = NbNodes() + NbElements();
3025 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
3026 if ( newNbEntities != nbEntities )
3028 // Add all SObjects with icons to soToUpdateIcons
3029 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
3031 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
3032 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
3033 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
3035 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
3036 i_gr != _mapGroups.end(); ++i_gr ) // groups
3037 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
3040 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
3041 for ( ; so != soToUpdateIcons.end(); ++so )
3042 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
3045 //=============================================================================
3047 * \brief Create standalone group from a group on geometry or filter
3049 //=============================================================================
3051 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
3052 throw (SALOME::SALOME_Exception)
3054 SMESH::SMESH_Group_var aGroup;
3059 _preMeshInfo->FullLoadFromFile();
3061 if ( theGroup->_is_nil() )
3062 return aGroup._retn();
3064 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
3066 return aGroup._retn();
3068 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
3070 const int anId = aGroupToRem->GetLocalID();
3071 if ( !_impl->ConvertToStandalone( anId ) )
3072 return aGroup._retn();
3073 removeGeomGroupData( theGroup );
3075 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3077 // remove old instance of group from own map
3078 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
3079 _mapGroups.erase( anId );
3081 SALOMEDS::StudyBuilder_var builder;
3082 SALOMEDS::SObject_wrap aGroupSO;
3083 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3084 if ( !aStudy->_is_nil() ) {
3085 builder = aStudy->NewBuilder();
3086 aGroupSO = _gen_i->ObjectToSObject( theGroup );
3087 if ( !aGroupSO->_is_nil() )
3089 // remove reference to geometry
3090 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
3091 for ( ; chItr->More(); chItr->Next() )
3093 // Remove group's child SObject
3094 SALOMEDS::SObject_wrap so = chItr->Value();
3095 builder->RemoveObject( so );
3097 // Update Python script
3098 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
3099 << ".ConvertToStandalone( " << aGroupSO << " )";
3101 // change icon of Group on Filter
3104 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
3105 // const int isEmpty = ( elemTypes->length() == 0 );
3108 SALOMEDS::GenericAttribute_wrap anAttr =
3109 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
3110 SALOMEDS::AttributePixMap_wrap pm = anAttr;
3111 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
3117 // remember new group in own map
3118 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
3119 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3121 // register CORBA object for persistence
3122 _gen_i->RegisterObject( aGroup );
3124 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
3125 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
3126 //aGroup->Register();
3127 aGroupToRem->UnRegister();
3129 SMESH_CATCH( SMESH::throwCorbaException );
3131 return aGroup._retn();
3134 //================================================================================
3136 * \brief Create a sub-mesh on a given sub-shape
3138 //================================================================================
3140 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
3142 if(MYDEBUG) MESSAGE( "createSubMesh" );
3143 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
3144 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
3147 SMESH_subMesh_i * subMeshServant;
3150 subMeshId = mySubMesh->GetId();
3151 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
3153 else // "invalid sub-mesh"
3155 // The invalid sub-mesh is created for the case where a valid sub-shape not found
3156 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
3157 if ( _mapSubMesh.empty() )
3160 subMeshId = _mapSubMesh.begin()->first - 1;
3161 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
3164 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
3166 _mapSubMesh [subMeshId] = mySubMesh;
3167 _mapSubMesh_i [subMeshId] = subMeshServant;
3168 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
3170 subMeshServant->Register();
3172 // register CORBA object for persistence
3173 int nextId = _gen_i->RegisterObject( subMesh );
3174 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
3175 else { nextId = 0; } // avoid "unused variable" warning
3177 // to track changes of GEOM groups
3178 if ( subMeshId > 0 )
3179 addGeomGroupData( theSubShapeObject, subMesh );
3181 return subMesh._retn();
3184 //================================================================================
3186 * \brief Return an existing sub-mesh based on a sub-shape with the given ID
3188 //================================================================================
3190 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3192 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3193 if ( it == _mapSubMeshIor.end() )
3194 return SMESH::SMESH_subMesh::_nil();
3196 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3199 //================================================================================
3201 * \brief Remove a sub-mesh based on the given sub-shape
3203 //================================================================================
3205 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3206 GEOM::GEOM_Object_ptr theSubShapeObject )
3208 bool isHypChanged = false;
3209 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3210 return isHypChanged;
3212 const int subMeshId = theSubMesh->GetId();
3214 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3217 if (( _mapSubMesh.count( subMeshId )) &&
3218 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3220 TopoDS_Shape S = sm->GetSubShape();
3223 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3224 isHypChanged = !hyps.empty();
3225 if ( isHypChanged && _preMeshInfo )
3226 _preMeshInfo->ForgetOrLoad();
3227 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3228 for ( ; hyp != hyps.end(); ++hyp )
3229 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3236 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3237 isHypChanged = ( aHypList->length() > 0 );
3238 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3239 removeHypothesis( theSubShapeObject, aHypList[i] );
3242 catch( const SALOME::SALOME_Exception& ) {
3243 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3245 removeGeomGroupData( theSubShapeObject );
3249 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3250 if ( id_smi != _mapSubMesh_i.end() )
3251 id_smi->second->UnRegister();
3253 // remove a CORBA object
3254 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3255 if ( id_smptr != _mapSubMeshIor.end() )
3256 SMESH::SMESH_subMesh_var( id_smptr->second );
3258 _mapSubMesh.erase(subMeshId);
3259 _mapSubMesh_i.erase(subMeshId);
3260 _mapSubMeshIor.erase(subMeshId);
3262 return isHypChanged;
3265 //================================================================================
3267 * \brief Create a group. Group type depends on given arguments
3269 //================================================================================
3271 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3272 const char* theName,
3274 const TopoDS_Shape& theShape,
3275 const SMESH_PredicatePtr& thePredicate )
3277 std::string newName;
3278 if ( !theName || !theName[0] )
3280 std::set< std::string > presentNames;
3281 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3282 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3284 CORBA::String_var name = i_gr->second->GetName();
3285 presentNames.insert( name.in() );
3288 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3289 } while ( !presentNames.insert( newName ).second );
3290 theName = newName.c_str();
3292 SMESH::SMESH_GroupBase_var aGroup;
3293 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3294 theID, theShape, thePredicate ))
3296 int anId = g->GetID();
3297 SMESH_GroupBase_i* aGroupImpl;
3298 if ( !theShape.IsNull() )
3299 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3300 else if ( thePredicate )
3301 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3303 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3305 aGroup = aGroupImpl->_this();
3306 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3307 aGroupImpl->Register();
3309 // register CORBA object for persistence
3310 int nextId = _gen_i->RegisterObject( aGroup );
3311 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3312 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3314 // to track changes of GEOM groups
3315 if ( !theShape.IsNull() ) {
3316 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3317 addGeomGroupData( geom, aGroup );
3320 return aGroup._retn();
3323 //=============================================================================
3325 * SMESH_Mesh_i::removeGroup
3327 * Should be called by ~SMESH_Group_i()
3329 //=============================================================================
3331 void SMESH_Mesh_i::removeGroup( const int theId )
3333 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3334 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3335 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3336 _mapGroups.erase( theId );
3337 removeGeomGroupData( group );
3338 if ( !_impl->RemoveGroup( theId ))
3340 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3341 RemoveGroup( group );
3343 group->UnRegister();
3347 //================================================================================
3349 * \brief Return a log that can be used to move another mesh to the same state as this one
3351 //================================================================================
3353 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3354 throw(SALOME::SALOME_Exception)
3356 SMESH::log_array_var aLog;
3360 _preMeshInfo->FullLoadFromFile();
3362 list < SMESHDS_Command * >logDS = _impl->GetLog();
3363 aLog = new SMESH::log_array;
3365 int lg = logDS.size();
3367 list < SMESHDS_Command * >::iterator its = logDS.begin();
3368 while(its != logDS.end()){
3369 SMESHDS_Command *com = *its;
3370 int comType = com->GetType();
3371 int lgcom = com->GetNumber();
3372 const list < int >&intList = com->GetIndexes();
3373 int inum = intList.size();
3374 list < int >::const_iterator ii = intList.begin();
3375 const list < double >&coordList = com->GetCoords();
3376 int rnum = coordList.size();
3377 list < double >::const_iterator ir = coordList.begin();
3378 aLog[indexLog].commandType = comType;
3379 aLog[indexLog].number = lgcom;
3380 aLog[indexLog].coords.length(rnum);
3381 aLog[indexLog].indexes.length(inum);
3382 for(int i = 0; i < rnum; i++){
3383 aLog[indexLog].coords[i] = *ir;
3386 for(int i = 0; i < inum; i++){
3387 aLog[indexLog].indexes[i] = *ii;
3396 SMESH_CATCH( SMESH::throwCorbaException );
3398 return aLog._retn();
3401 //================================================================================
3403 * \brief Remove the log of commands
3405 //================================================================================
3407 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3411 SMESH_CATCH( SMESH::throwCorbaException );
3414 //================================================================================
3416 * \brief Return a mesh ID
3418 //================================================================================
3420 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3425 //=============================================================================
3428 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3429 // issue 0020918: groups removal is caused by hyp modification
3430 // issue 0021208: to forget not loaded mesh data at hyp modification
3431 struct TCallUp_i : public SMESH_Mesh::TCallUp
3433 SMESH_Mesh_i* _mesh;
3434 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3435 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3436 virtual void HypothesisModified( int hypID,
3437 bool updIcons) { _mesh->onHypothesisModified( hypID,
3439 virtual void Load () { _mesh->Load(); }
3440 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3444 //================================================================================
3446 * \brief callback from _impl to
3447 * 1) forget not loaded mesh data (issue 0021208)
3448 * 2) mark hypothesis as valid
3450 //================================================================================
3452 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3455 _preMeshInfo->ForgetOrLoad();
3457 if ( theUpdateIcons )
3459 SMESH::SMESH_Mesh_var mesh = _this();
3460 _gen_i->UpdateIcons( mesh );
3463 if ( _nbInvalidHypos != 0 )
3465 // mark a hypothesis as valid after edition
3467 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3468 SALOMEDS::SObject_wrap hypRoot;
3469 if ( !smeshComp->_is_nil() &&
3470 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3472 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3473 for ( ; anIter->More(); anIter->Next() )
3475 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3476 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3477 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3478 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3479 _gen_i->HighLightInvalid( hyp, false );
3481 nbInvalid += _gen_i->IsInvalid( hypSO );
3484 _nbInvalidHypos = nbInvalid;
3488 //================================================================================
3490 * \brief Set mesh implementation
3492 //================================================================================
3494 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3496 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3499 _impl->SetCallUp( new TCallUp_i(this));
3502 //=============================================================================
3504 * Return a mesh implementation
3506 //=============================================================================
3508 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3510 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3514 //=============================================================================
3516 * Return mesh editor
3518 //=============================================================================
3520 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3521 throw (SALOME::SALOME_Exception)
3523 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3527 _preMeshInfo->FullLoadFromFile();
3529 // Create MeshEditor
3531 _editor = new SMESH_MeshEditor_i( this, false );
3532 aMeshEdVar = _editor->_this();
3534 // Update Python script
3535 TPythonDump() << _editor << " = "
3536 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3538 SMESH_CATCH( SMESH::throwCorbaException );
3540 return aMeshEdVar._retn();
3543 //=============================================================================
3545 * Return mesh edition previewer
3547 //=============================================================================
3549 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3550 throw (SALOME::SALOME_Exception)
3552 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3556 _preMeshInfo->FullLoadFromFile();
3558 if ( !_previewEditor )
3559 _previewEditor = new SMESH_MeshEditor_i( this, true );
3560 aMeshEdVar = _previewEditor->_this();
3562 SMESH_CATCH( SMESH::throwCorbaException );
3564 return aMeshEdVar._retn();
3567 //================================================================================
3569 * \brief Return true if the mesh has been edited since a last total re-compute
3570 * and those modifications may prevent successful partial re-compute
3572 //================================================================================
3574 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3576 Unexpect aCatch(SALOME_SalomeException);
3577 return _impl->HasModificationsToDiscard();
3580 //================================================================================
3582 * \brief Return a random unique color
3584 //================================================================================
3586 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3588 const int MAX_ATTEMPTS = 100;
3590 double tolerance = 0.5;
3591 SALOMEDS::Color col;
3595 // generate random color
3596 double red = (double)rand() / RAND_MAX;
3597 double green = (double)rand() / RAND_MAX;
3598 double blue = (double)rand() / RAND_MAX;
3599 // check existence in the list of the existing colors
3600 bool matched = false;
3601 std::list<SALOMEDS::Color>::const_iterator it;
3602 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3603 SALOMEDS::Color color = *it;
3604 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3605 matched = tol < tolerance;
3607 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3608 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3616 //=============================================================================
3618 * Set auto-color mode. If it is on, groups get unique random colors
3620 //=============================================================================
3622 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3624 Unexpect aCatch(SALOME_SalomeException);
3625 _impl->SetAutoColor(theAutoColor);
3627 TPythonDump pyDump; // not to dump group->SetColor() from below code
3628 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3630 std::list<SALOMEDS::Color> aReservedColors;
3631 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3632 for ( ; it != _mapGroups.end(); it++ ) {
3633 if ( CORBA::is_nil( it->second )) continue;
3634 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3635 it->second->SetColor( aColor );
3636 aReservedColors.push_back( aColor );
3640 //=============================================================================
3642 * Return true if auto-color mode is on
3644 //=============================================================================
3646 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3648 Unexpect aCatch(SALOME_SalomeException);
3649 return _impl->GetAutoColor();
3652 //=============================================================================
3654 * Check if there are groups with equal names
3656 //=============================================================================
3658 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3660 return _impl->HasDuplicatedGroupNamesMED();
3663 //================================================================================
3665 * \brief Care of a file before exporting mesh into it
3667 //================================================================================
3669 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3671 SMESH_File aFile( file, false );
3673 if ( aFile.exists() ) {
3674 // existing filesystem node
3675 if ( !aFile.isDirectory() ) {
3676 if ( aFile.openForWriting() ) {
3677 if ( overwrite && ! aFile.remove()) {
3678 msg << "Can't replace " << aFile.getName();
3681 msg << "Can't write into " << aFile.getName();
3684 msg << "Location " << aFile.getName() << " is not a file";
3688 // nonexisting file; check if it can be created
3689 if ( !aFile.openForWriting() ) {
3690 msg << "You cannot create the file "
3692 << ". Check the directory existence and access rights";
3700 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3704 //================================================================================
3706 * \brief Prepare a file for export and pass names of mesh groups from study to mesh DS
3707 * \param file - file name
3708 * \param overwrite - to erase the file or not
3709 * \retval string - mesh name
3711 //================================================================================
3713 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3714 CORBA::Boolean overwrite)
3717 PrepareForWriting(file, overwrite);
3718 string aMeshName = "Mesh";
3719 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3720 if ( !aStudy->_is_nil() ) {
3721 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3722 if ( !aMeshSO->_is_nil() ) {
3723 CORBA::String_var name = aMeshSO->GetName();
3725 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3726 if ( !aStudy->GetProperties()->IsLocked() )
3728 SALOMEDS::GenericAttribute_wrap anAttr;
3729 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3730 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3731 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3732 ASSERT(!aFileName->_is_nil());
3733 aFileName->SetValue(file);
3734 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3735 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3736 ASSERT(!aFileType->_is_nil());
3737 aFileType->SetValue("FICHIERMED");
3741 // Update Python script
3742 // set name of mesh before export
3743 TPythonDump() << _gen_i << ".SetName("
3744 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3746 // check names of groups
3752 //================================================================================
3754 * \brief Export to MED file
3756 //================================================================================
3758 void SMESH_Mesh_i::ExportMED(const char* file,
3759 CORBA::Boolean auto_groups,
3760 CORBA::Long version,
3761 CORBA::Boolean overwrite,
3762 CORBA::Boolean autoDimension)
3763 throw(SALOME::SALOME_Exception)
3765 //MESSAGE("MED minor version: "<< minor);
3768 _preMeshInfo->FullLoadFromFile();
3770 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3771 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3773 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3775 << "auto_groups=" <<auto_groups << ", "
3776 << "minor=" << version << ", "
3777 << "overwrite=" << overwrite << ", "
3778 << "meshPart=None, "
3779 << "autoDimension=" << autoDimension << " )";
3781 SMESH_CATCH( SMESH::throwCorbaException );
3784 //================================================================================
3786 * \brief Export a mesh to a SAUV file
3788 //================================================================================
3790 void SMESH_Mesh_i::ExportSAUV (const char* file,
3791 CORBA::Boolean auto_groups)
3792 throw(SALOME::SALOME_Exception)
3794 Unexpect aCatch(SALOME_SalomeException);
3796 _preMeshInfo->FullLoadFromFile();
3798 string aMeshName = prepareMeshNameAndGroups(file, true);
3799 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3800 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3801 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3805 //================================================================================
3807 * \brief Export a mesh to a DAT file
3809 //================================================================================
3811 void SMESH_Mesh_i::ExportDAT (const char *file)
3812 throw(SALOME::SALOME_Exception)
3814 Unexpect aCatch(SALOME_SalomeException);
3816 _preMeshInfo->FullLoadFromFile();
3818 // Update Python script
3819 // check names of groups
3821 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3824 PrepareForWriting(file);
3825 _impl->ExportDAT(file);
3828 //================================================================================
3830 * \brief Export a mesh to an UNV file
3832 //================================================================================
3834 void SMESH_Mesh_i::ExportUNV (const char *file)
3835 throw(SALOME::SALOME_Exception)
3837 Unexpect aCatch(SALOME_SalomeException);
3839 _preMeshInfo->FullLoadFromFile();
3841 // Update Python script
3842 // check names of groups
3844 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3847 PrepareForWriting(file);
3848 _impl->ExportUNV(file);
3851 //================================================================================
3853 * \brief Export a mesh to an STL file
3855 //================================================================================
3857 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3858 throw(SALOME::SALOME_Exception)
3860 Unexpect aCatch(SALOME_SalomeException);
3862 _preMeshInfo->FullLoadFromFile();
3864 // Update Python script
3865 // check names of groups
3867 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3868 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3870 CORBA::String_var name;
3871 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3872 if ( !so->_is_nil() )
3873 name = so->GetName();
3876 PrepareForWriting( file );
3877 _impl->ExportSTL( file, isascii, name.in() );
3880 //================================================================================
3882 * \brief Export a part of mesh to a med file
3884 //================================================================================
3886 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3888 CORBA::Boolean auto_groups,
3889 CORBA::Long version,
3890 CORBA::Boolean overwrite,
3891 CORBA::Boolean autoDimension,
3892 const GEOM::ListOfFields& fields,
3893 const char* geomAssocFields,
3894 CORBA::Double ZTolerance)
3895 throw (SALOME::SALOME_Exception)
3897 MESSAGE("MED version: "<< version);
3900 _preMeshInfo->FullLoadFromFile();
3903 bool have0dField = false;
3904 if ( fields.length() > 0 )
3906 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3907 if ( shapeToMesh->_is_nil() )
3908 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3910 for ( size_t i = 0; i < fields.length(); ++i )
3912 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3913 THROW_SALOME_CORBA_EXCEPTION
3914 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3915 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3916 if ( fieldShape->_is_nil() )
3917 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3918 if ( !fieldShape->IsSame( shapeToMesh ) )
3919 THROW_SALOME_CORBA_EXCEPTION
3920 ( "Field defined not on shape", SALOME::BAD_PARAM);
3921 if ( fields[i]->GetDimension() == 0 )
3924 if ( geomAssocFields )
3925 for ( int i = 0; geomAssocFields[i]; ++i )
3926 switch ( geomAssocFields[i] ) {
3927 case 'v':case 'e':case 'f':case 's': break;
3928 case 'V':case 'E':case 'F':case 'S': break;
3929 default: THROW_SALOME_CORBA_EXCEPTION
3930 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3934 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3938 string aMeshName = "Mesh";
3939 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3940 if ( CORBA::is_nil( meshPart ) ||
3941 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3943 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3944 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3945 0, autoDimension, /*addODOnVertices=*/have0dField,
3947 meshDS = _impl->GetMeshDS();
3952 _preMeshInfo->FullLoadFromFile();
3954 PrepareForWriting(file, overwrite);
3956 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3957 if ( !SO->_is_nil() ) {
3958 CORBA::String_var name = SO->GetName();
3962 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3963 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3964 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3965 meshDS = tmpDSDeleter._obj = partDS;
3970 if ( _impl->HasShapeToMesh() )
3972 DriverMED_W_Field fieldWriter;
3973 fieldWriter.SetFile( file );
3974 fieldWriter.SetMeshName( aMeshName );
3975 fieldWriter.AddODOnVertices( have0dField );
3977 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3981 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3982 goList->length( fields.length() );
3983 for ( size_t i = 0; i < fields.length(); ++i )
3985 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3988 TPythonDump() << _this() << ".ExportPartToMED( "
3989 << meshPart << ", r'"
3991 << auto_groups << ", "
3993 << overwrite << ", "
3994 << autoDimension << ", "
3996 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3997 << TVar( ZTolerance )
4000 SMESH_CATCH( SMESH::throwCorbaException );
4003 //================================================================================
4005 * Write GEOM fields to MED file
4007 //================================================================================
4009 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
4010 SMESHDS_Mesh* meshDS,
4011 const GEOM::ListOfFields& fields,
4012 const char* geomAssocFields)
4014 #define METH "SMESH_Mesh_i::exportMEDFields() "
4016 if (( fields.length() < 1 ) &&
4017 ( !geomAssocFields || !geomAssocFields[0] ))
4020 std::vector< std::vector< double > > dblVals;
4021 std::vector< std::vector< int > > intVals;
4022 std::vector< int > subIdsByDim[ 4 ];
4023 const double noneDblValue = 0.;
4024 const double noneIntValue = 0;
4026 for ( size_t iF = 0; iF < fields.length(); ++iF )
4030 int dim = fields[ iF ]->GetDimension();
4031 SMDSAbs_ElementType elemType;
4032 TopAbs_ShapeEnum shapeType;
4034 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
4035 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
4036 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
4037 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
4039 continue; // skip fields on whole shape
4041 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
4042 if ( dataType == GEOM::FDT_String )
4044 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
4045 if ( stepIDs->length() < 1 )
4047 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
4048 if ( comps->length() < 1 )
4050 CORBA::String_var name = fields[ iF ]->GetName();
4052 if ( !fieldWriter.Set( meshDS,
4056 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
4059 for ( size_t iC = 0; iC < comps->length(); ++iC )
4060 fieldWriter.SetCompName( iC, comps[ iC ].in() );
4062 dblVals.resize( comps->length() );
4063 intVals.resize( comps->length() );
4065 // find sub-shape IDs
4067 std::vector< int >& subIds = subIdsByDim[ dim ];
4068 if ( subIds.empty() )
4069 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
4070 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
4071 subIds.push_back( id );
4075 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4079 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
4081 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
4082 if ( step->_is_nil() )
4085 CORBA::Long stamp = step->GetStamp();
4086 CORBA::Long id = step->GetID();
4087 fieldWriter.SetDtIt( int( stamp ), int( id ));
4089 // fill dblVals or intVals
4090 for ( size_t iC = 0; iC < comps->length(); ++iC )
4091 if ( dataType == GEOM::FDT_Double )
4093 dblVals[ iC ].clear();
4094 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4098 intVals[ iC ].clear();
4099 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4103 case GEOM::FDT_Double:
4105 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
4106 if ( dblStep->_is_nil() ) continue;
4107 GEOM::ListOfDouble_var vv = dblStep->GetValues();
4108 if ( vv->length() != subIds.size() * comps->length() )
4109 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4110 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4111 for ( size_t iC = 0; iC < comps->length(); ++iC )
4112 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
4117 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
4118 if ( intStep->_is_nil() ) continue;
4119 GEOM::ListOfLong_var vv = intStep->GetValues();
4120 if ( vv->length() != subIds.size() * comps->length() )
4121 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4122 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4123 for ( size_t iC = 0; iC < comps->length(); ++iC )
4124 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4127 case GEOM::FDT_Bool:
4129 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
4130 if ( boolStep->_is_nil() ) continue;
4131 GEOM::short_array_var vv = boolStep->GetValues();
4132 if ( vv->length() != subIds.size() * comps->length() )
4133 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4134 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4135 for ( size_t iC = 0; iC < comps->length(); ++iC )
4136 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4142 // pass values to fieldWriter
4143 elemIt = fieldWriter.GetOrderedElems();
4144 if ( dataType == GEOM::FDT_Double )
4145 while ( elemIt->more() )
4147 const SMDS_MeshElement* e = elemIt->next();
4148 const int shapeID = e->getshapeId();
4149 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
4150 for ( size_t iC = 0; iC < comps->length(); ++iC )
4151 fieldWriter.AddValue( noneDblValue );
4153 for ( size_t iC = 0; iC < comps->length(); ++iC )
4154 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
4157 while ( elemIt->more() )
4159 const SMDS_MeshElement* e = elemIt->next();
4160 const int shapeID = e->getshapeId();
4161 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
4162 for ( size_t iC = 0; iC < comps->length(); ++iC )
4163 fieldWriter.AddValue( (double) noneIntValue );
4165 for ( size_t iC = 0; iC < comps->length(); ++iC )
4166 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4170 fieldWriter.Perform();
4171 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4172 if ( res && res->IsKO() )
4174 if ( res->myComment.empty() )
4175 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4177 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4183 if ( !geomAssocFields || !geomAssocFields[0] )
4186 // write geomAssocFields
4188 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4189 shapeDim[ TopAbs_COMPOUND ] = 3;
4190 shapeDim[ TopAbs_COMPSOLID ] = 3;
4191 shapeDim[ TopAbs_SOLID ] = 3;
4192 shapeDim[ TopAbs_SHELL ] = 2;
4193 shapeDim[ TopAbs_FACE ] = 2;
4194 shapeDim[ TopAbs_WIRE ] = 1;
4195 shapeDim[ TopAbs_EDGE ] = 1;
4196 shapeDim[ TopAbs_VERTEX ] = 0;
4197 shapeDim[ TopAbs_SHAPE ] = 3;
4199 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4201 std::vector< std::string > compNames;
4202 switch ( geomAssocFields[ iF ]) {
4204 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4205 compNames.push_back( "dim" );
4208 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4211 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4214 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4218 compNames.push_back( "id" );
4219 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4220 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4222 fieldWriter.SetDtIt( -1, -1 );
4224 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4228 if ( compNames.size() == 2 ) // _vertices_
4229 while ( elemIt->more() )
4231 const SMDS_MeshElement* e = elemIt->next();
4232 const int shapeID = e->getshapeId();
4235 fieldWriter.AddValue( (double) -1 );
4236 fieldWriter.AddValue( (double) -1 );
4240 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4241 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4242 fieldWriter.AddValue( (double) shapeID );
4246 while ( elemIt->more() )
4248 const SMDS_MeshElement* e = elemIt->next();
4249 const int shapeID = e->getshapeId();
4251 fieldWriter.AddValue( (double) -1 );
4253 fieldWriter.AddValue( (double) shapeID );
4257 fieldWriter.Perform();
4258 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4259 if ( res && res->IsKO() )
4261 if ( res->myComment.empty() )
4262 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4264 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4267 } // loop on geomAssocFields
4272 //================================================================================
4274 * \brief Export a part of mesh to a DAT file
4276 //================================================================================
4278 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4280 throw (SALOME::SALOME_Exception)
4282 Unexpect aCatch(SALOME_SalomeException);
4284 _preMeshInfo->FullLoadFromFile();
4286 PrepareForWriting(file);
4288 SMESH_MeshPartDS partDS( meshPart );
4289 _impl->ExportDAT(file,&partDS);
4291 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4292 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4294 //================================================================================
4296 * \brief Export a part of mesh to an UNV file
4298 //================================================================================
4300 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4302 throw (SALOME::SALOME_Exception)
4304 Unexpect aCatch(SALOME_SalomeException);
4306 _preMeshInfo->FullLoadFromFile();
4308 PrepareForWriting(file);
4310 SMESH_MeshPartDS partDS( meshPart );
4311 _impl->ExportUNV(file, &partDS);
4313 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4314 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4316 //================================================================================
4318 * \brief Export a part of mesh to an STL file
4320 //================================================================================
4322 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4324 ::CORBA::Boolean isascii)
4325 throw (SALOME::SALOME_Exception)
4327 Unexpect aCatch(SALOME_SalomeException);
4329 _preMeshInfo->FullLoadFromFile();
4331 PrepareForWriting(file);
4333 CORBA::String_var name;
4334 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4335 if ( !so->_is_nil() )
4336 name = so->GetName();
4338 SMESH_MeshPartDS partDS( meshPart );
4339 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4341 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4342 << meshPart<< ", r'" << file << "', " << isascii << ")";
4345 //================================================================================
4347 * \brief Export a part of mesh to an STL file
4349 //================================================================================
4351 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4353 CORBA::Boolean overwrite,
4354 CORBA::Boolean groupElemsByType)
4355 throw (SALOME::SALOME_Exception)
4358 Unexpect aCatch(SALOME_SalomeException);
4360 _preMeshInfo->FullLoadFromFile();
4362 PrepareForWriting(file,overwrite);
4364 std::string meshName("");
4365 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4366 if ( !so->_is_nil() )
4368 CORBA::String_var name = so->GetName();
4369 meshName = name.in();
4373 SMESH_MeshPartDS partDS( meshPart );
4374 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4376 SMESH_CATCH( SMESH::throwCorbaException );
4378 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4379 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4381 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4385 //================================================================================
4387 * \brief Export a part of mesh to a GMF file
4389 //================================================================================
4391 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4393 bool withRequiredGroups)
4394 throw (SALOME::SALOME_Exception)
4396 Unexpect aCatch(SALOME_SalomeException);
4398 _preMeshInfo->FullLoadFromFile();
4400 PrepareForWriting(file,/*overwrite=*/true);
4402 SMESH_MeshPartDS partDS( meshPart );
4403 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4405 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4406 << meshPart<< ", r'"
4408 << withRequiredGroups << ")";
4411 //=============================================================================
4413 * Return computation progress [0.,1]
4415 //=============================================================================
4417 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4421 return _impl->GetComputeProgress();
4423 SMESH_CATCH( SMESH::doNothing );
4427 //================================================================================
4429 * \brief Return nb of nodes
4431 //================================================================================
4433 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4435 Unexpect aCatch(SALOME_SalomeException);
4437 return _preMeshInfo->NbNodes();
4439 return _impl->NbNodes();
4442 //================================================================================
4444 * \brief Return nb of elements
4446 //================================================================================
4448 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4450 Unexpect aCatch(SALOME_SalomeException);
4452 return _preMeshInfo->NbElements();
4454 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4457 //================================================================================
4459 * \brief Return nb of 0D elements
4461 //================================================================================
4463 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4465 Unexpect aCatch(SALOME_SalomeException);
4467 return _preMeshInfo->Nb0DElements();
4469 return _impl->Nb0DElements();
4472 //================================================================================
4474 * \brief Return nb of BALL elements
4476 //================================================================================
4478 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4480 Unexpect aCatch(SALOME_SalomeException);
4482 return _preMeshInfo->NbBalls();
4484 return _impl->NbBalls();
4487 //================================================================================
4489 * \brief Return nb of 1D elements
4491 //================================================================================
4493 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4495 Unexpect aCatch(SALOME_SalomeException);
4497 return _preMeshInfo->NbEdges();
4499 return _impl->NbEdges();
4502 //================================================================================
4504 * \brief Return nb of edges
4506 //================================================================================
4508 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4509 throw(SALOME::SALOME_Exception)
4511 Unexpect aCatch(SALOME_SalomeException);
4513 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4515 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4518 //================================================================================
4520 * \brief Return nb of faces
4522 //================================================================================
4524 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4526 Unexpect aCatch(SALOME_SalomeException);
4528 return _preMeshInfo->NbFaces();
4530 return _impl->NbFaces();
4533 //================================================================================
4535 * \brief Return nb of tringles
4537 //================================================================================
4539 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4541 Unexpect aCatch(SALOME_SalomeException);
4543 return _preMeshInfo->NbTriangles();
4545 return _impl->NbTriangles();
4548 //================================================================================
4550 * \brief Return nb of bi-quadratic triangles
4552 //================================================================================
4554 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4556 Unexpect aCatch(SALOME_SalomeException);
4558 return _preMeshInfo->NbBiQuadTriangles();
4560 return _impl->NbBiQuadTriangles();
4563 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4565 Unexpect aCatch(SALOME_SalomeException);
4567 return _preMeshInfo->NbQuadrangles();
4569 return _impl->NbQuadrangles();
4572 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4574 Unexpect aCatch(SALOME_SalomeException);
4576 return _preMeshInfo->NbBiQuadQuadrangles();
4578 return _impl->NbBiQuadQuadrangles();
4581 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4583 Unexpect aCatch(SALOME_SalomeException);
4585 return _preMeshInfo->NbPolygons();
4587 return _impl->NbPolygons();
4590 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4592 Unexpect aCatch(SALOME_SalomeException);
4594 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4596 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4599 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4600 throw(SALOME::SALOME_Exception)
4602 Unexpect aCatch(SALOME_SalomeException);
4604 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4606 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4609 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4610 throw(SALOME::SALOME_Exception)
4612 Unexpect aCatch(SALOME_SalomeException);
4614 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4616 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4619 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4620 throw(SALOME::SALOME_Exception)
4622 Unexpect aCatch(SALOME_SalomeException);
4624 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4626 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4629 //=============================================================================
4631 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4633 Unexpect aCatch(SALOME_SalomeException);
4635 return _preMeshInfo->NbVolumes();
4637 return _impl->NbVolumes();
4640 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4642 Unexpect aCatch(SALOME_SalomeException);
4644 return _preMeshInfo->NbTetras();
4646 return _impl->NbTetras();
4649 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4651 Unexpect aCatch(SALOME_SalomeException);
4653 return _preMeshInfo->NbHexas();
4655 return _impl->NbHexas();
4658 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4660 Unexpect aCatch(SALOME_SalomeException);
4662 return _preMeshInfo->NbTriQuadHexas();
4664 return _impl->NbTriQuadraticHexas();
4667 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4669 Unexpect aCatch(SALOME_SalomeException);
4671 return _preMeshInfo->NbPyramids();
4673 return _impl->NbPyramids();
4676 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4678 Unexpect aCatch(SALOME_SalomeException);
4680 return _preMeshInfo->NbPrisms();
4682 return _impl->NbPrisms();
4685 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4687 Unexpect aCatch(SALOME_SalomeException);
4689 return _preMeshInfo->NbHexPrisms();
4691 return _impl->NbHexagonalPrisms();
4694 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4696 Unexpect aCatch(SALOME_SalomeException);
4698 return _preMeshInfo->NbPolyhedrons();
4700 return _impl->NbPolyhedrons();
4703 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4704 throw(SALOME::SALOME_Exception)
4706 Unexpect aCatch(SALOME_SalomeException);
4708 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4710 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4713 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4714 throw(SALOME::SALOME_Exception)
4716 Unexpect aCatch(SALOME_SalomeException);
4718 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4720 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4723 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4724 throw(SALOME::SALOME_Exception)
4726 Unexpect aCatch(SALOME_SalomeException);
4728 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4730 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4733 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4734 throw(SALOME::SALOME_Exception)
4736 Unexpect aCatch(SALOME_SalomeException);
4738 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4740 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4743 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4744 throw(SALOME::SALOME_Exception)
4746 Unexpect aCatch(SALOME_SalomeException);
4748 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4750 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4753 //=============================================================================
4755 * Return nb of published sub-meshes
4757 //=============================================================================
4759 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4761 Unexpect aCatch(SALOME_SalomeException);
4762 return _mapSubMesh_i.size();
4765 //=============================================================================
4767 * Dumps mesh into a string
4769 //=============================================================================
4771 char* SMESH_Mesh_i::Dump()
4775 return CORBA::string_dup( os.str().c_str() );
4778 //=============================================================================
4780 * Method of SMESH_IDSource interface
4782 //=============================================================================
4784 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4786 return GetElementsId();
4789 //=============================================================================
4791 * Return ids of all elements
4793 //=============================================================================
4795 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4796 throw (SALOME::SALOME_Exception)
4798 Unexpect aCatch(SALOME_SalomeException);
4800 _preMeshInfo->FullLoadFromFile();
4802 SMESH::long_array_var aResult = new SMESH::long_array();
4803 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4805 if ( aSMESHDS_Mesh == NULL )
4806 return aResult._retn();
4808 long nbElements = NbElements();
4809 aResult->length( nbElements );
4810 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4811 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4812 aResult[i] = anIt->next()->GetID();
4814 return aResult._retn();
4818 //=============================================================================
4820 * Return ids of all elements of given type
4822 //=============================================================================
4824 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4825 throw (SALOME::SALOME_Exception)
4827 Unexpect aCatch(SALOME_SalomeException);
4829 _preMeshInfo->FullLoadFromFile();
4831 SMESH::long_array_var aResult = new SMESH::long_array();
4832 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4834 if ( aSMESHDS_Mesh == NULL )
4835 return aResult._retn();
4837 long nbElements = NbElements();
4839 // No sense in returning ids of elements along with ids of nodes:
4840 // when theElemType == SMESH::ALL, return node ids only if
4841 // there are no elements
4842 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4843 return GetNodesId();
4845 aResult->length( nbElements );
4849 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4850 while ( i < nbElements && anIt->more() )
4851 aResult[i++] = anIt->next()->GetID();
4853 aResult->length( i );
4855 return aResult._retn();
4858 //=============================================================================
4860 * Return ids of all nodes
4862 //=============================================================================
4864 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4865 throw (SALOME::SALOME_Exception)
4867 Unexpect aCatch(SALOME_SalomeException);
4869 _preMeshInfo->FullLoadFromFile();
4871 SMESH::long_array_var aResult = new SMESH::long_array();
4872 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4874 if ( aMeshDS == NULL )
4875 return aResult._retn();
4877 long nbNodes = NbNodes();
4878 aResult->length( nbNodes );
4879 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4880 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4881 aResult[i] = anIt->next()->GetID();
4883 return aResult._retn();
4886 //=============================================================================
4888 * Return type of the given element
4890 //=============================================================================
4892 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4893 throw (SALOME::SALOME_Exception)
4895 SMESH::ElementType type = SMESH::ALL;
4899 _preMeshInfo->FullLoadFromFile();
4901 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4903 SMESH_CATCH( SMESH::throwCorbaException );
4908 //=============================================================================
4910 * Return geometric type of the given element
4912 //=============================================================================
4914 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4915 throw (SALOME::SALOME_Exception)
4918 _preMeshInfo->FullLoadFromFile();
4920 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4922 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4924 return ( SMESH::EntityType ) e->GetEntityType();
4927 //=============================================================================
4929 * Return type of the given element
4931 //=============================================================================
4933 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4934 throw (SALOME::SALOME_Exception)
4937 _preMeshInfo->FullLoadFromFile();
4939 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4941 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4943 return ( SMESH::GeometryType ) e->GetGeomType();
4946 //=============================================================================
4948 * Return ID of elements for given submesh
4950 //=============================================================================
4952 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4953 throw (SALOME::SALOME_Exception)
4955 SMESH::long_array_var aResult = new SMESH::long_array();
4959 _preMeshInfo->FullLoadFromFile();
4961 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4962 if(!SM) return aResult._retn();
4964 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4965 if(!SDSM) return aResult._retn();
4967 aResult->length(SDSM->NbElements());
4969 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4971 while ( eIt->more() ) {
4972 aResult[i++] = eIt->next()->GetID();
4975 SMESH_CATCH( SMESH::throwCorbaException );
4977 return aResult._retn();
4980 //=============================================================================
4982 * Return ID of nodes for given sub-mesh
4983 * If param all==true - return all nodes, else -
4984 * Return only nodes on shapes.
4986 //=============================================================================
4988 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4990 throw (SALOME::SALOME_Exception)
4992 SMESH::long_array_var aResult = new SMESH::long_array();
4996 _preMeshInfo->FullLoadFromFile();
4998 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4999 if(!SM) return aResult._retn();
5001 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
5002 if(!SDSM) return aResult._retn();
5005 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
5006 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
5007 while ( nIt->more() ) {
5008 const SMDS_MeshNode* elem = nIt->next();
5009 theElems.insert( elem->GetID() );
5012 else { // all nodes of submesh elements
5013 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5014 while ( eIt->more() ) {
5015 const SMDS_MeshElement* anElem = eIt->next();
5016 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
5017 while ( nIt->more() ) {
5018 const SMDS_MeshElement* elem = nIt->next();
5019 theElems.insert( elem->GetID() );
5024 aResult->length(theElems.size());
5025 set<int>::iterator itElem;
5027 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
5028 aResult[i++] = *itElem;
5030 SMESH_CATCH( SMESH::throwCorbaException );
5032 return aResult._retn();
5035 //=============================================================================
5037 * Return type of elements for given sub-mesh
5039 //=============================================================================
5041 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
5042 throw (SALOME::SALOME_Exception)
5044 SMESH::ElementType type = SMESH::ALL;
5048 _preMeshInfo->FullLoadFromFile();
5050 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
5051 if(!SM) return SMESH::ALL;
5053 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
5054 if(!SDSM) return SMESH::ALL;
5056 if(SDSM->NbElements()==0)
5057 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
5059 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5060 const SMDS_MeshElement* anElem = eIt->next();
5062 type = ( SMESH::ElementType ) anElem->GetType();
5064 SMESH_CATCH( SMESH::throwCorbaException );
5070 //=============================================================================
5072 * Return pointer to _impl as an integer value. Is called from constructor of SMESH_Client
5074 //=============================================================================
5076 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
5079 _preMeshInfo->FullLoadFromFile();
5081 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
5082 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
5087 //=============================================================================
5089 * Get XYZ coordinates of node as list of double
5090 * If there is not node for given ID - return empty list
5092 //=============================================================================
5094 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
5097 _preMeshInfo->FullLoadFromFile();
5099 SMESH::double_array_var aResult = new SMESH::double_array();
5100 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5101 if ( aMeshDS == NULL )
5102 return aResult._retn();
5105 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5107 return aResult._retn();
5111 aResult[0] = aNode->X();
5112 aResult[1] = aNode->Y();
5113 aResult[2] = aNode->Z();
5114 return aResult._retn();
5118 //=============================================================================
5120 * For given node return list of IDs of inverse elements
5121 * If there is not node for given ID - return empty list
5123 //=============================================================================
5125 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
5126 SMESH::ElementType elemType)
5129 _preMeshInfo->FullLoadFromFile();
5131 SMESH::long_array_var aResult = new SMESH::long_array();
5132 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5133 if ( aMeshDS == NULL )
5134 return aResult._retn();
5137 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
5139 return aResult._retn();
5141 // find inverse elements
5142 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
5143 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
5144 aResult->length( aNode->NbInverseElements( type ));
5145 for( int i = 0; eIt->more(); ++i )
5147 const SMDS_MeshElement* elem = eIt->next();
5148 aResult[ i ] = elem->GetID();
5150 return aResult._retn();
5153 //=============================================================================
5155 * \brief Return position of a node on shape
5157 //=============================================================================
5159 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
5162 _preMeshInfo->FullLoadFromFile();
5164 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
5165 aNodePosition->shapeID = 0;
5166 aNodePosition->shapeType = GEOM::SHAPE;
5168 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5169 if ( !mesh ) return aNodePosition;
5171 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
5173 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
5175 aNodePosition->shapeID = aNode->getshapeId();
5176 switch ( pos->GetTypeOfPosition() ) {
5178 aNodePosition->shapeType = GEOM::EDGE;
5179 aNodePosition->params.length(1);
5180 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
5182 case SMDS_TOP_FACE: {
5183 SMDS_FacePositionPtr fPos = pos;
5184 aNodePosition->shapeType = GEOM::FACE;
5185 aNodePosition->params.length(2);
5186 aNodePosition->params[0] = fPos->GetUParameter();
5187 aNodePosition->params[1] = fPos->GetVParameter();
5190 case SMDS_TOP_VERTEX:
5191 aNodePosition->shapeType = GEOM::VERTEX;
5193 case SMDS_TOP_3DSPACE:
5194 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
5195 aNodePosition->shapeType = GEOM::SOLID;
5196 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
5197 aNodePosition->shapeType = GEOM::SHELL;
5203 return aNodePosition;
5206 //=============================================================================
5208 * \brief Return position of an element on shape
5210 //=============================================================================
5212 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
5215 _preMeshInfo->FullLoadFromFile();
5217 SMESH::ElementPosition anElementPosition;
5218 anElementPosition.shapeID = 0;
5219 anElementPosition.shapeType = GEOM::SHAPE;
5221 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5222 if ( !mesh ) return anElementPosition;
5224 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5226 anElementPosition.shapeID = anElem->getshapeId();
5227 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5228 if ( !aSp.IsNull() ) {
5229 switch ( aSp.ShapeType() ) {
5231 anElementPosition.shapeType = GEOM::EDGE;
5234 anElementPosition.shapeType = GEOM::FACE;
5237 anElementPosition.shapeType = GEOM::VERTEX;
5240 anElementPosition.shapeType = GEOM::SOLID;
5243 anElementPosition.shapeType = GEOM::SHELL;
5249 return anElementPosition;
5252 //=============================================================================
5254 * If given element is node return IDs of shape from position
5255 * If there is not node for given ID - return -1
5257 //=============================================================================
5259 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5262 _preMeshInfo->FullLoadFromFile();
5264 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5265 if ( aMeshDS == NULL )
5269 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5271 return aNode->getshapeId();
5278 //=============================================================================
5280 * For given element return ID of result shape after
5281 * ::FindShape() from SMESH_MeshEditor
5282 * If there is not element for given ID - return -1
5284 //=============================================================================
5286 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5289 _preMeshInfo->FullLoadFromFile();
5291 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5292 if ( aMeshDS == NULL )
5295 // try to find element
5296 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5300 ::SMESH_MeshEditor aMeshEditor(_impl);
5301 int index = aMeshEditor.FindShape( elem );
5309 //=============================================================================
5311 * Return number of nodes for given element
5312 * If there is not element for given ID - return -1
5314 //=============================================================================
5316 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5319 _preMeshInfo->FullLoadFromFile();
5321 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5322 if ( aMeshDS == NULL ) return -1;
5323 // try to find element
5324 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5325 if(!elem) return -1;
5326 return elem->NbNodes();
5330 //=============================================================================
5332 * Return ID of node by given index for given element
5333 * If there is not element for given ID - return -1
5334 * If there is not node for given index - return -2
5336 //=============================================================================
5338 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5341 _preMeshInfo->FullLoadFromFile();
5343 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5344 if ( aMeshDS == NULL ) return -1;
5345 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5346 if(!elem) return -1;
5347 if( index>=elem->NbNodes() || index<0 ) return -1;
5348 return elem->GetNode(index)->GetID();
5351 //=============================================================================
5353 * Return IDs of nodes of given element
5355 //=============================================================================
5357 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5360 _preMeshInfo->FullLoadFromFile();
5362 SMESH::long_array_var aResult = new SMESH::long_array();
5363 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5365 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5367 aResult->length( elem->NbNodes() );
5368 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5369 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5370 aResult[ i ] = n->GetID();
5373 return aResult._retn();
5376 //=============================================================================
5378 * Return true if given node is medium node
5379 * in given quadratic element
5381 //=============================================================================
5383 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5386 _preMeshInfo->FullLoadFromFile();
5388 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5389 if ( aMeshDS == NULL ) return false;
5391 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5392 if(!aNode) return false;
5393 // try to find element
5394 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5395 if(!elem) return false;
5397 return elem->IsMediumNode(aNode);
5401 //=============================================================================
5403 * Return true if given node is medium node
5404 * in one of quadratic elements
5406 //=============================================================================
5408 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5409 SMESH::ElementType theElemType)
5412 _preMeshInfo->FullLoadFromFile();
5414 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5415 if ( aMeshDS == NULL ) return false;
5418 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5419 if(!aNode) return false;
5421 SMESH_MesherHelper aHelper( *(_impl) );
5423 SMDSAbs_ElementType aType;
5424 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5425 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5426 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5427 else aType = SMDSAbs_All;
5429 return aHelper.IsMedium(aNode,aType);
5433 //=============================================================================
5435 * Return number of edges for given element
5437 //=============================================================================
5439 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5442 _preMeshInfo->FullLoadFromFile();
5444 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5445 if ( aMeshDS == NULL ) return -1;
5446 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5447 if(!elem) return -1;
5448 return elem->NbEdges();
5452 //=============================================================================
5454 * Return number of faces for given element
5456 //=============================================================================
5458 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5461 _preMeshInfo->FullLoadFromFile();
5463 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5464 if ( aMeshDS == NULL ) return -1;
5465 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5466 if(!elem) return -1;
5467 return elem->NbFaces();
5470 //================================================================================
5472 * \brief Return nodes of given face (counted from zero) for given element.
5474 //================================================================================
5476 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5477 CORBA::Short faceIndex)
5480 _preMeshInfo->FullLoadFromFile();
5482 SMESH::long_array_var aResult = new SMESH::long_array();
5483 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5485 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5487 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5488 if ( faceIndex < vtool.NbFaces() )
5490 aResult->length( vtool.NbFaceNodes( faceIndex ));
5491 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5492 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5493 aResult[ i ] = nn[ i ]->GetID();
5497 return aResult._retn();
5500 //================================================================================
5502 * \brief Return three components of normal of given mesh face.
5504 //================================================================================
5506 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5507 CORBA::Boolean normalized)
5510 _preMeshInfo->FullLoadFromFile();
5512 SMESH::double_array_var aResult = new SMESH::double_array();
5514 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5517 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5519 aResult->length( 3 );
5520 aResult[ 0 ] = normal.X();
5521 aResult[ 1 ] = normal.Y();
5522 aResult[ 2 ] = normal.Z();
5525 return aResult._retn();
5528 //================================================================================
5530 * \brief Return an element based on all given nodes.
5532 //================================================================================
5534 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5537 _preMeshInfo->FullLoadFromFile();
5539 CORBA::Long elemID(0);
5540 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5542 vector< const SMDS_MeshNode * > nn( nodes.length() );
5543 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5544 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5547 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5548 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5549 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5550 _impl->NbVolumes( ORDER_QUADRATIC )))
5551 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5553 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5558 //================================================================================
5560 * \brief Return elements including all given nodes.
5562 //================================================================================
5564 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5565 SMESH::ElementType elemType)
5568 _preMeshInfo->FullLoadFromFile();
5570 SMESH::long_array_var result = new SMESH::long_array();
5572 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5574 vector< const SMDS_MeshNode * > nn( nodes.length() );
5575 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5576 nn[i] = mesh->FindNode( nodes[i] );
5578 std::vector<const SMDS_MeshElement *> elems;
5579 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5580 result->length( elems.size() );
5581 for ( size_t i = 0; i < elems.size(); ++i )
5582 result[i] = elems[i]->GetID();
5584 return result._retn();
5587 //=============================================================================
5589 * Return true if given element is polygon
5591 //=============================================================================
5593 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5596 _preMeshInfo->FullLoadFromFile();
5598 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5599 if ( aMeshDS == NULL ) return false;
5600 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5601 if(!elem) return false;
5602 return elem->IsPoly();
5606 //=============================================================================
5608 * Return true if given element is quadratic
5610 //=============================================================================
5612 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5615 _preMeshInfo->FullLoadFromFile();
5617 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5618 if ( aMeshDS == NULL ) return false;
5619 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5620 if(!elem) return false;
5621 return elem->IsQuadratic();
5624 //=============================================================================
5626 * Return diameter of ball discrete element or zero in case of an invalid \a id
5628 //=============================================================================
5630 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5633 _preMeshInfo->FullLoadFromFile();
5635 if ( const SMDS_BallElement* ball =
5636 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5637 return ball->GetDiameter();
5642 //=============================================================================
5644 * Return bary center for given element
5646 //=============================================================================
5648 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5651 _preMeshInfo->FullLoadFromFile();
5653 SMESH::double_array_var aResult = new SMESH::double_array();
5654 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5655 if ( aMeshDS == NULL )
5656 return aResult._retn();
5658 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5660 return aResult._retn();
5662 if(elem->GetType()==SMDSAbs_Volume) {
5663 SMDS_VolumeTool aTool;
5664 if(aTool.Set(elem)) {
5666 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5671 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5673 double x=0., y=0., z=0.;
5674 for(; anIt->more(); ) {
5676 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5690 return aResult._retn();
5693 //================================================================================
5695 * \brief Create a group of elements preventing computation of a sub-shape
5697 //================================================================================
5699 SMESH::ListOfGroups*
5700 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5701 const char* theGroupName )
5702 throw ( SALOME::SALOME_Exception )
5704 Unexpect aCatch(SALOME_SalomeException);
5706 if ( !theGroupName || strlen( theGroupName) == 0 )
5707 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5709 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5710 ::SMESH_MeshEditor::ElemFeatures elemType;
5712 // submesh by subshape id
5713 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5714 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5717 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5718 if ( error && error->HasBadElems() )
5720 // sort bad elements by type
5721 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5722 const list<const SMDS_MeshElement*>& badElems =
5723 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5724 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5725 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5726 for ( ; elemIt != elemEnd; ++elemIt )
5728 const SMDS_MeshElement* elem = *elemIt;
5729 if ( !elem ) continue;
5731 if ( elem->GetID() < 1 )
5733 // elem is a temporary element, make a real element
5734 vector< const SMDS_MeshNode* > nodes;
5735 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5736 while ( nIt->more() && elem )
5738 nodes.push_back( nIt->next() );
5739 if ( nodes.back()->GetID() < 1 )
5740 elem = 0; // a temporary element on temporary nodes
5744 ::SMESH_MeshEditor editor( _impl );
5745 elem = editor.AddElement( nodes, elemType.Init( elem ));
5749 elemsByType[ elem->GetType() ].push_back( elem );
5752 // how many groups to create?
5754 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5755 nbTypes += int( !elemsByType[ i ].empty() );
5756 groups->length( nbTypes );
5759 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5761 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5762 if ( elems.empty() ) continue;
5764 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5765 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5767 SMESH::SMESH_Mesh_var mesh = _this();
5768 SALOMEDS::SObject_wrap aSO =
5769 _gen_i->PublishGroup( mesh, groups[ iG ],
5770 GEOM::GEOM_Object::_nil(), theGroupName);
5772 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5773 if ( !grp_i ) continue;
5775 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5776 for ( size_t iE = 0; iE < elems.size(); ++iE )
5777 grpDS->SMDSGroup().Add( elems[ iE ]);
5782 return groups._retn();
5785 //=============================================================================
5787 * Create and publish group servants if any groups were imported or created anyhow
5789 //=============================================================================
5791 void SMESH_Mesh_i::CreateGroupServants()
5793 SMESH::SMESH_Mesh_var aMesh = _this();
5796 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5797 while ( groupIt->more() )
5799 ::SMESH_Group* group = groupIt->next();
5800 int anId = group->GetID();
5802 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5803 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5805 addedIDs.insert( anId );
5807 SMESH_GroupBase_i* aGroupImpl;
5809 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5810 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5812 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5813 shape = groupOnGeom->GetShape();
5816 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5819 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5820 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5821 aGroupImpl->Register();
5823 // register CORBA object for persistence
5824 int nextId = _gen_i->RegisterObject( groupVar );
5825 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5826 else { nextId = 0; } // avoid "unused variable" warning in release mode
5828 // publishing the groups in the study
5829 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5830 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5833 if ( !addedIDs.empty() )
5836 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
5837 for ( int index = 0; i_grp != _mapGroups.end(); ++index, ++i_grp )
5839 set<int>::iterator it = addedIDs.find( i_grp->first );
5840 if ( it != addedIDs.end() )
5842 TPythonDump() << i_grp->second << " = " << aMesh << ".GetGroups()[ "<< index << " ]";
5843 addedIDs.erase( it );
5844 if ( addedIDs.empty() )
5851 //=============================================================================
5853 * \brief Return true if all sub-meshes are computed OK - to update an icon
5855 //=============================================================================
5857 bool SMESH_Mesh_i::IsComputedOK()
5859 return _impl->IsComputedOK();
5862 //=============================================================================
5864 * \brief Return groups cantained in _mapGroups by their IDs
5866 //=============================================================================
5868 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5870 int nbGroups = groupIDs.size();
5871 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5872 aList->length( nbGroups );
5874 list<int>::const_iterator ids = groupIDs.begin();
5875 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5877 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5878 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5879 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5881 aList->length( nbGroups );
5882 return aList._retn();
5885 //=============================================================================
5887 * \brief Return information about imported file
5889 //=============================================================================
5891 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5893 SMESH::MedFileInfo_var res( _medFileInfo );
5894 if ( !res.operator->() ) {
5895 res = new SMESH::MedFileInfo;
5897 res->fileSize = res->major = res->minor = res->release = -1;
5902 //=======================================================================
5903 //function : FileInfoToString
5904 //purpose : Persistence of file info
5905 //=======================================================================
5907 std::string SMESH_Mesh_i::FileInfoToString()
5910 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5912 s = SMESH_Comment( _medFileInfo->fileSize )
5913 << " " << _medFileInfo->major
5914 << " " << _medFileInfo->minor
5915 << " " << _medFileInfo->release
5916 << " " << _medFileInfo->fileName;
5921 //=======================================================================
5922 //function : FileInfoFromString
5923 //purpose : Persistence of file info
5924 //=======================================================================
5926 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5928 std::string size, major, minor, release, fileName;
5929 std::istringstream is(info);
5930 is >> size >> major >> minor >> release;
5931 fileName = info.data() + ( size.size() + 1 +
5934 release.size()+ 1 );
5936 _medFileInfo = new SMESH::MedFileInfo();
5937 _medFileInfo->fileName = fileName.c_str();
5938 _medFileInfo->fileSize = atoi( size.c_str() );
5939 _medFileInfo->major = atoi( major.c_str() );
5940 _medFileInfo->minor = atoi( minor.c_str() );
5941 _medFileInfo->release = atoi( release.c_str() );
5944 //=============================================================================
5946 * \brief Pass names of mesh groups from study to mesh DS
5948 //=============================================================================
5950 void SMESH_Mesh_i::checkGroupNames()
5952 int nbGrp = NbGroups();
5956 SMESH::ListOfGroups* grpList = 0;
5957 // avoid dump of "GetGroups"
5959 // store python dump into a local variable inside local scope
5960 SMESH::TPythonDump pDump; // do not delete this line of code
5961 grpList = GetGroups();
5964 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5965 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5968 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5969 if ( aGrpSO->_is_nil() )
5971 // correct name of the mesh group if necessary
5972 const char* guiName = aGrpSO->GetName();
5973 if ( strcmp(guiName, aGrp->GetName()) )
5974 aGrp->SetName( guiName );
5978 //=============================================================================
5980 * \brief Set list of notebook variables used for Mesh operations separated by ":" symbol
5982 //=============================================================================
5983 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5985 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5989 //=============================================================================
5991 * \brief Return list of notebook variables used for Mesh operations separated by ":" symbol
5993 //=============================================================================
5995 char* SMESH_Mesh_i::GetParameters()
5997 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
6000 //=============================================================================
6002 * \brief Return list of notebook variables used for last Mesh operation
6004 //=============================================================================
6005 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
6007 SMESH::string_array_var aResult = new SMESH::string_array();
6008 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
6010 CORBA::String_var aParameters = GetParameters();
6011 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
6012 if ( aSections->length() > 0 ) {
6013 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
6014 aResult->length( aVars.length() );
6015 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
6016 aResult[i] = CORBA::string_dup( aVars[i] );
6019 return aResult._retn();
6022 //================================================================================
6024 * \brief Return types of elements it contains
6026 //================================================================================
6028 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
6031 return _preMeshInfo->GetTypes();
6033 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
6037 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
6038 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
6039 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
6040 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
6041 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
6042 if (_impl->NbNodes() &&
6043 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
6044 types->length( nbTypes );
6046 return types._retn();
6049 //================================================================================
6051 * \brief Return self
6053 //================================================================================
6055 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
6057 return SMESH::SMESH_Mesh::_duplicate( _this() );
6060 //================================================================================
6062 * \brief Return false if GetMeshInfo() return incorrect information that may
6063 * happen if mesh data is not yet fully loaded from the file of study.
6067 //================================================================================
6069 bool SMESH_Mesh_i::IsMeshInfoCorrect()
6071 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
6074 //=============================================================================
6076 * \brief Return number of mesh elements per each \a EntityType
6078 //=============================================================================
6080 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
6083 return _preMeshInfo->GetMeshInfo();
6085 SMESH::long_array_var aRes = new SMESH::long_array();
6086 aRes->length(SMESH::Entity_Last);
6087 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6089 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6091 return aRes._retn();
6092 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
6093 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6094 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
6095 return aRes._retn();
6098 //=============================================================================
6100 * \brief Return number of mesh elements per each \a ElementType
6102 //=============================================================================
6104 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
6106 SMESH::long_array_var aRes = new SMESH::long_array();
6107 aRes->length(SMESH::NB_ELEMENT_TYPES);
6108 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6111 const SMDS_MeshInfo* meshInfo = 0;
6113 meshInfo = _preMeshInfo;
6114 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
6115 meshInfo = & meshDS->GetMeshInfo();
6118 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6119 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
6121 return aRes._retn();
6124 //=============================================================================
6126 * Collect statistic of mesh elements given by iterator
6128 //=============================================================================
6130 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
6131 SMESH::long_array& theInfo)
6133 if (!theItr) return;
6134 while (theItr->more())
6135 theInfo[ theItr->next()->GetEntityType() ]++;
6137 //=============================================================================
6139 * Return mesh unstructed grid information.
6141 //=============================================================================
6143 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
6145 SALOMEDS::TMPFile_var SeqFile;
6146 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
6147 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
6149 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
6150 aWriter->WriteToOutputStringOn();
6151 aWriter->SetInputData(aGrid);
6152 aWriter->SetFileTypeToBinary();
6154 char* str = aWriter->GetOutputString();
6155 int size = aWriter->GetOutputStringLength();
6157 //Allocate octet buffer of required size
6158 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
6159 //Copy ostrstream content to the octet buffer
6160 memcpy(OctetBuf, str, size);
6161 //Create and return TMPFile
6162 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
6166 return SeqFile._retn();
6169 //=============================================================================
6170 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
6171 * SMESH::ElementType type) */
6173 using namespace SMESH::Controls;
6174 //-----------------------------------------------------------------------------
6175 struct PredicateIterator : public SMDS_ElemIterator
6177 SMDS_ElemIteratorPtr _elemIter;
6178 PredicatePtr _predicate;
6179 const SMDS_MeshElement* _elem;
6180 SMDSAbs_ElementType _type;
6182 PredicateIterator( SMDS_ElemIteratorPtr iterator,
6183 PredicatePtr predicate,
6184 SMDSAbs_ElementType type):
6185 _elemIter(iterator), _predicate(predicate), _type(type)
6193 virtual const SMDS_MeshElement* next()
6195 const SMDS_MeshElement* res = _elem;
6197 while ( _elemIter->more() && !_elem )
6199 if ((_elem = _elemIter->next()) &&
6200 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
6201 ( !_predicate->IsSatisfy( _elem->GetID() ))))
6208 //-----------------------------------------------------------------------------
6209 struct IDSourceIterator : public SMDS_ElemIterator
6211 const CORBA::Long* _idPtr;
6212 const CORBA::Long* _idEndPtr;
6213 SMESH::long_array_var _idArray;
6214 const SMDS_Mesh* _mesh;
6215 const SMDSAbs_ElementType _type;
6216 const SMDS_MeshElement* _elem;
6218 IDSourceIterator( const SMDS_Mesh* mesh,
6219 const CORBA::Long* ids,
6221 SMDSAbs_ElementType type):
6222 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
6224 if ( _idPtr && nbIds && _mesh )
6227 IDSourceIterator( const SMDS_Mesh* mesh,
6228 SMESH::long_array* idArray,
6229 SMDSAbs_ElementType type):
6230 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
6232 if ( idArray && _mesh )
6234 _idPtr = &_idArray[0];
6235 _idEndPtr = _idPtr + _idArray->length();
6243 virtual const SMDS_MeshElement* next()
6245 const SMDS_MeshElement* res = _elem;
6247 while ( _idPtr < _idEndPtr && !_elem )
6249 if ( _type == SMDSAbs_Node )
6251 _elem = _mesh->FindNode( *_idPtr++ );
6253 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6254 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6262 //-----------------------------------------------------------------------------
6264 struct NodeOfElemIterator : public SMDS_ElemIterator
6266 TColStd_MapOfInteger _checkedNodeIDs;
6267 SMDS_ElemIteratorPtr _elemIter;
6268 SMDS_ElemIteratorPtr _nodeIter;
6269 const SMDS_MeshElement* _node;
6271 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6273 if ( _elemIter && _elemIter->more() )
6275 _nodeIter = _elemIter->next()->nodesIterator();
6283 virtual const SMDS_MeshElement* next()
6285 const SMDS_MeshElement* res = _node;
6287 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6289 if ( _nodeIter->more() )
6291 _node = _nodeIter->next();
6292 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6297 _nodeIter = _elemIter->next()->nodesIterator();
6305 //=============================================================================
6307 * Return iterator on elements of given type in given object
6309 //=============================================================================
6311 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6312 SMESH::ElementType theType)
6314 SMDS_ElemIteratorPtr elemIt;
6315 bool typeOK = ( theType == SMESH::ALL );
6316 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6318 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6319 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6320 if ( !mesh_i ) return elemIt;
6321 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6323 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6325 elemIt = meshDS->elementsIterator( elemType );
6328 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6330 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6333 elemIt = sm->GetElements();
6334 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6336 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6337 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6341 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6343 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6344 if ( groupDS && ( elemType == groupDS->GetType() ||
6345 elemType == SMDSAbs_Node ||
6346 elemType == SMDSAbs_All ))
6348 elemIt = groupDS->GetElements();
6349 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6352 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6354 if ( filter_i->GetElementType() == theType ||
6355 filter_i->GetElementType() == SMESH::ALL ||
6356 elemType == SMDSAbs_Node ||
6357 elemType == SMDSAbs_All)
6359 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6360 if ( pred_i && pred_i->GetPredicate() )
6362 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6363 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6364 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6365 elemIt = SMDS_ElemIteratorPtr
6366 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6367 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6373 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6374 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6375 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6377 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6378 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6381 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6382 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6386 SMESH::long_array_var ids = theObject->GetIDs();
6387 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6389 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6392 if ( elemIt && elemIt->more() && !typeOK )
6394 if ( elemType == SMDSAbs_Node )
6396 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6400 elemIt = SMDS_ElemIteratorPtr();
6406 //=============================================================================
6407 namespace // Finding concurrent hypotheses
6408 //=============================================================================
6412 * \brief mapping of mesh dimension into shape type
6414 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6416 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6418 case 0: aType = TopAbs_VERTEX; break;
6419 case 1: aType = TopAbs_EDGE; break;
6420 case 2: aType = TopAbs_FACE; break;
6422 default:aType = TopAbs_SOLID; break;
6427 //-----------------------------------------------------------------------------
6429 * \brief Internal structure used to find concurrent submeshes
6431 * It represents a pair < submesh, concurrent dimension >, where
6432 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6433 * with another submesh. In other words, it is dimension of a hypothesis assigned
6440 int _dim; //!< a dimension the algo can build (concurrent dimension)
6441 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6442 TopTools_MapOfShape _shapeMap; //!< [sub-]shapes of dimension == _dim
6443 const SMESH_subMesh* _subMesh;
6444 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6446 //-----------------------------------------------------------------------------
6447 // Return the algorithm
6448 const SMESH_Algo* GetAlgo() const
6449 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6451 //-----------------------------------------------------------------------------
6453 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6455 const TopoDS_Shape& theShape)
6457 _subMesh = theSubMesh;
6458 SetShape( theDim, theShape );
6461 //-----------------------------------------------------------------------------
6463 void SetShape(const int theDim,
6464 const TopoDS_Shape& theShape)
6467 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6468 if (_dim >= _ownDim)
6469 _shapeMap.Add( theShape );
6471 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6472 for( ; anExp.More(); anExp.Next() )
6473 _shapeMap.Add( anExp.Current() );
6477 //-----------------------------------------------------------------------------
6478 //! Check sharing of sub-shapes
6479 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6480 const TopTools_MapOfShape& theToFind,
6481 const TopAbs_ShapeEnum theType)
6483 bool isShared = false;
6484 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6485 for (; !isShared && anItr.More(); anItr.Next() )
6487 const TopoDS_Shape aSubSh = anItr.Key();
6488 // check for case when concurrent dimensions are same
6489 isShared = theToFind.Contains( aSubSh );
6490 // check for sub-shape with concurrent dimension
6491 TopExp_Explorer anExp( aSubSh, theType );
6492 for ( ; !isShared && anExp.More(); anExp.Next() )
6493 isShared = theToFind.Contains( anExp.Current() );
6498 //-----------------------------------------------------------------------------
6499 //! check algorithms
6500 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6501 const SMESHDS_Hypothesis* theA2)
6503 if ( !theA1 || !theA2 ||
6504 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6505 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6506 return false; // one of the hypothesis is not algorithm
6507 // check algorithm names (should be equal)
6508 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6512 //-----------------------------------------------------------------------------
6513 //! Check if sub-shape hypotheses are concurrent
6514 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6516 if ( _subMesh == theOther->_subMesh )
6517 return false; // same sub-shape - should not be
6519 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6520 // any of the two submeshes is not on COMPOUND shape )
6521 // -> no concurrency
6522 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6523 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6524 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6525 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6526 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6529 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6530 if ( !checkSubShape )
6533 // check algorithms to be same
6534 const SMESH_Algo* a1 = this->GetAlgo();
6535 const SMESH_Algo* a2 = theOther->GetAlgo();
6536 bool isSame = checkAlgo( a1, a2 );
6540 // commented off for IPAL54678
6541 // if ( !a1 || !a2 )
6542 // return false; // pb?
6543 // return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6546 // check hypothesises for concurrence (skip first as algorithm)
6548 // pointers should be same, because it is referened from mesh hypothesis partition
6549 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6550 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6551 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6552 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6554 // the submeshes are concurrent if their algorithms has different parameters
6555 return nbSame != theOther->_hypotheses.size() - 1;
6558 // Return true if algorithm of this SMESH_DimHyp is used if no
6559 // sub-mesh order is imposed by the user
6560 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6562 // NeedDiscreteBoundary() algo has a higher priority
6563 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6564 theOther->GetAlgo()->NeedDiscreteBoundary() )
6565 return !this->GetAlgo()->NeedDiscreteBoundary();
6567 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6570 }; // end of SMESH_DimHyp
6571 //-----------------------------------------------------------------------------
6573 typedef list<const SMESH_DimHyp*> TDimHypList;
6575 //-----------------------------------------------------------------------------
6577 void addDimHypInstance(const int theDim,
6578 const TopoDS_Shape& theShape,
6579 const SMESH_Algo* theAlgo,
6580 const SMESH_subMesh* theSubMesh,
6581 const list <const SMESHDS_Hypothesis*>& theHypList,
6582 TDimHypList* theDimHypListArr )
6584 if ( !theAlgo->NeedDiscreteBoundary() &&
6585 theAlgo->NeedLowerHyps( theDim )) // IPAL54678
6587 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6588 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh )
6590 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6591 dimHyp->_hypotheses.push_front(theAlgo);
6592 listOfdimHyp.push_back( dimHyp );
6595 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6596 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6597 theHypList.begin(), theHypList.end() );
6600 //-----------------------------------------------------------------------------
6601 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6602 TDimHypList& theListOfConcurr)
6604 if ( theListOfConcurr.empty() )
6606 theListOfConcurr.push_back( theDimHyp );
6610 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6611 while ( hypIt != theListOfConcurr.end() &&
6612 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6614 theListOfConcurr.insert( hypIt, theDimHyp );
6618 //-----------------------------------------------------------------------------
6619 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6620 const TDimHypList& theListOfDimHyp,
6621 TDimHypList& theListOfConcurrHyp,
6622 set<int>& theSetOfConcurrId )
6624 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6625 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6627 const SMESH_DimHyp* curDimHyp = *rIt;
6628 if ( curDimHyp == theDimHyp )
6629 break; // meet own dimHyp pointer in same dimension
6631 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6632 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6634 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6639 //-----------------------------------------------------------------------------
6640 void unionLists(TListOfInt& theListOfId,
6641 TListOfListOfInt& theListOfListOfId,
6644 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6645 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ )
6648 continue; //skip already treated lists
6649 // check if other list has any same submesh object
6650 TListOfInt& otherListOfId = *it;
6651 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6652 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6655 // union two lists (from source into target)
6656 TListOfInt::iterator it2 = otherListOfId.begin();
6657 for ( ; it2 != otherListOfId.end(); it2++ ) {
6658 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6659 theListOfId.push_back(*it2);
6661 // clear source list
6662 otherListOfId.clear();
6665 //-----------------------------------------------------------------------------
6667 //! free memory allocated for dimension-hypothesis objects
6668 void removeDimHyps( TDimHypList* theArrOfList )
6670 for (int i = 0; i < 4; i++ ) {
6671 TDimHypList& listOfdimHyp = theArrOfList[i];
6672 TDimHypList::const_iterator it = listOfdimHyp.begin();
6673 for ( ; it != listOfdimHyp.end(); it++ )
6678 //-----------------------------------------------------------------------------
6680 * \brief find common submeshes with given submesh
6681 * \param theSubMeshList list of already collected submesh to check
6682 * \param theSubMesh given submesh to intersect with other
6683 * \param theCommonSubMeshes collected common submeshes
6685 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6686 const SMESH_subMesh* theSubMesh,
6687 set<const SMESH_subMesh*>& theCommon )
6691 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6692 for ( ; it != theSubMeshList.end(); it++ )
6693 theSubMesh->FindIntersection( *it, theCommon );
6694 theSubMeshList.push_back( theSubMesh );
6695 //theCommon.insert( theSubMesh );
6698 //-----------------------------------------------------------------------------
6699 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6701 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6702 for ( ; listsIt != smLists.end(); ++listsIt )
6704 const TListOfInt& smIDs = *listsIt;
6705 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6713 //=============================================================================
6715 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6717 //=============================================================================
6719 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6721 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6722 if ( isSubMeshInList( submeshID, anOrder ))
6725 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6726 return isSubMeshInList( submeshID, allConurrent );
6729 //=============================================================================
6731 * \brief Return sub-mesh objects list in meshing order
6733 //=============================================================================
6735 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6737 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6739 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6741 return aResult._retn();
6743 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6744 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6745 anOrder.splice( anOrder.end(), allConurrent );
6748 TListOfListOfInt::iterator listIt = anOrder.begin();
6749 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6750 unionLists( *listIt, anOrder, listIndx + 1 );
6752 // convert submesh ids into interface instances
6753 // and dump command into python
6754 convertMeshOrder( anOrder, aResult, false );
6756 return aResult._retn();
6759 //=============================================================================
6761 * \brief Finds concurrent sub-meshes
6763 //=============================================================================
6765 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6767 TListOfListOfInt anOrder;
6768 ::SMESH_Mesh& mesh = GetImpl();
6770 // collect submeshes and detect concurrent algorithms and hypothesises
6771 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6773 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6774 for ( ; i_sm != _mapSubMesh.end(); i_sm++ )
6776 ::SMESH_subMesh* sm = (*i_sm).second;
6778 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6780 // list of assigned hypothesises
6781 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6782 // Find out dimensions where the submesh can be concurrent.
6783 // We define the dimensions by algo of each of hypotheses in hypList
6784 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6785 for( ; hypIt != hypList.end(); hypIt++ )
6787 SMESH_Algo* anAlgo = 0;
6788 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6789 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6790 // hyp it-self is algo
6791 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6793 // try to find algorithm with help of sub-shapes
6794 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6795 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6796 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6799 continue; // no algorithm assigned to a current submesh
6801 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6802 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary()
6803 // and !anAlgo->NeedLowerHyps( dim ))
6805 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6806 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6807 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6809 } // end iterations on submesh
6811 // iterate on created dimension-hypotheses and check for concurrents
6812 for ( int i = 0; i < 4; i++ )
6814 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6815 // check for concurrents in own and other dimensions (step-by-step)
6816 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6817 for ( ; dhIt != listOfDimHyp.end(); dhIt++ )
6819 const SMESH_DimHyp* dimHyp = *dhIt;
6820 TDimHypList listOfConcurr;
6821 set<int> setOfConcurrIds;
6822 // looking for concurrents and collect into own list
6823 for ( int j = i; j < 4; j++ )
6824 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6825 // check if any concurrents found
6826 if ( listOfConcurr.size() > 0 )
6828 // add own submesh to list of concurrent
6829 addInOrderOfPriority( dimHyp, listOfConcurr );
6830 list<int> listOfConcurrIds;
6831 TDimHypList::iterator hypIt = listOfConcurr.begin();
6832 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6833 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6834 anOrder.push_back( listOfConcurrIds );
6839 removeDimHyps(dimHypListArr);
6841 // now, minimize the number of concurrent groups
6842 // Here we assume that lists of submeshes can have same submesh
6843 // in case of multi-dimension algorithms, as result
6844 // list with common submesh has to be united into one list
6846 TListOfListOfInt::iterator listIt = anOrder.begin();
6847 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6848 unionLists( *listIt, anOrder, listIndx + 1 );
6853 //=============================================================================
6855 * \brief Set submesh object order
6856 * \param theSubMeshArray submesh array order
6858 //=============================================================================
6860 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6863 _preMeshInfo->ForgetOrLoad();
6866 ::SMESH_Mesh& mesh = GetImpl();
6868 TPythonDump aPythonDump; // prevent dump of called methods
6869 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6871 TListOfListOfInt subMeshOrder;
6872 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6874 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6875 TListOfInt subMeshIds;
6877 aPythonDump << ", ";
6878 aPythonDump << "[ ";
6879 // Collect subMeshes which should be clear
6880 // do it list-by-list, because modification of submesh order
6881 // take effect between concurrent submeshes only
6882 set<const SMESH_subMesh*> subMeshToClear;
6883 list<const SMESH_subMesh*> subMeshList;
6884 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6886 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6888 aPythonDump << ", ";
6889 aPythonDump << subMesh;
6890 subMeshIds.push_back( subMesh->GetId() );
6891 // detect common parts of submeshes
6892 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6893 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6895 aPythonDump << " ]";
6896 subMeshOrder.push_back( subMeshIds );
6898 // clear collected sub-meshes
6899 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6900 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6901 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6903 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6904 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6905 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6908 aPythonDump << " ])";
6910 mesh.SetMeshOrder( subMeshOrder );
6913 SMESH::SMESH_Mesh_var me = _this();
6914 _gen_i->UpdateIcons( me );
6919 //=============================================================================
6921 * \brief Convert submesh ids into submesh interfaces
6923 //=============================================================================
6925 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6926 SMESH::submesh_array_array& theResOrder,
6927 const bool theIsDump)
6929 int nbSet = theIdsOrder.size();
6930 TPythonDump aPythonDump; // prevent dump of called methods
6932 aPythonDump << "[ ";
6933 theResOrder.length(nbSet);
6934 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6936 for( ; it != theIdsOrder.end(); it++ )
6938 // translate submesh identificators into submesh objects
6939 // takeing into account real number of concurrent lists
6940 const TListOfInt& aSubOrder = (*it);
6941 if (!aSubOrder.size())
6944 aPythonDump << "[ ";
6945 // convert shape indices into interfaces
6946 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6947 aResSubSet->length(aSubOrder.size());
6948 TListOfInt::const_iterator subIt = aSubOrder.begin();
6950 for( j = 0; subIt != aSubOrder.end(); subIt++ )
6952 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6954 SMESH::SMESH_subMesh_var subMesh =
6955 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6958 aPythonDump << ", ";
6959 aPythonDump << subMesh;
6961 aResSubSet[ j++ ] = subMesh;
6964 aPythonDump << " ]";
6966 theResOrder[ listIndx++ ] = aResSubSet;
6968 // correct number of lists
6969 theResOrder.length( listIndx );
6972 // finilise python dump
6973 aPythonDump << " ]";
6974 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6978 namespace // utils used by SMESH_MeshPartDS
6981 * \brief Class used to access to protected data of SMDS_MeshInfo
6983 struct TMeshInfo : public SMDS_MeshInfo
6985 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6988 * \brief Element holing its ID only
6990 struct TElemID : public SMDS_LinearEdge
6992 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6996 //================================================================================
6998 // Implementation of SMESH_MeshPartDS
7000 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
7001 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
7003 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
7004 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
7007 _meshDS = mesh_i->GetImpl().GetMeshDS();
7009 SetPersistentId( _meshDS->GetPersistentId() );
7011 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
7013 // <meshPart> is the whole mesh
7014 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
7016 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
7017 myGroupSet = _meshDS->GetGroups();
7022 SMESH::long_array_var anIDs = meshPart->GetIDs();
7023 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
7024 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
7026 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
7027 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
7028 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7033 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
7034 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
7035 if ( _elements[ e->GetType() ].insert( e ).second )
7038 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
7039 while ( nIt->more() )
7041 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
7042 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7049 ShapeToMesh( _meshDS->ShapeToMesh() );
7051 _meshDS = 0; // to enforce iteration on _elements and _nodes
7054 // -------------------------------------------------------------------------------------
7055 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
7056 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
7059 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
7060 for ( ; partIt != meshPart.end(); ++partIt )
7061 if ( const SMDS_MeshElement * e = *partIt )
7062 if ( _elements[ e->GetType() ].insert( e ).second )
7065 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
7066 while ( nIt->more() )
7068 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
7069 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7075 // -------------------------------------------------------------------------------------
7076 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
7078 if ( _meshDS ) return _meshDS->FindElement( IDelem );
7080 TElemID elem( IDelem );
7081 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7082 if ( !_elements[ iType ].empty() )
7084 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
7085 if ( it != _elements[ iType ].end() )
7090 // -------------------------------------------------------------------------------------
7091 bool SMESH_MeshPartDS::HasNumerationHoles()
7093 if ( _meshDS ) return _meshDS->HasNumerationHoles();
7095 return ( MinNodeID() != 1 ||
7096 MaxNodeID() != NbNodes() ||
7097 MinElementID() != 1 ||
7098 MaxElementID() != NbElements() );
7100 // -------------------------------------------------------------------------------------
7101 int SMESH_MeshPartDS::MaxNodeID() const
7103 if ( _meshDS ) return _meshDS->MaxNodeID();
7104 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
7106 // -------------------------------------------------------------------------------------
7107 int SMESH_MeshPartDS::MinNodeID() const
7109 if ( _meshDS ) return _meshDS->MinNodeID();
7110 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
7112 // -------------------------------------------------------------------------------------
7113 int SMESH_MeshPartDS::MaxElementID() const
7115 if ( _meshDS ) return _meshDS->MaxElementID();
7117 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7118 if ( !_elements[ iType ].empty() )
7119 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
7122 // -------------------------------------------------------------------------------------
7123 int SMESH_MeshPartDS::MinElementID() const
7125 if ( _meshDS ) return _meshDS->MinElementID();
7127 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7128 if ( !_elements[ iType ].empty() )
7129 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
7132 // -------------------------------------------------------------------------------------
7133 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
7135 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
7137 typedef SMDS_SetIterator
7138 <const SMDS_MeshElement*,
7139 TIDSortedElemSet::const_iterator,
7140 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7141 SMDS_MeshElement::GeomFilter
7144 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
7146 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7147 _elements[type].end(),
7148 SMDS_MeshElement::GeomFilter( geomType )));
7150 // -------------------------------------------------------------------------------------
7151 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
7153 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
7155 typedef SMDS_SetIterator
7156 <const SMDS_MeshElement*,
7157 TIDSortedElemSet::const_iterator,
7158 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7159 SMDS_MeshElement::EntityFilter
7162 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
7164 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7165 _elements[type].end(),
7166 SMDS_MeshElement::EntityFilter( entity )));
7168 // -------------------------------------------------------------------------------------
7169 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
7171 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
7172 if ( type == SMDSAbs_All && !_meshDS )
7174 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
7176 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
7177 if ( !_elements[i].empty() && i != SMDSAbs_Node )
7179 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
7181 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
7182 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
7184 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
7185 ( new TIter( _elements[type].begin(), _elements[type].end() ));
7187 // -------------------------------------------------------------------------------------
7188 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
7189 iterType SMESH_MeshPartDS::methName() const \
7191 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
7192 return _meshDS ? _meshDS->methName() : iterType \
7193 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
7195 // -------------------------------------------------------------------------------------
7196 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
7197 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
7198 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
7199 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
7200 #undef _GET_ITER_DEFINE
7202 // END Implementation of SMESH_MeshPartDS
7204 //================================================================================