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 _impl->GetMeshDS()->Modified();
1216 _impl->SetIsModified( true );
1218 // Update Python script (theGroup must be alive for this)
1219 pyDump << SMESH::SMESH_Mesh_var(_this())
1220 << ".RemoveGroupWithContents( " << theGroup << " )";
1222 SMESH_CATCH( SMESH::throwCorbaException );
1225 //================================================================================
1227 * \brief Get the list of groups existing in the mesh
1228 * \retval SMESH::ListOfGroups * - list of groups
1230 //================================================================================
1232 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1234 Unexpect aCatch(SALOME_SalomeException);
1235 if (MYDEBUG) MESSAGE("GetGroups");
1237 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1240 TPythonDump aPythonDump;
1241 if ( !_mapGroups.empty() )
1243 aPythonDump << "[ ";
1245 aList->length( _mapGroups.size() );
1247 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1248 for ( ; it != _mapGroups.end(); it++ ) {
1249 if ( CORBA::is_nil( it->second )) continue;
1250 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1252 if (i > 1) aPythonDump << ", ";
1253 aPythonDump << it->second;
1257 catch(SALOME_Exception & S_ex) {
1258 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1260 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1262 return aList._retn();
1265 //=============================================================================
1267 * Get number of groups existing in the mesh
1269 //=============================================================================
1271 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1273 Unexpect aCatch(SALOME_SalomeException);
1274 return _mapGroups.size();
1277 //=============================================================================
1279 * New group including all mesh elements present in initial groups is created.
1281 //=============================================================================
1283 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1284 SMESH::SMESH_GroupBase_ptr theGroup2,
1285 const char* theName )
1286 throw (SALOME::SALOME_Exception)
1288 SMESH::SMESH_Group_var aResGrp;
1292 _preMeshInfo->FullLoadFromFile();
1294 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1295 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1297 if ( theGroup1->GetType() != theGroup2->GetType() )
1298 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1303 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1304 if ( aResGrp->_is_nil() )
1305 return SMESH::SMESH_Group::_nil();
1307 aResGrp->AddFrom( theGroup1 );
1308 aResGrp->AddFrom( theGroup2 );
1310 // Update Python script
1311 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1312 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1314 SMESH_CATCH( SMESH::throwCorbaException );
1316 return aResGrp._retn();
1319 //=============================================================================
1321 * \brief New group including all mesh elements present in initial groups is created.
1322 * \param theGroups list of groups
1323 * \param theName name of group to be created
1324 * \return pointer to the new group
1326 //=============================================================================
1328 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1329 const char* theName )
1330 throw (SALOME::SALOME_Exception)
1332 SMESH::SMESH_Group_var aResGrp;
1335 _preMeshInfo->FullLoadFromFile();
1338 return SMESH::SMESH_Group::_nil();
1343 SMESH::ElementType aType = SMESH::ALL;
1344 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1346 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1347 if ( CORBA::is_nil( aGrp ) )
1349 if ( aType == SMESH::ALL )
1350 aType = aGrp->GetType();
1351 else if ( aType != aGrp->GetType() )
1352 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1355 if ( aType == SMESH::ALL )
1356 return SMESH::SMESH_Group::_nil();
1361 aResGrp = CreateGroup( aType, theName );
1362 if ( aResGrp->_is_nil() )
1363 return SMESH::SMESH_Group::_nil();
1365 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1366 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1368 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1369 if ( !CORBA::is_nil( aGrp ) )
1371 aResGrp->AddFrom( aGrp );
1372 if ( g > 0 ) pyDump << ", ";
1376 pyDump << " ], '" << theName << "' )";
1378 SMESH_CATCH( SMESH::throwCorbaException );
1380 return aResGrp._retn();
1383 //=============================================================================
1385 * New group is created. All mesh elements that are
1386 * present in both initial groups are added to the new one.
1388 //=============================================================================
1390 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1391 SMESH::SMESH_GroupBase_ptr theGroup2,
1392 const char* theName )
1393 throw (SALOME::SALOME_Exception)
1395 SMESH::SMESH_Group_var aResGrp;
1400 _preMeshInfo->FullLoadFromFile();
1402 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1403 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1405 if ( theGroup1->GetType() != theGroup2->GetType() )
1406 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1410 // Create Intersection
1411 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1412 if ( aResGrp->_is_nil() )
1413 return aResGrp._retn();
1415 SMESHDS_GroupBase* groupDS1 = 0;
1416 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1417 groupDS1 = grp_i->GetGroupDS();
1419 SMESHDS_GroupBase* groupDS2 = 0;
1420 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1421 groupDS2 = grp_i->GetGroupDS();
1423 SMESHDS_Group* resGroupDS = 0;
1424 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1425 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1427 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1429 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1430 while ( elemIt1->more() )
1432 const SMDS_MeshElement* e = elemIt1->next();
1433 if ( groupDS2->Contains( e ))
1434 resGroupDS->SMDSGroup().Add( e );
1437 // Update Python script
1438 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1439 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1441 SMESH_CATCH( SMESH::throwCorbaException );
1443 return aResGrp._retn();
1446 //=============================================================================
1448 \brief Intersect list of groups. New group is created. All mesh elements that
1449 are present in all initial groups simultaneously are added to the new one.
1450 \param theGroups list of groups
1451 \param theName name of group to be created
1452 \return pointer on the group
1454 //=============================================================================
1456 SMESH::SMESH_Group_ptr
1457 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1458 const char* theName )
1459 throw (SALOME::SALOME_Exception)
1461 SMESH::SMESH_Group_var aResGrp;
1466 _preMeshInfo->FullLoadFromFile();
1469 return SMESH::SMESH_Group::_nil();
1471 // check types and get SMESHDS_GroupBase's
1472 SMESH::ElementType aType = SMESH::ALL;
1473 vector< SMESHDS_GroupBase* > groupVec;
1474 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1476 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1477 if ( CORBA::is_nil( aGrp ) )
1479 if ( aType == SMESH::ALL )
1480 aType = aGrp->GetType();
1481 else if ( aType != aGrp->GetType() )
1482 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1485 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1486 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1488 if ( grpDS->IsEmpty() )
1493 groupVec.push_back( grpDS );
1496 if ( aType == SMESH::ALL ) // all groups are nil
1497 return SMESH::SMESH_Group::_nil();
1502 aResGrp = CreateGroup( aType, theName );
1504 SMESHDS_Group* resGroupDS = 0;
1505 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1506 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1507 if ( !resGroupDS || groupVec.empty() )
1508 return aResGrp._retn();
1511 size_t i, nb = groupVec.size();
1512 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1513 while ( elemIt1->more() )
1515 const SMDS_MeshElement* e = elemIt1->next();
1517 for ( i = 1; ( i < nb && inAll ); ++i )
1518 inAll = groupVec[i]->Contains( e );
1521 resGroupDS->SMDSGroup().Add( e );
1524 // Update Python script
1525 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1526 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1528 SMESH_CATCH( SMESH::throwCorbaException );
1530 return aResGrp._retn();
1533 //=============================================================================
1535 * New group is created. All mesh elements that are present in
1536 * a main group but is not present in a tool group are added to the new one
1538 //=============================================================================
1540 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1541 SMESH::SMESH_GroupBase_ptr theGroup2,
1542 const char* theName )
1543 throw (SALOME::SALOME_Exception)
1545 SMESH::SMESH_Group_var aResGrp;
1550 _preMeshInfo->FullLoadFromFile();
1552 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1553 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1555 if ( theGroup1->GetType() != theGroup2->GetType() )
1556 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1560 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1561 if ( aResGrp->_is_nil() )
1562 return aResGrp._retn();
1564 SMESHDS_GroupBase* groupDS1 = 0;
1565 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1566 groupDS1 = grp_i->GetGroupDS();
1568 SMESHDS_GroupBase* groupDS2 = 0;
1569 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1570 groupDS2 = grp_i->GetGroupDS();
1572 SMESHDS_Group* resGroupDS = 0;
1573 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1574 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1576 if ( groupDS1 && groupDS2 && resGroupDS )
1578 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1579 while ( elemIt1->more() )
1581 const SMDS_MeshElement* e = elemIt1->next();
1582 if ( !groupDS2->Contains( e ))
1583 resGroupDS->SMDSGroup().Add( e );
1586 // Update Python script
1587 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1588 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1590 SMESH_CATCH( SMESH::throwCorbaException );
1592 return aResGrp._retn();
1595 //=============================================================================
1597 \brief Cut lists of groups. New group is created. All mesh elements that are
1598 present in main groups but do not present in tool groups are added to the new one
1599 \param theMainGroups list of main groups
1600 \param theToolGroups list of tool groups
1601 \param theName name of group to be created
1602 \return pointer on the group
1604 //=============================================================================
1606 SMESH::SMESH_Group_ptr
1607 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1608 const SMESH::ListOfGroups& theToolGroups,
1609 const char* theName )
1610 throw (SALOME::SALOME_Exception)
1612 SMESH::SMESH_Group_var aResGrp;
1617 _preMeshInfo->FullLoadFromFile();
1620 return SMESH::SMESH_Group::_nil();
1622 // check types and get SMESHDS_GroupBase's
1623 SMESH::ElementType aType = SMESH::ALL;
1624 vector< SMESHDS_GroupBase* > toolGroupVec;
1625 vector< SMDS_ElemIteratorPtr > mainIterVec;
1627 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1629 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1630 if ( CORBA::is_nil( aGrp ) )
1632 if ( aType == SMESH::ALL )
1633 aType = aGrp->GetType();
1634 else if ( aType != aGrp->GetType() )
1635 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1637 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1638 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1639 if ( !grpDS->IsEmpty() )
1640 mainIterVec.push_back( grpDS->GetElements() );
1642 if ( aType == SMESH::ALL ) // all main groups are nil
1643 return SMESH::SMESH_Group::_nil();
1644 if ( mainIterVec.empty() ) // all main groups are empty
1645 return aResGrp._retn();
1647 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1649 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1650 if ( CORBA::is_nil( aGrp ) )
1652 if ( aType != aGrp->GetType() )
1653 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1655 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1656 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1657 toolGroupVec.push_back( grpDS );
1663 aResGrp = CreateGroup( aType, theName );
1665 SMESHDS_Group* resGroupDS = 0;
1666 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1667 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1669 return aResGrp._retn();
1672 size_t i, nb = toolGroupVec.size();
1673 SMDS_ElemIteratorPtr mainElemIt
1674 ( new SMDS_IteratorOnIterators
1675 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1676 while ( mainElemIt->more() )
1678 const SMDS_MeshElement* e = mainElemIt->next();
1680 for ( i = 0; ( i < nb && !isIn ); ++i )
1681 isIn = toolGroupVec[i]->Contains( e );
1684 resGroupDS->SMDSGroup().Add( e );
1687 // Update Python script
1688 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1689 << ".CutListOfGroups( " << theMainGroups << ", "
1690 << theToolGroups << ", '" << theName << "' )";
1692 SMESH_CATCH( SMESH::throwCorbaException );
1694 return aResGrp._retn();
1697 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1699 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1700 bool & toStopChecking )
1702 toStopChecking = ( nbCommon < nbChecked );
1703 return nbCommon == nbNodes;
1705 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1706 bool & toStopChecking )
1708 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1709 return nbCommon == nbCorners;
1711 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1712 bool & toStopChecking )
1714 return nbCommon > 0;
1716 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1717 bool & toStopChecking )
1719 return nbCommon >= (nbNodes+1) / 2;
1723 //=============================================================================
1725 * Create a group of entities basing on nodes of other groups.
1726 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1727 * \param [in] anElemType - a type of elements to include to the new group.
1728 * \param [in] theName - a name of the new group.
1729 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1730 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1731 * new group provided that it is based on nodes of an element of \a aListOfGroups
1732 * \return SMESH_Group - the created group
1734 // IMP 19939, bug 22010, IMP 22635
1735 //=============================================================================
1737 SMESH::SMESH_Group_ptr
1738 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1739 SMESH::ElementType theElemType,
1740 const char* theName,
1741 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1742 CORBA::Boolean theUnderlyingOnly)
1743 throw (SALOME::SALOME_Exception)
1745 SMESH::SMESH_Group_var aResGrp;
1749 _preMeshInfo->FullLoadFromFile();
1751 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1753 if ( !theName || !aMeshDS )
1754 return SMESH::SMESH_Group::_nil();
1756 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1758 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1759 SMESH_Comment nbCoNoStr( "SMESH.");
1760 switch ( theNbCommonNodes ) {
1761 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1762 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1763 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1764 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1765 default: return aResGrp._retn();
1767 int nbChecked, nbCommon, nbNodes, nbCorners;
1773 aResGrp = CreateGroup( theElemType, theName );
1774 if ( aResGrp->_is_nil() )
1775 return SMESH::SMESH_Group::_nil();
1777 SMESHDS_GroupBase* groupBaseDS =
1778 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1779 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1781 vector<bool> isNodeInGroups;
1783 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1785 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1786 if ( CORBA::is_nil( aGrp ) )
1788 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1789 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1792 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1793 if ( !elIt ) continue;
1795 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1797 while ( elIt->more() ) {
1798 const SMDS_MeshElement* el = elIt->next();
1799 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1800 while ( nIt->more() )
1801 resGroupCore.Add( nIt->next() );
1804 // get elements of theElemType based on nodes of every element of group
1805 else if ( theUnderlyingOnly )
1807 while ( elIt->more() )
1809 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1810 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1811 TIDSortedElemSet checkedElems;
1812 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1813 while ( nIt->more() )
1815 const SMDS_MeshNode* n = nIt->next();
1816 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1817 // check nodes of elements of theElemType around el
1818 while ( elOfTypeIt->more() )
1820 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1821 if ( !checkedElems.insert( elOfType ).second ) continue;
1822 nbNodes = elOfType->NbNodes();
1823 nbCorners = elOfType->NbCornerNodes();
1825 bool toStopChecking = false;
1826 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1827 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1828 if ( elNodes.count( nIt2->next() ) &&
1829 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1831 resGroupCore.Add( elOfType );
1838 // get all nodes of elements of groups
1841 while ( elIt->more() )
1843 const SMDS_MeshElement* el = elIt->next(); // an element of group
1844 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1845 while ( nIt->more() )
1847 const SMDS_MeshNode* n = nIt->next();
1848 if ( n->GetID() >= (int) isNodeInGroups.size() )
1849 isNodeInGroups.resize( n->GetID() + 1, false );
1850 isNodeInGroups[ n->GetID() ] = true;
1856 // Get elements of theElemType based on a certain number of nodes of elements of groups
1857 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1859 const SMDS_MeshNode* n;
1860 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1861 const int isNodeInGroupsSize = isNodeInGroups.size();
1862 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1864 if ( !isNodeInGroups[ iN ] ||
1865 !( n = aMeshDS->FindNode( iN )))
1868 // check nodes of elements of theElemType around n
1869 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1870 while ( elOfTypeIt->more() )
1872 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1873 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1878 nbNodes = elOfType->NbNodes();
1879 nbCorners = elOfType->NbCornerNodes();
1881 bool toStopChecking = false;
1882 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1883 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1885 const int nID = nIt->next()->GetID();
1886 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1887 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1889 resGroupCore.Add( elOfType );
1897 // Update Python script
1898 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1899 << ".CreateDimGroup( "
1900 << theGroups << ", " << theElemType << ", '" << theName << "', "
1901 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1903 SMESH_CATCH( SMESH::throwCorbaException );
1905 return aResGrp._retn();
1908 //================================================================================
1910 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1911 * existing 1D elements as group boundaries.
1912 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1913 * adjacent faces is more than \a sharpAngle in degrees.
1914 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1915 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1916 * \return ListOfGroups - the created groups
1918 //================================================================================
1920 SMESH::ListOfGroups*
1921 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1922 CORBA::Boolean theCreateEdges,
1923 CORBA::Boolean theUseExistingEdges )
1924 throw (SALOME::SALOME_Exception)
1926 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1927 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1930 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1936 _preMeshInfo->FullLoadFromFile();
1938 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1940 std::vector< SMESH_MeshAlgos::Edge > edges =
1941 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1943 if ( theCreateEdges )
1945 std::vector<const SMDS_MeshNode *> nodes(2);
1946 for ( size_t i = 0; i < edges.size(); ++i )
1948 nodes[0] = edges[i]._node1;
1949 nodes[1] = edges[i]._node2;
1950 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1952 if ( edges[i]._medium )
1953 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1955 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1959 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1960 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1962 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1964 resultGroups->length( faceGroups.size() );
1965 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1967 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1968 _editor->GenerateGroupName("Group").c_str());
1969 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1971 SMESHDS_GroupBase* groupBaseDS =
1972 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1973 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1975 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1976 for ( size_t i = 0; i < faces.size(); ++i )
1977 groupCore.Add( faces[i] );
1980 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1981 << ".FaceGroupsSeparatedByEdges( "
1982 << TVar( theSharpAngle ) << ", "
1983 << theCreateEdges << ", "
1984 << theUseExistingEdges << " )";
1986 SMESH_CATCH( SMESH::throwCorbaException );
1987 return resultGroups._retn();
1991 //================================================================================
1993 * \brief Remember GEOM group data
1995 //================================================================================
1997 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1998 CORBA::Object_ptr theSmeshObj)
2000 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2003 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2004 if ( groupSO->_is_nil() )
2007 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2008 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2009 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2012 _geomGroupData.push_back( TGeomGroupData() );
2013 TGeomGroupData & groupData = _geomGroupData.back();
2015 CORBA::String_var entry = groupSO->GetID();
2016 groupData._groupEntry = entry.in();
2018 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2019 groupData._indices.insert( ids[i] );
2021 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2022 // shape index in SMESHDS
2023 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2024 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2027 //================================================================================
2029 * Remove GEOM group data relating to removed smesh object
2031 //================================================================================
2033 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2035 list<TGeomGroupData>::iterator
2036 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2037 for ( ; data != dataEnd; ++data ) {
2038 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2039 _geomGroupData.erase( data );
2045 //================================================================================
2047 * \brief Replace a shape in the mesh upon Break Link
2049 //================================================================================
2051 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
2052 throw (SALOME::SALOME_Exception)
2054 // check if geometry changed
2055 bool geomChanged = true;
2056 GEOM::GEOM_Object_var oldGeom = GetShapeToMesh();
2057 if ( !theNewGeom->_is_nil() && !oldGeom->_is_nil() )
2058 geomChanged = ( oldGeom->GetTick() != theNewGeom->GetTick() );
2060 TopoDS_Shape S = _impl->GetShapeToMesh();
2061 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2062 TCollection_AsciiString aIOR;
2063 if ( geomClient->Find( S, aIOR ))
2064 geomClient->RemoveShapeFromBuffer( aIOR );
2066 // clear buffer also for sub-groups
2067 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2068 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2069 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2070 for (; g != groups.end(); ++g)
2071 if (const SMESHDS_GroupOnGeom* group = dynamic_cast<SMESHDS_GroupOnGeom*>(*g))
2073 const TopoDS_Shape& s = group->GetShape();
2074 if ( geomClient->Find( s, aIOR ))
2075 geomClient->RemoveShapeFromBuffer( aIOR );
2078 // clear buffer also for sub-meshes
2079 std::map<int, SMESH_subMesh_i*>::const_iterator aSubMeshIter = _mapSubMesh_i.cbegin();
2080 for(; aSubMeshIter != _mapSubMesh_i.cend(); aSubMeshIter++) {
2081 int aShapeID = aSubMeshIter->first;
2082 const TopoDS_Shape& aSubShape = meshDS->IndexToShape(aShapeID);
2083 TCollection_AsciiString aShapeIOR;
2084 if ( geomClient->Find( aSubShape, aShapeIOR ))
2085 geomClient->RemoveShapeFromBuffer( aShapeIOR );
2089 int shapeID, fromID, toID; // indices of elements of a sub-mesh
2091 std::vector< TRange > elemRanges, nodeRanges; // elements of sub-meshes
2092 std::vector< SMDS_PositionPtr > positions; // node positions
2095 // store positions of elements on geometry
2097 if ( meshDS->MaxNodeID() > meshDS->NbNodes() ||
2098 meshDS->MaxElementID() > meshDS->NbElements() )
2101 meshDS->CompactMesh();
2103 positions.resize( meshDS->NbNodes() + 1 );
2104 for ( SMDS_NodeIteratorPtr nodeIt = meshDS->nodesIterator(); nodeIt->more(); )
2106 const SMDS_MeshNode* n = nodeIt->next();
2107 positions[ n->GetID() ] = n->GetPosition();
2110 // remove elements from sub-meshes to avoid their removal at hypotheses addition
2111 for ( int isNode = 0; isNode < 2; ++isNode )
2113 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2114 ranges.reserve( meshDS->MaxShapeIndex() + 10 );
2115 ranges.push_back( TRange{ 0,0,0 });
2116 SMDS_ElemIteratorPtr elemIt = meshDS->elementsIterator( isNode ? SMDSAbs_Node : SMDSAbs_All );
2117 while ( elemIt->more() )
2119 const SMDS_MeshElement* e = elemIt->next();
2120 const int elemID = e->GetID();
2121 const int shapeID = e->GetShapeID();
2122 TRange & lastRange = ranges.back();
2123 if ( lastRange.shapeID != shapeID ||
2124 lastRange.toID != elemID )
2125 ranges.push_back( TRange{ shapeID, elemID, elemID + 1 });
2127 lastRange.toID = elemID + 1;
2129 if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( shapeID ))
2131 if ( isNode ) sm->RemoveNode( static_cast< const SMDS_MeshNode *>( e ));
2132 else sm->RemoveElement( e );
2139 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
2140 SMESH::SMESH_Mesh_var me = _this();
2141 SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
2142 CORBA::String_var entry = theNewGeom->GetStudyEntry();
2143 if ( !aSO->_is_nil() )
2145 SALOMEDS::SObject_wrap aShapeRefSO;
2146 if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
2148 SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
2149 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2150 builder->Addreference( aShapeRefSO, aShapeSO );
2154 // re-assign global hypotheses to the new shape
2155 _mainShapeTick = geomChanged ? -1 : theNewGeom->GetTick();
2156 CheckGeomModif( true );
2160 // restore positions of elements on geometry
2161 for ( int isNode = 0; isNode < 2; ++isNode )
2163 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2164 for ( size_t i = 1; i < ranges.size(); ++i )
2166 int elemID = ranges[ i ].fromID;
2167 int toID = ranges[ i ].toID;
2168 SMESHDS_SubMesh * smDS = meshDS->NewSubMesh( ranges[ i ].shapeID );
2170 for ( ; elemID < toID; ++elemID )
2171 smDS->AddNode( meshDS->FindNode( elemID ));
2173 for ( ; elemID < toID; ++elemID )
2174 smDS->AddElement( meshDS->FindElement( elemID ));
2176 if ( SMESH_subMesh* sm = _impl->GetSubMeshContaining( ranges[ i ].shapeID ))
2177 sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
2180 for ( unsigned int nodeID = 1; nodeID < positions.size(); ++nodeID )
2181 if ( positions[ nodeID ])
2182 if ( SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( meshDS->FindNode( nodeID )))
2183 n->SetPosition( positions[ nodeID ], n->GetShapeID() );
2186 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
2189 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
2190 << me <<".GetMesh()), " << entry.in() << ")";
2192 TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )";
2196 //================================================================================
2198 * \brief Return new group contents if it has been changed and update group data
2200 //================================================================================
2202 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2204 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2206 TopoDS_Shape newShape;
2207 SALOMEDS::SObject_wrap groupSO;
2209 if ( how == IS_BREAK_LINK )
2211 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2212 SALOMEDS::SObject_wrap geomRefSO;
2213 if ( !meshSO->_is_nil() &&
2214 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ))
2216 geomRefSO->ReferencedObject( groupSO.inout() );
2222 groupSO = _gen_i->getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2225 if ( groupSO->_is_nil() )
2228 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2229 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2230 if ( geomGroup->_is_nil() )
2233 // get indices of group items
2234 set<int> curIndices;
2235 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2236 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2237 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2238 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2239 curIndices.insert( ids[i] );
2241 bool sameIndices = ( groupData._indices == curIndices );
2242 if ( how == ONLY_IF_CHANGED && sameIndices )
2243 return newShape; // group not changed
2246 CORBA::String_var entry = geomGroup->GetStudyEntry();
2247 groupData._groupEntry = entry.in();
2248 groupData._indices = curIndices;
2250 newShape = _gen_i->GeomObjectToShape( geomGroup );
2252 // check if newShape is up-to-date
2253 if ( !newShape.IsNull() && ids->length() > 0 )
2255 bool toUpdate = ! _impl->GetMeshDS()->IsGroupOfSubShapes( newShape );
2258 TopExp_Explorer exp( newShape, (TopAbs_ShapeEnum)( groupOp->GetType( geomGroup )));
2259 for ( ; exp.More() && !toUpdate; exp.Next() )
2261 int ind = _impl->GetMeshDS()->ShapeToIndex( exp.Current() );
2262 toUpdate = ( curIndices.erase( ind ) == 0 );
2264 if ( !curIndices.empty() )
2269 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2270 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2271 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2272 newShape = _gen_i->GeomObjectToShape( geomGroup );
2277 // geom group becomes empty - return empty compound
2278 TopoDS_Compound compound;
2279 BRep_Builder().MakeCompound(compound);
2280 newShape = compound;
2288 //-----------------------------------------------------------------------------
2290 * \brief Storage of shape and index used in CheckGeomGroupModif()
2292 struct TIndexedShape
2295 TopoDS_Shape _shape;
2296 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2298 //-----------------------------------------------------------------------------
2300 * \brief Data to re-create a group on geometry
2302 struct TGroupOnGeomData
2305 TopoDS_Shape _shape;
2306 SMDSAbs_ElementType _type;
2308 Quantity_Color _color;
2310 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2312 _oldID = group->GetID();
2313 _type = group->GetType();
2314 _name = group->GetStoreName();
2315 _color = group->GetColor();
2319 //-----------------------------------------------------------------------------
2321 * \brief Check if a filter is still valid after geometry removal
2323 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2325 if ( theFilter->_is_nil() )
2327 SMESH::Filter::Criteria_var criteria;
2328 theFilter->GetCriteria( criteria.out() );
2330 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2332 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2334 switch ( criteria[ iCr ].Type )
2336 case SMESH::FT_BelongToGeom:
2337 case SMESH::FT_BelongToPlane:
2338 case SMESH::FT_BelongToCylinder:
2339 case SMESH::FT_BelongToGenSurface:
2340 case SMESH::FT_LyingOnGeom:
2341 entry = thresholdID;
2343 case SMESH::FT_ConnectedElements:
2346 entry = thresholdID;
2352 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2353 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2354 if ( so->_is_nil() )
2356 CORBA::Object_var obj = so->GetObject();
2357 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2358 if ( gen->GeomObjectToShape( geom ).IsNull() )
2361 } // loop on criteria
2367 //=============================================================================
2369 * \brief Update data if geometry changes
2373 //=============================================================================
2375 void SMESH_Mesh_i::CheckGeomModif( bool theIsBreakLink )
2377 SMESH::SMESH_Mesh_var me = _this();
2378 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2380 TPythonDump dumpNothing; // prevent any dump
2382 //bool removedFromClient = false;
2384 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2386 //removedFromClient = _impl->HasShapeToMesh();
2388 // try to find geometry by study reference
2389 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2390 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2391 if ( !meshSO->_is_nil() &&
2392 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2393 geomRefSO->ReferencedObject( geomSO.inout() ))
2395 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2396 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2399 if ( mainGO->_is_nil() && // geometry removed ==>
2400 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2402 // convert geom dependent groups into standalone ones
2403 CheckGeomGroupModif();
2405 _impl->ShapeToMesh( TopoDS_Shape() );
2407 // remove sub-meshes
2408 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2409 while ( i_sm != _mapSubMeshIor.end() )
2411 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2413 RemoveSubMesh( sm );
2415 // remove all children except groups in the study
2416 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2417 SALOMEDS::SObject_wrap so;
2418 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2419 if ( meshSO->FindSubObject( tag, so.inout() ))
2420 builder->RemoveObjectWithChildren( so );
2422 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2428 if ( !_impl->HasShapeToMesh() ) return;
2431 // Update after group modification
2433 const bool geomChanged = ( mainGO->GetTick() != _mainShapeTick );
2434 if ( !theIsBreakLink )
2435 if ( mainGO->GetType() == GEOM_GROUP || !geomChanged ) // is group or not modified
2437 int nb = NbNodes() + NbElements();
2438 CheckGeomGroupModif();
2439 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2440 _gen_i->UpdateIcons( me );
2444 // Update after shape modification or breakLink w/o geometry change
2446 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2447 if ( !geomClient ) return;
2448 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2449 if ( geomGen->_is_nil() ) return;
2450 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2451 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2453 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2455 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2456 if ( meshDS->ShapeToIndex( newShape ) == 1 ) // not yet updated
2458 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2459 geomClient->RemoveShapeFromBuffer( ior.in() );
2460 newShape = _gen_i->GeomObjectToShape( mainGO );
2463 // Update data taking into account that if topology doesn't change
2464 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2467 _preMeshInfo->ForgetAllData();
2469 if ( geomChanged || !isShaper )
2471 if ( newShape.IsNull() )
2474 _mainShapeTick = mainGO->GetTick();
2476 // store data of groups on geometry including new TopoDS_Shape's
2477 std::vector< TGroupOnGeomData > groupsData;
2478 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2479 groupsData.reserve( groups.size() );
2480 TopTools_DataMapOfShapeShape old2newShapeMap;
2481 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2482 for ( ; g != groups.end(); ++g )
2484 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2486 groupsData.push_back( TGroupOnGeomData( group ));
2489 SMESH::SMESH_GroupOnGeom_var gog;
2490 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2491 if ( i_grp != _mapGroups.end() )
2492 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2494 GEOM::GEOM_Object_var geom;
2495 if ( !gog->_is_nil() )
2497 if ( !theIsBreakLink )
2498 geom = gog->GetShape();
2500 if ( theIsBreakLink || geom->_is_nil() )
2502 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2503 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2504 if ( !grpSO->_is_nil() &&
2505 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2506 geomRefSO->ReferencedObject( geomSO.inout() ))
2508 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2509 geom = GEOM::GEOM_Object::_narrow( geomObj );
2513 if ( old2newShapeMap.IsBound( group->GetShape() ))
2515 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2517 else if ( !geom->_is_nil() )
2519 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2520 if ( meshDS->IsGroupOfSubShapes( groupsData.back()._shape ))
2522 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2523 geomClient->RemoveShapeFromBuffer( ior.in() );
2524 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2526 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2531 // store assigned hypotheses
2532 std::vector< pair< int, THypList > > ids2Hyps;
2533 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2534 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2536 const TopoDS_Shape& s = s2hyps.Key();
2537 const THypList& hyps = s2hyps.ChangeValue();
2538 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2541 std::multimap< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2543 // count shapes excluding compounds corresponding to geom groups
2544 int oldNbSubShapes = meshDS->MaxShapeIndex();
2545 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2547 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2548 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2551 std::set<int> subIds;
2552 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2553 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2554 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2557 // check if shape topology changes - save shape type per shape ID
2558 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2559 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2560 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2562 // change shape to mesh
2563 _impl->ShapeToMesh( TopoDS_Shape() );
2564 _impl->ShapeToMesh( newShape );
2566 // check if shape topology changes - check new shape types
2567 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2568 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2570 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2571 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2574 // re-add shapes (compounds) of geom groups
2575 typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData;
2576 TIndices2GroupData ii2grData;
2577 std::vector< int > ii;
2578 std::map< int, int > old2newIDs; // group IDs
2579 std::list<TGeomGroupData>::iterator dataIt = _geomGroupData.begin();
2580 for ( ; dataIt != _geomGroupData.end(); ++dataIt )
2582 TGeomGroupData* data = &(*dataIt);
2583 ii.reserve( data->_indices.size() );
2584 ii.assign( data->_indices.begin(), data->_indices.end() );
2585 TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first;
2586 if ( ii2gd->second != data )
2588 data->_groupEntry = ii2gd->second->_groupEntry;
2589 data->_indices = ii2gd->second->_indices;
2592 const int oldNbSub = data->_indices.size();
2593 const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0;
2595 std::multimap< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2596 if ( ii2i != ii2iMap.end() )
2598 oldID = ii2i->second;
2599 ii2iMap.erase( ii2i );
2601 if ( !oldID && oldNbSub == 1 )
2603 if ( old2newIDs.count( oldID ))
2606 int how = ( theIsBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2607 newShape = newGroupShape( *data, how );
2609 if ( !newShape.IsNull() )
2611 if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape
2613 TopoDS_Compound compound;
2614 BRep_Builder().MakeCompound( compound );
2615 BRep_Builder().Add( compound, newShape );
2616 newShape = compound;
2618 int newID = _impl->GetSubMesh( newShape )->GetId();
2619 if ( oldID /*&& oldID != newID*/ )
2620 old2newIDs.insert( std::make_pair( oldID, newID ));
2621 if ( oldNbSub == 1 )
2622 old2newIDs.insert( std::make_pair( soleOldID, newID ));
2626 // re-assign hypotheses
2627 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2629 int sID = ids2Hyps[i].first;
2632 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2633 if ( o2n != old2newIDs.end() )
2635 else if ( !sameTopology )
2638 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2641 const THypList& hyps = ids2Hyps[i].second;
2642 THypList::const_iterator h = hyps.begin();
2643 for ( ; h != hyps.end(); ++h )
2644 _impl->AddHypothesis( s, (*h)->GetID() );
2648 // restore groups on geometry
2649 for ( size_t i = 0; i < groupsData.size(); ++i )
2651 const TGroupOnGeomData& data = groupsData[i];
2652 if ( data._shape.IsNull() )
2655 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2656 if ( i2g == _mapGroups.end() ) continue;
2658 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2659 if ( !gr_i ) continue;
2661 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2663 _mapGroups.erase( i2g );
2665 g->GetGroupDS()->SetColor( data._color );
2668 if ( !sameTopology )
2670 std::map< int, int >::iterator o2n = old2newIDs.begin();
2671 for ( ; o2n != old2newIDs.end(); ++o2n )
2673 int newID = o2n->second, oldID = o2n->first;
2674 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2678 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2679 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2680 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2682 _mapSubMesh. erase(oldID);
2683 _mapSubMesh_i. erase(oldID);
2684 _mapSubMeshIor.erase(oldID);
2686 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2690 // update _mapSubMesh
2691 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2692 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2693 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2696 if ( !sameTopology )
2698 // remove invalid study sub-objects
2699 CheckGeomGroupModif();
2702 _gen_i->UpdateIcons( me );
2704 if ( !theIsBreakLink && isShaper )
2706 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2707 if ( !meshSO->_is_nil() )
2708 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2712 //=============================================================================
2714 * \brief Update objects depending on changed geom groups
2716 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2717 * issue 0020210: Update of a smesh group after modification of the associated geom group
2719 //=============================================================================
2721 void SMESH_Mesh_i::CheckGeomGroupModif()
2723 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2724 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2725 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2726 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2727 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2729 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2730 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2731 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2733 int nbValid = 0, nbRemoved = 0;
2734 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2735 for ( ; chItr->More(); chItr->Next() )
2737 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2738 if ( !smSO->_is_nil() &&
2739 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2740 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2742 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2743 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2744 if ( !geom->_non_existent() )
2747 continue; // keep the sub-mesh
2750 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2751 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2752 if ( !sm->_is_nil() && !sm->_non_existent() )
2754 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2755 if ( smGeom->_is_nil() )
2757 RemoveSubMesh( sm );
2764 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2765 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2769 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2770 builder->RemoveObjectWithChildren( rootSO );
2774 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2775 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2776 while ( i_gr != _mapGroups.end())
2778 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2780 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO;
2781 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2782 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2783 bool isValidGeom = false;
2784 if ( !onGeom->_is_nil() )
2786 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); // check TopoDS
2787 if ( !isValidGeom ) // check reference
2789 isValidGeom = ( ! groupSO->_is_nil() &&
2790 groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) &&
2791 refSO->ReferencedObject( geomSO.inout() ) &&
2792 ! geomSO->_is_nil() &&
2793 !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() )));
2796 else if ( !onFilt->_is_nil() )
2798 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2802 isValidGeom = ( !groupSO->_is_nil() &&
2803 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2807 if ( !IsLoaded() || group->IsEmpty() )
2809 RemoveGroup( group );
2811 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2813 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2815 else // is it possible?
2817 builder->RemoveObjectWithChildren( refSO );
2823 if ( !_impl->HasShapeToMesh() ) return;
2825 CORBA::Long nbEntities = NbNodes() + NbElements();
2827 // Check if group contents changed
2829 typedef map< string, TopoDS_Shape > TEntry2Geom;
2830 TEntry2Geom newGroupContents;
2832 list<TGeomGroupData>::iterator
2833 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2834 for ( ; data != dataEnd; ++data )
2836 pair< TEntry2Geom::iterator, bool > it_new =
2837 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2838 bool processedGroup = !it_new.second;
2839 TopoDS_Shape& newShape = it_new.first->second;
2840 if ( !processedGroup )
2841 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2842 if ( newShape.IsNull() )
2843 continue; // no changes
2846 _preMeshInfo->ForgetOrLoad();
2848 if ( processedGroup ) { // update group indices
2849 list<TGeomGroupData>::iterator data2 = data;
2850 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2851 data->_indices = data2->_indices;
2854 // Update SMESH objects according to new GEOM group contents
2856 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2857 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2859 int oldID = submesh->GetId();
2860 if ( !_mapSubMeshIor.count( oldID ))
2862 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2864 // update hypotheses
2865 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2866 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2867 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2869 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2870 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2872 // care of submeshes
2873 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2874 int newID = newSubmesh->GetId();
2875 if ( newID != oldID ) {
2876 _mapSubMesh [ newID ] = newSubmesh;
2877 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2878 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2879 _mapSubMesh. erase(oldID);
2880 _mapSubMesh_i. erase(oldID);
2881 _mapSubMeshIor.erase(oldID);
2882 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2887 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2888 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2889 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2891 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2893 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2894 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2895 ds->SetShape( newShape );
2900 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2901 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2903 // Remove groups and submeshes basing on removed sub-shapes
2905 TopTools_MapOfShape newShapeMap;
2906 TopoDS_Iterator shapeIt( newShape );
2907 for ( ; shapeIt.More(); shapeIt.Next() )
2908 newShapeMap.Add( shapeIt.Value() );
2910 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2911 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2913 if ( newShapeMap.Contains( shapeIt.Value() ))
2915 TopTools_IndexedMapOfShape oldShapeMap;
2916 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2917 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2919 const TopoDS_Shape& oldShape = oldShapeMap(i);
2920 int oldInd = meshDS->ShapeToIndex( oldShape );
2922 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2923 if ( i_smIor != _mapSubMeshIor.end() ) {
2924 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2927 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2928 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2930 // check if a group bases on oldInd shape
2931 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2932 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2933 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2934 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2936 RemoveGroup( i_grp->second ); // several groups can base on same shape
2937 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2942 // Reassign hypotheses and update groups after setting the new shape to mesh
2944 // collect anassigned hypotheses
2945 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2946 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2947 TShapeHypList assignedHyps;
2948 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2950 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2951 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2952 if ( !hyps.empty() ) {
2953 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2954 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2955 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2958 // collect shapes supporting groups
2959 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2960 TShapeTypeList groupData;
2961 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2962 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2963 for ( ; grIt != groups.end(); ++grIt )
2965 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2967 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2969 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2971 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2972 _impl->ShapeToMesh( newShape );
2974 // reassign hypotheses
2975 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2976 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2978 TIndexedShape& geom = indS_hyps->first;
2979 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2980 int oldID = geom._index;
2981 int newID = meshDS->ShapeToIndex( geom._shape );
2982 if ( oldID == 1 ) { // main shape
2984 geom._shape = newShape;
2988 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2989 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2990 // care of sub-meshes
2991 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2992 if ( newID != oldID ) {
2993 _mapSubMesh [ newID ] = newSubmesh;
2994 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2995 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2996 _mapSubMesh. erase(oldID);
2997 _mapSubMesh_i. erase(oldID);
2998 _mapSubMeshIor.erase(oldID);
2999 _mapSubMesh_i [ newID ]->changeLocalId( newID );
3003 TShapeTypeList::iterator geomType = groupData.begin();
3004 for ( ; geomType != groupData.end(); ++geomType )
3006 const TIndexedShape& geom = geomType->first;
3007 int oldID = geom._index;
3008 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
3011 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
3012 CORBA::String_var name = groupSO->GetName();
3014 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
3015 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
3016 /*id=*/-1, geom._shape ))
3017 group_i->changeLocalId( group->GetID() );
3020 break; // everything has been updated
3023 } // loop on group data
3027 CORBA::Long newNbEntities = NbNodes() + NbElements();
3028 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
3029 if ( newNbEntities != nbEntities )
3031 // Add all SObjects with icons to soToUpdateIcons
3032 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
3034 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
3035 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
3036 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
3038 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
3039 i_gr != _mapGroups.end(); ++i_gr ) // groups
3040 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
3043 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
3044 for ( ; so != soToUpdateIcons.end(); ++so )
3045 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
3048 //=============================================================================
3050 * \brief Create standalone group from a group on geometry or filter
3052 //=============================================================================
3054 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
3055 throw (SALOME::SALOME_Exception)
3057 SMESH::SMESH_Group_var aGroup;
3062 _preMeshInfo->FullLoadFromFile();
3064 if ( theGroup->_is_nil() )
3065 return aGroup._retn();
3067 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
3069 return aGroup._retn();
3071 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
3073 const int anId = aGroupToRem->GetLocalID();
3074 if ( !_impl->ConvertToStandalone( anId ) )
3075 return aGroup._retn();
3076 removeGeomGroupData( theGroup );
3078 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3080 // remove old instance of group from own map
3081 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
3082 _mapGroups.erase( anId );
3084 SALOMEDS::StudyBuilder_var builder;
3085 SALOMEDS::SObject_wrap aGroupSO;
3086 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3087 if ( !aStudy->_is_nil() ) {
3088 builder = aStudy->NewBuilder();
3089 aGroupSO = _gen_i->ObjectToSObject( theGroup );
3090 if ( !aGroupSO->_is_nil() )
3092 // remove reference to geometry
3093 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
3094 for ( ; chItr->More(); chItr->Next() )
3096 // Remove group's child SObject
3097 SALOMEDS::SObject_wrap so = chItr->Value();
3098 builder->RemoveObject( so );
3100 // Update Python script
3101 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
3102 << ".ConvertToStandalone( " << aGroupSO << " )";
3104 // change icon of Group on Filter
3107 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
3108 // const int isEmpty = ( elemTypes->length() == 0 );
3111 SALOMEDS::GenericAttribute_wrap anAttr =
3112 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
3113 SALOMEDS::AttributePixMap_wrap pm = anAttr;
3114 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
3120 // remember new group in own map
3121 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
3122 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3124 // register CORBA object for persistence
3125 _gen_i->RegisterObject( aGroup );
3127 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
3128 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
3129 //aGroup->Register();
3130 aGroupToRem->UnRegister();
3132 SMESH_CATCH( SMESH::throwCorbaException );
3134 return aGroup._retn();
3137 //================================================================================
3139 * \brief Create a sub-mesh on a given sub-shape
3141 //================================================================================
3143 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
3145 if(MYDEBUG) MESSAGE( "createSubMesh" );
3146 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
3147 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
3150 SMESH_subMesh_i * subMeshServant;
3153 subMeshId = mySubMesh->GetId();
3154 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
3156 else // "invalid sub-mesh"
3158 // The invalid sub-mesh is created for the case where a valid sub-shape not found
3159 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
3160 if ( _mapSubMesh.empty() )
3163 subMeshId = _mapSubMesh.begin()->first - 1;
3164 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
3167 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
3169 _mapSubMesh [subMeshId] = mySubMesh;
3170 _mapSubMesh_i [subMeshId] = subMeshServant;
3171 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
3173 subMeshServant->Register();
3175 // register CORBA object for persistence
3176 int nextId = _gen_i->RegisterObject( subMesh );
3177 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
3178 else { nextId = 0; } // avoid "unused variable" warning
3180 // to track changes of GEOM groups
3181 if ( subMeshId > 0 )
3182 addGeomGroupData( theSubShapeObject, subMesh );
3184 return subMesh._retn();
3187 //================================================================================
3189 * \brief Return an existing sub-mesh based on a sub-shape with the given ID
3191 //================================================================================
3193 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3195 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3196 if ( it == _mapSubMeshIor.end() )
3197 return SMESH::SMESH_subMesh::_nil();
3199 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3202 //================================================================================
3204 * \brief Remove a sub-mesh based on the given sub-shape
3206 //================================================================================
3208 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3209 GEOM::GEOM_Object_ptr theSubShapeObject )
3211 bool isHypChanged = false;
3212 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3213 return isHypChanged;
3215 const int subMeshId = theSubMesh->GetId();
3217 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3220 if (( _mapSubMesh.count( subMeshId )) &&
3221 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3223 TopoDS_Shape S = sm->GetSubShape();
3226 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3227 isHypChanged = !hyps.empty();
3228 if ( isHypChanged && _preMeshInfo )
3229 _preMeshInfo->ForgetOrLoad();
3230 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3231 for ( ; hyp != hyps.end(); ++hyp )
3232 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3239 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3240 isHypChanged = ( aHypList->length() > 0 );
3241 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3242 removeHypothesis( theSubShapeObject, aHypList[i] );
3245 catch( const SALOME::SALOME_Exception& ) {
3246 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3248 removeGeomGroupData( theSubShapeObject );
3252 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3253 if ( id_smi != _mapSubMesh_i.end() )
3254 id_smi->second->UnRegister();
3256 // remove a CORBA object
3257 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3258 if ( id_smptr != _mapSubMeshIor.end() )
3259 SMESH::SMESH_subMesh_var( id_smptr->second );
3261 _mapSubMesh.erase(subMeshId);
3262 _mapSubMesh_i.erase(subMeshId);
3263 _mapSubMeshIor.erase(subMeshId);
3265 return isHypChanged;
3268 //================================================================================
3270 * \brief Create a group. Group type depends on given arguments
3272 //================================================================================
3274 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3275 const char* theName,
3277 const TopoDS_Shape& theShape,
3278 const SMESH_PredicatePtr& thePredicate )
3280 std::string newName;
3281 if ( !theName || !theName[0] )
3283 std::set< std::string > presentNames;
3284 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3285 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3287 CORBA::String_var name = i_gr->second->GetName();
3288 presentNames.insert( name.in() );
3291 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3292 } while ( !presentNames.insert( newName ).second );
3293 theName = newName.c_str();
3295 SMESH::SMESH_GroupBase_var aGroup;
3296 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3297 theID, theShape, thePredicate ))
3299 int anId = g->GetID();
3300 SMESH_GroupBase_i* aGroupImpl;
3301 if ( !theShape.IsNull() )
3302 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3303 else if ( thePredicate )
3304 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3306 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3308 aGroup = aGroupImpl->_this();
3309 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3310 aGroupImpl->Register();
3312 // register CORBA object for persistence
3313 int nextId = _gen_i->RegisterObject( aGroup );
3314 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3315 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3317 // to track changes of GEOM groups
3318 if ( !theShape.IsNull() ) {
3319 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3320 addGeomGroupData( geom, aGroup );
3323 return aGroup._retn();
3326 //=============================================================================
3328 * SMESH_Mesh_i::removeGroup
3330 * Should be called by ~SMESH_Group_i()
3332 //=============================================================================
3334 void SMESH_Mesh_i::removeGroup( const int theId )
3336 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3337 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3338 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3339 _mapGroups.erase( theId );
3340 removeGeomGroupData( group );
3341 if ( !_impl->RemoveGroup( theId ))
3343 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3344 RemoveGroup( group );
3346 group->UnRegister();
3350 //================================================================================
3352 * \brief Return a log that can be used to move another mesh to the same state as this one
3354 //================================================================================
3356 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3357 throw(SALOME::SALOME_Exception)
3359 SMESH::log_array_var aLog;
3363 _preMeshInfo->FullLoadFromFile();
3365 list < SMESHDS_Command * >logDS = _impl->GetLog();
3366 aLog = new SMESH::log_array;
3368 int lg = logDS.size();
3370 list < SMESHDS_Command * >::iterator its = logDS.begin();
3371 while(its != logDS.end()){
3372 SMESHDS_Command *com = *its;
3373 int comType = com->GetType();
3374 int lgcom = com->GetNumber();
3375 const list < int >&intList = com->GetIndexes();
3376 int inum = intList.size();
3377 list < int >::const_iterator ii = intList.begin();
3378 const list < double >&coordList = com->GetCoords();
3379 int rnum = coordList.size();
3380 list < double >::const_iterator ir = coordList.begin();
3381 aLog[indexLog].commandType = comType;
3382 aLog[indexLog].number = lgcom;
3383 aLog[indexLog].coords.length(rnum);
3384 aLog[indexLog].indexes.length(inum);
3385 for(int i = 0; i < rnum; i++){
3386 aLog[indexLog].coords[i] = *ir;
3389 for(int i = 0; i < inum; i++){
3390 aLog[indexLog].indexes[i] = *ii;
3399 SMESH_CATCH( SMESH::throwCorbaException );
3401 return aLog._retn();
3404 //================================================================================
3406 * \brief Remove the log of commands
3408 //================================================================================
3410 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3414 SMESH_CATCH( SMESH::throwCorbaException );
3417 //================================================================================
3419 * \brief Return a mesh ID
3421 //================================================================================
3423 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3428 //=============================================================================
3431 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3432 // issue 0020918: groups removal is caused by hyp modification
3433 // issue 0021208: to forget not loaded mesh data at hyp modification
3434 struct TCallUp_i : public SMESH_Mesh::TCallUp
3436 SMESH_Mesh_i* _mesh;
3437 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3438 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3439 virtual void HypothesisModified( int hypID,
3440 bool updIcons) { _mesh->onHypothesisModified( hypID,
3442 virtual void Load () { _mesh->Load(); }
3443 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3447 //================================================================================
3449 * \brief callback from _impl to
3450 * 1) forget not loaded mesh data (issue 0021208)
3451 * 2) mark hypothesis as valid
3453 //================================================================================
3455 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3458 _preMeshInfo->ForgetOrLoad();
3460 if ( theUpdateIcons )
3462 SMESH::SMESH_Mesh_var mesh = _this();
3463 _gen_i->UpdateIcons( mesh );
3466 if ( _nbInvalidHypos != 0 )
3468 // mark a hypothesis as valid after edition
3470 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3471 SALOMEDS::SObject_wrap hypRoot;
3472 if ( !smeshComp->_is_nil() &&
3473 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3475 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3476 for ( ; anIter->More(); anIter->Next() )
3478 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3479 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3480 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3481 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3482 _gen_i->HighLightInvalid( hyp, false );
3484 nbInvalid += _gen_i->IsInvalid( hypSO );
3487 _nbInvalidHypos = nbInvalid;
3491 //================================================================================
3493 * \brief Set mesh implementation
3495 //================================================================================
3497 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3499 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3502 _impl->SetCallUp( new TCallUp_i(this));
3505 //=============================================================================
3507 * Return a mesh implementation
3509 //=============================================================================
3511 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3513 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3517 //=============================================================================
3519 * Return mesh editor
3521 //=============================================================================
3523 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3524 throw (SALOME::SALOME_Exception)
3526 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3530 _preMeshInfo->FullLoadFromFile();
3532 // Create MeshEditor
3534 _editor = new SMESH_MeshEditor_i( this, false );
3535 aMeshEdVar = _editor->_this();
3537 // Update Python script
3538 TPythonDump() << _editor << " = "
3539 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3541 SMESH_CATCH( SMESH::throwCorbaException );
3543 return aMeshEdVar._retn();
3546 //=============================================================================
3548 * Return mesh edition previewer
3550 //=============================================================================
3552 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3553 throw (SALOME::SALOME_Exception)
3555 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3559 _preMeshInfo->FullLoadFromFile();
3561 if ( !_previewEditor )
3562 _previewEditor = new SMESH_MeshEditor_i( this, true );
3563 aMeshEdVar = _previewEditor->_this();
3565 SMESH_CATCH( SMESH::throwCorbaException );
3567 return aMeshEdVar._retn();
3570 //================================================================================
3572 * \brief Return true if the mesh has been edited since a last total re-compute
3573 * and those modifications may prevent successful partial re-compute
3575 //================================================================================
3577 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3579 Unexpect aCatch(SALOME_SalomeException);
3580 return _impl->HasModificationsToDiscard();
3583 //================================================================================
3585 * \brief Return a random unique color
3587 //================================================================================
3589 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3591 const int MAX_ATTEMPTS = 100;
3593 double tolerance = 0.5;
3594 SALOMEDS::Color col;
3598 // generate random color
3599 double red = (double)rand() / RAND_MAX;
3600 double green = (double)rand() / RAND_MAX;
3601 double blue = (double)rand() / RAND_MAX;
3602 // check existence in the list of the existing colors
3603 bool matched = false;
3604 std::list<SALOMEDS::Color>::const_iterator it;
3605 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3606 SALOMEDS::Color color = *it;
3607 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3608 matched = tol < tolerance;
3610 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3611 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3619 //=============================================================================
3621 * Set auto-color mode. If it is on, groups get unique random colors
3623 //=============================================================================
3625 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3627 Unexpect aCatch(SALOME_SalomeException);
3628 _impl->SetAutoColor(theAutoColor);
3630 TPythonDump pyDump; // not to dump group->SetColor() from below code
3631 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3633 std::list<SALOMEDS::Color> aReservedColors;
3634 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3635 for ( ; it != _mapGroups.end(); it++ ) {
3636 if ( CORBA::is_nil( it->second )) continue;
3637 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3638 it->second->SetColor( aColor );
3639 aReservedColors.push_back( aColor );
3643 //=============================================================================
3645 * Return true if auto-color mode is on
3647 //=============================================================================
3649 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3651 Unexpect aCatch(SALOME_SalomeException);
3652 return _impl->GetAutoColor();
3655 //=============================================================================
3657 * Check if there are groups with equal names
3659 //=============================================================================
3661 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3663 return _impl->HasDuplicatedGroupNamesMED();
3666 //================================================================================
3668 * \brief Care of a file before exporting mesh into it
3670 //================================================================================
3672 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3674 SMESH_File aFile( file, false );
3676 if ( aFile.exists() ) {
3677 // existing filesystem node
3678 if ( !aFile.isDirectory() ) {
3679 if ( aFile.openForWriting() ) {
3680 if ( overwrite && ! aFile.remove()) {
3681 msg << "Can't replace " << aFile.getName();
3684 msg << "Can't write into " << aFile.getName();
3687 msg << "Location " << aFile.getName() << " is not a file";
3691 // nonexisting file; check if it can be created
3692 if ( !aFile.openForWriting() ) {
3693 msg << "You cannot create the file "
3695 << ". Check the directory existence and access rights";
3703 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3707 //================================================================================
3709 * \brief Prepare a file for export and pass names of mesh groups from study to mesh DS
3710 * \param file - file name
3711 * \param overwrite - to erase the file or not
3712 * \retval string - mesh name
3714 //================================================================================
3716 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3717 CORBA::Boolean overwrite)
3720 PrepareForWriting(file, overwrite);
3721 string aMeshName = "Mesh";
3722 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3723 if ( !aStudy->_is_nil() ) {
3724 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3725 if ( !aMeshSO->_is_nil() ) {
3726 CORBA::String_var name = aMeshSO->GetName();
3728 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3729 if ( !aStudy->GetProperties()->IsLocked() )
3731 SALOMEDS::GenericAttribute_wrap anAttr;
3732 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3733 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3734 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3735 ASSERT(!aFileName->_is_nil());
3736 aFileName->SetValue(file);
3737 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3738 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3739 ASSERT(!aFileType->_is_nil());
3740 aFileType->SetValue("FICHIERMED");
3744 // Update Python script
3745 // set name of mesh before export
3746 TPythonDump() << _gen_i << ".SetName("
3747 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3749 // check names of groups
3755 //================================================================================
3757 * \brief Export to MED file
3759 //================================================================================
3761 void SMESH_Mesh_i::ExportMED(const char* file,
3762 CORBA::Boolean auto_groups,
3763 CORBA::Long version,
3764 CORBA::Boolean overwrite,
3765 CORBA::Boolean autoDimension)
3766 throw(SALOME::SALOME_Exception)
3768 //MESSAGE("MED minor version: "<< minor);
3771 _preMeshInfo->FullLoadFromFile();
3773 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3774 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3776 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3778 << "auto_groups=" <<auto_groups << ", "
3779 << "minor=" << version << ", "
3780 << "overwrite=" << overwrite << ", "
3781 << "meshPart=None, "
3782 << "autoDimension=" << autoDimension << " )";
3784 SMESH_CATCH( SMESH::throwCorbaException );
3787 //================================================================================
3789 * \brief Export a mesh to a SAUV file
3791 //================================================================================
3793 void SMESH_Mesh_i::ExportSAUV (const char* file,
3794 CORBA::Boolean auto_groups)
3795 throw(SALOME::SALOME_Exception)
3797 Unexpect aCatch(SALOME_SalomeException);
3799 _preMeshInfo->FullLoadFromFile();
3801 string aMeshName = prepareMeshNameAndGroups(file, true);
3802 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3803 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3804 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3808 //================================================================================
3810 * \brief Export a mesh to a DAT file
3812 //================================================================================
3814 void SMESH_Mesh_i::ExportDAT (const char *file)
3815 throw(SALOME::SALOME_Exception)
3817 Unexpect aCatch(SALOME_SalomeException);
3819 _preMeshInfo->FullLoadFromFile();
3821 // Update Python script
3822 // check names of groups
3824 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3827 PrepareForWriting(file);
3828 _impl->ExportDAT(file);
3831 //================================================================================
3833 * \brief Export a mesh to an UNV file
3835 //================================================================================
3837 void SMESH_Mesh_i::ExportUNV (const char *file)
3838 throw(SALOME::SALOME_Exception)
3840 Unexpect aCatch(SALOME_SalomeException);
3842 _preMeshInfo->FullLoadFromFile();
3844 // Update Python script
3845 // check names of groups
3847 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3850 PrepareForWriting(file);
3851 _impl->ExportUNV(file);
3854 //================================================================================
3856 * \brief Export a mesh to an STL file
3858 //================================================================================
3860 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3861 throw(SALOME::SALOME_Exception)
3863 Unexpect aCatch(SALOME_SalomeException);
3865 _preMeshInfo->FullLoadFromFile();
3867 // Update Python script
3868 // check names of groups
3870 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3871 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3873 CORBA::String_var name;
3874 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3875 if ( !so->_is_nil() )
3876 name = so->GetName();
3879 PrepareForWriting( file );
3880 _impl->ExportSTL( file, isascii, name.in() );
3883 //================================================================================
3885 * \brief Export a part of mesh to a med file
3887 //================================================================================
3889 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3891 CORBA::Boolean auto_groups,
3892 CORBA::Long version,
3893 CORBA::Boolean overwrite,
3894 CORBA::Boolean autoDimension,
3895 const GEOM::ListOfFields& fields,
3896 const char* geomAssocFields,
3897 CORBA::Double ZTolerance)
3898 throw (SALOME::SALOME_Exception)
3900 MESSAGE("MED version: "<< version);
3903 _preMeshInfo->FullLoadFromFile();
3906 bool have0dField = false;
3907 if ( fields.length() > 0 )
3909 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3910 if ( shapeToMesh->_is_nil() )
3911 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3913 for ( size_t i = 0; i < fields.length(); ++i )
3915 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3916 THROW_SALOME_CORBA_EXCEPTION
3917 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3918 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3919 if ( fieldShape->_is_nil() )
3920 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3921 if ( !fieldShape->IsSame( shapeToMesh ) )
3922 THROW_SALOME_CORBA_EXCEPTION
3923 ( "Field defined not on shape", SALOME::BAD_PARAM);
3924 if ( fields[i]->GetDimension() == 0 )
3927 if ( geomAssocFields )
3928 for ( int i = 0; geomAssocFields[i]; ++i )
3929 switch ( geomAssocFields[i] ) {
3930 case 'v':case 'e':case 'f':case 's': break;
3931 case 'V':case 'E':case 'F':case 'S': break;
3932 default: THROW_SALOME_CORBA_EXCEPTION
3933 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3937 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3941 string aMeshName = "Mesh";
3942 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3943 if ( CORBA::is_nil( meshPart ) ||
3944 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3946 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3947 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3948 0, autoDimension, /*addODOnVertices=*/have0dField,
3950 meshDS = _impl->GetMeshDS();
3955 _preMeshInfo->FullLoadFromFile();
3957 PrepareForWriting(file, overwrite);
3959 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3960 if ( !SO->_is_nil() ) {
3961 CORBA::String_var name = SO->GetName();
3965 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3966 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3967 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3968 meshDS = tmpDSDeleter._obj = partDS;
3973 if ( _impl->HasShapeToMesh() )
3975 DriverMED_W_Field fieldWriter;
3976 fieldWriter.SetFile( file );
3977 fieldWriter.SetMeshName( aMeshName );
3978 fieldWriter.AddODOnVertices( have0dField );
3980 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3984 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3985 goList->length( fields.length() );
3986 for ( size_t i = 0; i < fields.length(); ++i )
3988 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3991 TPythonDump() << _this() << ".ExportPartToMED( "
3992 << meshPart << ", r'"
3994 << auto_groups << ", "
3996 << overwrite << ", "
3997 << autoDimension << ", "
3999 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
4000 << TVar( ZTolerance )
4003 SMESH_CATCH( SMESH::throwCorbaException );
4006 //================================================================================
4008 * Write GEOM fields to MED file
4010 //================================================================================
4012 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
4013 SMESHDS_Mesh* meshDS,
4014 const GEOM::ListOfFields& fields,
4015 const char* geomAssocFields)
4017 #define METH "SMESH_Mesh_i::exportMEDFields() "
4019 if (( fields.length() < 1 ) &&
4020 ( !geomAssocFields || !geomAssocFields[0] ))
4023 std::vector< std::vector< double > > dblVals;
4024 std::vector< std::vector< int > > intVals;
4025 std::vector< int > subIdsByDim[ 4 ];
4026 const double noneDblValue = 0.;
4027 const double noneIntValue = 0;
4029 for ( size_t iF = 0; iF < fields.length(); ++iF )
4033 int dim = fields[ iF ]->GetDimension();
4034 SMDSAbs_ElementType elemType;
4035 TopAbs_ShapeEnum shapeType;
4037 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
4038 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
4039 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
4040 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
4042 continue; // skip fields on whole shape
4044 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
4045 if ( dataType == GEOM::FDT_String )
4047 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
4048 if ( stepIDs->length() < 1 )
4050 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
4051 if ( comps->length() < 1 )
4053 CORBA::String_var name = fields[ iF ]->GetName();
4055 if ( !fieldWriter.Set( meshDS,
4059 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
4062 for ( size_t iC = 0; iC < comps->length(); ++iC )
4063 fieldWriter.SetCompName( iC, comps[ iC ].in() );
4065 dblVals.resize( comps->length() );
4066 intVals.resize( comps->length() );
4068 // find sub-shape IDs
4070 std::vector< int >& subIds = subIdsByDim[ dim ];
4071 if ( subIds.empty() )
4072 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
4073 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
4074 subIds.push_back( id );
4078 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4082 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
4084 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
4085 if ( step->_is_nil() )
4088 CORBA::Long stamp = step->GetStamp();
4089 CORBA::Long id = step->GetID();
4090 fieldWriter.SetDtIt( int( stamp ), int( id ));
4092 // fill dblVals or intVals
4093 for ( size_t iC = 0; iC < comps->length(); ++iC )
4094 if ( dataType == GEOM::FDT_Double )
4096 dblVals[ iC ].clear();
4097 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4101 intVals[ iC ].clear();
4102 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4106 case GEOM::FDT_Double:
4108 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
4109 if ( dblStep->_is_nil() ) continue;
4110 GEOM::ListOfDouble_var vv = dblStep->GetValues();
4111 if ( vv->length() != subIds.size() * comps->length() )
4112 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4113 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4114 for ( size_t iC = 0; iC < comps->length(); ++iC )
4115 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
4120 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
4121 if ( intStep->_is_nil() ) continue;
4122 GEOM::ListOfLong_var vv = intStep->GetValues();
4123 if ( vv->length() != subIds.size() * comps->length() )
4124 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4125 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4126 for ( size_t iC = 0; iC < comps->length(); ++iC )
4127 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4130 case GEOM::FDT_Bool:
4132 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
4133 if ( boolStep->_is_nil() ) continue;
4134 GEOM::short_array_var vv = boolStep->GetValues();
4135 if ( vv->length() != subIds.size() * comps->length() )
4136 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4137 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4138 for ( size_t iC = 0; iC < comps->length(); ++iC )
4139 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4145 // pass values to fieldWriter
4146 elemIt = fieldWriter.GetOrderedElems();
4147 if ( dataType == GEOM::FDT_Double )
4148 while ( elemIt->more() )
4150 const SMDS_MeshElement* e = elemIt->next();
4151 const int shapeID = e->getshapeId();
4152 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
4153 for ( size_t iC = 0; iC < comps->length(); ++iC )
4154 fieldWriter.AddValue( noneDblValue );
4156 for ( size_t iC = 0; iC < comps->length(); ++iC )
4157 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
4160 while ( elemIt->more() )
4162 const SMDS_MeshElement* e = elemIt->next();
4163 const int shapeID = e->getshapeId();
4164 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
4165 for ( size_t iC = 0; iC < comps->length(); ++iC )
4166 fieldWriter.AddValue( (double) noneIntValue );
4168 for ( size_t iC = 0; iC < comps->length(); ++iC )
4169 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4173 fieldWriter.Perform();
4174 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4175 if ( res && res->IsKO() )
4177 if ( res->myComment.empty() )
4178 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4180 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4186 if ( !geomAssocFields || !geomAssocFields[0] )
4189 // write geomAssocFields
4191 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4192 shapeDim[ TopAbs_COMPOUND ] = 3;
4193 shapeDim[ TopAbs_COMPSOLID ] = 3;
4194 shapeDim[ TopAbs_SOLID ] = 3;
4195 shapeDim[ TopAbs_SHELL ] = 2;
4196 shapeDim[ TopAbs_FACE ] = 2;
4197 shapeDim[ TopAbs_WIRE ] = 1;
4198 shapeDim[ TopAbs_EDGE ] = 1;
4199 shapeDim[ TopAbs_VERTEX ] = 0;
4200 shapeDim[ TopAbs_SHAPE ] = 3;
4202 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4204 std::vector< std::string > compNames;
4205 switch ( geomAssocFields[ iF ]) {
4207 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4208 compNames.push_back( "dim" );
4211 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4214 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4217 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4221 compNames.push_back( "id" );
4222 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4223 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4225 fieldWriter.SetDtIt( -1, -1 );
4227 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4231 if ( compNames.size() == 2 ) // _vertices_
4232 while ( elemIt->more() )
4234 const SMDS_MeshElement* e = elemIt->next();
4235 const int shapeID = e->getshapeId();
4238 fieldWriter.AddValue( (double) -1 );
4239 fieldWriter.AddValue( (double) -1 );
4243 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4244 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4245 fieldWriter.AddValue( (double) shapeID );
4249 while ( elemIt->more() )
4251 const SMDS_MeshElement* e = elemIt->next();
4252 const int shapeID = e->getshapeId();
4254 fieldWriter.AddValue( (double) -1 );
4256 fieldWriter.AddValue( (double) shapeID );
4260 fieldWriter.Perform();
4261 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4262 if ( res && res->IsKO() )
4264 if ( res->myComment.empty() )
4265 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4267 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4270 } // loop on geomAssocFields
4275 //================================================================================
4277 * \brief Export a part of mesh to a DAT file
4279 //================================================================================
4281 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4283 throw (SALOME::SALOME_Exception)
4285 Unexpect aCatch(SALOME_SalomeException);
4287 _preMeshInfo->FullLoadFromFile();
4289 PrepareForWriting(file);
4291 SMESH_MeshPartDS partDS( meshPart );
4292 _impl->ExportDAT(file,&partDS);
4294 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4295 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4297 //================================================================================
4299 * \brief Export a part of mesh to an UNV file
4301 //================================================================================
4303 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4305 throw (SALOME::SALOME_Exception)
4307 Unexpect aCatch(SALOME_SalomeException);
4309 _preMeshInfo->FullLoadFromFile();
4311 PrepareForWriting(file);
4313 SMESH_MeshPartDS partDS( meshPart );
4314 _impl->ExportUNV(file, &partDS);
4316 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4317 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4319 //================================================================================
4321 * \brief Export a part of mesh to an STL file
4323 //================================================================================
4325 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4327 ::CORBA::Boolean isascii)
4328 throw (SALOME::SALOME_Exception)
4330 Unexpect aCatch(SALOME_SalomeException);
4332 _preMeshInfo->FullLoadFromFile();
4334 PrepareForWriting(file);
4336 CORBA::String_var name;
4337 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4338 if ( !so->_is_nil() )
4339 name = so->GetName();
4341 SMESH_MeshPartDS partDS( meshPart );
4342 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4344 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4345 << meshPart<< ", r'" << file << "', " << isascii << ")";
4348 //================================================================================
4350 * \brief Export a part of mesh to an STL file
4352 //================================================================================
4354 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4356 CORBA::Boolean overwrite,
4357 CORBA::Boolean groupElemsByType)
4358 throw (SALOME::SALOME_Exception)
4361 Unexpect aCatch(SALOME_SalomeException);
4363 _preMeshInfo->FullLoadFromFile();
4365 PrepareForWriting(file,overwrite);
4367 std::string meshName("");
4368 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4369 if ( !so->_is_nil() )
4371 CORBA::String_var name = so->GetName();
4372 meshName = name.in();
4376 SMESH_MeshPartDS partDS( meshPart );
4377 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4379 SMESH_CATCH( SMESH::throwCorbaException );
4381 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4382 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4384 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4388 //================================================================================
4390 * \brief Export a part of mesh to a GMF file
4392 //================================================================================
4394 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4396 bool withRequiredGroups)
4397 throw (SALOME::SALOME_Exception)
4399 Unexpect aCatch(SALOME_SalomeException);
4401 _preMeshInfo->FullLoadFromFile();
4403 PrepareForWriting(file,/*overwrite=*/true);
4405 SMESH_MeshPartDS partDS( meshPart );
4406 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4408 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4409 << meshPart<< ", r'"
4411 << withRequiredGroups << ")";
4414 //=============================================================================
4416 * Return computation progress [0.,1]
4418 //=============================================================================
4420 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4424 return _impl->GetComputeProgress();
4426 SMESH_CATCH( SMESH::doNothing );
4430 //================================================================================
4432 * \brief Return nb of nodes
4434 //================================================================================
4436 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4438 Unexpect aCatch(SALOME_SalomeException);
4440 return _preMeshInfo->NbNodes();
4442 return _impl->NbNodes();
4445 //================================================================================
4447 * \brief Return nb of elements
4449 //================================================================================
4451 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4453 Unexpect aCatch(SALOME_SalomeException);
4455 return _preMeshInfo->NbElements();
4457 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4460 //================================================================================
4462 * \brief Return nb of 0D elements
4464 //================================================================================
4466 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4468 Unexpect aCatch(SALOME_SalomeException);
4470 return _preMeshInfo->Nb0DElements();
4472 return _impl->Nb0DElements();
4475 //================================================================================
4477 * \brief Return nb of BALL elements
4479 //================================================================================
4481 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4483 Unexpect aCatch(SALOME_SalomeException);
4485 return _preMeshInfo->NbBalls();
4487 return _impl->NbBalls();
4490 //================================================================================
4492 * \brief Return nb of 1D elements
4494 //================================================================================
4496 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4498 Unexpect aCatch(SALOME_SalomeException);
4500 return _preMeshInfo->NbEdges();
4502 return _impl->NbEdges();
4505 //================================================================================
4507 * \brief Return nb of edges
4509 //================================================================================
4511 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4512 throw(SALOME::SALOME_Exception)
4514 Unexpect aCatch(SALOME_SalomeException);
4516 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4518 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4521 //================================================================================
4523 * \brief Return nb of faces
4525 //================================================================================
4527 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4529 Unexpect aCatch(SALOME_SalomeException);
4531 return _preMeshInfo->NbFaces();
4533 return _impl->NbFaces();
4536 //================================================================================
4538 * \brief Return nb of tringles
4540 //================================================================================
4542 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4544 Unexpect aCatch(SALOME_SalomeException);
4546 return _preMeshInfo->NbTriangles();
4548 return _impl->NbTriangles();
4551 //================================================================================
4553 * \brief Return nb of bi-quadratic triangles
4555 //================================================================================
4557 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4559 Unexpect aCatch(SALOME_SalomeException);
4561 return _preMeshInfo->NbBiQuadTriangles();
4563 return _impl->NbBiQuadTriangles();
4566 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4568 Unexpect aCatch(SALOME_SalomeException);
4570 return _preMeshInfo->NbQuadrangles();
4572 return _impl->NbQuadrangles();
4575 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4577 Unexpect aCatch(SALOME_SalomeException);
4579 return _preMeshInfo->NbBiQuadQuadrangles();
4581 return _impl->NbBiQuadQuadrangles();
4584 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4586 Unexpect aCatch(SALOME_SalomeException);
4588 return _preMeshInfo->NbPolygons();
4590 return _impl->NbPolygons();
4593 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4595 Unexpect aCatch(SALOME_SalomeException);
4597 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4599 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4602 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4603 throw(SALOME::SALOME_Exception)
4605 Unexpect aCatch(SALOME_SalomeException);
4607 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4609 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4612 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4613 throw(SALOME::SALOME_Exception)
4615 Unexpect aCatch(SALOME_SalomeException);
4617 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4619 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4622 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4623 throw(SALOME::SALOME_Exception)
4625 Unexpect aCatch(SALOME_SalomeException);
4627 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4629 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4632 //=============================================================================
4634 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4636 Unexpect aCatch(SALOME_SalomeException);
4638 return _preMeshInfo->NbVolumes();
4640 return _impl->NbVolumes();
4643 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4645 Unexpect aCatch(SALOME_SalomeException);
4647 return _preMeshInfo->NbTetras();
4649 return _impl->NbTetras();
4652 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4654 Unexpect aCatch(SALOME_SalomeException);
4656 return _preMeshInfo->NbHexas();
4658 return _impl->NbHexas();
4661 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4663 Unexpect aCatch(SALOME_SalomeException);
4665 return _preMeshInfo->NbTriQuadHexas();
4667 return _impl->NbTriQuadraticHexas();
4670 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4672 Unexpect aCatch(SALOME_SalomeException);
4674 return _preMeshInfo->NbPyramids();
4676 return _impl->NbPyramids();
4679 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4681 Unexpect aCatch(SALOME_SalomeException);
4683 return _preMeshInfo->NbPrisms();
4685 return _impl->NbPrisms();
4688 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4690 Unexpect aCatch(SALOME_SalomeException);
4692 return _preMeshInfo->NbHexPrisms();
4694 return _impl->NbHexagonalPrisms();
4697 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4699 Unexpect aCatch(SALOME_SalomeException);
4701 return _preMeshInfo->NbPolyhedrons();
4703 return _impl->NbPolyhedrons();
4706 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4707 throw(SALOME::SALOME_Exception)
4709 Unexpect aCatch(SALOME_SalomeException);
4711 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4713 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4716 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4717 throw(SALOME::SALOME_Exception)
4719 Unexpect aCatch(SALOME_SalomeException);
4721 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4723 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4726 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4727 throw(SALOME::SALOME_Exception)
4729 Unexpect aCatch(SALOME_SalomeException);
4731 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4733 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4736 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4737 throw(SALOME::SALOME_Exception)
4739 Unexpect aCatch(SALOME_SalomeException);
4741 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4743 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4746 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4747 throw(SALOME::SALOME_Exception)
4749 Unexpect aCatch(SALOME_SalomeException);
4751 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4753 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4756 //=============================================================================
4758 * Return nb of published sub-meshes
4760 //=============================================================================
4762 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4764 Unexpect aCatch(SALOME_SalomeException);
4765 return _mapSubMesh_i.size();
4768 //=============================================================================
4770 * Dumps mesh into a string
4772 //=============================================================================
4774 char* SMESH_Mesh_i::Dump()
4778 return CORBA::string_dup( os.str().c_str() );
4781 //=============================================================================
4783 * Method of SMESH_IDSource interface
4785 //=============================================================================
4787 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4789 return GetElementsId();
4792 //=============================================================================
4794 * Return ids of all elements
4796 //=============================================================================
4798 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4799 throw (SALOME::SALOME_Exception)
4801 Unexpect aCatch(SALOME_SalomeException);
4803 _preMeshInfo->FullLoadFromFile();
4805 SMESH::long_array_var aResult = new SMESH::long_array();
4806 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4808 if ( aSMESHDS_Mesh == NULL )
4809 return aResult._retn();
4811 long nbElements = NbElements();
4812 aResult->length( nbElements );
4813 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4814 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4815 aResult[i] = anIt->next()->GetID();
4817 return aResult._retn();
4821 //=============================================================================
4823 * Return ids of all elements of given type
4825 //=============================================================================
4827 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4828 throw (SALOME::SALOME_Exception)
4830 Unexpect aCatch(SALOME_SalomeException);
4832 _preMeshInfo->FullLoadFromFile();
4834 SMESH::long_array_var aResult = new SMESH::long_array();
4835 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4837 if ( aSMESHDS_Mesh == NULL )
4838 return aResult._retn();
4840 long nbElements = NbElements();
4842 // No sense in returning ids of elements along with ids of nodes:
4843 // when theElemType == SMESH::ALL, return node ids only if
4844 // there are no elements
4845 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4846 return GetNodesId();
4848 aResult->length( nbElements );
4852 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4853 while ( i < nbElements && anIt->more() )
4854 aResult[i++] = anIt->next()->GetID();
4856 aResult->length( i );
4858 return aResult._retn();
4861 //=============================================================================
4863 * Return ids of all nodes
4865 //=============================================================================
4867 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4868 throw (SALOME::SALOME_Exception)
4870 Unexpect aCatch(SALOME_SalomeException);
4872 _preMeshInfo->FullLoadFromFile();
4874 SMESH::long_array_var aResult = new SMESH::long_array();
4875 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4877 if ( aMeshDS == NULL )
4878 return aResult._retn();
4880 long nbNodes = NbNodes();
4881 aResult->length( nbNodes );
4882 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4883 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4884 aResult[i] = anIt->next()->GetID();
4886 return aResult._retn();
4889 //=============================================================================
4891 * Return type of the given element
4893 //=============================================================================
4895 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4896 throw (SALOME::SALOME_Exception)
4898 SMESH::ElementType type = SMESH::ALL;
4902 _preMeshInfo->FullLoadFromFile();
4904 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4906 SMESH_CATCH( SMESH::throwCorbaException );
4911 //=============================================================================
4913 * Return geometric type of the given element
4915 //=============================================================================
4917 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4918 throw (SALOME::SALOME_Exception)
4921 _preMeshInfo->FullLoadFromFile();
4923 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4925 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4927 return ( SMESH::EntityType ) e->GetEntityType();
4930 //=============================================================================
4932 * Return type of the given element
4934 //=============================================================================
4936 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4937 throw (SALOME::SALOME_Exception)
4940 _preMeshInfo->FullLoadFromFile();
4942 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4944 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4946 return ( SMESH::GeometryType ) e->GetGeomType();
4949 //=============================================================================
4951 * Return ID of elements for given submesh
4953 //=============================================================================
4955 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4956 throw (SALOME::SALOME_Exception)
4958 SMESH::long_array_var aResult = new SMESH::long_array();
4962 _preMeshInfo->FullLoadFromFile();
4964 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4965 if(!SM) return aResult._retn();
4967 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4968 if(!SDSM) return aResult._retn();
4970 aResult->length(SDSM->NbElements());
4972 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4974 while ( eIt->more() ) {
4975 aResult[i++] = eIt->next()->GetID();
4978 SMESH_CATCH( SMESH::throwCorbaException );
4980 return aResult._retn();
4983 //=============================================================================
4985 * Return ID of nodes for given sub-mesh
4986 * If param all==true - return all nodes, else -
4987 * Return only nodes on shapes.
4989 //=============================================================================
4991 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4993 throw (SALOME::SALOME_Exception)
4995 SMESH::long_array_var aResult = new SMESH::long_array();
4999 _preMeshInfo->FullLoadFromFile();
5001 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
5002 if(!SM) return aResult._retn();
5004 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
5005 if(!SDSM) return aResult._retn();
5008 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
5009 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
5010 while ( nIt->more() ) {
5011 const SMDS_MeshNode* elem = nIt->next();
5012 theElems.insert( elem->GetID() );
5015 else { // all nodes of submesh elements
5016 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5017 while ( eIt->more() ) {
5018 const SMDS_MeshElement* anElem = eIt->next();
5019 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
5020 while ( nIt->more() ) {
5021 const SMDS_MeshElement* elem = nIt->next();
5022 theElems.insert( elem->GetID() );
5027 aResult->length(theElems.size());
5028 set<int>::iterator itElem;
5030 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
5031 aResult[i++] = *itElem;
5033 SMESH_CATCH( SMESH::throwCorbaException );
5035 return aResult._retn();
5038 //=============================================================================
5040 * Return type of elements for given sub-mesh
5042 //=============================================================================
5044 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
5045 throw (SALOME::SALOME_Exception)
5047 SMESH::ElementType type = SMESH::ALL;
5051 _preMeshInfo->FullLoadFromFile();
5053 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
5054 if(!SM) return SMESH::ALL;
5056 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
5057 if(!SDSM) return SMESH::ALL;
5059 if(SDSM->NbElements()==0)
5060 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
5062 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5063 const SMDS_MeshElement* anElem = eIt->next();
5065 type = ( SMESH::ElementType ) anElem->GetType();
5067 SMESH_CATCH( SMESH::throwCorbaException );
5073 //=============================================================================
5075 * Return pointer to _impl as an integer value. Is called from constructor of SMESH_Client
5077 //=============================================================================
5079 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
5082 _preMeshInfo->FullLoadFromFile();
5084 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
5085 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
5090 //=============================================================================
5092 * Get XYZ coordinates of node as list of double
5093 * If there is not node for given ID - return empty list
5095 //=============================================================================
5097 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
5100 _preMeshInfo->FullLoadFromFile();
5102 SMESH::double_array_var aResult = new SMESH::double_array();
5103 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5104 if ( aMeshDS == NULL )
5105 return aResult._retn();
5108 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5110 return aResult._retn();
5114 aResult[0] = aNode->X();
5115 aResult[1] = aNode->Y();
5116 aResult[2] = aNode->Z();
5117 return aResult._retn();
5121 //=============================================================================
5123 * For given node return list of IDs of inverse elements
5124 * If there is not node for given ID - return empty list
5126 //=============================================================================
5128 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
5129 SMESH::ElementType elemType)
5132 _preMeshInfo->FullLoadFromFile();
5134 SMESH::long_array_var aResult = new SMESH::long_array();
5135 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5136 if ( aMeshDS == NULL )
5137 return aResult._retn();
5140 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
5142 return aResult._retn();
5144 // find inverse elements
5145 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
5146 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
5147 aResult->length( aNode->NbInverseElements( type ));
5148 for( int i = 0; eIt->more(); ++i )
5150 const SMDS_MeshElement* elem = eIt->next();
5151 aResult[ i ] = elem->GetID();
5153 return aResult._retn();
5156 //=============================================================================
5158 * \brief Return position of a node on shape
5160 //=============================================================================
5162 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
5165 _preMeshInfo->FullLoadFromFile();
5167 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
5168 aNodePosition->shapeID = 0;
5169 aNodePosition->shapeType = GEOM::SHAPE;
5171 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5172 if ( !mesh ) return aNodePosition;
5174 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
5176 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
5178 aNodePosition->shapeID = aNode->getshapeId();
5179 switch ( pos->GetTypeOfPosition() ) {
5181 aNodePosition->shapeType = GEOM::EDGE;
5182 aNodePosition->params.length(1);
5183 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
5185 case SMDS_TOP_FACE: {
5186 SMDS_FacePositionPtr fPos = pos;
5187 aNodePosition->shapeType = GEOM::FACE;
5188 aNodePosition->params.length(2);
5189 aNodePosition->params[0] = fPos->GetUParameter();
5190 aNodePosition->params[1] = fPos->GetVParameter();
5193 case SMDS_TOP_VERTEX:
5194 aNodePosition->shapeType = GEOM::VERTEX;
5196 case SMDS_TOP_3DSPACE:
5197 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
5198 aNodePosition->shapeType = GEOM::SOLID;
5199 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
5200 aNodePosition->shapeType = GEOM::SHELL;
5206 return aNodePosition;
5209 //=============================================================================
5211 * \brief Return position of an element on shape
5213 //=============================================================================
5215 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
5218 _preMeshInfo->FullLoadFromFile();
5220 SMESH::ElementPosition anElementPosition;
5221 anElementPosition.shapeID = 0;
5222 anElementPosition.shapeType = GEOM::SHAPE;
5224 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5225 if ( !mesh ) return anElementPosition;
5227 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5229 anElementPosition.shapeID = anElem->getshapeId();
5230 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5231 if ( !aSp.IsNull() ) {
5232 switch ( aSp.ShapeType() ) {
5234 anElementPosition.shapeType = GEOM::EDGE;
5237 anElementPosition.shapeType = GEOM::FACE;
5240 anElementPosition.shapeType = GEOM::VERTEX;
5243 anElementPosition.shapeType = GEOM::SOLID;
5246 anElementPosition.shapeType = GEOM::SHELL;
5252 return anElementPosition;
5255 //=============================================================================
5257 * If given element is node return IDs of shape from position
5258 * If there is not node for given ID - return -1
5260 //=============================================================================
5262 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5265 _preMeshInfo->FullLoadFromFile();
5267 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5268 if ( aMeshDS == NULL )
5272 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5274 return aNode->getshapeId();
5281 //=============================================================================
5283 * For given element return ID of result shape after
5284 * ::FindShape() from SMESH_MeshEditor
5285 * If there is not element for given ID - return -1
5287 //=============================================================================
5289 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5292 _preMeshInfo->FullLoadFromFile();
5294 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5295 if ( aMeshDS == NULL )
5298 // try to find element
5299 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5303 ::SMESH_MeshEditor aMeshEditor(_impl);
5304 int index = aMeshEditor.FindShape( elem );
5312 //=============================================================================
5314 * Return number of nodes for given element
5315 * If there is not element for given ID - return -1
5317 //=============================================================================
5319 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5322 _preMeshInfo->FullLoadFromFile();
5324 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5325 if ( aMeshDS == NULL ) return -1;
5326 // try to find element
5327 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5328 if(!elem) return -1;
5329 return elem->NbNodes();
5333 //=============================================================================
5335 * Return ID of node by given index for given element
5336 * If there is not element for given ID - return -1
5337 * If there is not node for given index - return -2
5339 //=============================================================================
5341 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5344 _preMeshInfo->FullLoadFromFile();
5346 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5347 if ( aMeshDS == NULL ) return -1;
5348 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5349 if(!elem) return -1;
5350 if( index>=elem->NbNodes() || index<0 ) return -1;
5351 return elem->GetNode(index)->GetID();
5354 //=============================================================================
5356 * Return IDs of nodes of given element
5358 //=============================================================================
5360 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5363 _preMeshInfo->FullLoadFromFile();
5365 SMESH::long_array_var aResult = new SMESH::long_array();
5366 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5368 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5370 aResult->length( elem->NbNodes() );
5371 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5372 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5373 aResult[ i ] = n->GetID();
5376 return aResult._retn();
5379 //=============================================================================
5381 * Return true if given node is medium node
5382 * in given quadratic element
5384 //=============================================================================
5386 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5389 _preMeshInfo->FullLoadFromFile();
5391 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5392 if ( aMeshDS == NULL ) return false;
5394 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5395 if(!aNode) return false;
5396 // try to find element
5397 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5398 if(!elem) return false;
5400 return elem->IsMediumNode(aNode);
5404 //=============================================================================
5406 * Return true if given node is medium node
5407 * in one of quadratic elements
5409 //=============================================================================
5411 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5412 SMESH::ElementType theElemType)
5415 _preMeshInfo->FullLoadFromFile();
5417 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5418 if ( aMeshDS == NULL ) return false;
5421 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5422 if(!aNode) return false;
5424 SMESH_MesherHelper aHelper( *(_impl) );
5426 SMDSAbs_ElementType aType;
5427 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5428 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5429 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5430 else aType = SMDSAbs_All;
5432 return aHelper.IsMedium(aNode,aType);
5436 //=============================================================================
5438 * Return number of edges for given element
5440 //=============================================================================
5442 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5445 _preMeshInfo->FullLoadFromFile();
5447 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5448 if ( aMeshDS == NULL ) return -1;
5449 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5450 if(!elem) return -1;
5451 return elem->NbEdges();
5455 //=============================================================================
5457 * Return number of faces for given element
5459 //=============================================================================
5461 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5464 _preMeshInfo->FullLoadFromFile();
5466 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5467 if ( aMeshDS == NULL ) return -1;
5468 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5469 if(!elem) return -1;
5470 return elem->NbFaces();
5473 //================================================================================
5475 * \brief Return nodes of given face (counted from zero) for given element.
5477 //================================================================================
5479 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5480 CORBA::Short faceIndex)
5483 _preMeshInfo->FullLoadFromFile();
5485 SMESH::long_array_var aResult = new SMESH::long_array();
5486 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5488 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5490 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5491 if ( faceIndex < vtool.NbFaces() )
5493 aResult->length( vtool.NbFaceNodes( faceIndex ));
5494 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5495 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5496 aResult[ i ] = nn[ i ]->GetID();
5500 return aResult._retn();
5503 //================================================================================
5505 * \brief Return three components of normal of given mesh face.
5507 //================================================================================
5509 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5510 CORBA::Boolean normalized)
5513 _preMeshInfo->FullLoadFromFile();
5515 SMESH::double_array_var aResult = new SMESH::double_array();
5517 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5520 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5522 aResult->length( 3 );
5523 aResult[ 0 ] = normal.X();
5524 aResult[ 1 ] = normal.Y();
5525 aResult[ 2 ] = normal.Z();
5528 return aResult._retn();
5531 //================================================================================
5533 * \brief Return an element based on all given nodes.
5535 //================================================================================
5537 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5540 _preMeshInfo->FullLoadFromFile();
5542 CORBA::Long elemID(0);
5543 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5545 vector< const SMDS_MeshNode * > nn( nodes.length() );
5546 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5547 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5550 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5551 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5552 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5553 _impl->NbVolumes( ORDER_QUADRATIC )))
5554 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5556 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5561 //================================================================================
5563 * \brief Return elements including all given nodes.
5565 //================================================================================
5567 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5568 SMESH::ElementType elemType)
5571 _preMeshInfo->FullLoadFromFile();
5573 SMESH::long_array_var result = new SMESH::long_array();
5575 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5577 vector< const SMDS_MeshNode * > nn( nodes.length() );
5578 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5579 nn[i] = mesh->FindNode( nodes[i] );
5581 std::vector<const SMDS_MeshElement *> elems;
5582 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5583 result->length( elems.size() );
5584 for ( size_t i = 0; i < elems.size(); ++i )
5585 result[i] = elems[i]->GetID();
5587 return result._retn();
5590 //=============================================================================
5592 * Return true if given element is polygon
5594 //=============================================================================
5596 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5599 _preMeshInfo->FullLoadFromFile();
5601 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5602 if ( aMeshDS == NULL ) return false;
5603 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5604 if(!elem) return false;
5605 return elem->IsPoly();
5609 //=============================================================================
5611 * Return true if given element is quadratic
5613 //=============================================================================
5615 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5618 _preMeshInfo->FullLoadFromFile();
5620 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5621 if ( aMeshDS == NULL ) return false;
5622 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5623 if(!elem) return false;
5624 return elem->IsQuadratic();
5627 //=============================================================================
5629 * Return diameter of ball discrete element or zero in case of an invalid \a id
5631 //=============================================================================
5633 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5636 _preMeshInfo->FullLoadFromFile();
5638 if ( const SMDS_BallElement* ball =
5639 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5640 return ball->GetDiameter();
5645 //=============================================================================
5647 * Return bary center for given element
5649 //=============================================================================
5651 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5654 _preMeshInfo->FullLoadFromFile();
5656 SMESH::double_array_var aResult = new SMESH::double_array();
5657 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5658 if ( aMeshDS == NULL )
5659 return aResult._retn();
5661 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5663 return aResult._retn();
5665 if(elem->GetType()==SMDSAbs_Volume) {
5666 SMDS_VolumeTool aTool;
5667 if(aTool.Set(elem)) {
5669 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5674 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5676 double x=0., y=0., z=0.;
5677 for(; anIt->more(); ) {
5679 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5693 return aResult._retn();
5696 //================================================================================
5698 * \brief Create a group of elements preventing computation of a sub-shape
5700 //================================================================================
5702 SMESH::ListOfGroups*
5703 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5704 const char* theGroupName )
5705 throw ( SALOME::SALOME_Exception )
5707 Unexpect aCatch(SALOME_SalomeException);
5709 if ( !theGroupName || strlen( theGroupName) == 0 )
5710 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5712 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5713 ::SMESH_MeshEditor::ElemFeatures elemType;
5715 // submesh by subshape id
5716 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5717 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5720 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5721 if ( error && error->HasBadElems() )
5723 // sort bad elements by type
5724 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5725 const list<const SMDS_MeshElement*>& badElems =
5726 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5727 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5728 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5729 for ( ; elemIt != elemEnd; ++elemIt )
5731 const SMDS_MeshElement* elem = *elemIt;
5732 if ( !elem ) continue;
5734 if ( elem->GetID() < 1 )
5736 // elem is a temporary element, make a real element
5737 vector< const SMDS_MeshNode* > nodes;
5738 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5739 while ( nIt->more() && elem )
5741 nodes.push_back( nIt->next() );
5742 if ( nodes.back()->GetID() < 1 )
5743 elem = 0; // a temporary element on temporary nodes
5747 ::SMESH_MeshEditor editor( _impl );
5748 elem = editor.AddElement( nodes, elemType.Init( elem ));
5752 elemsByType[ elem->GetType() ].push_back( elem );
5755 // how many groups to create?
5757 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5758 nbTypes += int( !elemsByType[ i ].empty() );
5759 groups->length( nbTypes );
5762 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5764 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5765 if ( elems.empty() ) continue;
5767 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5768 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5770 SMESH::SMESH_Mesh_var mesh = _this();
5771 SALOMEDS::SObject_wrap aSO =
5772 _gen_i->PublishGroup( mesh, groups[ iG ],
5773 GEOM::GEOM_Object::_nil(), theGroupName);
5775 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5776 if ( !grp_i ) continue;
5778 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5779 for ( size_t iE = 0; iE < elems.size(); ++iE )
5780 grpDS->SMDSGroup().Add( elems[ iE ]);
5785 return groups._retn();
5788 //=============================================================================
5790 * Create and publish group servants if any groups were imported or created anyhow
5792 //=============================================================================
5794 void SMESH_Mesh_i::CreateGroupServants()
5796 SMESH::SMESH_Mesh_var aMesh = _this();
5799 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5800 while ( groupIt->more() )
5802 ::SMESH_Group* group = groupIt->next();
5803 int anId = group->GetID();
5805 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5806 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5808 addedIDs.insert( anId );
5810 SMESH_GroupBase_i* aGroupImpl;
5812 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5813 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5815 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5816 shape = groupOnGeom->GetShape();
5819 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5822 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5823 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5824 aGroupImpl->Register();
5826 // register CORBA object for persistence
5827 int nextId = _gen_i->RegisterObject( groupVar );
5828 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5829 else { nextId = 0; } // avoid "unused variable" warning in release mode
5831 // publishing the groups in the study
5832 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5833 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5836 if ( !addedIDs.empty() )
5839 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
5840 for ( int index = 0; i_grp != _mapGroups.end(); ++index, ++i_grp )
5842 set<int>::iterator it = addedIDs.find( i_grp->first );
5843 if ( it != addedIDs.end() )
5845 TPythonDump() << i_grp->second << " = " << aMesh << ".GetGroups()[ "<< index << " ]";
5846 addedIDs.erase( it );
5847 if ( addedIDs.empty() )
5854 //=============================================================================
5856 * \brief Return true if all sub-meshes are computed OK - to update an icon
5858 //=============================================================================
5860 bool SMESH_Mesh_i::IsComputedOK()
5862 return _impl->IsComputedOK();
5865 //=============================================================================
5867 * \brief Return groups cantained in _mapGroups by their IDs
5869 //=============================================================================
5871 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5873 int nbGroups = groupIDs.size();
5874 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5875 aList->length( nbGroups );
5877 list<int>::const_iterator ids = groupIDs.begin();
5878 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5880 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5881 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5882 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5884 aList->length( nbGroups );
5885 return aList._retn();
5888 //=============================================================================
5890 * \brief Return information about imported file
5892 //=============================================================================
5894 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5896 SMESH::MedFileInfo_var res( _medFileInfo );
5897 if ( !res.operator->() ) {
5898 res = new SMESH::MedFileInfo;
5900 res->fileSize = res->major = res->minor = res->release = -1;
5905 //=======================================================================
5906 //function : FileInfoToString
5907 //purpose : Persistence of file info
5908 //=======================================================================
5910 std::string SMESH_Mesh_i::FileInfoToString()
5913 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5915 s = SMESH_Comment( _medFileInfo->fileSize )
5916 << " " << _medFileInfo->major
5917 << " " << _medFileInfo->minor
5918 << " " << _medFileInfo->release
5919 << " " << _medFileInfo->fileName;
5924 //=======================================================================
5925 //function : FileInfoFromString
5926 //purpose : Persistence of file info
5927 //=======================================================================
5929 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5931 std::string size, major, minor, release, fileName;
5932 std::istringstream is(info);
5933 is >> size >> major >> minor >> release;
5934 fileName = info.data() + ( size.size() + 1 +
5937 release.size()+ 1 );
5939 _medFileInfo = new SMESH::MedFileInfo();
5940 _medFileInfo->fileName = fileName.c_str();
5941 _medFileInfo->fileSize = atoi( size.c_str() );
5942 _medFileInfo->major = atoi( major.c_str() );
5943 _medFileInfo->minor = atoi( minor.c_str() );
5944 _medFileInfo->release = atoi( release.c_str() );
5947 //=============================================================================
5949 * \brief Pass names of mesh groups from study to mesh DS
5951 //=============================================================================
5953 void SMESH_Mesh_i::checkGroupNames()
5955 int nbGrp = NbGroups();
5959 SMESH::ListOfGroups* grpList = 0;
5960 // avoid dump of "GetGroups"
5962 // store python dump into a local variable inside local scope
5963 SMESH::TPythonDump pDump; // do not delete this line of code
5964 grpList = GetGroups();
5967 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5968 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5971 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5972 if ( aGrpSO->_is_nil() )
5974 // correct name of the mesh group if necessary
5975 const char* guiName = aGrpSO->GetName();
5976 if ( strcmp(guiName, aGrp->GetName()) )
5977 aGrp->SetName( guiName );
5981 //=============================================================================
5983 * \brief Set list of notebook variables used for Mesh operations separated by ":" symbol
5985 //=============================================================================
5986 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5988 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5992 //=============================================================================
5994 * \brief Return list of notebook variables used for Mesh operations separated by ":" symbol
5996 //=============================================================================
5998 char* SMESH_Mesh_i::GetParameters()
6000 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
6003 //=============================================================================
6005 * \brief Return list of notebook variables used for last Mesh operation
6007 //=============================================================================
6008 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
6010 SMESH::string_array_var aResult = new SMESH::string_array();
6011 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
6013 CORBA::String_var aParameters = GetParameters();
6014 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
6015 if ( aSections->length() > 0 ) {
6016 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
6017 aResult->length( aVars.length() );
6018 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
6019 aResult[i] = CORBA::string_dup( aVars[i] );
6022 return aResult._retn();
6025 //================================================================================
6027 * \brief Return types of elements it contains
6029 //================================================================================
6031 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
6034 return _preMeshInfo->GetTypes();
6036 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
6040 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
6041 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
6042 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
6043 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
6044 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
6045 if (_impl->NbNodes() &&
6046 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
6047 types->length( nbTypes );
6049 return types._retn();
6052 //================================================================================
6054 * \brief Return self
6056 //================================================================================
6058 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
6060 return SMESH::SMESH_Mesh::_duplicate( _this() );
6063 //================================================================================
6065 * \brief Return false if GetMeshInfo() return incorrect information that may
6066 * happen if mesh data is not yet fully loaded from the file of study.
6070 //================================================================================
6072 bool SMESH_Mesh_i::IsMeshInfoCorrect()
6074 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
6077 //=============================================================================
6079 * \brief Return number of mesh elements per each \a EntityType
6081 //=============================================================================
6083 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
6086 return _preMeshInfo->GetMeshInfo();
6088 SMESH::long_array_var aRes = new SMESH::long_array();
6089 aRes->length(SMESH::Entity_Last);
6090 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6092 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6094 return aRes._retn();
6095 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
6096 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6097 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
6098 return aRes._retn();
6101 //=============================================================================
6103 * \brief Return number of mesh elements per each \a ElementType
6105 //=============================================================================
6107 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
6109 SMESH::long_array_var aRes = new SMESH::long_array();
6110 aRes->length(SMESH::NB_ELEMENT_TYPES);
6111 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6114 const SMDS_MeshInfo* meshInfo = 0;
6116 meshInfo = _preMeshInfo;
6117 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
6118 meshInfo = & meshDS->GetMeshInfo();
6121 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6122 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
6124 return aRes._retn();
6127 //=============================================================================
6129 * Collect statistic of mesh elements given by iterator
6131 //=============================================================================
6133 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
6134 SMESH::long_array& theInfo)
6136 if (!theItr) return;
6137 while (theItr->more())
6138 theInfo[ theItr->next()->GetEntityType() ]++;
6140 //=============================================================================
6142 * Return mesh unstructed grid information.
6144 //=============================================================================
6146 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
6148 SALOMEDS::TMPFile_var SeqFile;
6149 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
6150 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
6152 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
6153 aWriter->WriteToOutputStringOn();
6154 aWriter->SetInputData(aGrid);
6155 aWriter->SetFileTypeToBinary();
6157 char* str = aWriter->GetOutputString();
6158 int size = aWriter->GetOutputStringLength();
6160 //Allocate octet buffer of required size
6161 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
6162 //Copy ostrstream content to the octet buffer
6163 memcpy(OctetBuf, str, size);
6164 //Create and return TMPFile
6165 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
6169 return SeqFile._retn();
6172 //=============================================================================
6173 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
6174 * SMESH::ElementType type) */
6176 using namespace SMESH::Controls;
6177 //-----------------------------------------------------------------------------
6178 struct PredicateIterator : public SMDS_ElemIterator
6180 SMDS_ElemIteratorPtr _elemIter;
6181 PredicatePtr _predicate;
6182 const SMDS_MeshElement* _elem;
6183 SMDSAbs_ElementType _type;
6185 PredicateIterator( SMDS_ElemIteratorPtr iterator,
6186 PredicatePtr predicate,
6187 SMDSAbs_ElementType type):
6188 _elemIter(iterator), _predicate(predicate), _type(type)
6196 virtual const SMDS_MeshElement* next()
6198 const SMDS_MeshElement* res = _elem;
6200 while ( _elemIter->more() && !_elem )
6202 if ((_elem = _elemIter->next()) &&
6203 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
6204 ( !_predicate->IsSatisfy( _elem->GetID() ))))
6211 //-----------------------------------------------------------------------------
6212 struct IDSourceIterator : public SMDS_ElemIterator
6214 const CORBA::Long* _idPtr;
6215 const CORBA::Long* _idEndPtr;
6216 SMESH::long_array_var _idArray;
6217 const SMDS_Mesh* _mesh;
6218 const SMDSAbs_ElementType _type;
6219 const SMDS_MeshElement* _elem;
6221 IDSourceIterator( const SMDS_Mesh* mesh,
6222 const CORBA::Long* ids,
6224 SMDSAbs_ElementType type):
6225 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
6227 if ( _idPtr && nbIds && _mesh )
6230 IDSourceIterator( const SMDS_Mesh* mesh,
6231 SMESH::long_array* idArray,
6232 SMDSAbs_ElementType type):
6233 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
6235 if ( idArray && _mesh )
6237 _idPtr = &_idArray[0];
6238 _idEndPtr = _idPtr + _idArray->length();
6246 virtual const SMDS_MeshElement* next()
6248 const SMDS_MeshElement* res = _elem;
6250 while ( _idPtr < _idEndPtr && !_elem )
6252 if ( _type == SMDSAbs_Node )
6254 _elem = _mesh->FindNode( *_idPtr++ );
6256 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6257 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6265 //-----------------------------------------------------------------------------
6267 struct NodeOfElemIterator : public SMDS_ElemIterator
6269 TColStd_MapOfInteger _checkedNodeIDs;
6270 SMDS_ElemIteratorPtr _elemIter;
6271 SMDS_ElemIteratorPtr _nodeIter;
6272 const SMDS_MeshElement* _node;
6274 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6276 if ( _elemIter && _elemIter->more() )
6278 _nodeIter = _elemIter->next()->nodesIterator();
6286 virtual const SMDS_MeshElement* next()
6288 const SMDS_MeshElement* res = _node;
6290 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6292 if ( _nodeIter->more() )
6294 _node = _nodeIter->next();
6295 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6300 _nodeIter = _elemIter->next()->nodesIterator();
6308 //=============================================================================
6310 * Return iterator on elements of given type in given object
6312 //=============================================================================
6314 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6315 SMESH::ElementType theType)
6317 SMDS_ElemIteratorPtr elemIt;
6318 bool typeOK = ( theType == SMESH::ALL );
6319 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6321 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6322 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6323 if ( !mesh_i ) return elemIt;
6324 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6326 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6328 elemIt = meshDS->elementsIterator( elemType );
6331 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6333 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6336 elemIt = sm->GetElements();
6337 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6339 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6340 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6344 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6346 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6347 if ( groupDS && ( elemType == groupDS->GetType() ||
6348 elemType == SMDSAbs_Node ||
6349 elemType == SMDSAbs_All ))
6351 elemIt = groupDS->GetElements();
6352 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6355 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6357 if ( filter_i->GetElementType() == theType ||
6358 filter_i->GetElementType() == SMESH::ALL ||
6359 elemType == SMDSAbs_Node ||
6360 elemType == SMDSAbs_All)
6362 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6363 if ( pred_i && pred_i->GetPredicate() )
6365 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6366 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6367 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6368 elemIt = SMDS_ElemIteratorPtr
6369 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6370 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6376 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6377 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6378 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6380 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6381 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6384 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6385 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6389 SMESH::long_array_var ids = theObject->GetIDs();
6390 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6392 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6395 if ( elemIt && elemIt->more() && !typeOK )
6397 if ( elemType == SMDSAbs_Node )
6399 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6403 elemIt = SMDS_ElemIteratorPtr();
6409 //=============================================================================
6410 namespace // Finding concurrent hypotheses
6411 //=============================================================================
6415 * \brief mapping of mesh dimension into shape type
6417 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6419 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6421 case 0: aType = TopAbs_VERTEX; break;
6422 case 1: aType = TopAbs_EDGE; break;
6423 case 2: aType = TopAbs_FACE; break;
6425 default:aType = TopAbs_SOLID; break;
6430 //-----------------------------------------------------------------------------
6432 * \brief Internal structure used to find concurrent submeshes
6434 * It represents a pair < submesh, concurrent dimension >, where
6435 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6436 * with another submesh. In other words, it is dimension of a hypothesis assigned
6443 int _dim; //!< a dimension the algo can build (concurrent dimension)
6444 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6445 TopTools_MapOfShape _shapeMap; //!< [sub-]shapes of dimension == _dim
6446 const SMESH_subMesh* _subMesh;
6447 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6449 //-----------------------------------------------------------------------------
6450 // Return the algorithm
6451 const SMESH_Algo* GetAlgo() const
6452 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6454 //-----------------------------------------------------------------------------
6456 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6458 const TopoDS_Shape& theShape)
6460 _subMesh = theSubMesh;
6461 SetShape( theDim, theShape );
6464 //-----------------------------------------------------------------------------
6466 void SetShape(const int theDim,
6467 const TopoDS_Shape& theShape)
6470 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6471 if (_dim >= _ownDim)
6472 _shapeMap.Add( theShape );
6474 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6475 for( ; anExp.More(); anExp.Next() )
6476 _shapeMap.Add( anExp.Current() );
6480 //-----------------------------------------------------------------------------
6481 //! Check sharing of sub-shapes
6482 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6483 const TopTools_MapOfShape& theToFind,
6484 const TopAbs_ShapeEnum theType)
6486 bool isShared = false;
6487 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6488 for (; !isShared && anItr.More(); anItr.Next() )
6490 const TopoDS_Shape aSubSh = anItr.Key();
6491 // check for case when concurrent dimensions are same
6492 isShared = theToFind.Contains( aSubSh );
6493 // check for sub-shape with concurrent dimension
6494 TopExp_Explorer anExp( aSubSh, theType );
6495 for ( ; !isShared && anExp.More(); anExp.Next() )
6496 isShared = theToFind.Contains( anExp.Current() );
6501 //-----------------------------------------------------------------------------
6502 //! check algorithms
6503 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6504 const SMESHDS_Hypothesis* theA2)
6506 if ( !theA1 || !theA2 ||
6507 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6508 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6509 return false; // one of the hypothesis is not algorithm
6510 // check algorithm names (should be equal)
6511 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6515 //-----------------------------------------------------------------------------
6516 //! Check if sub-shape hypotheses are concurrent
6517 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6519 if ( _subMesh == theOther->_subMesh )
6520 return false; // same sub-shape - should not be
6522 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6523 // any of the two submeshes is not on COMPOUND shape )
6524 // -> no concurrency
6525 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6526 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6527 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6528 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6529 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6532 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6533 if ( !checkSubShape )
6536 // check algorithms to be same
6537 const SMESH_Algo* a1 = this->GetAlgo();
6538 const SMESH_Algo* a2 = theOther->GetAlgo();
6539 bool isSame = checkAlgo( a1, a2 );
6543 // commented off for IPAL54678
6544 // if ( !a1 || !a2 )
6545 // return false; // pb?
6546 // return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6549 // check hypothesises for concurrence (skip first as algorithm)
6551 // pointers should be same, because it is referened from mesh hypothesis partition
6552 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6553 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6554 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6555 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6557 // the submeshes are concurrent if their algorithms has different parameters
6558 return nbSame != theOther->_hypotheses.size() - 1;
6561 // Return true if algorithm of this SMESH_DimHyp is used if no
6562 // sub-mesh order is imposed by the user
6563 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6565 // NeedDiscreteBoundary() algo has a higher priority
6566 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6567 theOther->GetAlgo()->NeedDiscreteBoundary() )
6568 return !this->GetAlgo()->NeedDiscreteBoundary();
6570 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6573 }; // end of SMESH_DimHyp
6574 //-----------------------------------------------------------------------------
6576 typedef list<const SMESH_DimHyp*> TDimHypList;
6578 //-----------------------------------------------------------------------------
6580 void addDimHypInstance(const int theDim,
6581 const TopoDS_Shape& theShape,
6582 const SMESH_Algo* theAlgo,
6583 const SMESH_subMesh* theSubMesh,
6584 const list <const SMESHDS_Hypothesis*>& theHypList,
6585 TDimHypList* theDimHypListArr )
6587 if ( !theAlgo->NeedDiscreteBoundary() &&
6588 theAlgo->NeedLowerHyps( theDim )) // IPAL54678
6590 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6591 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh )
6593 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6594 dimHyp->_hypotheses.push_front(theAlgo);
6595 listOfdimHyp.push_back( dimHyp );
6598 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6599 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6600 theHypList.begin(), theHypList.end() );
6603 //-----------------------------------------------------------------------------
6604 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6605 TDimHypList& theListOfConcurr)
6607 if ( theListOfConcurr.empty() )
6609 theListOfConcurr.push_back( theDimHyp );
6613 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6614 while ( hypIt != theListOfConcurr.end() &&
6615 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6617 theListOfConcurr.insert( hypIt, theDimHyp );
6621 //-----------------------------------------------------------------------------
6622 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6623 const TDimHypList& theListOfDimHyp,
6624 TDimHypList& theListOfConcurrHyp,
6625 set<int>& theSetOfConcurrId )
6627 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6628 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6630 const SMESH_DimHyp* curDimHyp = *rIt;
6631 if ( curDimHyp == theDimHyp )
6632 break; // meet own dimHyp pointer in same dimension
6634 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6635 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6637 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6642 //-----------------------------------------------------------------------------
6643 void unionLists(TListOfInt& theListOfId,
6644 TListOfListOfInt& theListOfListOfId,
6647 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6648 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ )
6651 continue; //skip already treated lists
6652 // check if other list has any same submesh object
6653 TListOfInt& otherListOfId = *it;
6654 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6655 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6658 // union two lists (from source into target)
6659 TListOfInt::iterator it2 = otherListOfId.begin();
6660 for ( ; it2 != otherListOfId.end(); it2++ ) {
6661 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6662 theListOfId.push_back(*it2);
6664 // clear source list
6665 otherListOfId.clear();
6668 //-----------------------------------------------------------------------------
6670 //! free memory allocated for dimension-hypothesis objects
6671 void removeDimHyps( TDimHypList* theArrOfList )
6673 for (int i = 0; i < 4; i++ ) {
6674 TDimHypList& listOfdimHyp = theArrOfList[i];
6675 TDimHypList::const_iterator it = listOfdimHyp.begin();
6676 for ( ; it != listOfdimHyp.end(); it++ )
6681 //-----------------------------------------------------------------------------
6683 * \brief find common submeshes with given submesh
6684 * \param theSubMeshList list of already collected submesh to check
6685 * \param theSubMesh given submesh to intersect with other
6686 * \param theCommonSubMeshes collected common submeshes
6688 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6689 const SMESH_subMesh* theSubMesh,
6690 set<const SMESH_subMesh*>& theCommon )
6694 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6695 for ( ; it != theSubMeshList.end(); it++ )
6696 theSubMesh->FindIntersection( *it, theCommon );
6697 theSubMeshList.push_back( theSubMesh );
6698 //theCommon.insert( theSubMesh );
6701 //-----------------------------------------------------------------------------
6702 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6704 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6705 for ( ; listsIt != smLists.end(); ++listsIt )
6707 const TListOfInt& smIDs = *listsIt;
6708 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6716 //=============================================================================
6718 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6720 //=============================================================================
6722 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6724 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6725 if ( isSubMeshInList( submeshID, anOrder ))
6728 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6729 return isSubMeshInList( submeshID, allConurrent );
6732 //=============================================================================
6734 * \brief Return sub-mesh objects list in meshing order
6736 //=============================================================================
6738 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6740 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6742 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6744 return aResult._retn();
6746 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6747 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6748 anOrder.splice( anOrder.end(), allConurrent );
6751 TListOfListOfInt::iterator listIt = anOrder.begin();
6752 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6753 unionLists( *listIt, anOrder, listIndx + 1 );
6755 // convert submesh ids into interface instances
6756 // and dump command into python
6757 convertMeshOrder( anOrder, aResult, false );
6759 return aResult._retn();
6762 //=============================================================================
6764 * \brief Finds concurrent sub-meshes
6766 //=============================================================================
6768 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6770 TListOfListOfInt anOrder;
6771 ::SMESH_Mesh& mesh = GetImpl();
6773 // collect submeshes and detect concurrent algorithms and hypothesises
6774 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6776 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6777 for ( ; i_sm != _mapSubMesh.end(); i_sm++ )
6779 ::SMESH_subMesh* sm = (*i_sm).second;
6781 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6783 // list of assigned hypothesises
6784 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6785 // Find out dimensions where the submesh can be concurrent.
6786 // We define the dimensions by algo of each of hypotheses in hypList
6787 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6788 for( ; hypIt != hypList.end(); hypIt++ )
6790 SMESH_Algo* anAlgo = 0;
6791 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6792 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6793 // hyp it-self is algo
6794 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6796 // try to find algorithm with help of sub-shapes
6797 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6798 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6799 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6802 continue; // no algorithm assigned to a current submesh
6804 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6805 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary()
6806 // and !anAlgo->NeedLowerHyps( dim ))
6808 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6809 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6810 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6812 } // end iterations on submesh
6814 // iterate on created dimension-hypotheses and check for concurrents
6815 for ( int i = 0; i < 4; i++ )
6817 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6818 // check for concurrents in own and other dimensions (step-by-step)
6819 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6820 for ( ; dhIt != listOfDimHyp.end(); dhIt++ )
6822 const SMESH_DimHyp* dimHyp = *dhIt;
6823 TDimHypList listOfConcurr;
6824 set<int> setOfConcurrIds;
6825 // looking for concurrents and collect into own list
6826 for ( int j = i; j < 4; j++ )
6827 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6828 // check if any concurrents found
6829 if ( listOfConcurr.size() > 0 )
6831 // add own submesh to list of concurrent
6832 addInOrderOfPriority( dimHyp, listOfConcurr );
6833 list<int> listOfConcurrIds;
6834 TDimHypList::iterator hypIt = listOfConcurr.begin();
6835 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6836 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6837 anOrder.push_back( listOfConcurrIds );
6842 removeDimHyps(dimHypListArr);
6844 // now, minimize the number of concurrent groups
6845 // Here we assume that lists of submeshes can have same submesh
6846 // in case of multi-dimension algorithms, as result
6847 // list with common submesh has to be united into one list
6849 TListOfListOfInt::iterator listIt = anOrder.begin();
6850 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6851 unionLists( *listIt, anOrder, listIndx + 1 );
6856 //=============================================================================
6858 * \brief Set submesh object order
6859 * \param theSubMeshArray submesh array order
6861 //=============================================================================
6863 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6866 _preMeshInfo->ForgetOrLoad();
6869 ::SMESH_Mesh& mesh = GetImpl();
6871 TPythonDump aPythonDump; // prevent dump of called methods
6872 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6874 TListOfListOfInt subMeshOrder;
6875 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6877 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6878 TListOfInt subMeshIds;
6880 aPythonDump << ", ";
6881 aPythonDump << "[ ";
6882 // Collect subMeshes which should be clear
6883 // do it list-by-list, because modification of submesh order
6884 // take effect between concurrent submeshes only
6885 set<const SMESH_subMesh*> subMeshToClear;
6886 list<const SMESH_subMesh*> subMeshList;
6887 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6889 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6891 aPythonDump << ", ";
6892 aPythonDump << subMesh;
6893 subMeshIds.push_back( subMesh->GetId() );
6894 // detect common parts of submeshes
6895 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6896 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6898 aPythonDump << " ]";
6899 subMeshOrder.push_back( subMeshIds );
6901 // clear collected sub-meshes
6902 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6903 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6904 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6906 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6907 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6908 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6911 aPythonDump << " ])";
6913 mesh.SetMeshOrder( subMeshOrder );
6916 SMESH::SMESH_Mesh_var me = _this();
6917 _gen_i->UpdateIcons( me );
6922 //=============================================================================
6924 * \brief Convert submesh ids into submesh interfaces
6926 //=============================================================================
6928 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6929 SMESH::submesh_array_array& theResOrder,
6930 const bool theIsDump)
6932 int nbSet = theIdsOrder.size();
6933 TPythonDump aPythonDump; // prevent dump of called methods
6935 aPythonDump << "[ ";
6936 theResOrder.length(nbSet);
6937 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6939 for( ; it != theIdsOrder.end(); it++ )
6941 // translate submesh identificators into submesh objects
6942 // takeing into account real number of concurrent lists
6943 const TListOfInt& aSubOrder = (*it);
6944 if (!aSubOrder.size())
6947 aPythonDump << "[ ";
6948 // convert shape indices into interfaces
6949 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6950 aResSubSet->length(aSubOrder.size());
6951 TListOfInt::const_iterator subIt = aSubOrder.begin();
6953 for( j = 0; subIt != aSubOrder.end(); subIt++ )
6955 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6957 SMESH::SMESH_subMesh_var subMesh =
6958 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6961 aPythonDump << ", ";
6962 aPythonDump << subMesh;
6964 aResSubSet[ j++ ] = subMesh;
6967 aPythonDump << " ]";
6969 theResOrder[ listIndx++ ] = aResSubSet;
6971 // correct number of lists
6972 theResOrder.length( listIndx );
6975 // finilise python dump
6976 aPythonDump << " ]";
6977 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6981 namespace // utils used by SMESH_MeshPartDS
6984 * \brief Class used to access to protected data of SMDS_MeshInfo
6986 struct TMeshInfo : public SMDS_MeshInfo
6988 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6991 * \brief Element holing its ID only
6993 struct TElemID : public SMDS_LinearEdge
6995 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6999 //================================================================================
7001 // Implementation of SMESH_MeshPartDS
7003 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
7004 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
7006 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
7007 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
7010 _meshDS = mesh_i->GetImpl().GetMeshDS();
7012 SetPersistentId( _meshDS->GetPersistentId() );
7014 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
7016 // <meshPart> is the whole mesh
7017 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
7019 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
7020 myGroupSet = _meshDS->GetGroups();
7025 SMESH::long_array_var anIDs = meshPart->GetIDs();
7026 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
7027 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
7029 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
7030 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
7031 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7036 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
7037 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
7038 if ( _elements[ e->GetType() ].insert( e ).second )
7041 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
7042 while ( nIt->more() )
7044 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
7045 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7052 ShapeToMesh( _meshDS->ShapeToMesh() );
7054 _meshDS = 0; // to enforce iteration on _elements and _nodes
7057 // -------------------------------------------------------------------------------------
7058 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
7059 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
7062 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
7063 for ( ; partIt != meshPart.end(); ++partIt )
7064 if ( const SMDS_MeshElement * e = *partIt )
7065 if ( _elements[ e->GetType() ].insert( e ).second )
7068 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
7069 while ( nIt->more() )
7071 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
7072 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7078 // -------------------------------------------------------------------------------------
7079 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
7081 if ( _meshDS ) return _meshDS->FindElement( IDelem );
7083 TElemID elem( IDelem );
7084 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7085 if ( !_elements[ iType ].empty() )
7087 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
7088 if ( it != _elements[ iType ].end() )
7093 // -------------------------------------------------------------------------------------
7094 bool SMESH_MeshPartDS::HasNumerationHoles()
7096 if ( _meshDS ) return _meshDS->HasNumerationHoles();
7098 return ( MinNodeID() != 1 ||
7099 MaxNodeID() != NbNodes() ||
7100 MinElementID() != 1 ||
7101 MaxElementID() != NbElements() );
7103 // -------------------------------------------------------------------------------------
7104 int SMESH_MeshPartDS::MaxNodeID() const
7106 if ( _meshDS ) return _meshDS->MaxNodeID();
7107 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
7109 // -------------------------------------------------------------------------------------
7110 int SMESH_MeshPartDS::MinNodeID() const
7112 if ( _meshDS ) return _meshDS->MinNodeID();
7113 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
7115 // -------------------------------------------------------------------------------------
7116 int SMESH_MeshPartDS::MaxElementID() const
7118 if ( _meshDS ) return _meshDS->MaxElementID();
7120 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7121 if ( !_elements[ iType ].empty() )
7122 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
7125 // -------------------------------------------------------------------------------------
7126 int SMESH_MeshPartDS::MinElementID() const
7128 if ( _meshDS ) return _meshDS->MinElementID();
7130 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7131 if ( !_elements[ iType ].empty() )
7132 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
7135 // -------------------------------------------------------------------------------------
7136 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
7138 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
7140 typedef SMDS_SetIterator
7141 <const SMDS_MeshElement*,
7142 TIDSortedElemSet::const_iterator,
7143 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7144 SMDS_MeshElement::GeomFilter
7147 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
7149 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7150 _elements[type].end(),
7151 SMDS_MeshElement::GeomFilter( geomType )));
7153 // -------------------------------------------------------------------------------------
7154 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
7156 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
7158 typedef SMDS_SetIterator
7159 <const SMDS_MeshElement*,
7160 TIDSortedElemSet::const_iterator,
7161 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7162 SMDS_MeshElement::EntityFilter
7165 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
7167 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7168 _elements[type].end(),
7169 SMDS_MeshElement::EntityFilter( entity )));
7171 // -------------------------------------------------------------------------------------
7172 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
7174 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
7175 if ( type == SMDSAbs_All && !_meshDS )
7177 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
7179 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
7180 if ( !_elements[i].empty() && i != SMDSAbs_Node )
7182 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
7184 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
7185 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
7187 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
7188 ( new TIter( _elements[type].begin(), _elements[type].end() ));
7190 // -------------------------------------------------------------------------------------
7191 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
7192 iterType SMESH_MeshPartDS::methName() const \
7194 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
7195 return _meshDS ? _meshDS->methName() : iterType \
7196 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
7198 // -------------------------------------------------------------------------------------
7199 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
7200 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
7201 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
7202 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
7203 #undef _GET_ITER_DEFINE
7205 // END Implementation of SMESH_MeshPartDS
7207 //================================================================================