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 * Associates <this> mesh with <theShape> and puts 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 //=======================================================================
223 //function : GetShapeToMesh
225 //=======================================================================
227 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
228 throw (SALOME::SALOME_Exception)
230 Unexpect aCatch(SALOME_SalomeException);
231 GEOM::GEOM_Object_var aShapeObj;
233 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
236 aShapeObj = _gen_i->ShapeToGeomObject( S );
237 if ( aShapeObj->_is_nil() )
239 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
240 // find GEOM_Object by entry (IPAL52735)
241 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
242 for ( ; data != _geomGroupData.end(); ++data )
243 if ( data->_smeshObject->_is_equivalent( _this() ))
245 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
246 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
247 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
253 catch(SALOME_Exception & S_ex) {
254 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
256 return aShapeObj._retn();
259 //================================================================================
261 * \brief Replace a shape in the mesh
263 //================================================================================
265 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
266 throw (SALOME::SALOME_Exception)
268 // check if geometry changed
269 bool geomChanged = true;
270 GEOM::GEOM_Object_var oldGeom = GetShapeToMesh();
271 if ( !theNewGeom->_is_nil() && !oldGeom->_is_nil() )
272 geomChanged = ( //oldGeom->_is_equivalent( theNewGeom ) ||
273 oldGeom->GetTick() < theNewGeom->GetTick() );
275 TopoDS_Shape S = _impl->GetShapeToMesh();
276 GEOM_Client* geomClient = _gen_i->GetShapeReader();
277 TCollection_AsciiString aIOR;
278 CORBA::String_var ior;
279 if ( geomClient->Find( S, aIOR ))
280 geomClient->RemoveShapeFromBuffer( aIOR );
282 // clear buffer also for sub-groups
283 const std::set<SMESHDS_GroupBase*>& groups = _impl->GetMeshDS()->GetGroups();
284 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
285 for (; g != groups.end(); ++g)
286 if (const SMESHDS_GroupOnGeom* group = dynamic_cast<SMESHDS_GroupOnGeom*>(*g))
288 const TopoDS_Shape& s = group->GetShape();
289 if ( geomClient->Find( s, aIOR ))
290 geomClient->RemoveShapeFromBuffer( aIOR );
294 int shapeID, fromID, toID; // indices of elements of a sub-mesh
296 std::vector< TRange > elemRanges, nodeRanges; // elements of sub-meshes
297 std::vector< SMDS_PositionPtr > positions; // node positions
298 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
301 // store positions of elements on geometry
303 if ( meshDS->MaxNodeID() > meshDS->NbNodes() ||
304 meshDS->MaxElementID() > meshDS->NbElements() )
307 meshDS->CompactMesh();
309 positions.resize( meshDS->NbNodes() + 1 );
310 for ( SMDS_NodeIteratorPtr nodeIt = meshDS->nodesIterator(); nodeIt->more(); )
312 const SMDS_MeshNode* n = nodeIt->next();
313 positions[ n->GetID() ] = n->GetPosition();
316 // remove elements from sub-meshes to avoid their removal at hypotheses addition
317 for ( int isNode = 0; isNode < 2; ++isNode )
319 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
320 ranges.reserve( meshDS->MaxShapeIndex() + 10 );
321 ranges.push_back( TRange{ 0,0,0 });
322 SMDS_ElemIteratorPtr elemIt = meshDS->elementsIterator( isNode ? SMDSAbs_Node : SMDSAbs_All );
323 while ( elemIt->more() )
325 const SMDS_MeshElement* e = elemIt->next();
326 const int elemID = e->GetID();
327 const int shapeID = e->GetShapeID();
328 TRange & lastRange = ranges.back();
329 if ( lastRange.shapeID != shapeID ||
330 lastRange.toID != elemID )
331 ranges.push_back( TRange{ shapeID, elemID, elemID + 1 });
333 lastRange.toID = elemID + 1;
335 if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( shapeID ))
337 if ( isNode ) sm->RemoveNode( static_cast< const SMDS_MeshNode *>( e ));
338 else sm->RemoveElement( e );
345 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
346 SMESH::SMESH_Mesh_var me = _this();
347 SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
348 CORBA::String_var entry = theNewGeom->GetStudyEntry();
349 if ( !aSO->_is_nil() )
351 SALOMEDS::SObject_wrap aShapeRefSO;
352 if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
354 SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
355 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
356 builder->Addreference( aShapeRefSO, aShapeSO );
360 // re-assign global hypotheses to the new shape
361 _mainShapeTick = geomChanged ? -1 : theNewGeom->GetTick();
362 CheckGeomModif( true );
366 // restore positions of elements on geometry
367 for ( int isNode = 0; isNode < 2; ++isNode )
369 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
370 for ( size_t i = 1; i < ranges.size(); ++i )
372 int elemID = ranges[ i ].fromID;
373 int toID = ranges[ i ].toID;
374 SMESHDS_SubMesh * smDS = meshDS->NewSubMesh( ranges[ i ].shapeID );
376 for ( ; elemID < toID; ++elemID )
377 smDS->AddNode( meshDS->FindNode( elemID ));
379 for ( ; elemID < toID; ++elemID )
380 smDS->AddElement( meshDS->FindElement( elemID ));
382 if ( SMESH_subMesh* sm = _impl->GetSubMeshContaining( ranges[ i ].shapeID ))
383 sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
386 for ( unsigned int nodeID = 1; nodeID < positions.size(); ++nodeID )
387 if ( positions[ nodeID ])
388 if ( SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( meshDS->FindNode( nodeID )))
389 n->SetPosition( positions[ nodeID ], n->GetShapeID() );
392 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
395 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
396 << me <<".GetMesh()), " << entry.in() << ")";
398 TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )";
402 //================================================================================
404 * \brief Return false if the mesh is not yet fully loaded from the study file
406 //================================================================================
408 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
410 Unexpect aCatch(SALOME_SalomeException);
411 return !_preMeshInfo;
414 //================================================================================
416 * \brief Load full mesh data from the study file
418 //================================================================================
420 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
422 Unexpect aCatch(SALOME_SalomeException);
424 _preMeshInfo->FullLoadFromFile();
427 //================================================================================
429 * \brief Remove all nodes and elements
431 //================================================================================
433 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
435 Unexpect aCatch(SALOME_SalomeException);
437 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
441 //CheckGeomGroupModif(); // issue 20145
443 catch(SALOME_Exception & S_ex) {
444 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
447 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
449 SMESH::SMESH_Mesh_var mesh = _this();
450 _gen_i->UpdateIcons( mesh );
453 //================================================================================
455 * \brief Remove all nodes and elements for indicated shape
457 //================================================================================
459 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
460 throw (SALOME::SALOME_Exception)
462 Unexpect aCatch(SALOME_SalomeException);
464 _preMeshInfo->FullLoadFromFile();
467 _impl->ClearSubMesh( ShapeID );
469 catch(SALOME_Exception & S_ex) {
470 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
472 _impl->GetMeshDS()->Modified();
474 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
477 //=============================================================================
479 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
481 //=============================================================================
483 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
485 SMESH::DriverMED_ReadStatus res;
488 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
489 res = SMESH::DRS_OK; break;
490 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
491 res = SMESH::DRS_EMPTY; break;
492 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
493 res = SMESH::DRS_WARN_RENUMBER; break;
494 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
495 res = SMESH::DRS_WARN_SKIP_ELEM; break;
496 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
497 res = SMESH::DRS_WARN_DESCENDING; break;
498 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
500 res = SMESH::DRS_FAIL; break;
505 //=============================================================================
507 * Convert ::SMESH_ComputeError to SMESH::ComputeError
509 //=============================================================================
511 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
513 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
514 errVar->subShapeID = -1;
515 errVar->hasBadMesh = false;
517 if ( !errorPtr || errorPtr->IsOK() )
519 errVar->code = SMESH::COMPERR_OK;
523 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
524 errVar->comment = errorPtr->myComment.c_str();
526 return errVar._retn();
529 //=============================================================================
533 * Imports mesh data from MED file
535 //=============================================================================
537 SMESH::DriverMED_ReadStatus
538 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
539 throw ( SALOME::SALOME_Exception )
541 Unexpect aCatch(SALOME_SalomeException);
544 status = _impl->MEDToMesh( theFileName, theMeshName );
546 catch( SALOME_Exception& S_ex ) {
547 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
550 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
553 CreateGroupServants();
555 int major, minor, release;
556 major = minor = release = 0;
557 MED::GetMEDVersion(theFileName, major, minor, release);
558 _medFileInfo = new SMESH::MedFileInfo();
559 _medFileInfo->fileName = theFileName;
560 _medFileInfo->fileSize = 0;
561 _medFileInfo->major = major;
562 _medFileInfo->minor = minor;
563 _medFileInfo->release = release;
564 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
566 return ConvertDriverMEDReadStatus(status);
569 //================================================================================
571 * \brief Imports mesh data from the CGNS file
573 //================================================================================
575 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
576 const int theMeshIndex,
577 std::string& theMeshName )
578 throw ( SALOME::SALOME_Exception )
580 Unexpect aCatch(SALOME_SalomeException);
583 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
585 catch( SALOME_Exception& S_ex ) {
586 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
589 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
592 CreateGroupServants();
594 _medFileInfo = new SMESH::MedFileInfo();
595 _medFileInfo->fileName = theFileName;
596 _medFileInfo->major = 0;
597 _medFileInfo->minor = 0;
598 _medFileInfo->release = 0;
599 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
601 return ConvertDriverMEDReadStatus(status);
604 //================================================================================
606 * \brief Return string representation of a MED file version comprising nbDigits
608 //================================================================================
610 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
612 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
614 return CORBA::string_dup( ver.c_str() );
617 //================================================================================
619 * Return the list of med versions compatibles for write/append,
620 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
622 //================================================================================
623 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
625 SMESH::long_array_var aResult = new SMESH::long_array();
626 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
627 long nbver = mvok.size();
628 aResult->length( nbver );
629 for ( int i = 0; i < nbver; i++ )
630 aResult[i] = mvok[i];
631 return aResult._retn();
634 //=============================================================================
638 * Imports mesh data from MED file
640 //=============================================================================
642 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
643 throw ( SALOME::SALOME_Exception )
647 // Read mesh with name = <theMeshName> into SMESH_Mesh
648 _impl->UNVToMesh( theFileName );
650 CreateGroupServants();
652 _medFileInfo = new SMESH::MedFileInfo();
653 _medFileInfo->fileName = theFileName;
654 _medFileInfo->major = 0;
655 _medFileInfo->minor = 0;
656 _medFileInfo->release = 0;
657 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
659 SMESH_CATCH( SMESH::throwCorbaException );
664 //=============================================================================
668 * Imports mesh data from STL file
670 //=============================================================================
671 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
672 throw ( SALOME::SALOME_Exception )
676 // Read mesh with name = <theMeshName> into SMESH_Mesh
677 std::string name = _impl->STLToMesh( theFileName );
680 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
681 _gen_i->SetName( meshSO, name.c_str() );
683 _medFileInfo = new SMESH::MedFileInfo();
684 _medFileInfo->fileName = theFileName;
685 _medFileInfo->major = 0;
686 _medFileInfo->minor = 0;
687 _medFileInfo->release = 0;
688 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
690 SMESH_CATCH( SMESH::throwCorbaException );
695 //================================================================================
697 * \brief Function used in SMESH_CATCH by ImportGMFFile()
699 //================================================================================
703 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
705 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
709 //================================================================================
711 * \brief Imports data from a GMF file and returns an error description
713 //================================================================================
715 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
716 bool theMakeRequiredGroups )
717 throw (SALOME::SALOME_Exception)
719 SMESH_ComputeErrorPtr error;
722 #define SMESH_CAUGHT error =
725 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
727 _medFileInfo = new SMESH::MedFileInfo();
728 _medFileInfo->fileName = theFileName;
729 _medFileInfo->major = 0;
730 _medFileInfo->minor = 0;
731 _medFileInfo->release = 0;
732 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
734 SMESH_CATCH( exceptionToComputeError );
738 CreateGroupServants();
740 return ConvertComputeError( error );
743 //=============================================================================
747 //=============================================================================
749 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
751 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
752 (SMESH_Hypothesis::Hypothesis_Status theStatus)
755 RETURNCASE( HYP_OK );
756 RETURNCASE( HYP_MISSING );
757 RETURNCASE( HYP_CONCURRENT );
758 RETURNCASE( HYP_BAD_PARAMETER );
759 RETURNCASE( HYP_HIDDEN_ALGO );
760 RETURNCASE( HYP_HIDING_ALGO );
761 RETURNCASE( HYP_UNKNOWN_FATAL );
762 RETURNCASE( HYP_INCOMPATIBLE );
763 RETURNCASE( HYP_NOTCONFORM );
764 RETURNCASE( HYP_ALREADY_EXIST );
765 RETURNCASE( HYP_BAD_DIM );
766 RETURNCASE( HYP_BAD_SUBSHAPE );
767 RETURNCASE( HYP_BAD_GEOMETRY );
768 RETURNCASE( HYP_NEED_SHAPE );
769 RETURNCASE( HYP_INCOMPAT_HYPS );
772 return SMESH::HYP_UNKNOWN_FATAL;
775 //=============================================================================
779 * calls internal addHypothesis() and then adds a reference to <anHyp> under
780 * the SObject actually having a reference to <aSubShape>.
781 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
783 //=============================================================================
785 SMESH::Hypothesis_Status
786 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
787 SMESH::SMESH_Hypothesis_ptr anHyp,
788 CORBA::String_out anErrorText)
789 throw(SALOME::SALOME_Exception)
791 Unexpect aCatch(SALOME_SalomeException);
793 _preMeshInfo->ForgetOrLoad();
795 const int prevNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
798 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
799 anErrorText = error.c_str();
801 SMESH::SMESH_Mesh_var mesh( _this() );
802 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
804 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
806 int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
807 if ( newNbMeshEnt != prevNbMeshEnt )
808 _gen_i->UpdateIcons( mesh );
810 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
812 // Update Python script
813 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
814 << aSubShape << ", " << anHyp << " )";
816 return ConvertHypothesisStatus(status);
819 //=============================================================================
823 //=============================================================================
825 SMESH_Hypothesis::Hypothesis_Status
826 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
827 SMESH::SMESH_Hypothesis_ptr anHyp,
828 std::string* anErrorText)
830 if(MYDEBUG) MESSAGE("addHypothesis");
832 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
833 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
835 if (CORBA::is_nil( anHyp ))
836 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
838 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
841 TopoDS_Shape myLocSubShape;
842 //use PseudoShape in case if mesh has no shape
844 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
846 myLocSubShape = _impl->GetShapeToMesh();
848 const int hypId = anHyp->GetId();
850 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
851 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
853 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
855 // assure there is a corresponding submesh
856 if ( !_impl->IsMainShape( myLocSubShape )) {
857 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
858 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
859 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
862 else if ( anErrorText )
864 *anErrorText = error;
867 catch(SALOME_Exception & S_ex)
869 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
874 //=============================================================================
878 //=============================================================================
880 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
881 SMESH::SMESH_Hypothesis_ptr anHyp)
882 throw(SALOME::SALOME_Exception)
884 Unexpect aCatch(SALOME_SalomeException);
886 _preMeshInfo->ForgetOrLoad();
888 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
889 SMESH::SMESH_Mesh_var mesh = _this();
891 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
893 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
894 _gen_i->UpdateIcons( mesh );
896 // Update Python script
897 if(_impl->HasShapeToMesh())
898 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
899 << aSubShape << ", " << anHyp << " )";
901 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
904 return ConvertHypothesisStatus(status);
907 //=============================================================================
911 //=============================================================================
913 SMESH_Hypothesis::Hypothesis_Status
914 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
915 SMESH::SMESH_Hypothesis_ptr anHyp)
917 if(MYDEBUG) MESSAGE("removeHypothesis()");
919 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
920 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
922 if (CORBA::is_nil( anHyp ))
923 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
926 _preMeshInfo->ForgetOrLoad();
928 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
931 TopoDS_Shape myLocSubShape;
932 //use PseudoShape in case if mesh has no shape
933 if( _impl->HasShapeToMesh() )
934 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
936 myLocSubShape = _impl->GetShapeToMesh();
938 const int hypId = anHyp->GetId();
939 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
940 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
942 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
946 catch(SALOME_Exception & S_ex)
948 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
953 //=============================================================================
957 //=============================================================================
959 SMESH::ListOfHypothesis *
960 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
961 throw(SALOME::SALOME_Exception)
963 Unexpect aCatch(SALOME_SalomeException);
964 if (MYDEBUG) MESSAGE("GetHypothesisList");
965 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
966 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
968 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
971 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
972 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
973 myLocSubShape = _impl->GetShapeToMesh();
974 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
975 int i = 0, n = aLocalList.size();
978 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
979 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
980 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
982 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
983 if ( id_hypptr != _mapHypo.end() )
984 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
988 catch(SALOME_Exception & S_ex) {
989 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
992 return aList._retn();
995 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
997 Unexpect aCatch(SALOME_SalomeException);
998 if (MYDEBUG) MESSAGE("GetSubMeshes");
1000 SMESH::submesh_array_var aList = new SMESH::submesh_array();
1003 TPythonDump aPythonDump;
1004 if ( !_mapSubMeshIor.empty() )
1005 aPythonDump << "[ ";
1008 aList->length( _mapSubMeshIor.size() );
1010 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
1011 for ( ; it != _mapSubMeshIor.end(); it++ ) {
1012 if ( CORBA::is_nil( it->second )) continue;
1013 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
1015 if (i > 1) aPythonDump << ", ";
1016 aPythonDump << it->second;
1020 catch(SALOME_Exception & S_ex) {
1021 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1024 // Update Python script
1025 if ( !_mapSubMeshIor.empty() )
1026 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
1028 return aList._retn();
1031 //=============================================================================
1035 //=============================================================================
1037 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
1038 const char* theName )
1039 throw(SALOME::SALOME_Exception)
1041 Unexpect aCatch(SALOME_SalomeException);
1042 if (CORBA::is_nil(aSubShape))
1043 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
1045 SMESH::SMESH_subMesh_var subMesh;
1046 SMESH::SMESH_Mesh_var aMesh = _this();
1048 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
1050 //Get or Create the SMESH_subMesh object implementation
1052 TopoDS_Iterator it( myLocSubShape );
1053 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1054 bool isValidSub = ( subMeshId || _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ));
1055 if ( isValidSub && myLocSubShape.ShapeType() == TopAbs_COMPOUND )
1056 isValidSub = !it.Value().IsSame( _impl->GetShapeToMesh() );
1060 THROW_SALOME_CORBA_EXCEPTION("Not a sub-shape of the main shape", SALOME::BAD_PARAM);
1062 subMesh = getSubMesh( subMeshId );
1064 // create a new subMesh object servant if there is none for the shape
1065 if ( subMesh->_is_nil() )
1066 subMesh = createSubMesh( aSubShape );
1067 if ( _gen_i->CanPublishInStudy( subMesh ))
1069 SALOMEDS::SObject_wrap aSO =
1070 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
1071 if ( !aSO->_is_nil()) {
1072 // Update Python script
1073 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
1074 << aSubShape << ", '" << theName << "' )";
1078 catch(SALOME_Exception & S_ex) {
1079 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1081 return subMesh._retn();
1084 //=============================================================================
1088 //=============================================================================
1090 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
1091 throw (SALOME::SALOME_Exception)
1095 if ( theSubMesh->_is_nil() )
1098 GEOM::GEOM_Object_var aSubShape;
1099 // Remove submesh's SObject
1100 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
1101 if ( !anSO->_is_nil() ) {
1102 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
1103 SALOMEDS::SObject_wrap anObj, aRef;
1104 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
1105 anObj->ReferencedObject( aRef.inout() ))
1107 CORBA::Object_var obj = aRef->GetObject();
1108 aSubShape = GEOM::GEOM_Object::_narrow( obj );
1110 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
1111 // aSubShape = theSubMesh->GetSubShape();
1113 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
1114 builder->RemoveObjectWithChildren( anSO );
1116 // Update Python script
1117 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
1120 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
1122 _preMeshInfo->ForgetOrLoad();
1124 SMESH_CATCH( SMESH::throwCorbaException );
1127 //=============================================================================
1131 //=============================================================================
1133 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1134 const char* theName )
1135 throw(SALOME::SALOME_Exception)
1137 Unexpect aCatch(SALOME_SalomeException);
1139 _preMeshInfo->FullLoadFromFile();
1141 SMESH::SMESH_Group_var aNewGroup =
1142 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1144 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1146 SMESH::SMESH_Mesh_var mesh = _this();
1147 SALOMEDS::SObject_wrap aSO =
1148 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1149 if ( !aSO->_is_nil())
1150 // Update Python script
1151 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1152 << theElemType << ", '" << theName << "' )";
1154 return aNewGroup._retn();
1157 //=============================================================================
1161 //=============================================================================
1162 SMESH::SMESH_GroupOnGeom_ptr
1163 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1164 const char* theName,
1165 GEOM::GEOM_Object_ptr theGeomObj)
1166 throw(SALOME::SALOME_Exception)
1168 Unexpect aCatch(SALOME_SalomeException);
1170 _preMeshInfo->FullLoadFromFile();
1172 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1174 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1175 if ( !aShape.IsNull() )
1178 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1180 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1182 SMESH::SMESH_Mesh_var mesh = _this();
1183 SALOMEDS::SObject_wrap aSO =
1184 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1185 if ( !aSO->_is_nil())
1186 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1187 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1191 return aNewGroup._retn();
1194 //================================================================================
1196 * \brief Creates a group whose contents is defined by filter
1197 * \param theElemType - group type
1198 * \param theName - group name
1199 * \param theFilter - the filter
1200 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1202 //================================================================================
1204 SMESH::SMESH_GroupOnFilter_ptr
1205 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1206 const char* theName,
1207 SMESH::Filter_ptr theFilter )
1208 throw (SALOME::SALOME_Exception)
1210 Unexpect aCatch(SALOME_SalomeException);
1212 _preMeshInfo->FullLoadFromFile();
1214 if ( CORBA::is_nil( theFilter ))
1215 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1217 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1219 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1221 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1222 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1225 if ( !aNewGroup->_is_nil() )
1226 aNewGroup->SetFilter( theFilter );
1228 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1230 SMESH::SMESH_Mesh_var mesh = _this();
1231 SALOMEDS::SObject_wrap aSO =
1232 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1234 if ( !aSO->_is_nil())
1235 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1236 << theElemType << ", '" << theName << "', " << theFilter << " )";
1238 return aNewGroup._retn();
1241 //=============================================================================
1245 //=============================================================================
1247 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1248 throw (SALOME::SALOME_Exception)
1250 if ( theGroup->_is_nil() )
1255 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1259 if ( aGroup->GetMeshServant() != this )
1260 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1261 SALOME::BAD_PARAM );
1263 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1264 if ( !aGroupSO->_is_nil() )
1266 // Update Python script
1267 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1269 // Remove group's SObject
1270 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1271 builder->RemoveObjectWithChildren( aGroupSO );
1273 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1275 // Remove the group from SMESH data structures
1276 removeGroup( aGroup->GetLocalID() );
1278 SMESH_CATCH( SMESH::throwCorbaException );
1281 //=============================================================================
1283 * Remove group with its contents
1285 //=============================================================================
1287 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1288 throw (SALOME::SALOME_Exception)
1292 _preMeshInfo->FullLoadFromFile();
1294 if ( theGroup->_is_nil() )
1297 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1298 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1299 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1302 vector<int> nodeIds; // to remove nodes becoming free
1303 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1304 if ( !isNodal && !theGroup->IsEmpty() )
1306 CORBA::Long elemID = theGroup->GetID( 1 );
1307 int nbElemNodes = GetElemNbNodes( elemID );
1308 if ( nbElemNodes > 0 )
1309 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1312 // Retrieve contents
1313 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1314 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1315 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1316 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1317 elems.assign( elemBeg, elemEnd );
1319 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1322 RemoveGroup( theGroup );
1325 for ( size_t i = 0; i < elems.size(); ++i )
1327 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1331 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1332 nodeIds.push_back( nIt->next()->GetID() );
1334 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1338 _impl->GetMeshDS()->RemoveElement( elems[i] );
1342 // Remove free nodes
1343 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1344 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1345 if ( n->NbInverseElements() == 0 )
1346 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1348 // Update Python script (theGroup must be alive for this)
1349 pyDump << SMESH::SMESH_Mesh_var(_this())
1350 << ".RemoveGroupWithContents( " << theGroup << " )";
1352 SMESH_CATCH( SMESH::throwCorbaException );
1355 //================================================================================
1357 * \brief Get the list of groups existing in the mesh
1358 * \retval SMESH::ListOfGroups * - list of groups
1360 //================================================================================
1362 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1364 Unexpect aCatch(SALOME_SalomeException);
1365 if (MYDEBUG) MESSAGE("GetGroups");
1367 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1370 TPythonDump aPythonDump;
1371 if ( !_mapGroups.empty() )
1373 aPythonDump << "[ ";
1375 aList->length( _mapGroups.size() );
1377 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1378 for ( ; it != _mapGroups.end(); it++ ) {
1379 if ( CORBA::is_nil( it->second )) continue;
1380 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1382 if (i > 1) aPythonDump << ", ";
1383 aPythonDump << it->second;
1387 catch(SALOME_Exception & S_ex) {
1388 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1390 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1392 return aList._retn();
1395 //=============================================================================
1397 * Get number of groups existing in the mesh
1399 //=============================================================================
1401 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1403 Unexpect aCatch(SALOME_SalomeException);
1404 return _mapGroups.size();
1407 //=============================================================================
1409 * New group including all mesh elements present in initial groups is created.
1411 //=============================================================================
1413 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1414 SMESH::SMESH_GroupBase_ptr theGroup2,
1415 const char* theName )
1416 throw (SALOME::SALOME_Exception)
1418 SMESH::SMESH_Group_var aResGrp;
1422 _preMeshInfo->FullLoadFromFile();
1424 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1425 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1427 if ( theGroup1->GetType() != theGroup2->GetType() )
1428 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1433 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1434 if ( aResGrp->_is_nil() )
1435 return SMESH::SMESH_Group::_nil();
1437 aResGrp->AddFrom( theGroup1 );
1438 aResGrp->AddFrom( theGroup2 );
1440 // Update Python script
1441 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1442 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1444 SMESH_CATCH( SMESH::throwCorbaException );
1446 return aResGrp._retn();
1449 //=============================================================================
1451 * \brief New group including all mesh elements present in initial groups is created.
1452 * \param theGroups list of groups
1453 * \param theName name of group to be created
1454 * \return pointer to the new group
1456 //=============================================================================
1458 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1459 const char* theName )
1460 throw (SALOME::SALOME_Exception)
1462 SMESH::SMESH_Group_var aResGrp;
1465 _preMeshInfo->FullLoadFromFile();
1468 return SMESH::SMESH_Group::_nil();
1473 SMESH::ElementType aType = SMESH::ALL;
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("UnionListOfGroups(): different group types",
1485 if ( aType == SMESH::ALL )
1486 return SMESH::SMESH_Group::_nil();
1491 aResGrp = CreateGroup( aType, theName );
1492 if ( aResGrp->_is_nil() )
1493 return SMESH::SMESH_Group::_nil();
1495 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1496 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1498 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1499 if ( !CORBA::is_nil( aGrp ) )
1501 aResGrp->AddFrom( aGrp );
1502 if ( g > 0 ) pyDump << ", ";
1506 pyDump << " ], '" << theName << "' )";
1508 SMESH_CATCH( SMESH::throwCorbaException );
1510 return aResGrp._retn();
1513 //=============================================================================
1515 * New group is created. All mesh elements that are
1516 * present in both initial groups are added to the new one.
1518 //=============================================================================
1520 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1521 SMESH::SMESH_GroupBase_ptr theGroup2,
1522 const char* theName )
1523 throw (SALOME::SALOME_Exception)
1525 SMESH::SMESH_Group_var aResGrp;
1530 _preMeshInfo->FullLoadFromFile();
1532 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1533 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1535 if ( theGroup1->GetType() != theGroup2->GetType() )
1536 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1540 // Create Intersection
1541 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1542 if ( aResGrp->_is_nil() )
1543 return aResGrp._retn();
1545 SMESHDS_GroupBase* groupDS1 = 0;
1546 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1547 groupDS1 = grp_i->GetGroupDS();
1549 SMESHDS_GroupBase* groupDS2 = 0;
1550 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1551 groupDS2 = grp_i->GetGroupDS();
1553 SMESHDS_Group* resGroupDS = 0;
1554 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1555 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1557 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1559 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1560 while ( elemIt1->more() )
1562 const SMDS_MeshElement* e = elemIt1->next();
1563 if ( groupDS2->Contains( e ))
1564 resGroupDS->SMDSGroup().Add( e );
1567 // Update Python script
1568 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1569 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1571 SMESH_CATCH( SMESH::throwCorbaException );
1573 return aResGrp._retn();
1576 //=============================================================================
1578 \brief Intersect list of groups. New group is created. All mesh elements that
1579 are present in all initial groups simultaneously are added to the new one.
1580 \param theGroups list of groups
1581 \param theName name of group to be created
1582 \return pointer on the group
1584 //=============================================================================
1585 SMESH::SMESH_Group_ptr
1586 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1587 const char* theName )
1588 throw (SALOME::SALOME_Exception)
1590 SMESH::SMESH_Group_var aResGrp;
1595 _preMeshInfo->FullLoadFromFile();
1598 return SMESH::SMESH_Group::_nil();
1600 // check types and get SMESHDS_GroupBase's
1601 SMESH::ElementType aType = SMESH::ALL;
1602 vector< SMESHDS_GroupBase* > groupVec;
1603 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1605 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1606 if ( CORBA::is_nil( aGrp ) )
1608 if ( aType == SMESH::ALL )
1609 aType = aGrp->GetType();
1610 else if ( aType != aGrp->GetType() )
1611 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1614 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1615 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1617 if ( grpDS->IsEmpty() )
1622 groupVec.push_back( grpDS );
1625 if ( aType == SMESH::ALL ) // all groups are nil
1626 return SMESH::SMESH_Group::_nil();
1631 aResGrp = CreateGroup( aType, theName );
1633 SMESHDS_Group* resGroupDS = 0;
1634 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1635 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1636 if ( !resGroupDS || groupVec.empty() )
1637 return aResGrp._retn();
1640 size_t i, nb = groupVec.size();
1641 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1642 while ( elemIt1->more() )
1644 const SMDS_MeshElement* e = elemIt1->next();
1646 for ( i = 1; ( i < nb && inAll ); ++i )
1647 inAll = groupVec[i]->Contains( e );
1650 resGroupDS->SMDSGroup().Add( e );
1653 // Update Python script
1654 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1655 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1657 SMESH_CATCH( SMESH::throwCorbaException );
1659 return aResGrp._retn();
1662 //=============================================================================
1664 * New group is created. All mesh elements that are present in
1665 * a main group but is not present in a tool group are added to the new one
1667 //=============================================================================
1669 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1670 SMESH::SMESH_GroupBase_ptr theGroup2,
1671 const char* theName )
1672 throw (SALOME::SALOME_Exception)
1674 SMESH::SMESH_Group_var aResGrp;
1679 _preMeshInfo->FullLoadFromFile();
1681 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1682 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1684 if ( theGroup1->GetType() != theGroup2->GetType() )
1685 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1689 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1690 if ( aResGrp->_is_nil() )
1691 return aResGrp._retn();
1693 SMESHDS_GroupBase* groupDS1 = 0;
1694 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1695 groupDS1 = grp_i->GetGroupDS();
1697 SMESHDS_GroupBase* groupDS2 = 0;
1698 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1699 groupDS2 = grp_i->GetGroupDS();
1701 SMESHDS_Group* resGroupDS = 0;
1702 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1703 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1705 if ( groupDS1 && groupDS2 && resGroupDS )
1707 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1708 while ( elemIt1->more() )
1710 const SMDS_MeshElement* e = elemIt1->next();
1711 if ( !groupDS2->Contains( e ))
1712 resGroupDS->SMDSGroup().Add( e );
1715 // Update Python script
1716 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1717 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1719 SMESH_CATCH( SMESH::throwCorbaException );
1721 return aResGrp._retn();
1724 //=============================================================================
1726 \brief Cut lists of groups. New group is created. All mesh elements that are
1727 present in main groups but do not present in tool groups are added to the new one
1728 \param theMainGroups list of main groups
1729 \param theToolGroups list of tool groups
1730 \param theName name of group to be created
1731 \return pointer on the group
1733 //=============================================================================
1734 SMESH::SMESH_Group_ptr
1735 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1736 const SMESH::ListOfGroups& theToolGroups,
1737 const char* theName )
1738 throw (SALOME::SALOME_Exception)
1740 SMESH::SMESH_Group_var aResGrp;
1745 _preMeshInfo->FullLoadFromFile();
1748 return SMESH::SMESH_Group::_nil();
1750 // check types and get SMESHDS_GroupBase's
1751 SMESH::ElementType aType = SMESH::ALL;
1752 vector< SMESHDS_GroupBase* > toolGroupVec;
1753 vector< SMDS_ElemIteratorPtr > mainIterVec;
1755 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1757 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1758 if ( CORBA::is_nil( aGrp ) )
1760 if ( aType == SMESH::ALL )
1761 aType = aGrp->GetType();
1762 else if ( aType != aGrp->GetType() )
1763 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1765 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1766 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1767 if ( !grpDS->IsEmpty() )
1768 mainIterVec.push_back( grpDS->GetElements() );
1770 if ( aType == SMESH::ALL ) // all main groups are nil
1771 return SMESH::SMESH_Group::_nil();
1772 if ( mainIterVec.empty() ) // all main groups are empty
1773 return aResGrp._retn();
1775 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1777 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1778 if ( CORBA::is_nil( aGrp ) )
1780 if ( aType != aGrp->GetType() )
1781 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1783 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1784 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1785 toolGroupVec.push_back( grpDS );
1791 aResGrp = CreateGroup( aType, theName );
1793 SMESHDS_Group* resGroupDS = 0;
1794 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1795 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1797 return aResGrp._retn();
1800 size_t i, nb = toolGroupVec.size();
1801 SMDS_ElemIteratorPtr mainElemIt
1802 ( new SMDS_IteratorOnIterators
1803 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1804 while ( mainElemIt->more() )
1806 const SMDS_MeshElement* e = mainElemIt->next();
1808 for ( i = 0; ( i < nb && !isIn ); ++i )
1809 isIn = toolGroupVec[i]->Contains( e );
1812 resGroupDS->SMDSGroup().Add( e );
1815 // Update Python script
1816 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1817 << ".CutListOfGroups( " << theMainGroups << ", "
1818 << theToolGroups << ", '" << theName << "' )";
1820 SMESH_CATCH( SMESH::throwCorbaException );
1822 return aResGrp._retn();
1825 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1827 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1828 bool & toStopChecking )
1830 toStopChecking = ( nbCommon < nbChecked );
1831 return nbCommon == nbNodes;
1833 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1834 bool & toStopChecking )
1836 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1837 return nbCommon == nbCorners;
1839 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1840 bool & toStopChecking )
1842 return nbCommon > 0;
1844 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1845 bool & toStopChecking )
1847 return nbCommon >= (nbNodes+1) / 2;
1851 //=============================================================================
1853 * Create a group of entities basing on nodes of other groups.
1854 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1855 * \param [in] anElemType - a type of elements to include to the new group.
1856 * \param [in] theName - a name of the new group.
1857 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1858 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1859 * new group provided that it is based on nodes of an element of \a aListOfGroups
1860 * \return SMESH_Group - the created group
1862 // IMP 19939, bug 22010, IMP 22635
1863 //=============================================================================
1865 SMESH::SMESH_Group_ptr
1866 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1867 SMESH::ElementType theElemType,
1868 const char* theName,
1869 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1870 CORBA::Boolean theUnderlyingOnly)
1871 throw (SALOME::SALOME_Exception)
1873 SMESH::SMESH_Group_var aResGrp;
1877 _preMeshInfo->FullLoadFromFile();
1879 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1881 if ( !theName || !aMeshDS )
1882 return SMESH::SMESH_Group::_nil();
1884 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1886 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1887 SMESH_Comment nbCoNoStr( "SMESH.");
1888 switch ( theNbCommonNodes ) {
1889 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1890 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1891 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1892 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1893 default: return aResGrp._retn();
1895 int nbChecked, nbCommon, nbNodes, nbCorners;
1901 aResGrp = CreateGroup( theElemType, theName );
1902 if ( aResGrp->_is_nil() )
1903 return SMESH::SMESH_Group::_nil();
1905 SMESHDS_GroupBase* groupBaseDS =
1906 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1907 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1909 vector<bool> isNodeInGroups;
1911 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1913 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1914 if ( CORBA::is_nil( aGrp ) )
1916 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1917 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1920 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1921 if ( !elIt ) continue;
1923 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1925 while ( elIt->more() ) {
1926 const SMDS_MeshElement* el = elIt->next();
1927 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1928 while ( nIt->more() )
1929 resGroupCore.Add( nIt->next() );
1932 // get elements of theElemType based on nodes of every element of group
1933 else if ( theUnderlyingOnly )
1935 while ( elIt->more() )
1937 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1938 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1939 TIDSortedElemSet checkedElems;
1940 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1941 while ( nIt->more() )
1943 const SMDS_MeshNode* n = nIt->next();
1944 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1945 // check nodes of elements of theElemType around el
1946 while ( elOfTypeIt->more() )
1948 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1949 if ( !checkedElems.insert( elOfType ).second ) continue;
1950 nbNodes = elOfType->NbNodes();
1951 nbCorners = elOfType->NbCornerNodes();
1953 bool toStopChecking = false;
1954 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1955 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1956 if ( elNodes.count( nIt2->next() ) &&
1957 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1959 resGroupCore.Add( elOfType );
1966 // get all nodes of elements of groups
1969 while ( elIt->more() )
1971 const SMDS_MeshElement* el = elIt->next(); // an element of group
1972 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1973 while ( nIt->more() )
1975 const SMDS_MeshNode* n = nIt->next();
1976 if ( n->GetID() >= (int) isNodeInGroups.size() )
1977 isNodeInGroups.resize( n->GetID() + 1, false );
1978 isNodeInGroups[ n->GetID() ] = true;
1984 // Get elements of theElemType based on a certain number of nodes of elements of groups
1985 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1987 const SMDS_MeshNode* n;
1988 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1989 const int isNodeInGroupsSize = isNodeInGroups.size();
1990 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1992 if ( !isNodeInGroups[ iN ] ||
1993 !( n = aMeshDS->FindNode( iN )))
1996 // check nodes of elements of theElemType around n
1997 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1998 while ( elOfTypeIt->more() )
2000 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
2001 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
2006 nbNodes = elOfType->NbNodes();
2007 nbCorners = elOfType->NbCornerNodes();
2009 bool toStopChecking = false;
2010 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
2011 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
2013 const int nID = nIt->next()->GetID();
2014 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
2015 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
2017 resGroupCore.Add( elOfType );
2025 // Update Python script
2026 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
2027 << ".CreateDimGroup( "
2028 << theGroups << ", " << theElemType << ", '" << theName << "', "
2029 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
2031 SMESH_CATCH( SMESH::throwCorbaException );
2033 return aResGrp._retn();
2036 //================================================================================
2038 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
2039 * existing 1D elements as group boundaries.
2040 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
2041 * adjacent faces is more than \a sharpAngle in degrees.
2042 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
2043 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
2044 * \return ListOfGroups - the created groups
2046 //================================================================================
2048 SMESH::ListOfGroups*
2049 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
2050 CORBA::Boolean theCreateEdges,
2051 CORBA::Boolean theUseExistingEdges )
2052 throw (SALOME::SALOME_Exception)
2054 if ( theSharpAngle < 0 || theSharpAngle > 180 )
2055 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
2058 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
2064 _preMeshInfo->FullLoadFromFile();
2066 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2068 std::vector< SMESH_MeshAlgos::Edge > edges =
2069 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
2071 if ( theCreateEdges )
2073 std::vector<const SMDS_MeshNode *> nodes(2);
2074 for ( size_t i = 0; i < edges.size(); ++i )
2076 nodes[0] = edges[i]._node1;
2077 nodes[1] = edges[i]._node2;
2078 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
2080 if ( edges[i]._medium )
2081 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
2083 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
2087 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
2088 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
2090 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
2092 resultGroups->length( faceGroups.size() );
2093 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
2095 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
2096 _editor->GenerateGroupName("Group").c_str());
2097 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
2099 SMESHDS_GroupBase* groupBaseDS =
2100 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
2101 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
2103 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
2104 for ( size_t i = 0; i < faces.size(); ++i )
2105 groupCore.Add( faces[i] );
2108 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
2109 << ".FaceGroupsSeparatedByEdges( "
2110 << TVar( theSharpAngle ) << ", "
2111 << theCreateEdges << ", "
2112 << theUseExistingEdges << " )";
2114 SMESH_CATCH( SMESH::throwCorbaException );
2115 return resultGroups._retn();
2119 //================================================================================
2121 * \brief Remember GEOM group data
2123 //================================================================================
2125 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
2126 CORBA::Object_ptr theSmeshObj)
2128 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2131 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2132 if ( groupSO->_is_nil() )
2135 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2136 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2137 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2140 _geomGroupData.push_back( TGeomGroupData() );
2141 TGeomGroupData & groupData = _geomGroupData.back();
2143 CORBA::String_var entry = groupSO->GetID();
2144 groupData._groupEntry = entry.in();
2146 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2147 groupData._indices.insert( ids[i] );
2149 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2150 // shape index in SMESHDS
2151 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2152 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2155 //================================================================================
2157 * Remove GEOM group data relating to removed smesh object
2159 //================================================================================
2161 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2163 list<TGeomGroupData>::iterator
2164 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2165 for ( ; data != dataEnd; ++data ) {
2166 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2167 _geomGroupData.erase( data );
2173 //================================================================================
2175 * \brief Return new group contents if it has been changed and update group data
2177 //================================================================================
2178 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2180 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2182 TopoDS_Shape newShape;
2183 SALOMEDS::SObject_wrap groupSO;
2185 if ( how == IS_BREAK_LINK )
2187 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2188 SALOMEDS::SObject_wrap geomRefSO;
2189 if ( !meshSO->_is_nil() &&
2190 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ))
2192 geomRefSO->ReferencedObject( groupSO.inout() );
2198 groupSO = _gen_i->getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2201 if ( groupSO->_is_nil() )
2204 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2205 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2206 if ( geomGroup->_is_nil() )
2209 // get indices of group items
2210 set<int> curIndices;
2211 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2212 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2213 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2214 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2215 curIndices.insert( ids[i] );
2217 bool sameIndices = ( groupData._indices == curIndices );
2218 if ( how == ONLY_IF_CHANGED && sameIndices )
2219 return newShape; // group not changed
2222 CORBA::String_var entry = geomGroup->GetStudyEntry();
2223 groupData._groupEntry = entry.in();
2224 groupData._indices = curIndices;
2226 newShape = _gen_i->GeomObjectToShape( geomGroup );
2228 // check if newShape is up-to-date
2229 if ( !newShape.IsNull() && ids->length() > 0 )
2231 bool toUpdate = ! _impl->GetMeshDS()->IsGroupOfSubShapes( newShape );
2234 TopExp_Explorer exp( newShape, (TopAbs_ShapeEnum)( groupOp->GetType( geomGroup )));
2235 for ( ; exp.More() && !toUpdate; exp.Next() )
2237 int ind = _impl->GetMeshDS()->ShapeToIndex( exp.Current() );
2238 toUpdate = ( curIndices.erase( ind ) == 0 );
2240 if ( !curIndices.empty() )
2245 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2246 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2247 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2248 newShape = _gen_i->GeomObjectToShape( geomGroup );
2253 // geom group becomes empty - return empty compound
2254 TopoDS_Compound compound;
2255 BRep_Builder().MakeCompound(compound);
2256 newShape = compound;
2264 //-----------------------------------------------------------------------------
2266 * \brief Storage of shape and index used in CheckGeomGroupModif()
2268 struct TIndexedShape
2271 TopoDS_Shape _shape;
2272 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2274 //-----------------------------------------------------------------------------
2276 * \brief Data to re-create a group on geometry
2278 struct TGroupOnGeomData
2281 TopoDS_Shape _shape;
2282 SMDSAbs_ElementType _type;
2284 Quantity_Color _color;
2286 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2288 _oldID = group->GetID();
2289 _type = group->GetType();
2290 _name = group->GetStoreName();
2291 _color = group->GetColor();
2295 //-----------------------------------------------------------------------------
2297 * \brief Check if a filter is still valid after geometry removal
2299 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2301 if ( theFilter->_is_nil() )
2303 SMESH::Filter::Criteria_var criteria;
2304 theFilter->GetCriteria( criteria.out() );
2306 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2308 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2310 switch ( criteria[ iCr ].Type )
2312 case SMESH::FT_BelongToGeom:
2313 case SMESH::FT_BelongToPlane:
2314 case SMESH::FT_BelongToCylinder:
2315 case SMESH::FT_BelongToGenSurface:
2316 case SMESH::FT_LyingOnGeom:
2317 entry = thresholdID;
2319 case SMESH::FT_ConnectedElements:
2322 entry = thresholdID;
2328 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2329 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2330 if ( so->_is_nil() )
2332 CORBA::Object_var obj = so->GetObject();
2333 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2334 if ( gen->GeomObjectToShape( geom ).IsNull() )
2337 } // loop on criteria
2343 //=============================================================================
2345 * \brief Update data if geometry changes
2349 //=============================================================================
2351 void SMESH_Mesh_i::CheckGeomModif( bool theIsBreakLink )
2353 SMESH::SMESH_Mesh_var me = _this();
2354 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2356 TPythonDump dumpNothing; // prevent any dump
2358 //bool removedFromClient = false;
2360 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2362 //removedFromClient = _impl->HasShapeToMesh();
2364 // try to find geometry by study reference
2365 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2366 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2367 if ( !meshSO->_is_nil() &&
2368 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2369 geomRefSO->ReferencedObject( geomSO.inout() ))
2371 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2372 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2375 if ( mainGO->_is_nil() && // geometry removed ==>
2376 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2378 // convert geom dependent groups into standalone ones
2379 CheckGeomGroupModif();
2381 _impl->ShapeToMesh( TopoDS_Shape() );
2383 // remove sub-meshes
2384 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2385 while ( i_sm != _mapSubMeshIor.end() )
2387 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2389 RemoveSubMesh( sm );
2391 // remove all children except groups in the study
2392 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2393 SALOMEDS::SObject_wrap so;
2394 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2395 if ( meshSO->FindSubObject( tag, so.inout() ))
2396 builder->RemoveObjectWithChildren( so );
2398 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2404 if ( !_impl->HasShapeToMesh() ) return;
2407 // Update after group modification
2409 const bool geomChanged = ( mainGO->GetTick() != _mainShapeTick );
2410 if ( !theIsBreakLink )
2411 if ( mainGO->GetType() == GEOM_GROUP || !geomChanged ) // is group or not modified
2413 int nb = NbNodes() + NbElements();
2414 CheckGeomGroupModif();
2415 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2416 _gen_i->UpdateIcons( me );
2420 // Update after shape modification or breakLink w/o geometry change
2422 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2423 if ( !geomClient ) return;
2424 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2425 if ( geomGen->_is_nil() ) return;
2426 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2427 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2429 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2431 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2432 if ( meshDS->ShapeToIndex( newShape ) == 1 ) // not yet updated
2434 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2435 geomClient->RemoveShapeFromBuffer( ior.in() );
2436 newShape = _gen_i->GeomObjectToShape( mainGO );
2439 // Update data taking into account that if topology doesn't change
2440 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2443 _preMeshInfo->ForgetAllData();
2445 if ( geomChanged || !isShaper )
2447 if ( newShape.IsNull() )
2450 _mainShapeTick = mainGO->GetTick();
2452 // store data of groups on geometry including new TopoDS_Shape's
2453 std::vector< TGroupOnGeomData > groupsData;
2454 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2455 groupsData.reserve( groups.size() );
2456 TopTools_DataMapOfShapeShape old2newShapeMap;
2457 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2458 for ( ; g != groups.end(); ++g )
2460 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2462 groupsData.push_back( TGroupOnGeomData( group ));
2465 SMESH::SMESH_GroupOnGeom_var gog;
2466 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2467 if ( i_grp != _mapGroups.end() )
2468 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2470 GEOM::GEOM_Object_var geom;
2471 if ( !gog->_is_nil() )
2473 if ( !theIsBreakLink )
2474 geom = gog->GetShape();
2476 if ( theIsBreakLink || geom->_is_nil() )
2478 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2479 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2480 if ( !grpSO->_is_nil() &&
2481 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2482 geomRefSO->ReferencedObject( geomSO.inout() ))
2484 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2485 geom = GEOM::GEOM_Object::_narrow( geomObj );
2489 if ( old2newShapeMap.IsBound( group->GetShape() ))
2491 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2493 else if ( !geom->_is_nil() )
2495 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2496 if ( meshDS->IsGroupOfSubShapes( groupsData.back()._shape ))
2498 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2499 geomClient->RemoveShapeFromBuffer( ior.in() );
2500 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2502 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2507 // store assigned hypotheses
2508 std::vector< pair< int, THypList > > ids2Hyps;
2509 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2510 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2512 const TopoDS_Shape& s = s2hyps.Key();
2513 const THypList& hyps = s2hyps.ChangeValue();
2514 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2517 std::multimap< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2519 // count shapes excluding compounds corresponding to geom groups
2520 int oldNbSubShapes = meshDS->MaxShapeIndex();
2521 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2523 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2524 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2527 std::set<int> subIds;
2528 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2529 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2530 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2533 // check if shape topology changes - save shape type per shape ID
2534 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2535 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2536 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2538 // change shape to mesh
2539 _impl->ShapeToMesh( TopoDS_Shape() );
2540 _impl->ShapeToMesh( newShape );
2542 // check if shape topology changes - check new shape types
2543 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2544 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2546 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2547 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2550 // re-add shapes (compounds) of geom groups
2551 typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData;
2552 TIndices2GroupData ii2grData;
2553 std::vector< int > ii;
2554 std::map< int, int > old2newIDs; // group IDs
2555 std::list<TGeomGroupData>::iterator dataIt = _geomGroupData.begin();
2556 for ( ; dataIt != _geomGroupData.end(); ++dataIt )
2558 TGeomGroupData* data = &(*dataIt);
2559 ii.reserve( data->_indices.size() );
2560 ii.assign( data->_indices.begin(), data->_indices.end() );
2561 TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first;
2562 if ( ii2gd->second != data )
2564 data->_groupEntry = ii2gd->second->_groupEntry;
2565 data->_indices = ii2gd->second->_indices;
2568 const int oldNbSub = data->_indices.size();
2569 const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0;
2571 std::multimap< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2572 if ( ii2i != ii2iMap.end() )
2574 oldID = ii2i->second;
2575 ii2iMap.erase( ii2i );
2577 if ( !oldID && oldNbSub == 1 )
2579 if ( old2newIDs.count( oldID ))
2582 int how = ( theIsBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2583 newShape = newGroupShape( *data, how );
2585 if ( !newShape.IsNull() )
2587 if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape
2589 TopoDS_Compound compound;
2590 BRep_Builder().MakeCompound( compound );
2591 BRep_Builder().Add( compound, newShape );
2592 newShape = compound;
2594 int newID = _impl->GetSubMesh( newShape )->GetId();
2595 if ( oldID /*&& oldID != newID*/ )
2596 old2newIDs.insert( std::make_pair( oldID, newID ));
2597 if ( oldNbSub == 1 )
2598 old2newIDs.insert( std::make_pair( soleOldID, newID ));
2602 // re-assign hypotheses
2603 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2605 int sID = ids2Hyps[i].first;
2608 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2609 if ( o2n != old2newIDs.end() )
2611 else if ( !sameTopology )
2614 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2617 const THypList& hyps = ids2Hyps[i].second;
2618 THypList::const_iterator h = hyps.begin();
2619 for ( ; h != hyps.end(); ++h )
2620 _impl->AddHypothesis( s, (*h)->GetID() );
2624 // restore groups on geometry
2625 for ( size_t i = 0; i < groupsData.size(); ++i )
2627 const TGroupOnGeomData& data = groupsData[i];
2628 if ( data._shape.IsNull() )
2631 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2632 if ( i2g == _mapGroups.end() ) continue;
2634 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2635 if ( !gr_i ) continue;
2637 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2639 _mapGroups.erase( i2g );
2641 g->GetGroupDS()->SetColor( data._color );
2644 if ( !sameTopology )
2646 std::map< int, int >::iterator o2n = old2newIDs.begin();
2647 for ( ; o2n != old2newIDs.end(); ++o2n )
2649 int newID = o2n->second, oldID = o2n->first;
2650 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2654 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2655 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2656 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2658 _mapSubMesh. erase(oldID);
2659 _mapSubMesh_i. erase(oldID);
2660 _mapSubMeshIor.erase(oldID);
2662 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2666 // update _mapSubMesh
2667 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2668 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2669 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2672 if ( !sameTopology )
2674 // remove invalid study sub-objects
2675 CheckGeomGroupModif();
2678 _gen_i->UpdateIcons( me );
2680 if ( !theIsBreakLink && isShaper )
2682 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2683 if ( !meshSO->_is_nil() )
2684 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2688 //=============================================================================
2690 * \brief Update objects depending on changed geom groups
2692 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2693 * issue 0020210: Update of a smesh group after modification of the associated geom group
2695 //=============================================================================
2697 void SMESH_Mesh_i::CheckGeomGroupModif()
2699 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2700 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2701 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2702 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2703 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2705 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2706 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2707 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2709 int nbValid = 0, nbRemoved = 0;
2710 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2711 for ( ; chItr->More(); chItr->Next() )
2713 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2714 if ( !smSO->_is_nil() &&
2715 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2716 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2718 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2719 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2720 if ( !geom->_non_existent() )
2723 continue; // keep the sub-mesh
2726 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2727 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2728 if ( !sm->_is_nil() && !sm->_non_existent() )
2730 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2731 if ( smGeom->_is_nil() )
2733 RemoveSubMesh( sm );
2740 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2741 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2745 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2746 builder->RemoveObjectWithChildren( rootSO );
2750 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2751 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2752 while ( i_gr != _mapGroups.end())
2754 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2756 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO;
2757 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2758 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2759 bool isValidGeom = false;
2760 if ( !onGeom->_is_nil() )
2762 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); // check TopoDS
2763 if ( !isValidGeom ) // check reference
2765 isValidGeom = ( ! groupSO->_is_nil() &&
2766 groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) &&
2767 refSO->ReferencedObject( geomSO.inout() ) &&
2768 ! geomSO->_is_nil() &&
2769 !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() )));
2772 else if ( !onFilt->_is_nil() )
2774 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2778 isValidGeom = ( !groupSO->_is_nil() &&
2779 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2783 if ( !IsLoaded() || group->IsEmpty() )
2785 RemoveGroup( group );
2787 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2789 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2791 else // is it possible?
2793 builder->RemoveObjectWithChildren( refSO );
2799 if ( !_impl->HasShapeToMesh() ) return;
2801 CORBA::Long nbEntities = NbNodes() + NbElements();
2803 // Check if group contents changed
2805 typedef map< string, TopoDS_Shape > TEntry2Geom;
2806 TEntry2Geom newGroupContents;
2808 list<TGeomGroupData>::iterator
2809 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2810 for ( ; data != dataEnd; ++data )
2812 pair< TEntry2Geom::iterator, bool > it_new =
2813 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2814 bool processedGroup = !it_new.second;
2815 TopoDS_Shape& newShape = it_new.first->second;
2816 if ( !processedGroup )
2817 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2818 if ( newShape.IsNull() )
2819 continue; // no changes
2822 _preMeshInfo->ForgetOrLoad();
2824 if ( processedGroup ) { // update group indices
2825 list<TGeomGroupData>::iterator data2 = data;
2826 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2827 data->_indices = data2->_indices;
2830 // Update SMESH objects according to new GEOM group contents
2832 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2833 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2835 int oldID = submesh->GetId();
2836 if ( !_mapSubMeshIor.count( oldID ))
2838 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2840 // update hypotheses
2841 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2842 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2843 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2845 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2846 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2848 // care of submeshes
2849 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2850 int newID = newSubmesh->GetId();
2851 if ( newID != oldID ) {
2852 _mapSubMesh [ newID ] = newSubmesh;
2853 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2854 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2855 _mapSubMesh. erase(oldID);
2856 _mapSubMesh_i. erase(oldID);
2857 _mapSubMeshIor.erase(oldID);
2858 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2863 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2864 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2865 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2867 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2869 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2870 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2871 ds->SetShape( newShape );
2876 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2877 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2879 // Remove groups and submeshes basing on removed sub-shapes
2881 TopTools_MapOfShape newShapeMap;
2882 TopoDS_Iterator shapeIt( newShape );
2883 for ( ; shapeIt.More(); shapeIt.Next() )
2884 newShapeMap.Add( shapeIt.Value() );
2886 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2887 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2889 if ( newShapeMap.Contains( shapeIt.Value() ))
2891 TopTools_IndexedMapOfShape oldShapeMap;
2892 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2893 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2895 const TopoDS_Shape& oldShape = oldShapeMap(i);
2896 int oldInd = meshDS->ShapeToIndex( oldShape );
2898 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2899 if ( i_smIor != _mapSubMeshIor.end() ) {
2900 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2903 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2904 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2906 // check if a group bases on oldInd shape
2907 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2908 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2909 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2910 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2912 RemoveGroup( i_grp->second ); // several groups can base on same shape
2913 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2918 // Reassign hypotheses and update groups after setting the new shape to mesh
2920 // collect anassigned hypotheses
2921 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2922 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2923 TShapeHypList assignedHyps;
2924 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2926 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2927 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2928 if ( !hyps.empty() ) {
2929 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2930 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2931 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2934 // collect shapes supporting groups
2935 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2936 TShapeTypeList groupData;
2937 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2938 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2939 for ( ; grIt != groups.end(); ++grIt )
2941 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2943 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2945 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2947 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2948 _impl->ShapeToMesh( newShape );
2950 // reassign hypotheses
2951 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2952 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2954 TIndexedShape& geom = indS_hyps->first;
2955 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2956 int oldID = geom._index;
2957 int newID = meshDS->ShapeToIndex( geom._shape );
2958 if ( oldID == 1 ) { // main shape
2960 geom._shape = newShape;
2964 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2965 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2966 // care of sub-meshes
2967 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2968 if ( newID != oldID ) {
2969 _mapSubMesh [ newID ] = newSubmesh;
2970 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2971 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2972 _mapSubMesh. erase(oldID);
2973 _mapSubMesh_i. erase(oldID);
2974 _mapSubMeshIor.erase(oldID);
2975 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2979 TShapeTypeList::iterator geomType = groupData.begin();
2980 for ( ; geomType != groupData.end(); ++geomType )
2982 const TIndexedShape& geom = geomType->first;
2983 int oldID = geom._index;
2984 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2987 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2988 CORBA::String_var name = groupSO->GetName();
2990 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2991 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2992 /*id=*/-1, geom._shape ))
2993 group_i->changeLocalId( group->GetID() );
2996 break; // everything has been updated
2999 } // loop on group data
3003 CORBA::Long newNbEntities = NbNodes() + NbElements();
3004 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
3005 if ( newNbEntities != nbEntities )
3007 // Add all SObjects with icons to soToUpdateIcons
3008 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
3010 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
3011 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
3012 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
3014 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
3015 i_gr != _mapGroups.end(); ++i_gr ) // groups
3016 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
3019 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
3020 for ( ; so != soToUpdateIcons.end(); ++so )
3021 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
3024 //=============================================================================
3026 * \brief Create standalone group from a group on geometry or filter
3028 //=============================================================================
3030 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
3031 throw (SALOME::SALOME_Exception)
3033 SMESH::SMESH_Group_var aGroup;
3038 _preMeshInfo->FullLoadFromFile();
3040 if ( theGroup->_is_nil() )
3041 return aGroup._retn();
3043 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
3045 return aGroup._retn();
3047 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
3049 const int anId = aGroupToRem->GetLocalID();
3050 if ( !_impl->ConvertToStandalone( anId ) )
3051 return aGroup._retn();
3052 removeGeomGroupData( theGroup );
3054 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3056 // remove old instance of group from own map
3057 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
3058 _mapGroups.erase( anId );
3060 SALOMEDS::StudyBuilder_var builder;
3061 SALOMEDS::SObject_wrap aGroupSO;
3062 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3063 if ( !aStudy->_is_nil() ) {
3064 builder = aStudy->NewBuilder();
3065 aGroupSO = _gen_i->ObjectToSObject( theGroup );
3066 if ( !aGroupSO->_is_nil() )
3068 // remove reference to geometry
3069 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
3070 for ( ; chItr->More(); chItr->Next() )
3072 // Remove group's child SObject
3073 SALOMEDS::SObject_wrap so = chItr->Value();
3074 builder->RemoveObject( so );
3076 // Update Python script
3077 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
3078 << ".ConvertToStandalone( " << aGroupSO << " )";
3080 // change icon of Group on Filter
3083 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
3084 // const int isEmpty = ( elemTypes->length() == 0 );
3087 SALOMEDS::GenericAttribute_wrap anAttr =
3088 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
3089 SALOMEDS::AttributePixMap_wrap pm = anAttr;
3090 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
3096 // remember new group in own map
3097 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
3098 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3100 // register CORBA object for persistence
3101 _gen_i->RegisterObject( aGroup );
3103 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
3104 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
3105 //aGroup->Register();
3106 aGroupToRem->UnRegister();
3108 SMESH_CATCH( SMESH::throwCorbaException );
3110 return aGroup._retn();
3113 //=============================================================================
3117 //=============================================================================
3119 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
3121 if(MYDEBUG) MESSAGE( "createSubMesh" );
3122 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
3123 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
3126 SMESH_subMesh_i * subMeshServant;
3129 subMeshId = mySubMesh->GetId();
3130 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
3132 else // "invalid sub-mesh"
3134 // The invalid sub-mesh is created for the case where a valid sub-shape not found
3135 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
3136 if ( _mapSubMesh.empty() )
3139 subMeshId = _mapSubMesh.begin()->first - 1;
3140 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
3143 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
3145 _mapSubMesh [subMeshId] = mySubMesh;
3146 _mapSubMesh_i [subMeshId] = subMeshServant;
3147 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
3149 subMeshServant->Register();
3151 // register CORBA object for persistence
3152 int nextId = _gen_i->RegisterObject( subMesh );
3153 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
3154 else { nextId = 0; } // avoid "unused variable" warning
3156 // to track changes of GEOM groups
3157 if ( subMeshId > 0 )
3158 addGeomGroupData( theSubShapeObject, subMesh );
3160 return subMesh._retn();
3163 //=======================================================================
3164 //function : getSubMesh
3166 //=======================================================================
3168 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3170 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3171 if ( it == _mapSubMeshIor.end() )
3172 return SMESH::SMESH_subMesh::_nil();
3174 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3177 //=============================================================================
3181 //=============================================================================
3183 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3184 GEOM::GEOM_Object_ptr theSubShapeObject )
3186 bool isHypChanged = false;
3187 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3188 return isHypChanged;
3190 const int subMeshId = theSubMesh->GetId();
3192 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3195 if (( _mapSubMesh.count( subMeshId )) &&
3196 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3198 TopoDS_Shape S = sm->GetSubShape();
3201 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3202 isHypChanged = !hyps.empty();
3203 if ( isHypChanged && _preMeshInfo )
3204 _preMeshInfo->ForgetOrLoad();
3205 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3206 for ( ; hyp != hyps.end(); ++hyp )
3207 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3214 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3215 isHypChanged = ( aHypList->length() > 0 );
3216 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3217 removeHypothesis( theSubShapeObject, aHypList[i] );
3220 catch( const SALOME::SALOME_Exception& ) {
3221 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3223 removeGeomGroupData( theSubShapeObject );
3227 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3228 if ( id_smi != _mapSubMesh_i.end() )
3229 id_smi->second->UnRegister();
3231 // remove a CORBA object
3232 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3233 if ( id_smptr != _mapSubMeshIor.end() )
3234 SMESH::SMESH_subMesh_var( id_smptr->second );
3236 _mapSubMesh.erase(subMeshId);
3237 _mapSubMesh_i.erase(subMeshId);
3238 _mapSubMeshIor.erase(subMeshId);
3240 return isHypChanged;
3243 //=============================================================================
3247 //=============================================================================
3249 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3250 const char* theName,
3252 const TopoDS_Shape& theShape,
3253 const SMESH_PredicatePtr& thePredicate )
3255 std::string newName;
3256 if ( !theName || !theName[0] )
3258 std::set< std::string > presentNames;
3259 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3260 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3262 CORBA::String_var name = i_gr->second->GetName();
3263 presentNames.insert( name.in() );
3266 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3267 } while ( !presentNames.insert( newName ).second );
3268 theName = newName.c_str();
3270 SMESH::SMESH_GroupBase_var aGroup;
3271 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3272 theID, theShape, thePredicate ))
3274 int anId = g->GetID();
3275 SMESH_GroupBase_i* aGroupImpl;
3276 if ( !theShape.IsNull() )
3277 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3278 else if ( thePredicate )
3279 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3281 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3283 aGroup = aGroupImpl->_this();
3284 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3285 aGroupImpl->Register();
3287 // register CORBA object for persistence
3288 int nextId = _gen_i->RegisterObject( aGroup );
3289 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3290 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3292 // to track changes of GEOM groups
3293 if ( !theShape.IsNull() ) {
3294 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3295 addGeomGroupData( geom, aGroup );
3298 return aGroup._retn();
3301 //=============================================================================
3303 * SMESH_Mesh_i::removeGroup
3305 * Should be called by ~SMESH_Group_i()
3307 //=============================================================================
3309 void SMESH_Mesh_i::removeGroup( const int theId )
3311 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3312 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3313 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3314 _mapGroups.erase( theId );
3315 removeGeomGroupData( group );
3316 if ( !_impl->RemoveGroup( theId ))
3318 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3319 RemoveGroup( group );
3321 group->UnRegister();
3325 //=============================================================================
3329 //=============================================================================
3331 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3332 throw(SALOME::SALOME_Exception)
3334 SMESH::log_array_var aLog;
3338 _preMeshInfo->FullLoadFromFile();
3340 list < SMESHDS_Command * >logDS = _impl->GetLog();
3341 aLog = new SMESH::log_array;
3343 int lg = logDS.size();
3346 list < SMESHDS_Command * >::iterator its = logDS.begin();
3347 while(its != logDS.end()){
3348 SMESHDS_Command *com = *its;
3349 int comType = com->GetType();
3351 int lgcom = com->GetNumber();
3353 const list < int >&intList = com->GetIndexes();
3354 int inum = intList.size();
3356 list < int >::const_iterator ii = intList.begin();
3357 const list < double >&coordList = com->GetCoords();
3358 int rnum = coordList.size();
3360 list < double >::const_iterator ir = coordList.begin();
3361 aLog[indexLog].commandType = comType;
3362 aLog[indexLog].number = lgcom;
3363 aLog[indexLog].coords.length(rnum);
3364 aLog[indexLog].indexes.length(inum);
3365 for(int i = 0; i < rnum; i++){
3366 aLog[indexLog].coords[i] = *ir;
3367 //MESSAGE(" "<<i<<" "<<ir.Value());
3370 for(int i = 0; i < inum; i++){
3371 aLog[indexLog].indexes[i] = *ii;
3372 //MESSAGE(" "<<i<<" "<<ii.Value());
3381 SMESH_CATCH( SMESH::throwCorbaException );
3383 return aLog._retn();
3387 //=============================================================================
3391 //=============================================================================
3393 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3397 SMESH_CATCH( SMESH::throwCorbaException );
3400 //=============================================================================
3404 //=============================================================================
3406 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3411 //=============================================================================
3414 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3415 // issue 0020918: groups removal is caused by hyp modification
3416 // issue 0021208: to forget not loaded mesh data at hyp modification
3417 struct TCallUp_i : public SMESH_Mesh::TCallUp
3419 SMESH_Mesh_i* _mesh;
3420 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3421 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3422 virtual void HypothesisModified( int hypID,
3423 bool updIcons) { _mesh->onHypothesisModified( hypID,
3425 virtual void Load () { _mesh->Load(); }
3426 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3430 //================================================================================
3432 * \brief callback from _impl to
3433 * 1) forget not loaded mesh data (issue 0021208)
3434 * 2) mark hypothesis as valid
3436 //================================================================================
3438 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3441 _preMeshInfo->ForgetOrLoad();
3443 if ( theUpdateIcons )
3445 SMESH::SMESH_Mesh_var mesh = _this();
3446 _gen_i->UpdateIcons( mesh );
3449 if ( _nbInvalidHypos != 0 )
3451 // mark a hypothesis as valid after edition
3453 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3454 SALOMEDS::SObject_wrap hypRoot;
3455 if ( !smeshComp->_is_nil() &&
3456 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3458 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3459 for ( ; anIter->More(); anIter->Next() )
3461 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3462 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3463 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3464 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3465 _gen_i->HighLightInvalid( hyp, false );
3467 nbInvalid += _gen_i->IsInvalid( hypSO );
3470 _nbInvalidHypos = nbInvalid;
3474 //=============================================================================
3478 //=============================================================================
3480 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3482 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3485 _impl->SetCallUp( new TCallUp_i(this));
3488 //=============================================================================
3492 //=============================================================================
3494 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3496 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3500 //=============================================================================
3502 * Return mesh editor
3504 //=============================================================================
3506 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3507 throw (SALOME::SALOME_Exception)
3509 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3513 _preMeshInfo->FullLoadFromFile();
3515 // Create MeshEditor
3517 _editor = new SMESH_MeshEditor_i( this, false );
3518 aMeshEdVar = _editor->_this();
3520 // Update Python script
3521 TPythonDump() << _editor << " = "
3522 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3524 SMESH_CATCH( SMESH::throwCorbaException );
3526 return aMeshEdVar._retn();
3529 //=============================================================================
3531 * Return mesh edition previewer
3533 //=============================================================================
3535 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3536 throw (SALOME::SALOME_Exception)
3538 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3542 _preMeshInfo->FullLoadFromFile();
3544 if ( !_previewEditor )
3545 _previewEditor = new SMESH_MeshEditor_i( this, true );
3546 aMeshEdVar = _previewEditor->_this();
3548 SMESH_CATCH( SMESH::throwCorbaException );
3550 return aMeshEdVar._retn();
3553 //================================================================================
3555 * \brief Return true if the mesh has been edited since a last total re-compute
3556 * and those modifications may prevent successful partial re-compute
3558 //================================================================================
3560 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3562 Unexpect aCatch(SALOME_SalomeException);
3563 return _impl->HasModificationsToDiscard();
3566 //================================================================================
3568 * \brief Returns a random unique color
3570 //================================================================================
3572 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3574 const int MAX_ATTEMPTS = 100;
3576 double tolerance = 0.5;
3577 SALOMEDS::Color col;
3581 // generate random color
3582 double red = (double)rand() / RAND_MAX;
3583 double green = (double)rand() / RAND_MAX;
3584 double blue = (double)rand() / RAND_MAX;
3585 // check existence in the list of the existing colors
3586 bool matched = false;
3587 std::list<SALOMEDS::Color>::const_iterator it;
3588 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3589 SALOMEDS::Color color = *it;
3590 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3591 matched = tol < tolerance;
3593 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3594 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3602 //=============================================================================
3604 * Sets auto-color mode. If it is on, groups get unique random colors
3606 //=============================================================================
3608 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3610 Unexpect aCatch(SALOME_SalomeException);
3611 _impl->SetAutoColor(theAutoColor);
3613 TPythonDump pyDump; // not to dump group->SetColor() from below code
3614 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3616 std::list<SALOMEDS::Color> aReservedColors;
3617 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3618 for ( ; it != _mapGroups.end(); it++ ) {
3619 if ( CORBA::is_nil( it->second )) continue;
3620 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3621 it->second->SetColor( aColor );
3622 aReservedColors.push_back( aColor );
3626 //=============================================================================
3628 * Returns true if auto-color mode is on
3630 //=============================================================================
3632 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3634 Unexpect aCatch(SALOME_SalomeException);
3635 return _impl->GetAutoColor();
3638 //=============================================================================
3640 * Checks if there are groups with equal names
3642 //=============================================================================
3644 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3646 return _impl->HasDuplicatedGroupNamesMED();
3649 //================================================================================
3651 * \brief Care of a file before exporting mesh into it
3653 //================================================================================
3655 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3657 SMESH_File aFile( file, false );
3659 if ( aFile.exists() ) {
3660 // existing filesystem node
3661 if ( !aFile.isDirectory() ) {
3662 if ( aFile.openForWriting() ) {
3663 if ( overwrite && ! aFile.remove()) {
3664 msg << "Can't replace " << aFile.getName();
3667 msg << "Can't write into " << aFile.getName();
3670 msg << "Location " << aFile.getName() << " is not a file";
3674 // nonexisting file; check if it can be created
3675 if ( !aFile.openForWriting() ) {
3676 msg << "You cannot create the file "
3678 << ". Check the directory existence and access rights";
3686 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3690 //================================================================================
3692 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3693 * \param file - file name
3694 * \param overwrite - to erase the file or not
3695 * \retval string - mesh name
3697 //================================================================================
3699 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3700 CORBA::Boolean overwrite)
3703 PrepareForWriting(file, overwrite);
3704 string aMeshName = "Mesh";
3705 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3706 if ( !aStudy->_is_nil() ) {
3707 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3708 if ( !aMeshSO->_is_nil() ) {
3709 CORBA::String_var name = aMeshSO->GetName();
3711 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3712 if ( !aStudy->GetProperties()->IsLocked() )
3714 SALOMEDS::GenericAttribute_wrap anAttr;
3715 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3716 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3717 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3718 ASSERT(!aFileName->_is_nil());
3719 aFileName->SetValue(file);
3720 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3721 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3722 ASSERT(!aFileType->_is_nil());
3723 aFileType->SetValue("FICHIERMED");
3727 // Update Python script
3728 // set name of mesh before export
3729 TPythonDump() << _gen_i << ".SetName("
3730 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3732 // check names of groups
3738 //================================================================================
3740 * \brief Export to MED file
3742 //================================================================================
3744 void SMESH_Mesh_i::ExportMED(const char* file,
3745 CORBA::Boolean auto_groups,
3746 CORBA::Long version,
3747 CORBA::Boolean overwrite,
3748 CORBA::Boolean autoDimension)
3749 throw(SALOME::SALOME_Exception)
3751 //MESSAGE("MED minor version: "<< minor);
3754 _preMeshInfo->FullLoadFromFile();
3756 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3757 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3759 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3761 << "auto_groups=" <<auto_groups << ", "
3762 << "minor=" << version << ", "
3763 << "overwrite=" << overwrite << ", "
3764 << "meshPart=None, "
3765 << "autoDimension=" << autoDimension << " )";
3767 SMESH_CATCH( SMESH::throwCorbaException );
3770 //================================================================================
3772 * \brief Export a mesh to a SAUV file
3774 //================================================================================
3776 void SMESH_Mesh_i::ExportSAUV (const char* file,
3777 CORBA::Boolean auto_groups)
3778 throw(SALOME::SALOME_Exception)
3780 Unexpect aCatch(SALOME_SalomeException);
3782 _preMeshInfo->FullLoadFromFile();
3784 string aMeshName = prepareMeshNameAndGroups(file, true);
3785 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3786 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3787 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3791 //================================================================================
3793 * \brief Export a mesh to a DAT file
3795 //================================================================================
3797 void SMESH_Mesh_i::ExportDAT (const char *file)
3798 throw(SALOME::SALOME_Exception)
3800 Unexpect aCatch(SALOME_SalomeException);
3802 _preMeshInfo->FullLoadFromFile();
3804 // Update Python script
3805 // check names of groups
3807 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3810 PrepareForWriting(file);
3811 _impl->ExportDAT(file);
3814 //================================================================================
3816 * \brief Export a mesh to an UNV file
3818 //================================================================================
3820 void SMESH_Mesh_i::ExportUNV (const char *file)
3821 throw(SALOME::SALOME_Exception)
3823 Unexpect aCatch(SALOME_SalomeException);
3825 _preMeshInfo->FullLoadFromFile();
3827 // Update Python script
3828 // check names of groups
3830 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3833 PrepareForWriting(file);
3834 _impl->ExportUNV(file);
3837 //================================================================================
3839 * \brief Export a mesh to an STL file
3841 //================================================================================
3843 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3844 throw(SALOME::SALOME_Exception)
3846 Unexpect aCatch(SALOME_SalomeException);
3848 _preMeshInfo->FullLoadFromFile();
3850 // Update Python script
3851 // check names of groups
3853 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3854 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3856 CORBA::String_var name;
3857 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3858 if ( !so->_is_nil() )
3859 name = so->GetName();
3862 PrepareForWriting( file );
3863 _impl->ExportSTL( file, isascii, name.in() );
3866 //================================================================================
3868 * \brief Export a part of mesh to a med file
3870 //================================================================================
3872 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3874 CORBA::Boolean auto_groups,
3875 CORBA::Long version,
3876 CORBA::Boolean overwrite,
3877 CORBA::Boolean autoDimension,
3878 const GEOM::ListOfFields& fields,
3879 const char* geomAssocFields,
3880 CORBA::Double ZTolerance)
3881 throw (SALOME::SALOME_Exception)
3883 MESSAGE("MED version: "<< version);
3886 _preMeshInfo->FullLoadFromFile();
3889 bool have0dField = false;
3890 if ( fields.length() > 0 )
3892 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3893 if ( shapeToMesh->_is_nil() )
3894 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3896 for ( size_t i = 0; i < fields.length(); ++i )
3898 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3899 THROW_SALOME_CORBA_EXCEPTION
3900 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3901 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3902 if ( fieldShape->_is_nil() )
3903 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3904 if ( !fieldShape->IsSame( shapeToMesh ) )
3905 THROW_SALOME_CORBA_EXCEPTION
3906 ( "Field defined not on shape", SALOME::BAD_PARAM);
3907 if ( fields[i]->GetDimension() == 0 )
3910 if ( geomAssocFields )
3911 for ( int i = 0; geomAssocFields[i]; ++i )
3912 switch ( geomAssocFields[i] ) {
3913 case 'v':case 'e':case 'f':case 's': break;
3914 case 'V':case 'E':case 'F':case 'S': break;
3915 default: THROW_SALOME_CORBA_EXCEPTION
3916 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3920 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3924 string aMeshName = "Mesh";
3925 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3926 if ( CORBA::is_nil( meshPart ) ||
3927 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3929 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3930 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3931 0, autoDimension, /*addODOnVertices=*/have0dField,
3933 meshDS = _impl->GetMeshDS();
3938 _preMeshInfo->FullLoadFromFile();
3940 PrepareForWriting(file, overwrite);
3942 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3943 if ( !SO->_is_nil() ) {
3944 CORBA::String_var name = SO->GetName();
3948 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3949 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3950 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3951 meshDS = tmpDSDeleter._obj = partDS;
3956 if ( _impl->HasShapeToMesh() )
3958 DriverMED_W_Field fieldWriter;
3959 fieldWriter.SetFile( file );
3960 fieldWriter.SetMeshName( aMeshName );
3961 fieldWriter.AddODOnVertices( have0dField );
3963 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3967 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3968 goList->length( fields.length() );
3969 for ( size_t i = 0; i < fields.length(); ++i )
3971 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3974 TPythonDump() << _this() << ".ExportPartToMED( "
3975 << meshPart << ", r'"
3977 << auto_groups << ", "
3979 << overwrite << ", "
3980 << autoDimension << ", "
3982 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3983 << TVar( ZTolerance )
3986 SMESH_CATCH( SMESH::throwCorbaException );
3989 //================================================================================
3991 * Write GEOM fields to MED file
3993 //================================================================================
3995 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3996 SMESHDS_Mesh* meshDS,
3997 const GEOM::ListOfFields& fields,
3998 const char* geomAssocFields)
4000 #define METH "SMESH_Mesh_i::exportMEDFields() "
4002 if (( fields.length() < 1 ) &&
4003 ( !geomAssocFields || !geomAssocFields[0] ))
4006 std::vector< std::vector< double > > dblVals;
4007 std::vector< std::vector< int > > intVals;
4008 std::vector< int > subIdsByDim[ 4 ];
4009 const double noneDblValue = 0.;
4010 const double noneIntValue = 0;
4012 for ( size_t iF = 0; iF < fields.length(); ++iF )
4016 int dim = fields[ iF ]->GetDimension();
4017 SMDSAbs_ElementType elemType;
4018 TopAbs_ShapeEnum shapeType;
4020 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
4021 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
4022 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
4023 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
4025 continue; // skip fields on whole shape
4027 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
4028 if ( dataType == GEOM::FDT_String )
4030 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
4031 if ( stepIDs->length() < 1 )
4033 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
4034 if ( comps->length() < 1 )
4036 CORBA::String_var name = fields[ iF ]->GetName();
4038 if ( !fieldWriter.Set( meshDS,
4042 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
4045 for ( size_t iC = 0; iC < comps->length(); ++iC )
4046 fieldWriter.SetCompName( iC, comps[ iC ].in() );
4048 dblVals.resize( comps->length() );
4049 intVals.resize( comps->length() );
4051 // find sub-shape IDs
4053 std::vector< int >& subIds = subIdsByDim[ dim ];
4054 if ( subIds.empty() )
4055 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
4056 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
4057 subIds.push_back( id );
4061 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4065 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
4067 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
4068 if ( step->_is_nil() )
4071 CORBA::Long stamp = step->GetStamp();
4072 CORBA::Long id = step->GetID();
4073 fieldWriter.SetDtIt( int( stamp ), int( id ));
4075 // fill dblVals or intVals
4076 for ( size_t iC = 0; iC < comps->length(); ++iC )
4077 if ( dataType == GEOM::FDT_Double )
4079 dblVals[ iC ].clear();
4080 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4084 intVals[ iC ].clear();
4085 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4089 case GEOM::FDT_Double:
4091 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
4092 if ( dblStep->_is_nil() ) continue;
4093 GEOM::ListOfDouble_var vv = dblStep->GetValues();
4094 if ( vv->length() != subIds.size() * comps->length() )
4095 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4096 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4097 for ( size_t iC = 0; iC < comps->length(); ++iC )
4098 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
4103 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
4104 if ( intStep->_is_nil() ) continue;
4105 GEOM::ListOfLong_var vv = intStep->GetValues();
4106 if ( vv->length() != subIds.size() * comps->length() )
4107 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4108 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4109 for ( size_t iC = 0; iC < comps->length(); ++iC )
4110 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4113 case GEOM::FDT_Bool:
4115 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
4116 if ( boolStep->_is_nil() ) continue;
4117 GEOM::short_array_var vv = boolStep->GetValues();
4118 if ( vv->length() != subIds.size() * comps->length() )
4119 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4120 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4121 for ( size_t iC = 0; iC < comps->length(); ++iC )
4122 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4128 // pass values to fieldWriter
4129 elemIt = fieldWriter.GetOrderedElems();
4130 if ( dataType == GEOM::FDT_Double )
4131 while ( elemIt->more() )
4133 const SMDS_MeshElement* e = elemIt->next();
4134 const int shapeID = e->getshapeId();
4135 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
4136 for ( size_t iC = 0; iC < comps->length(); ++iC )
4137 fieldWriter.AddValue( noneDblValue );
4139 for ( size_t iC = 0; iC < comps->length(); ++iC )
4140 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
4143 while ( elemIt->more() )
4145 const SMDS_MeshElement* e = elemIt->next();
4146 const int shapeID = e->getshapeId();
4147 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
4148 for ( size_t iC = 0; iC < comps->length(); ++iC )
4149 fieldWriter.AddValue( (double) noneIntValue );
4151 for ( size_t iC = 0; iC < comps->length(); ++iC )
4152 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4156 fieldWriter.Perform();
4157 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4158 if ( res && res->IsKO() )
4160 if ( res->myComment.empty() )
4161 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4163 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4169 if ( !geomAssocFields || !geomAssocFields[0] )
4172 // write geomAssocFields
4174 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4175 shapeDim[ TopAbs_COMPOUND ] = 3;
4176 shapeDim[ TopAbs_COMPSOLID ] = 3;
4177 shapeDim[ TopAbs_SOLID ] = 3;
4178 shapeDim[ TopAbs_SHELL ] = 2;
4179 shapeDim[ TopAbs_FACE ] = 2;
4180 shapeDim[ TopAbs_WIRE ] = 1;
4181 shapeDim[ TopAbs_EDGE ] = 1;
4182 shapeDim[ TopAbs_VERTEX ] = 0;
4183 shapeDim[ TopAbs_SHAPE ] = 3;
4185 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4187 std::vector< std::string > compNames;
4188 switch ( geomAssocFields[ iF ]) {
4190 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4191 compNames.push_back( "dim" );
4194 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4197 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4200 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4204 compNames.push_back( "id" );
4205 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4206 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4208 fieldWriter.SetDtIt( -1, -1 );
4210 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4214 if ( compNames.size() == 2 ) // _vertices_
4215 while ( elemIt->more() )
4217 const SMDS_MeshElement* e = elemIt->next();
4218 const int shapeID = e->getshapeId();
4221 fieldWriter.AddValue( (double) -1 );
4222 fieldWriter.AddValue( (double) -1 );
4226 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4227 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4228 fieldWriter.AddValue( (double) shapeID );
4232 while ( elemIt->more() )
4234 const SMDS_MeshElement* e = elemIt->next();
4235 const int shapeID = e->getshapeId();
4237 fieldWriter.AddValue( (double) -1 );
4239 fieldWriter.AddValue( (double) shapeID );
4243 fieldWriter.Perform();
4244 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4245 if ( res && res->IsKO() )
4247 if ( res->myComment.empty() )
4248 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4250 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4253 } // loop on geomAssocFields
4258 //================================================================================
4260 * \brief Export a part of mesh to a DAT file
4262 //================================================================================
4264 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4266 throw (SALOME::SALOME_Exception)
4268 Unexpect aCatch(SALOME_SalomeException);
4270 _preMeshInfo->FullLoadFromFile();
4272 PrepareForWriting(file);
4274 SMESH_MeshPartDS partDS( meshPart );
4275 _impl->ExportDAT(file,&partDS);
4277 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4278 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4280 //================================================================================
4282 * \brief Export a part of mesh to an UNV file
4284 //================================================================================
4286 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4288 throw (SALOME::SALOME_Exception)
4290 Unexpect aCatch(SALOME_SalomeException);
4292 _preMeshInfo->FullLoadFromFile();
4294 PrepareForWriting(file);
4296 SMESH_MeshPartDS partDS( meshPart );
4297 _impl->ExportUNV(file, &partDS);
4299 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4300 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4302 //================================================================================
4304 * \brief Export a part of mesh to an STL file
4306 //================================================================================
4308 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4310 ::CORBA::Boolean isascii)
4311 throw (SALOME::SALOME_Exception)
4313 Unexpect aCatch(SALOME_SalomeException);
4315 _preMeshInfo->FullLoadFromFile();
4317 PrepareForWriting(file);
4319 CORBA::String_var name;
4320 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4321 if ( !so->_is_nil() )
4322 name = so->GetName();
4324 SMESH_MeshPartDS partDS( meshPart );
4325 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4327 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4328 << meshPart<< ", r'" << file << "', " << isascii << ")";
4331 //================================================================================
4333 * \brief Export a part of mesh to an STL file
4335 //================================================================================
4337 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4339 CORBA::Boolean overwrite,
4340 CORBA::Boolean groupElemsByType)
4341 throw (SALOME::SALOME_Exception)
4344 Unexpect aCatch(SALOME_SalomeException);
4346 _preMeshInfo->FullLoadFromFile();
4348 PrepareForWriting(file,overwrite);
4350 std::string meshName("");
4351 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4352 if ( !so->_is_nil() )
4354 CORBA::String_var name = so->GetName();
4355 meshName = name.in();
4359 SMESH_MeshPartDS partDS( meshPart );
4360 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4362 SMESH_CATCH( SMESH::throwCorbaException );
4364 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4365 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4367 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4371 //================================================================================
4373 * \brief Export a part of mesh to a GMF file
4375 //================================================================================
4377 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4379 bool withRequiredGroups)
4380 throw (SALOME::SALOME_Exception)
4382 Unexpect aCatch(SALOME_SalomeException);
4384 _preMeshInfo->FullLoadFromFile();
4386 PrepareForWriting(file,/*overwrite=*/true);
4388 SMESH_MeshPartDS partDS( meshPart );
4389 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4391 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4392 << meshPart<< ", r'"
4394 << withRequiredGroups << ")";
4397 //=============================================================================
4399 * Return computation progress [0.,1]
4401 //=============================================================================
4403 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4407 return _impl->GetComputeProgress();
4409 SMESH_CATCH( SMESH::doNothing );
4413 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4415 Unexpect aCatch(SALOME_SalomeException);
4417 return _preMeshInfo->NbNodes();
4419 return _impl->NbNodes();
4422 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4424 Unexpect aCatch(SALOME_SalomeException);
4426 return _preMeshInfo->NbElements();
4428 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4431 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4433 Unexpect aCatch(SALOME_SalomeException);
4435 return _preMeshInfo->Nb0DElements();
4437 return _impl->Nb0DElements();
4440 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4442 Unexpect aCatch(SALOME_SalomeException);
4444 return _preMeshInfo->NbBalls();
4446 return _impl->NbBalls();
4449 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4451 Unexpect aCatch(SALOME_SalomeException);
4453 return _preMeshInfo->NbEdges();
4455 return _impl->NbEdges();
4458 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4459 throw(SALOME::SALOME_Exception)
4461 Unexpect aCatch(SALOME_SalomeException);
4463 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4465 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4468 //=============================================================================
4470 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4472 Unexpect aCatch(SALOME_SalomeException);
4474 return _preMeshInfo->NbFaces();
4476 return _impl->NbFaces();
4479 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4481 Unexpect aCatch(SALOME_SalomeException);
4483 return _preMeshInfo->NbTriangles();
4485 return _impl->NbTriangles();
4488 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4490 Unexpect aCatch(SALOME_SalomeException);
4492 return _preMeshInfo->NbBiQuadTriangles();
4494 return _impl->NbBiQuadTriangles();
4497 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4499 Unexpect aCatch(SALOME_SalomeException);
4501 return _preMeshInfo->NbQuadrangles();
4503 return _impl->NbQuadrangles();
4506 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4508 Unexpect aCatch(SALOME_SalomeException);
4510 return _preMeshInfo->NbBiQuadQuadrangles();
4512 return _impl->NbBiQuadQuadrangles();
4515 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4517 Unexpect aCatch(SALOME_SalomeException);
4519 return _preMeshInfo->NbPolygons();
4521 return _impl->NbPolygons();
4524 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4526 Unexpect aCatch(SALOME_SalomeException);
4528 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4530 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4533 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4534 throw(SALOME::SALOME_Exception)
4536 Unexpect aCatch(SALOME_SalomeException);
4538 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4540 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4543 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4544 throw(SALOME::SALOME_Exception)
4546 Unexpect aCatch(SALOME_SalomeException);
4548 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4550 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4553 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4554 throw(SALOME::SALOME_Exception)
4556 Unexpect aCatch(SALOME_SalomeException);
4558 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4560 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4563 //=============================================================================
4565 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4567 Unexpect aCatch(SALOME_SalomeException);
4569 return _preMeshInfo->NbVolumes();
4571 return _impl->NbVolumes();
4574 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4576 Unexpect aCatch(SALOME_SalomeException);
4578 return _preMeshInfo->NbTetras();
4580 return _impl->NbTetras();
4583 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4585 Unexpect aCatch(SALOME_SalomeException);
4587 return _preMeshInfo->NbHexas();
4589 return _impl->NbHexas();
4592 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4594 Unexpect aCatch(SALOME_SalomeException);
4596 return _preMeshInfo->NbTriQuadHexas();
4598 return _impl->NbTriQuadraticHexas();
4601 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4603 Unexpect aCatch(SALOME_SalomeException);
4605 return _preMeshInfo->NbPyramids();
4607 return _impl->NbPyramids();
4610 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4612 Unexpect aCatch(SALOME_SalomeException);
4614 return _preMeshInfo->NbPrisms();
4616 return _impl->NbPrisms();
4619 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4621 Unexpect aCatch(SALOME_SalomeException);
4623 return _preMeshInfo->NbHexPrisms();
4625 return _impl->NbHexagonalPrisms();
4628 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4630 Unexpect aCatch(SALOME_SalomeException);
4632 return _preMeshInfo->NbPolyhedrons();
4634 return _impl->NbPolyhedrons();
4637 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4638 throw(SALOME::SALOME_Exception)
4640 Unexpect aCatch(SALOME_SalomeException);
4642 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4644 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4647 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4648 throw(SALOME::SALOME_Exception)
4650 Unexpect aCatch(SALOME_SalomeException);
4652 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4654 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4657 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4658 throw(SALOME::SALOME_Exception)
4660 Unexpect aCatch(SALOME_SalomeException);
4662 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4664 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4667 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4668 throw(SALOME::SALOME_Exception)
4670 Unexpect aCatch(SALOME_SalomeException);
4672 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4674 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4677 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4678 throw(SALOME::SALOME_Exception)
4680 Unexpect aCatch(SALOME_SalomeException);
4682 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4684 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4687 //=============================================================================
4689 * Returns nb of published sub-meshes
4691 //=============================================================================
4693 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4695 Unexpect aCatch(SALOME_SalomeException);
4696 return _mapSubMesh_i.size();
4699 //=============================================================================
4701 * Dumps mesh into a string
4703 //=============================================================================
4705 char* SMESH_Mesh_i::Dump()
4709 return CORBA::string_dup( os.str().c_str() );
4712 //=============================================================================
4714 * Method of SMESH_IDSource interface
4716 //=============================================================================
4718 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4720 return GetElementsId();
4723 //=============================================================================
4725 * Returns ids of all elements
4727 //=============================================================================
4729 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4730 throw (SALOME::SALOME_Exception)
4732 Unexpect aCatch(SALOME_SalomeException);
4734 _preMeshInfo->FullLoadFromFile();
4736 SMESH::long_array_var aResult = new SMESH::long_array();
4737 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4739 if ( aSMESHDS_Mesh == NULL )
4740 return aResult._retn();
4742 long nbElements = NbElements();
4743 aResult->length( nbElements );
4744 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4745 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4746 aResult[i] = anIt->next()->GetID();
4748 return aResult._retn();
4752 //=============================================================================
4754 * Returns ids of all elements of given type
4756 //=============================================================================
4758 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4759 throw (SALOME::SALOME_Exception)
4761 Unexpect aCatch(SALOME_SalomeException);
4763 _preMeshInfo->FullLoadFromFile();
4765 SMESH::long_array_var aResult = new SMESH::long_array();
4766 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4768 if ( aSMESHDS_Mesh == NULL )
4769 return aResult._retn();
4771 long nbElements = NbElements();
4773 // No sense in returning ids of elements along with ids of nodes:
4774 // when theElemType == SMESH::ALL, return node ids only if
4775 // there are no elements
4776 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4777 return GetNodesId();
4779 aResult->length( nbElements );
4783 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4784 while ( i < nbElements && anIt->more() )
4785 aResult[i++] = anIt->next()->GetID();
4787 aResult->length( i );
4789 return aResult._retn();
4792 //=============================================================================
4794 * Returns ids of all nodes
4796 //=============================================================================
4798 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
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* aMeshDS = _impl->GetMeshDS();
4808 if ( aMeshDS == NULL )
4809 return aResult._retn();
4811 long nbNodes = NbNodes();
4812 aResult->length( nbNodes );
4813 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4814 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4815 aResult[i] = anIt->next()->GetID();
4817 return aResult._retn();
4820 //=============================================================================
4824 //=============================================================================
4826 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4827 throw (SALOME::SALOME_Exception)
4829 SMESH::ElementType type = SMESH::ALL;
4833 _preMeshInfo->FullLoadFromFile();
4835 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4837 SMESH_CATCH( SMESH::throwCorbaException );
4842 //=============================================================================
4846 //=============================================================================
4848 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4849 throw (SALOME::SALOME_Exception)
4852 _preMeshInfo->FullLoadFromFile();
4854 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4856 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4858 return ( SMESH::EntityType ) e->GetEntityType();
4861 //=============================================================================
4865 //=============================================================================
4867 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4868 throw (SALOME::SALOME_Exception)
4871 _preMeshInfo->FullLoadFromFile();
4873 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4875 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4877 return ( SMESH::GeometryType ) e->GetGeomType();
4880 //=============================================================================
4882 * Returns ID of elements for given submesh
4884 //=============================================================================
4885 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4886 throw (SALOME::SALOME_Exception)
4888 SMESH::long_array_var aResult = new SMESH::long_array();
4892 _preMeshInfo->FullLoadFromFile();
4894 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4895 if(!SM) return aResult._retn();
4897 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4898 if(!SDSM) return aResult._retn();
4900 aResult->length(SDSM->NbElements());
4902 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4904 while ( eIt->more() ) {
4905 aResult[i++] = eIt->next()->GetID();
4908 SMESH_CATCH( SMESH::throwCorbaException );
4910 return aResult._retn();
4913 //=============================================================================
4915 * Returns ID of nodes for given submesh
4916 * If param all==true - returns all nodes, else -
4917 * returns only nodes on shapes.
4919 //=============================================================================
4921 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4923 throw (SALOME::SALOME_Exception)
4925 SMESH::long_array_var aResult = new SMESH::long_array();
4929 _preMeshInfo->FullLoadFromFile();
4931 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4932 if(!SM) return aResult._retn();
4934 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4935 if(!SDSM) return aResult._retn();
4938 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4939 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4940 while ( nIt->more() ) {
4941 const SMDS_MeshNode* elem = nIt->next();
4942 theElems.insert( elem->GetID() );
4945 else { // all nodes of submesh elements
4946 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4947 while ( eIt->more() ) {
4948 const SMDS_MeshElement* anElem = eIt->next();
4949 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4950 while ( nIt->more() ) {
4951 const SMDS_MeshElement* elem = nIt->next();
4952 theElems.insert( elem->GetID() );
4957 aResult->length(theElems.size());
4958 set<int>::iterator itElem;
4960 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4961 aResult[i++] = *itElem;
4963 SMESH_CATCH( SMESH::throwCorbaException );
4965 return aResult._retn();
4968 //=============================================================================
4970 * Returns type of elements for given submesh
4972 //=============================================================================
4974 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4975 throw (SALOME::SALOME_Exception)
4977 SMESH::ElementType type = SMESH::ALL;
4981 _preMeshInfo->FullLoadFromFile();
4983 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4984 if(!SM) return SMESH::ALL;
4986 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4987 if(!SDSM) return SMESH::ALL;
4989 if(SDSM->NbElements()==0)
4990 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4992 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4993 const SMDS_MeshElement* anElem = eIt->next();
4995 type = ( SMESH::ElementType ) anElem->GetType();
4997 SMESH_CATCH( SMESH::throwCorbaException );
5003 //=============================================================================
5005 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
5007 //=============================================================================
5009 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
5012 _preMeshInfo->FullLoadFromFile();
5014 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
5015 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
5020 //=============================================================================
5022 * Get XYZ coordinates of node as list of double
5023 * If there is not node for given ID - returns empty list
5025 //=============================================================================
5027 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
5030 _preMeshInfo->FullLoadFromFile();
5032 SMESH::double_array_var aResult = new SMESH::double_array();
5033 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5034 if ( aMeshDS == NULL )
5035 return aResult._retn();
5038 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5040 return aResult._retn();
5044 aResult[0] = aNode->X();
5045 aResult[1] = aNode->Y();
5046 aResult[2] = aNode->Z();
5047 return aResult._retn();
5051 //=============================================================================
5053 * For given node returns list of IDs of inverse elements
5054 * If there is not node for given ID - returns empty list
5056 //=============================================================================
5058 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
5059 SMESH::ElementType elemType)
5062 _preMeshInfo->FullLoadFromFile();
5064 SMESH::long_array_var aResult = new SMESH::long_array();
5065 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5066 if ( aMeshDS == NULL )
5067 return aResult._retn();
5070 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
5072 return aResult._retn();
5074 // find inverse elements
5075 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
5076 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
5077 aResult->length( aNode->NbInverseElements( type ));
5078 for( int i = 0; eIt->more(); ++i )
5080 const SMDS_MeshElement* elem = eIt->next();
5081 aResult[ i ] = elem->GetID();
5083 return aResult._retn();
5086 //=============================================================================
5088 * \brief Return position of a node on shape
5090 //=============================================================================
5092 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
5095 _preMeshInfo->FullLoadFromFile();
5097 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
5098 aNodePosition->shapeID = 0;
5099 aNodePosition->shapeType = GEOM::SHAPE;
5101 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5102 if ( !mesh ) return aNodePosition;
5104 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
5106 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
5108 aNodePosition->shapeID = aNode->getshapeId();
5109 switch ( pos->GetTypeOfPosition() ) {
5111 aNodePosition->shapeType = GEOM::EDGE;
5112 aNodePosition->params.length(1);
5113 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
5115 case SMDS_TOP_FACE: {
5116 SMDS_FacePositionPtr fPos = pos;
5117 aNodePosition->shapeType = GEOM::FACE;
5118 aNodePosition->params.length(2);
5119 aNodePosition->params[0] = fPos->GetUParameter();
5120 aNodePosition->params[1] = fPos->GetVParameter();
5123 case SMDS_TOP_VERTEX:
5124 aNodePosition->shapeType = GEOM::VERTEX;
5126 case SMDS_TOP_3DSPACE:
5127 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
5128 aNodePosition->shapeType = GEOM::SOLID;
5129 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
5130 aNodePosition->shapeType = GEOM::SHELL;
5136 return aNodePosition;
5139 //=============================================================================
5141 * \brief Return position of an element on shape
5143 //=============================================================================
5145 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
5148 _preMeshInfo->FullLoadFromFile();
5150 SMESH::ElementPosition anElementPosition;
5151 anElementPosition.shapeID = 0;
5152 anElementPosition.shapeType = GEOM::SHAPE;
5154 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5155 if ( !mesh ) return anElementPosition;
5157 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5159 anElementPosition.shapeID = anElem->getshapeId();
5160 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5161 if ( !aSp.IsNull() ) {
5162 switch ( aSp.ShapeType() ) {
5164 anElementPosition.shapeType = GEOM::EDGE;
5167 anElementPosition.shapeType = GEOM::FACE;
5170 anElementPosition.shapeType = GEOM::VERTEX;
5173 anElementPosition.shapeType = GEOM::SOLID;
5176 anElementPosition.shapeType = GEOM::SHELL;
5182 return anElementPosition;
5185 //=============================================================================
5187 * If given element is node returns IDs of shape from position
5188 * If there is not node for given ID - returns -1
5190 //=============================================================================
5192 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5195 _preMeshInfo->FullLoadFromFile();
5197 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5198 if ( aMeshDS == NULL )
5202 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5204 return aNode->getshapeId();
5211 //=============================================================================
5213 * For given element returns ID of result shape after
5214 * ::FindShape() from SMESH_MeshEditor
5215 * If there is not element for given ID - returns -1
5217 //=============================================================================
5219 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5222 _preMeshInfo->FullLoadFromFile();
5224 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5225 if ( aMeshDS == NULL )
5228 // try to find element
5229 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5233 ::SMESH_MeshEditor aMeshEditor(_impl);
5234 int index = aMeshEditor.FindShape( elem );
5242 //=============================================================================
5244 * Returns number of nodes for given element
5245 * If there is not element for given ID - returns -1
5247 //=============================================================================
5249 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5252 _preMeshInfo->FullLoadFromFile();
5254 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5255 if ( aMeshDS == NULL ) return -1;
5256 // try to find element
5257 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5258 if(!elem) return -1;
5259 return elem->NbNodes();
5263 //=============================================================================
5265 * Returns ID of node by given index for given element
5266 * If there is not element for given ID - returns -1
5267 * If there is not node for given index - returns -2
5269 //=============================================================================
5271 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5274 _preMeshInfo->FullLoadFromFile();
5276 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5277 if ( aMeshDS == NULL ) return -1;
5278 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5279 if(!elem) return -1;
5280 if( index>=elem->NbNodes() || index<0 ) return -1;
5281 return elem->GetNode(index)->GetID();
5284 //=============================================================================
5286 * Returns IDs of nodes of given element
5288 //=============================================================================
5290 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5293 _preMeshInfo->FullLoadFromFile();
5295 SMESH::long_array_var aResult = new SMESH::long_array();
5296 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5298 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5300 aResult->length( elem->NbNodes() );
5301 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5302 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5303 aResult[ i ] = n->GetID();
5306 return aResult._retn();
5309 //=============================================================================
5311 * Returns true if given node is medium node
5312 * in given quadratic element
5314 //=============================================================================
5316 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5319 _preMeshInfo->FullLoadFromFile();
5321 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5322 if ( aMeshDS == NULL ) return false;
5324 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5325 if(!aNode) return false;
5326 // try to find element
5327 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5328 if(!elem) return false;
5330 return elem->IsMediumNode(aNode);
5334 //=============================================================================
5336 * Returns true if given node is medium node
5337 * in one of quadratic elements
5339 //=============================================================================
5341 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5342 SMESH::ElementType theElemType)
5345 _preMeshInfo->FullLoadFromFile();
5347 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5348 if ( aMeshDS == NULL ) return false;
5351 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5352 if(!aNode) return false;
5354 SMESH_MesherHelper aHelper( *(_impl) );
5356 SMDSAbs_ElementType aType;
5357 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5358 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5359 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5360 else aType = SMDSAbs_All;
5362 return aHelper.IsMedium(aNode,aType);
5366 //=============================================================================
5368 * Returns number of edges for given element
5370 //=============================================================================
5372 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5375 _preMeshInfo->FullLoadFromFile();
5377 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5378 if ( aMeshDS == NULL ) return -1;
5379 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5380 if(!elem) return -1;
5381 return elem->NbEdges();
5385 //=============================================================================
5387 * Returns number of faces for given element
5389 //=============================================================================
5391 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5394 _preMeshInfo->FullLoadFromFile();
5396 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5397 if ( aMeshDS == NULL ) return -1;
5398 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5399 if(!elem) return -1;
5400 return elem->NbFaces();
5403 //=======================================================================
5404 //function : GetElemFaceNodes
5405 //purpose : Returns nodes of given face (counted from zero) for given element.
5406 //=======================================================================
5408 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5409 CORBA::Short faceIndex)
5412 _preMeshInfo->FullLoadFromFile();
5414 SMESH::long_array_var aResult = new SMESH::long_array();
5415 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5417 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5419 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5420 if ( faceIndex < vtool.NbFaces() )
5422 aResult->length( vtool.NbFaceNodes( faceIndex ));
5423 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5424 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5425 aResult[ i ] = nn[ i ]->GetID();
5429 return aResult._retn();
5432 //=======================================================================
5433 //function : GetFaceNormal
5434 //purpose : Returns three components of normal of given mesh face.
5435 //=======================================================================
5437 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5438 CORBA::Boolean normalized)
5441 _preMeshInfo->FullLoadFromFile();
5443 SMESH::double_array_var aResult = new SMESH::double_array();
5445 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5448 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5450 aResult->length( 3 );
5451 aResult[ 0 ] = normal.X();
5452 aResult[ 1 ] = normal.Y();
5453 aResult[ 2 ] = normal.Z();
5456 return aResult._retn();
5459 //=======================================================================
5460 //function : FindElementByNodes
5461 //purpose : Returns an element based on all given nodes.
5462 //=======================================================================
5464 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5467 _preMeshInfo->FullLoadFromFile();
5469 CORBA::Long elemID(0);
5470 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5472 vector< const SMDS_MeshNode * > nn( nodes.length() );
5473 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5474 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5477 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5478 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5479 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5480 _impl->NbVolumes( ORDER_QUADRATIC )))
5481 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5483 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5488 //================================================================================
5490 * \brief Return elements including all given nodes.
5492 //================================================================================
5494 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5495 SMESH::ElementType elemType)
5498 _preMeshInfo->FullLoadFromFile();
5500 SMESH::long_array_var result = new SMESH::long_array();
5502 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5504 vector< const SMDS_MeshNode * > nn( nodes.length() );
5505 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5506 nn[i] = mesh->FindNode( nodes[i] );
5508 std::vector<const SMDS_MeshElement *> elems;
5509 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5510 result->length( elems.size() );
5511 for ( size_t i = 0; i < elems.size(); ++i )
5512 result[i] = elems[i]->GetID();
5514 return result._retn();
5517 //=============================================================================
5519 * Returns true if given element is polygon
5521 //=============================================================================
5523 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5526 _preMeshInfo->FullLoadFromFile();
5528 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5529 if ( aMeshDS == NULL ) return false;
5530 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5531 if(!elem) return false;
5532 return elem->IsPoly();
5536 //=============================================================================
5538 * Returns true if given element is quadratic
5540 //=============================================================================
5542 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5545 _preMeshInfo->FullLoadFromFile();
5547 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5548 if ( aMeshDS == NULL ) return false;
5549 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5550 if(!elem) return false;
5551 return elem->IsQuadratic();
5554 //=============================================================================
5556 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5558 //=============================================================================
5560 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5563 _preMeshInfo->FullLoadFromFile();
5565 if ( const SMDS_BallElement* ball =
5566 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5567 return ball->GetDiameter();
5572 //=============================================================================
5574 * Returns bary center for given element
5576 //=============================================================================
5578 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5581 _preMeshInfo->FullLoadFromFile();
5583 SMESH::double_array_var aResult = new SMESH::double_array();
5584 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5585 if ( aMeshDS == NULL )
5586 return aResult._retn();
5588 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5590 return aResult._retn();
5592 if(elem->GetType()==SMDSAbs_Volume) {
5593 SMDS_VolumeTool aTool;
5594 if(aTool.Set(elem)) {
5596 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5601 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5603 double x=0., y=0., z=0.;
5604 for(; anIt->more(); ) {
5606 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5620 return aResult._retn();
5623 //================================================================================
5625 * \brief Create a group of elements preventing computation of a sub-shape
5627 //================================================================================
5629 SMESH::ListOfGroups*
5630 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5631 const char* theGroupName )
5632 throw ( SALOME::SALOME_Exception )
5634 Unexpect aCatch(SALOME_SalomeException);
5636 if ( !theGroupName || strlen( theGroupName) == 0 )
5637 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5639 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5640 ::SMESH_MeshEditor::ElemFeatures elemType;
5642 // submesh by subshape id
5643 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5644 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5647 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5648 if ( error && error->HasBadElems() )
5650 // sort bad elements by type
5651 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5652 const list<const SMDS_MeshElement*>& badElems =
5653 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5654 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5655 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5656 for ( ; elemIt != elemEnd; ++elemIt )
5658 const SMDS_MeshElement* elem = *elemIt;
5659 if ( !elem ) continue;
5661 if ( elem->GetID() < 1 )
5663 // elem is a temporary element, make a real element
5664 vector< const SMDS_MeshNode* > nodes;
5665 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5666 while ( nIt->more() && elem )
5668 nodes.push_back( nIt->next() );
5669 if ( nodes.back()->GetID() < 1 )
5670 elem = 0; // a temporary element on temporary nodes
5674 ::SMESH_MeshEditor editor( _impl );
5675 elem = editor.AddElement( nodes, elemType.Init( elem ));
5679 elemsByType[ elem->GetType() ].push_back( elem );
5682 // how many groups to create?
5684 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5685 nbTypes += int( !elemsByType[ i ].empty() );
5686 groups->length( nbTypes );
5689 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5691 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5692 if ( elems.empty() ) continue;
5694 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5695 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5697 SMESH::SMESH_Mesh_var mesh = _this();
5698 SALOMEDS::SObject_wrap aSO =
5699 _gen_i->PublishGroup( mesh, groups[ iG ],
5700 GEOM::GEOM_Object::_nil(), theGroupName);
5702 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5703 if ( !grp_i ) continue;
5705 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5706 for ( size_t iE = 0; iE < elems.size(); ++iE )
5707 grpDS->SMDSGroup().Add( elems[ iE ]);
5712 return groups._retn();
5715 //=============================================================================
5717 * Create and publish group servants if any groups were imported or created anyhow
5719 //=============================================================================
5721 void SMESH_Mesh_i::CreateGroupServants()
5723 SMESH::SMESH_Mesh_var aMesh = _this();
5726 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5727 while ( groupIt->more() )
5729 ::SMESH_Group* group = groupIt->next();
5730 int anId = group->GetID();
5732 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5733 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5735 addedIDs.insert( anId );
5737 SMESH_GroupBase_i* aGroupImpl;
5739 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5740 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5742 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5743 shape = groupOnGeom->GetShape();
5746 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5749 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5750 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5751 aGroupImpl->Register();
5753 // register CORBA object for persistence
5754 int nextId = _gen_i->RegisterObject( groupVar );
5755 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5756 else { nextId = 0; } // avoid "unused variable" warning in release mode
5758 // publishing the groups in the study
5759 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5760 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5762 if ( !addedIDs.empty() )
5765 set<int>::iterator id = addedIDs.begin();
5766 for ( ; id != addedIDs.end(); ++id )
5768 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5769 int i = std::distance( _mapGroups.begin(), it );
5770 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5775 //=============================================================================
5777 * \brief Return true if all sub-meshes are computed OK - to update an icon
5779 //=============================================================================
5781 bool SMESH_Mesh_i::IsComputedOK()
5783 return _impl->IsComputedOK();
5786 //=============================================================================
5788 * \brief Return groups cantained in _mapGroups by their IDs
5790 //=============================================================================
5792 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5794 int nbGroups = groupIDs.size();
5795 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5796 aList->length( nbGroups );
5798 list<int>::const_iterator ids = groupIDs.begin();
5799 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5801 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5802 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5803 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5805 aList->length( nbGroups );
5806 return aList._retn();
5809 //=============================================================================
5811 * \brief Return information about imported file
5813 //=============================================================================
5815 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5817 SMESH::MedFileInfo_var res( _medFileInfo );
5818 if ( !res.operator->() ) {
5819 res = new SMESH::MedFileInfo;
5821 res->fileSize = res->major = res->minor = res->release = -1;
5826 //=======================================================================
5827 //function : FileInfoToString
5828 //purpose : Persistence of file info
5829 //=======================================================================
5831 std::string SMESH_Mesh_i::FileInfoToString()
5834 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5836 s = SMESH_Comment( _medFileInfo->fileSize )
5837 << " " << _medFileInfo->major
5838 << " " << _medFileInfo->minor
5839 << " " << _medFileInfo->release
5840 << " " << _medFileInfo->fileName;
5845 //=======================================================================
5846 //function : FileInfoFromString
5847 //purpose : Persistence of file info
5848 //=======================================================================
5850 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5852 std::string size, major, minor, release, fileName;
5853 std::istringstream is(info);
5854 is >> size >> major >> minor >> release;
5855 fileName = info.data() + ( size.size() + 1 +
5858 release.size()+ 1 );
5860 _medFileInfo = new SMESH::MedFileInfo();
5861 _medFileInfo->fileName = fileName.c_str();
5862 _medFileInfo->fileSize = atoi( size.c_str() );
5863 _medFileInfo->major = atoi( major.c_str() );
5864 _medFileInfo->minor = atoi( minor.c_str() );
5865 _medFileInfo->release = atoi( release.c_str() );
5868 //=============================================================================
5870 * \brief Pass names of mesh groups from study to mesh DS
5872 //=============================================================================
5874 void SMESH_Mesh_i::checkGroupNames()
5876 int nbGrp = NbGroups();
5880 SMESH::ListOfGroups* grpList = 0;
5881 // avoid dump of "GetGroups"
5883 // store python dump into a local variable inside local scope
5884 SMESH::TPythonDump pDump; // do not delete this line of code
5885 grpList = GetGroups();
5888 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5889 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5892 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5893 if ( aGrpSO->_is_nil() )
5895 // correct name of the mesh group if necessary
5896 const char* guiName = aGrpSO->GetName();
5897 if ( strcmp(guiName, aGrp->GetName()) )
5898 aGrp->SetName( guiName );
5902 //=============================================================================
5904 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5906 //=============================================================================
5907 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5909 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5913 //=============================================================================
5915 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5917 //=============================================================================
5919 char* SMESH_Mesh_i::GetParameters()
5921 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5924 //=============================================================================
5926 * \brief Returns list of notebook variables used for last Mesh operation
5928 //=============================================================================
5929 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5931 SMESH::string_array_var aResult = new SMESH::string_array();
5932 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5934 CORBA::String_var aParameters = GetParameters();
5935 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5936 if ( aSections->length() > 0 ) {
5937 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5938 aResult->length( aVars.length() );
5939 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5940 aResult[i] = CORBA::string_dup( aVars[i] );
5943 return aResult._retn();
5946 //=======================================================================
5947 //function : GetTypes
5948 //purpose : Returns types of elements it contains
5949 //=======================================================================
5951 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5954 return _preMeshInfo->GetTypes();
5956 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5960 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5961 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5962 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5963 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5964 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5965 if (_impl->NbNodes() &&
5966 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5967 types->length( nbTypes );
5969 return types._retn();
5972 //=======================================================================
5973 //function : GetMesh
5974 //purpose : Returns self
5975 //=======================================================================
5977 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5979 return SMESH::SMESH_Mesh::_duplicate( _this() );
5982 //=======================================================================
5983 //function : IsMeshInfoCorrect
5984 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5985 // * happen if mesh data is not yet fully loaded from the file of study.
5986 //=======================================================================
5988 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5990 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5993 //=============================================================================
5995 * \brief Returns number of mesh elements per each \a EntityType
5997 //=============================================================================
5999 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
6002 return _preMeshInfo->GetMeshInfo();
6004 SMESH::long_array_var aRes = new SMESH::long_array();
6005 aRes->length(SMESH::Entity_Last);
6006 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6008 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6010 return aRes._retn();
6011 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
6012 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6013 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
6014 return aRes._retn();
6017 //=============================================================================
6019 * \brief Returns number of mesh elements per each \a ElementType
6021 //=============================================================================
6023 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
6025 SMESH::long_array_var aRes = new SMESH::long_array();
6026 aRes->length(SMESH::NB_ELEMENT_TYPES);
6027 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6030 const SMDS_MeshInfo* meshInfo = 0;
6032 meshInfo = _preMeshInfo;
6033 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
6034 meshInfo = & meshDS->GetMeshInfo();
6037 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6038 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
6040 return aRes._retn();
6043 //=============================================================================
6045 * Collect statistic of mesh elements given by iterator
6047 //=============================================================================
6049 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
6050 SMESH::long_array& theInfo)
6052 if (!theItr) return;
6053 while (theItr->more())
6054 theInfo[ theItr->next()->GetEntityType() ]++;
6056 //=============================================================================
6058 * Returns mesh unstructed grid information.
6060 //=============================================================================
6062 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
6064 SALOMEDS::TMPFile_var SeqFile;
6065 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
6066 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
6068 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
6069 aWriter->WriteToOutputStringOn();
6070 aWriter->SetInputData(aGrid);
6071 aWriter->SetFileTypeToBinary();
6073 char* str = aWriter->GetOutputString();
6074 int size = aWriter->GetOutputStringLength();
6076 //Allocate octet buffer of required size
6077 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
6078 //Copy ostrstream content to the octet buffer
6079 memcpy(OctetBuf, str, size);
6080 //Create and return TMPFile
6081 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
6085 return SeqFile._retn();
6088 //=============================================================================
6089 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
6090 * SMESH::ElementType type) */
6092 using namespace SMESH::Controls;
6093 //-----------------------------------------------------------------------------
6094 struct PredicateIterator : public SMDS_ElemIterator
6096 SMDS_ElemIteratorPtr _elemIter;
6097 PredicatePtr _predicate;
6098 const SMDS_MeshElement* _elem;
6099 SMDSAbs_ElementType _type;
6101 PredicateIterator( SMDS_ElemIteratorPtr iterator,
6102 PredicatePtr predicate,
6103 SMDSAbs_ElementType type):
6104 _elemIter(iterator), _predicate(predicate), _type(type)
6112 virtual const SMDS_MeshElement* next()
6114 const SMDS_MeshElement* res = _elem;
6116 while ( _elemIter->more() && !_elem )
6118 if ((_elem = _elemIter->next()) &&
6119 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
6120 ( !_predicate->IsSatisfy( _elem->GetID() ))))
6127 //-----------------------------------------------------------------------------
6128 struct IDSourceIterator : public SMDS_ElemIterator
6130 const CORBA::Long* _idPtr;
6131 const CORBA::Long* _idEndPtr;
6132 SMESH::long_array_var _idArray;
6133 const SMDS_Mesh* _mesh;
6134 const SMDSAbs_ElementType _type;
6135 const SMDS_MeshElement* _elem;
6137 IDSourceIterator( const SMDS_Mesh* mesh,
6138 const CORBA::Long* ids,
6140 SMDSAbs_ElementType type):
6141 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
6143 if ( _idPtr && nbIds && _mesh )
6146 IDSourceIterator( const SMDS_Mesh* mesh,
6147 SMESH::long_array* idArray,
6148 SMDSAbs_ElementType type):
6149 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
6151 if ( idArray && _mesh )
6153 _idPtr = &_idArray[0];
6154 _idEndPtr = _idPtr + _idArray->length();
6162 virtual const SMDS_MeshElement* next()
6164 const SMDS_MeshElement* res = _elem;
6166 while ( _idPtr < _idEndPtr && !_elem )
6168 if ( _type == SMDSAbs_Node )
6170 _elem = _mesh->FindNode( *_idPtr++ );
6172 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6173 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6181 //-----------------------------------------------------------------------------
6183 struct NodeOfElemIterator : public SMDS_ElemIterator
6185 TColStd_MapOfInteger _checkedNodeIDs;
6186 SMDS_ElemIteratorPtr _elemIter;
6187 SMDS_ElemIteratorPtr _nodeIter;
6188 const SMDS_MeshElement* _node;
6190 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6192 if ( _elemIter && _elemIter->more() )
6194 _nodeIter = _elemIter->next()->nodesIterator();
6202 virtual const SMDS_MeshElement* next()
6204 const SMDS_MeshElement* res = _node;
6206 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6208 if ( _nodeIter->more() )
6210 _node = _nodeIter->next();
6211 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6216 _nodeIter = _elemIter->next()->nodesIterator();
6224 //=============================================================================
6226 * Return iterator on elements of given type in given object
6228 //=============================================================================
6230 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6231 SMESH::ElementType theType)
6233 SMDS_ElemIteratorPtr elemIt;
6234 bool typeOK = ( theType == SMESH::ALL );
6235 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6237 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6238 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6239 if ( !mesh_i ) return elemIt;
6240 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6242 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6244 elemIt = meshDS->elementsIterator( elemType );
6247 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6249 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6252 elemIt = sm->GetElements();
6253 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6255 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6256 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6260 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6262 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6263 if ( groupDS && ( elemType == groupDS->GetType() ||
6264 elemType == SMDSAbs_Node ||
6265 elemType == SMDSAbs_All ))
6267 elemIt = groupDS->GetElements();
6268 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6271 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6273 if ( filter_i->GetElementType() == theType ||
6274 filter_i->GetElementType() == SMESH::ALL ||
6275 elemType == SMDSAbs_Node ||
6276 elemType == SMDSAbs_All)
6278 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6279 if ( pred_i && pred_i->GetPredicate() )
6281 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6282 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6283 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6284 elemIt = SMDS_ElemIteratorPtr
6285 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6286 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6292 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6293 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6294 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6296 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6297 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6300 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6301 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6305 SMESH::long_array_var ids = theObject->GetIDs();
6306 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6308 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6311 if ( elemIt && elemIt->more() && !typeOK )
6313 if ( elemType == SMDSAbs_Node )
6315 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6319 elemIt = SMDS_ElemIteratorPtr();
6325 //=============================================================================
6326 namespace // Finding concurrent hypotheses
6327 //=============================================================================
6331 * \brief mapping of mesh dimension into shape type
6333 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6335 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6337 case 0: aType = TopAbs_VERTEX; break;
6338 case 1: aType = TopAbs_EDGE; break;
6339 case 2: aType = TopAbs_FACE; break;
6341 default:aType = TopAbs_SOLID; break;
6346 //-----------------------------------------------------------------------------
6348 * \brief Internal structure used to find concurrent submeshes
6350 * It represents a pair < submesh, concurrent dimension >, where
6351 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6352 * with another submesh. In other words, it is dimension of a hypothesis assigned
6359 int _dim; //!< a dimension the algo can build (concurrent dimension)
6360 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6361 TopTools_MapOfShape _shapeMap;
6362 SMESH_subMesh* _subMesh;
6363 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6365 //-----------------------------------------------------------------------------
6366 // Return the algorithm
6367 const SMESH_Algo* GetAlgo() const
6368 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6370 //-----------------------------------------------------------------------------
6372 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6374 const TopoDS_Shape& theShape)
6376 _subMesh = (SMESH_subMesh*)theSubMesh;
6377 SetShape( theDim, theShape );
6380 //-----------------------------------------------------------------------------
6382 void SetShape(const int theDim,
6383 const TopoDS_Shape& theShape)
6386 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6387 if (_dim >= _ownDim)
6388 _shapeMap.Add( theShape );
6390 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6391 for( ; anExp.More(); anExp.Next() )
6392 _shapeMap.Add( anExp.Current() );
6396 //-----------------------------------------------------------------------------
6397 //! Check sharing of sub-shapes
6398 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6399 const TopTools_MapOfShape& theToFind,
6400 const TopAbs_ShapeEnum theType)
6402 bool isShared = false;
6403 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6404 for (; !isShared && anItr.More(); anItr.Next() )
6406 const TopoDS_Shape aSubSh = anItr.Key();
6407 // check for case when concurrent dimensions are same
6408 isShared = theToFind.Contains( aSubSh );
6409 // check for sub-shape with concurrent dimension
6410 TopExp_Explorer anExp( aSubSh, theType );
6411 for ( ; !isShared && anExp.More(); anExp.Next() )
6412 isShared = theToFind.Contains( anExp.Current() );
6417 //-----------------------------------------------------------------------------
6418 //! check algorithms
6419 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6420 const SMESHDS_Hypothesis* theA2)
6422 if ( !theA1 || !theA2 ||
6423 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6424 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6425 return false; // one of the hypothesis is not algorithm
6426 // check algorithm names (should be equal)
6427 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6431 //-----------------------------------------------------------------------------
6432 //! Check if sub-shape hypotheses are concurrent
6433 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6435 if ( _subMesh == theOther->_subMesh )
6436 return false; // same sub-shape - should not be
6438 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6439 // any of the two submeshes is not on COMPOUND shape )
6440 // -> no concurrency
6441 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6442 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6443 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6444 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6445 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6448 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6449 if ( !checkSubShape )
6452 // check algorithms to be same
6453 const SMESH_Algo* a1 = this->GetAlgo();
6454 const SMESH_Algo* a2 = theOther->GetAlgo();
6455 bool isSame = checkAlgo( a1, a2 );
6459 return false; // pb?
6460 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6463 // check hypothesises for concurrence (skip first as algorithm)
6465 // pointers should be same, because it is referened from mesh hypothesis partition
6466 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6467 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6468 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6469 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6471 // the submeshes are concurrent if their algorithms has different parameters
6472 return nbSame != theOther->_hypotheses.size() - 1;
6475 // Return true if algorithm of this SMESH_DimHyp is used if no
6476 // sub-mesh order is imposed by the user
6477 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6479 // NeedDiscreteBoundary() algo has a higher priority
6480 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6481 theOther->GetAlgo()->NeedDiscreteBoundary() )
6482 return !this->GetAlgo()->NeedDiscreteBoundary();
6484 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6487 }; // end of SMESH_DimHyp
6488 //-----------------------------------------------------------------------------
6490 typedef list<const SMESH_DimHyp*> TDimHypList;
6492 //-----------------------------------------------------------------------------
6494 void addDimHypInstance(const int theDim,
6495 const TopoDS_Shape& theShape,
6496 const SMESH_Algo* theAlgo,
6497 const SMESH_subMesh* theSubMesh,
6498 const list <const SMESHDS_Hypothesis*>& theHypList,
6499 TDimHypList* theDimHypListArr )
6501 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6502 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6503 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6504 dimHyp->_hypotheses.push_front(theAlgo);
6505 listOfdimHyp.push_back( dimHyp );
6508 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6509 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6510 theHypList.begin(), theHypList.end() );
6513 //-----------------------------------------------------------------------------
6514 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6515 TDimHypList& theListOfConcurr)
6517 if ( theListOfConcurr.empty() )
6519 theListOfConcurr.push_back( theDimHyp );
6523 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6524 while ( hypIt != theListOfConcurr.end() &&
6525 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6527 theListOfConcurr.insert( hypIt, theDimHyp );
6531 //-----------------------------------------------------------------------------
6532 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6533 const TDimHypList& theListOfDimHyp,
6534 TDimHypList& theListOfConcurrHyp,
6535 set<int>& theSetOfConcurrId )
6537 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6538 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6540 const SMESH_DimHyp* curDimHyp = *rIt;
6541 if ( curDimHyp == theDimHyp )
6542 break; // meet own dimHyp pointer in same dimension
6544 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6545 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6547 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6552 //-----------------------------------------------------------------------------
6553 void unionLists(TListOfInt& theListOfId,
6554 TListOfListOfInt& theListOfListOfId,
6557 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6558 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6560 continue; //skip already treated lists
6561 // check if other list has any same submesh object
6562 TListOfInt& otherListOfId = *it;
6563 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6564 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6567 // union two lists (from source into target)
6568 TListOfInt::iterator it2 = otherListOfId.begin();
6569 for ( ; it2 != otherListOfId.end(); it2++ ) {
6570 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6571 theListOfId.push_back(*it2);
6573 // clear source list
6574 otherListOfId.clear();
6577 //-----------------------------------------------------------------------------
6579 //! free memory allocated for dimension-hypothesis objects
6580 void removeDimHyps( TDimHypList* theArrOfList )
6582 for (int i = 0; i < 4; i++ ) {
6583 TDimHypList& listOfdimHyp = theArrOfList[i];
6584 TDimHypList::const_iterator it = listOfdimHyp.begin();
6585 for ( ; it != listOfdimHyp.end(); it++ )
6590 //-----------------------------------------------------------------------------
6592 * \brief find common submeshes with given submesh
6593 * \param theSubMeshList list of already collected submesh to check
6594 * \param theSubMesh given submesh to intersect with other
6595 * \param theCommonSubMeshes collected common submeshes
6597 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6598 const SMESH_subMesh* theSubMesh,
6599 set<const SMESH_subMesh*>& theCommon )
6603 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6604 for ( ; it != theSubMeshList.end(); it++ )
6605 theSubMesh->FindIntersection( *it, theCommon );
6606 theSubMeshList.push_back( theSubMesh );
6607 //theCommon.insert( theSubMesh );
6610 //-----------------------------------------------------------------------------
6611 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6613 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6614 for ( ; listsIt != smLists.end(); ++listsIt )
6616 const TListOfInt& smIDs = *listsIt;
6617 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6625 //=============================================================================
6627 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6629 //=============================================================================
6631 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6633 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6634 if ( isSubMeshInList( submeshID, anOrder ))
6637 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6638 return isSubMeshInList( submeshID, allConurrent );
6641 //=============================================================================
6643 * \brief Return submesh objects list in meshing order
6645 //=============================================================================
6647 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6649 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6651 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6653 return aResult._retn();
6655 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6656 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6657 anOrder.splice( anOrder.end(), allConurrent );
6660 TListOfListOfInt::iterator listIt = anOrder.begin();
6661 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6662 unionLists( *listIt, anOrder, listIndx + 1 );
6664 // convert submesh ids into interface instances
6665 // and dump command into python
6666 convertMeshOrder( anOrder, aResult, false );
6668 return aResult._retn();
6671 //=============================================================================
6673 * \brief Finds concurrent sub-meshes
6675 //=============================================================================
6677 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6679 TListOfListOfInt anOrder;
6680 ::SMESH_Mesh& mesh = GetImpl();
6682 // collect submeshes and detect concurrent algorithms and hypothesises
6683 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6685 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6686 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6687 ::SMESH_subMesh* sm = (*i_sm).second;
6689 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6691 // list of assigned hypothesises
6692 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6693 // Find out dimensions where the submesh can be concurrent.
6694 // We define the dimensions by algo of each of hypotheses in hypList
6695 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6696 for( ; hypIt != hypList.end(); hypIt++ ) {
6697 SMESH_Algo* anAlgo = 0;
6698 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6699 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6700 // hyp it-self is algo
6701 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6703 // try to find algorithm with help of sub-shapes
6704 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6705 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6706 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6709 continue; // no algorithm assigned to a current submesh
6711 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6712 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6714 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6715 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6716 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6718 } // end iterations on submesh
6720 // iterate on created dimension-hypotheses and check for concurrents
6721 for ( int i = 0; i < 4; i++ ) {
6722 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6723 // check for concurrents in own and other dimensions (step-by-step)
6724 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6725 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6726 const SMESH_DimHyp* dimHyp = *dhIt;
6727 TDimHypList listOfConcurr;
6728 set<int> setOfConcurrIds;
6729 // looking for concurrents and collect into own list
6730 for ( int j = i; j < 4; j++ )
6731 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6732 // check if any concurrents found
6733 if ( listOfConcurr.size() > 0 ) {
6734 // add own submesh to list of concurrent
6735 addInOrderOfPriority( dimHyp, listOfConcurr );
6736 list<int> listOfConcurrIds;
6737 TDimHypList::iterator hypIt = listOfConcurr.begin();
6738 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6739 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6740 anOrder.push_back( listOfConcurrIds );
6745 removeDimHyps(dimHypListArr);
6747 // now, minimize the number of concurrent groups
6748 // Here we assume that lists of submeshes can have same submesh
6749 // in case of multi-dimension algorithms, as result
6750 // list with common submesh has to be united into one list
6752 TListOfListOfInt::iterator listIt = anOrder.begin();
6753 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6754 unionLists( *listIt, anOrder, listIndx + 1 );
6760 //=============================================================================
6762 * \brief Set submesh object order
6763 * \param theSubMeshArray submesh array order
6765 //=============================================================================
6767 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6770 _preMeshInfo->ForgetOrLoad();
6773 ::SMESH_Mesh& mesh = GetImpl();
6775 TPythonDump aPythonDump; // prevent dump of called methods
6776 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6778 TListOfListOfInt subMeshOrder;
6779 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6781 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6782 TListOfInt subMeshIds;
6784 aPythonDump << ", ";
6785 aPythonDump << "[ ";
6786 // Collect subMeshes which should be clear
6787 // do it list-by-list, because modification of submesh order
6788 // take effect between concurrent submeshes only
6789 set<const SMESH_subMesh*> subMeshToClear;
6790 list<const SMESH_subMesh*> subMeshList;
6791 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6793 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6795 aPythonDump << ", ";
6796 aPythonDump << subMesh;
6797 subMeshIds.push_back( subMesh->GetId() );
6798 // detect common parts of submeshes
6799 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6800 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6802 aPythonDump << " ]";
6803 subMeshOrder.push_back( subMeshIds );
6805 // clear collected sub-meshes
6806 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6807 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6808 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6810 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6811 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6812 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6815 aPythonDump << " ])";
6817 mesh.SetMeshOrder( subMeshOrder );
6820 SMESH::SMESH_Mesh_var me = _this();
6821 _gen_i->UpdateIcons( me );
6826 //=============================================================================
6828 * \brief Convert submesh ids into submesh interfaces
6830 //=============================================================================
6832 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6833 SMESH::submesh_array_array& theResOrder,
6834 const bool theIsDump)
6836 int nbSet = theIdsOrder.size();
6837 TPythonDump aPythonDump; // prevent dump of called methods
6839 aPythonDump << "[ ";
6840 theResOrder.length(nbSet);
6841 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6843 for( ; it != theIdsOrder.end(); it++ ) {
6844 // translate submesh identificators into submesh objects
6845 // takeing into account real number of concurrent lists
6846 const TListOfInt& aSubOrder = (*it);
6847 if (!aSubOrder.size())
6850 aPythonDump << "[ ";
6851 // convert shape indices into interfaces
6852 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6853 aResSubSet->length(aSubOrder.size());
6854 TListOfInt::const_iterator subIt = aSubOrder.begin();
6856 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6857 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6859 SMESH::SMESH_subMesh_var subMesh =
6860 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6863 aPythonDump << ", ";
6864 aPythonDump << subMesh;
6866 aResSubSet[ j++ ] = subMesh;
6869 aPythonDump << " ]";
6871 theResOrder[ listIndx++ ] = aResSubSet;
6873 // correct number of lists
6874 theResOrder.length( listIndx );
6877 // finilise python dump
6878 aPythonDump << " ]";
6879 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6883 namespace // utils used by SMESH_MeshPartDS
6886 * \brief Class used to access to protected data of SMDS_MeshInfo
6888 struct TMeshInfo : public SMDS_MeshInfo
6890 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6893 * \brief Element holing its ID only
6895 struct TElemID : public SMDS_LinearEdge
6897 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6901 //================================================================================
6903 // Implementation of SMESH_MeshPartDS
6905 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6906 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6908 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6909 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6912 _meshDS = mesh_i->GetImpl().GetMeshDS();
6914 SetPersistentId( _meshDS->GetPersistentId() );
6916 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6918 // <meshPart> is the whole mesh
6919 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6921 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6922 myGroupSet = _meshDS->GetGroups();
6927 SMESH::long_array_var anIDs = meshPart->GetIDs();
6928 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6929 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6931 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6932 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6933 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6938 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6939 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6940 if ( _elements[ e->GetType() ].insert( e ).second )
6943 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6944 while ( nIt->more() )
6946 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6947 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6954 ShapeToMesh( _meshDS->ShapeToMesh() );
6956 _meshDS = 0; // to enforce iteration on _elements and _nodes
6959 // -------------------------------------------------------------------------------------
6960 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6961 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6964 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6965 for ( ; partIt != meshPart.end(); ++partIt )
6966 if ( const SMDS_MeshElement * e = *partIt )
6967 if ( _elements[ e->GetType() ].insert( e ).second )
6970 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6971 while ( nIt->more() )
6973 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6974 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6980 // -------------------------------------------------------------------------------------
6981 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6983 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6985 TElemID elem( IDelem );
6986 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6987 if ( !_elements[ iType ].empty() )
6989 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6990 if ( it != _elements[ iType ].end() )
6995 // -------------------------------------------------------------------------------------
6996 bool SMESH_MeshPartDS::HasNumerationHoles()
6998 if ( _meshDS ) return _meshDS->HasNumerationHoles();
7000 return ( MinNodeID() != 1 ||
7001 MaxNodeID() != NbNodes() ||
7002 MinElementID() != 1 ||
7003 MaxElementID() != NbElements() );
7005 // -------------------------------------------------------------------------------------
7006 int SMESH_MeshPartDS::MaxNodeID() const
7008 if ( _meshDS ) return _meshDS->MaxNodeID();
7009 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
7011 // -------------------------------------------------------------------------------------
7012 int SMESH_MeshPartDS::MinNodeID() const
7014 if ( _meshDS ) return _meshDS->MinNodeID();
7015 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
7017 // -------------------------------------------------------------------------------------
7018 int SMESH_MeshPartDS::MaxElementID() const
7020 if ( _meshDS ) return _meshDS->MaxElementID();
7022 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7023 if ( !_elements[ iType ].empty() )
7024 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
7027 // -------------------------------------------------------------------------------------
7028 int SMESH_MeshPartDS::MinElementID() const
7030 if ( _meshDS ) return _meshDS->MinElementID();
7032 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7033 if ( !_elements[ iType ].empty() )
7034 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
7037 // -------------------------------------------------------------------------------------
7038 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
7040 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
7042 typedef SMDS_SetIterator
7043 <const SMDS_MeshElement*,
7044 TIDSortedElemSet::const_iterator,
7045 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7046 SMDS_MeshElement::GeomFilter
7049 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
7051 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7052 _elements[type].end(),
7053 SMDS_MeshElement::GeomFilter( geomType )));
7055 // -------------------------------------------------------------------------------------
7056 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
7058 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
7060 typedef SMDS_SetIterator
7061 <const SMDS_MeshElement*,
7062 TIDSortedElemSet::const_iterator,
7063 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7064 SMDS_MeshElement::EntityFilter
7067 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
7069 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7070 _elements[type].end(),
7071 SMDS_MeshElement::EntityFilter( entity )));
7073 // -------------------------------------------------------------------------------------
7074 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
7076 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
7077 if ( type == SMDSAbs_All && !_meshDS )
7079 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
7081 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
7082 if ( !_elements[i].empty() && i != SMDSAbs_Node )
7084 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
7086 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
7087 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
7089 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
7090 ( new TIter( _elements[type].begin(), _elements[type].end() ));
7092 // -------------------------------------------------------------------------------------
7093 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
7094 iterType SMESH_MeshPartDS::methName() const \
7096 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
7097 return _meshDS ? _meshDS->methName() : iterType \
7098 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
7100 // -------------------------------------------------------------------------------------
7101 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
7102 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
7103 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
7104 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
7105 #undef _GET_ITER_DEFINE
7107 // END Implementation of SMESH_MeshPartDS
7109 //================================================================================