1 // Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_DataMapOfShapeShape.hxx>
76 #include <TopTools_MapIteratorOfMapOfShape.hxx>
77 #include <TopTools_MapOfShape.hxx>
78 #include <TopoDS_Compound.hxx>
85 #include <vtkUnstructuredGridWriter.h>
87 // to pass CORBA exception through SMESH_TRY
88 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
90 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 static int MYDEBUG = 0;
95 static int MYDEBUG = 0;
99 using SMESH::TPythonDump;
102 int SMESH_Mesh_i::_idGenerator = 0;
104 //=============================================================================
108 //=============================================================================
110 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
112 : SALOME::GenericObj_i( thePOA )
116 _id = _idGenerator++;
118 _previewEditor = NULL;
123 //=============================================================================
127 //=============================================================================
129 SMESH_Mesh_i::~SMESH_Mesh_i()
132 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
133 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
134 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
136 aGroup->UnRegister();
137 SMESH::SMESH_GroupBase_var( itGr->second );
142 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
143 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
144 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
146 aSubMesh->UnRegister();
147 SMESH::SMESH_subMesh_var( itSM->second );
149 _mapSubMeshIor.clear();
151 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
152 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
153 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
154 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
155 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
156 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
159 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
163 // clear cached shapes if no more meshes remain; (the cache is blame,
164 // together with publishing, of spent time increasing in issue 22874)
165 if ( _impl->NbMeshes() == 1 )
166 _gen_i->GetShapeReader()->ClearClientBuffer();
168 delete _editor; _editor = NULL;
169 delete _previewEditor; _previewEditor = NULL;
170 delete _impl; _impl = NULL;
171 delete _preMeshInfo; _preMeshInfo = NULL;
174 //=============================================================================
178 * Associates <this> mesh with <theShape> and puts a reference
179 * to <theShape> into the current study;
180 * the previous shape is substituted by the new one.
182 //=============================================================================
184 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
185 throw (SALOME::SALOME_Exception)
187 Unexpect aCatch(SALOME_SalomeException);
189 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
191 catch(SALOME_Exception & S_ex) {
192 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
194 // to track changes of GEOM groups
195 SMESH::SMESH_Mesh_var mesh = _this();
196 addGeomGroupData( theShapeObject, mesh );
197 if ( !CORBA::is_nil( theShapeObject ))
198 _mainShapeTick = theShapeObject->GetTick();
201 //================================================================================
203 * \brief return true if mesh has a shape to build a shape on
205 //================================================================================
207 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
208 throw (SALOME::SALOME_Exception)
210 Unexpect aCatch(SALOME_SalomeException);
213 res = _impl->HasShapeToMesh();
215 catch(SALOME_Exception & S_ex) {
216 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
221 //=======================================================================
222 //function : GetShapeToMesh
224 //=======================================================================
226 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
227 throw (SALOME::SALOME_Exception)
229 Unexpect aCatch(SALOME_SalomeException);
230 GEOM::GEOM_Object_var aShapeObj;
232 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
236 if ( aShapeObj->_is_nil() )
238 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
239 // find GEOM_Object by entry (IPAL52735)
240 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
241 for ( ; data != _geomGroupData.end(); ++data )
242 if ( data->_smeshObject->_is_equivalent( _this() ))
244 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
245 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
246 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
252 catch(SALOME_Exception & S_ex) {
253 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
255 return aShapeObj._retn();
258 //================================================================================
260 * \brief Replaces a shape in the mesh
262 //================================================================================
263 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
264 throw (SALOME::SALOME_Exception)
266 TopoDS_Shape S = _impl->GetShapeToMesh();
267 GEOM_Client* geomClient = _gen_i->GetShapeReader();
268 TCollection_AsciiString aIOR;
269 if (geomClient->Find(S, aIOR)) {
270 geomClient->RemoveShapeFromBuffer(aIOR);
273 // re-assign global hypotheses to the new shape
275 CheckGeomModif( true );
277 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
278 SALOMEDS::SObject_var aSO = _gen_i->ObjectToSObject(_this());
279 if (!aSO->_is_nil()) {
280 SALOMEDS::SObject_var aShapeRefSO;
281 if (aSO->FindSubObject(1, aShapeRefSO)) {
282 _gen_i->getStudyServant()->NewBuilder()->Addreference(
283 aShapeRefSO, _gen_i->getStudyServant()->FindObjectID(theNewGeom->GetStudyEntry()));
287 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ReplaceShape( "
288 << theNewGeom->GetStudyEntry() << " )";
290 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
291 << SMESH::SMESH_Mesh_var(_this()) <<".GetMesh()), " << theNewGeom->GetStudyEntry() << ")";
294 //================================================================================
296 * \brief Return false if the mesh is not yet fully loaded from the study file
298 //================================================================================
300 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
302 Unexpect aCatch(SALOME_SalomeException);
303 return !_preMeshInfo;
306 //================================================================================
308 * \brief Load full mesh data from the study file
310 //================================================================================
312 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
314 Unexpect aCatch(SALOME_SalomeException);
316 _preMeshInfo->FullLoadFromFile();
319 //================================================================================
321 * \brief Remove all nodes and elements
323 //================================================================================
325 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
327 Unexpect aCatch(SALOME_SalomeException);
329 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
333 //CheckGeomGroupModif(); // issue 20145
335 catch(SALOME_Exception & S_ex) {
336 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
339 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
341 SMESH::SMESH_Mesh_var mesh = _this();
342 _gen_i->UpdateIcons( mesh );
345 //================================================================================
347 * \brief Remove all nodes and elements for indicated shape
349 //================================================================================
351 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
352 throw (SALOME::SALOME_Exception)
354 Unexpect aCatch(SALOME_SalomeException);
356 _preMeshInfo->FullLoadFromFile();
359 _impl->ClearSubMesh( ShapeID );
361 catch(SALOME_Exception & S_ex) {
362 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
364 _impl->GetMeshDS()->Modified();
366 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
369 //=============================================================================
371 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
373 //=============================================================================
375 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
377 SMESH::DriverMED_ReadStatus res;
380 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
381 res = SMESH::DRS_OK; break;
382 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
383 res = SMESH::DRS_EMPTY; break;
384 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
385 res = SMESH::DRS_WARN_RENUMBER; break;
386 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
387 res = SMESH::DRS_WARN_SKIP_ELEM; break;
388 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
389 res = SMESH::DRS_WARN_DESCENDING; break;
390 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
392 res = SMESH::DRS_FAIL; break;
397 //=============================================================================
399 * Convert ::SMESH_ComputeError to SMESH::ComputeError
401 //=============================================================================
403 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
405 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
406 errVar->subShapeID = -1;
407 errVar->hasBadMesh = false;
409 if ( !errorPtr || errorPtr->IsOK() )
411 errVar->code = SMESH::COMPERR_OK;
415 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
416 errVar->comment = errorPtr->myComment.c_str();
418 return errVar._retn();
421 //=============================================================================
425 * Imports mesh data from MED file
427 //=============================================================================
429 SMESH::DriverMED_ReadStatus
430 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
431 throw ( SALOME::SALOME_Exception )
433 Unexpect aCatch(SALOME_SalomeException);
436 status = _impl->MEDToMesh( theFileName, theMeshName );
438 catch( SALOME_Exception& S_ex ) {
439 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
442 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
445 CreateGroupServants();
447 int major, minor, release;
448 major = minor = release = 0;
449 MED::GetMEDVersion(theFileName, major, minor, release);
450 _medFileInfo = new SMESH::MedFileInfo();
451 _medFileInfo->fileName = theFileName;
452 _medFileInfo->fileSize = 0;
453 _medFileInfo->major = major;
454 _medFileInfo->minor = minor;
455 _medFileInfo->release = release;
456 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
458 return ConvertDriverMEDReadStatus(status);
461 //================================================================================
463 * \brief Imports mesh data from the CGNS file
465 //================================================================================
467 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
468 const int theMeshIndex,
469 std::string& theMeshName )
470 throw ( SALOME::SALOME_Exception )
472 Unexpect aCatch(SALOME_SalomeException);
475 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
477 catch( SALOME_Exception& S_ex ) {
478 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
481 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
484 CreateGroupServants();
486 _medFileInfo = new SMESH::MedFileInfo();
487 _medFileInfo->fileName = theFileName;
488 _medFileInfo->major = 0;
489 _medFileInfo->minor = 0;
490 _medFileInfo->release = 0;
491 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
493 return ConvertDriverMEDReadStatus(status);
496 //================================================================================
498 * \brief Return string representation of a MED file version comprising nbDigits
500 //================================================================================
502 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
504 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
506 return CORBA::string_dup( ver.c_str() );
509 //================================================================================
511 * Return the list of med versions compatibles for write/append,
512 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
514 //================================================================================
515 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
517 SMESH::long_array_var aResult = new SMESH::long_array();
518 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
519 long nbver = mvok.size();
520 aResult->length( nbver );
521 for ( int i = 0; i < nbver; i++ )
522 aResult[i] = mvok[i];
523 return aResult._retn();
526 //=============================================================================
530 * Imports mesh data from MED file
532 //=============================================================================
534 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
535 throw ( SALOME::SALOME_Exception )
539 // Read mesh with name = <theMeshName> into SMESH_Mesh
540 _impl->UNVToMesh( theFileName );
542 CreateGroupServants();
544 _medFileInfo = new SMESH::MedFileInfo();
545 _medFileInfo->fileName = theFileName;
546 _medFileInfo->major = 0;
547 _medFileInfo->minor = 0;
548 _medFileInfo->release = 0;
549 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
551 SMESH_CATCH( SMESH::throwCorbaException );
556 //=============================================================================
560 * Imports mesh data from STL file
562 //=============================================================================
563 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
564 throw ( SALOME::SALOME_Exception )
568 // Read mesh with name = <theMeshName> into SMESH_Mesh
569 std::string name = _impl->STLToMesh( theFileName );
572 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
573 _gen_i->SetName( meshSO, name.c_str() );
575 _medFileInfo = new SMESH::MedFileInfo();
576 _medFileInfo->fileName = theFileName;
577 _medFileInfo->major = 0;
578 _medFileInfo->minor = 0;
579 _medFileInfo->release = 0;
580 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
582 SMESH_CATCH( SMESH::throwCorbaException );
587 //================================================================================
589 * \brief Function used in SMESH_CATCH by ImportGMFFile()
591 //================================================================================
595 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
597 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
601 //================================================================================
603 * \brief Imports data from a GMF file and returns an error description
605 //================================================================================
607 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
608 bool theMakeRequiredGroups )
609 throw (SALOME::SALOME_Exception)
611 SMESH_ComputeErrorPtr error;
614 #define SMESH_CAUGHT error =
617 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
619 _medFileInfo = new SMESH::MedFileInfo();
620 _medFileInfo->fileName = theFileName;
621 _medFileInfo->major = 0;
622 _medFileInfo->minor = 0;
623 _medFileInfo->release = 0;
624 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
626 SMESH_CATCH( exceptionToComputeError );
630 CreateGroupServants();
632 return ConvertComputeError( error );
635 //=============================================================================
639 //=============================================================================
641 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
643 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
644 (SMESH_Hypothesis::Hypothesis_Status theStatus)
647 RETURNCASE( HYP_OK );
648 RETURNCASE( HYP_MISSING );
649 RETURNCASE( HYP_CONCURRENT );
650 RETURNCASE( HYP_BAD_PARAMETER );
651 RETURNCASE( HYP_HIDDEN_ALGO );
652 RETURNCASE( HYP_HIDING_ALGO );
653 RETURNCASE( HYP_UNKNOWN_FATAL );
654 RETURNCASE( HYP_INCOMPATIBLE );
655 RETURNCASE( HYP_NOTCONFORM );
656 RETURNCASE( HYP_ALREADY_EXIST );
657 RETURNCASE( HYP_BAD_DIM );
658 RETURNCASE( HYP_BAD_SUBSHAPE );
659 RETURNCASE( HYP_BAD_GEOMETRY );
660 RETURNCASE( HYP_NEED_SHAPE );
661 RETURNCASE( HYP_INCOMPAT_HYPS );
664 return SMESH::HYP_UNKNOWN_FATAL;
667 //=============================================================================
671 * calls internal addHypothesis() and then adds a reference to <anHyp> under
672 * the SObject actually having a reference to <aSubShape>.
673 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
675 //=============================================================================
677 SMESH::Hypothesis_Status
678 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
679 SMESH::SMESH_Hypothesis_ptr anHyp,
680 CORBA::String_out anErrorText)
681 throw(SALOME::SALOME_Exception)
683 Unexpect aCatch(SALOME_SalomeException);
685 _preMeshInfo->ForgetOrLoad();
688 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
689 anErrorText = error.c_str();
691 SMESH::SMESH_Mesh_var mesh( _this() );
692 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
694 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
695 _gen_i->UpdateIcons( mesh );
697 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
699 // Update Python script
700 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
701 << aSubShape << ", " << anHyp << " )";
703 return ConvertHypothesisStatus(status);
706 //=============================================================================
710 //=============================================================================
712 SMESH_Hypothesis::Hypothesis_Status
713 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
714 SMESH::SMESH_Hypothesis_ptr anHyp,
715 std::string* anErrorText)
717 if(MYDEBUG) MESSAGE("addHypothesis");
719 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
720 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
722 if (CORBA::is_nil( anHyp ))
723 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
725 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
728 TopoDS_Shape myLocSubShape;
729 //use PseudoShape in case if mesh has no shape
731 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
733 myLocSubShape = _impl->GetShapeToMesh();
735 const int hypId = anHyp->GetId();
737 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
738 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
740 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
742 // assure there is a corresponding submesh
743 if ( !_impl->IsMainShape( myLocSubShape )) {
744 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
745 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
746 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
749 else if ( anErrorText )
751 *anErrorText = error;
754 catch(SALOME_Exception & S_ex)
756 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
761 //=============================================================================
765 //=============================================================================
767 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
768 SMESH::SMESH_Hypothesis_ptr anHyp)
769 throw(SALOME::SALOME_Exception)
771 Unexpect aCatch(SALOME_SalomeException);
773 _preMeshInfo->ForgetOrLoad();
775 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
776 SMESH::SMESH_Mesh_var mesh = _this();
778 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
780 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
781 _gen_i->UpdateIcons( mesh );
783 // Update Python script
784 if(_impl->HasShapeToMesh())
785 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
786 << aSubShape << ", " << anHyp << " )";
788 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
791 return ConvertHypothesisStatus(status);
794 //=============================================================================
798 //=============================================================================
800 SMESH_Hypothesis::Hypothesis_Status
801 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
802 SMESH::SMESH_Hypothesis_ptr anHyp)
804 if(MYDEBUG) MESSAGE("removeHypothesis()");
806 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
807 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
809 if (CORBA::is_nil( anHyp ))
810 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
813 _preMeshInfo->ForgetOrLoad();
815 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
818 TopoDS_Shape myLocSubShape;
819 //use PseudoShape in case if mesh has no shape
820 if( _impl->HasShapeToMesh() )
821 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
823 myLocSubShape = _impl->GetShapeToMesh();
825 const int hypId = anHyp->GetId();
826 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
827 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
829 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
833 catch(SALOME_Exception & S_ex)
835 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
840 //=============================================================================
844 //=============================================================================
846 SMESH::ListOfHypothesis *
847 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
848 throw(SALOME::SALOME_Exception)
850 Unexpect aCatch(SALOME_SalomeException);
851 if (MYDEBUG) MESSAGE("GetHypothesisList");
852 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
853 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
855 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
858 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
859 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
860 myLocSubShape = _impl->GetShapeToMesh();
861 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
862 int i = 0, n = aLocalList.size();
865 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
866 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
867 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
869 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
870 if ( id_hypptr != _mapHypo.end() )
871 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
875 catch(SALOME_Exception & S_ex) {
876 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
879 return aList._retn();
882 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
884 Unexpect aCatch(SALOME_SalomeException);
885 if (MYDEBUG) MESSAGE("GetSubMeshes");
887 SMESH::submesh_array_var aList = new SMESH::submesh_array();
890 TPythonDump aPythonDump;
891 if ( !_mapSubMeshIor.empty() )
895 aList->length( _mapSubMeshIor.size() );
897 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
898 for ( ; it != _mapSubMeshIor.end(); it++ ) {
899 if ( CORBA::is_nil( it->second )) continue;
900 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
902 if (i > 1) aPythonDump << ", ";
903 aPythonDump << it->second;
907 catch(SALOME_Exception & S_ex) {
908 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
911 // Update Python script
912 if ( !_mapSubMeshIor.empty() )
913 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
915 return aList._retn();
918 //=============================================================================
922 //=============================================================================
924 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
925 const char* theName )
926 throw(SALOME::SALOME_Exception)
928 Unexpect aCatch(SALOME_SalomeException);
929 if (CORBA::is_nil(aSubShape))
930 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
932 SMESH::SMESH_subMesh_var subMesh;
933 SMESH::SMESH_Mesh_var aMesh = _this();
935 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
937 //Get or Create the SMESH_subMesh object implementation
939 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
941 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
943 TopoDS_Iterator it( myLocSubShape );
945 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
947 subMesh = getSubMesh( subMeshId );
949 // create a new subMesh object servant if there is none for the shape
950 if ( subMesh->_is_nil() )
951 subMesh = createSubMesh( aSubShape );
952 if ( _gen_i->CanPublishInStudy( subMesh ))
954 SALOMEDS::SObject_wrap aSO =
955 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
956 if ( !aSO->_is_nil()) {
957 // Update Python script
958 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
959 << aSubShape << ", '" << theName << "' )";
963 catch(SALOME_Exception & S_ex) {
964 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
966 return subMesh._retn();
969 //=============================================================================
973 //=============================================================================
975 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
976 throw (SALOME::SALOME_Exception)
980 if ( theSubMesh->_is_nil() )
983 GEOM::GEOM_Object_var aSubShape;
984 // Remove submesh's SObject
985 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
986 if ( !anSO->_is_nil() ) {
987 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
988 SALOMEDS::SObject_wrap anObj, aRef;
989 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
990 anObj->ReferencedObject( aRef.inout() ))
992 CORBA::Object_var obj = aRef->GetObject();
993 aSubShape = GEOM::GEOM_Object::_narrow( obj );
995 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
996 // aSubShape = theSubMesh->GetSubShape();
998 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
999 builder->RemoveObjectWithChildren( anSO );
1001 // Update Python script
1002 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
1005 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
1007 _preMeshInfo->ForgetOrLoad();
1009 SMESH_CATCH( SMESH::throwCorbaException );
1012 //=============================================================================
1016 //=============================================================================
1018 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1019 const char* theName )
1020 throw(SALOME::SALOME_Exception)
1022 Unexpect aCatch(SALOME_SalomeException);
1024 _preMeshInfo->FullLoadFromFile();
1026 SMESH::SMESH_Group_var aNewGroup =
1027 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1029 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1031 SMESH::SMESH_Mesh_var mesh = _this();
1032 SALOMEDS::SObject_wrap aSO =
1033 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1034 if ( !aSO->_is_nil())
1035 // Update Python script
1036 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1037 << theElemType << ", '" << theName << "' )";
1039 return aNewGroup._retn();
1042 //=============================================================================
1046 //=============================================================================
1047 SMESH::SMESH_GroupOnGeom_ptr
1048 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1049 const char* theName,
1050 GEOM::GEOM_Object_ptr theGeomObj)
1051 throw(SALOME::SALOME_Exception)
1053 Unexpect aCatch(SALOME_SalomeException);
1055 _preMeshInfo->FullLoadFromFile();
1057 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1059 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1060 if ( !aShape.IsNull() )
1063 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1065 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1067 SMESH::SMESH_Mesh_var mesh = _this();
1068 SALOMEDS::SObject_wrap aSO =
1069 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1070 if ( !aSO->_is_nil())
1071 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1072 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1076 return aNewGroup._retn();
1079 //================================================================================
1081 * \brief Creates a group whose contents is defined by filter
1082 * \param theElemType - group type
1083 * \param theName - group name
1084 * \param theFilter - the filter
1085 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1087 //================================================================================
1089 SMESH::SMESH_GroupOnFilter_ptr
1090 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1091 const char* theName,
1092 SMESH::Filter_ptr theFilter )
1093 throw (SALOME::SALOME_Exception)
1095 Unexpect aCatch(SALOME_SalomeException);
1097 _preMeshInfo->FullLoadFromFile();
1099 if ( CORBA::is_nil( theFilter ))
1100 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1102 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1104 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1106 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1107 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1110 if ( !aNewGroup->_is_nil() )
1111 aNewGroup->SetFilter( theFilter );
1113 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1115 SMESH::SMESH_Mesh_var mesh = _this();
1116 SALOMEDS::SObject_wrap aSO =
1117 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1119 if ( !aSO->_is_nil())
1120 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1121 << theElemType << ", '" << theName << "', " << theFilter << " )";
1123 return aNewGroup._retn();
1126 //=============================================================================
1130 //=============================================================================
1132 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1133 throw (SALOME::SALOME_Exception)
1135 if ( theGroup->_is_nil() )
1140 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1144 if ( aGroup->GetMeshServant() != this )
1145 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1146 SALOME::BAD_PARAM );
1148 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1149 if ( !aGroupSO->_is_nil() )
1151 // Update Python script
1152 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1154 // Remove group's SObject
1155 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1156 builder->RemoveObjectWithChildren( aGroupSO );
1158 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1160 // Remove the group from SMESH data structures
1161 removeGroup( aGroup->GetLocalID() );
1163 SMESH_CATCH( SMESH::throwCorbaException );
1166 //=============================================================================
1168 * Remove group with its contents
1170 //=============================================================================
1172 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1173 throw (SALOME::SALOME_Exception)
1177 _preMeshInfo->FullLoadFromFile();
1179 if ( theGroup->_is_nil() )
1182 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1183 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1184 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1187 vector<int> nodeIds; // to remove nodes becoming free
1188 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1189 if ( !isNodal && !theGroup->IsEmpty() )
1191 CORBA::Long elemID = theGroup->GetID( 1 );
1192 int nbElemNodes = GetElemNbNodes( elemID );
1193 if ( nbElemNodes > 0 )
1194 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1197 // Retrieve contents
1198 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1199 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1200 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1201 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1202 elems.assign( elemBeg, elemEnd );
1204 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1207 RemoveGroup( theGroup );
1210 for ( size_t i = 0; i < elems.size(); ++i )
1212 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1216 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1217 nodeIds.push_back( nIt->next()->GetID() );
1219 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1223 _impl->GetMeshDS()->RemoveElement( elems[i] );
1227 // Remove free nodes
1228 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1229 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1230 if ( n->NbInverseElements() == 0 )
1231 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1233 // Update Python script (theGroup must be alive for this)
1234 pyDump << SMESH::SMESH_Mesh_var(_this())
1235 << ".RemoveGroupWithContents( " << theGroup << " )";
1237 SMESH_CATCH( SMESH::throwCorbaException );
1240 //================================================================================
1242 * \brief Get the list of groups existing in the mesh
1243 * \retval SMESH::ListOfGroups * - list of groups
1245 //================================================================================
1247 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1249 Unexpect aCatch(SALOME_SalomeException);
1250 if (MYDEBUG) MESSAGE("GetGroups");
1252 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1255 TPythonDump aPythonDump;
1256 if ( !_mapGroups.empty() )
1258 aPythonDump << "[ ";
1260 aList->length( _mapGroups.size() );
1262 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1263 for ( ; it != _mapGroups.end(); it++ ) {
1264 if ( CORBA::is_nil( it->second )) continue;
1265 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1267 if (i > 1) aPythonDump << ", ";
1268 aPythonDump << it->second;
1272 catch(SALOME_Exception & S_ex) {
1273 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1275 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1277 return aList._retn();
1280 //=============================================================================
1282 * Get number of groups existing in the mesh
1284 //=============================================================================
1286 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1288 Unexpect aCatch(SALOME_SalomeException);
1289 return _mapGroups.size();
1292 //=============================================================================
1294 * New group including all mesh elements present in initial groups is created.
1296 //=============================================================================
1298 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1299 SMESH::SMESH_GroupBase_ptr theGroup2,
1300 const char* theName )
1301 throw (SALOME::SALOME_Exception)
1303 SMESH::SMESH_Group_var aResGrp;
1307 _preMeshInfo->FullLoadFromFile();
1309 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1310 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1312 if ( theGroup1->GetType() != theGroup2->GetType() )
1313 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1318 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1319 if ( aResGrp->_is_nil() )
1320 return SMESH::SMESH_Group::_nil();
1322 aResGrp->AddFrom( theGroup1 );
1323 aResGrp->AddFrom( theGroup2 );
1325 // Update Python script
1326 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1327 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1329 SMESH_CATCH( SMESH::throwCorbaException );
1331 return aResGrp._retn();
1334 //=============================================================================
1336 * \brief New group including all mesh elements present in initial groups is created.
1337 * \param theGroups list of groups
1338 * \param theName name of group to be created
1339 * \return pointer to the new group
1341 //=============================================================================
1343 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1344 const char* theName )
1345 throw (SALOME::SALOME_Exception)
1347 SMESH::SMESH_Group_var aResGrp;
1350 _preMeshInfo->FullLoadFromFile();
1353 return SMESH::SMESH_Group::_nil();
1358 SMESH::ElementType aType = SMESH::ALL;
1359 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1361 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1362 if ( CORBA::is_nil( aGrp ) )
1364 if ( aType == SMESH::ALL )
1365 aType = aGrp->GetType();
1366 else if ( aType != aGrp->GetType() )
1367 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1370 if ( aType == SMESH::ALL )
1371 return SMESH::SMESH_Group::_nil();
1376 aResGrp = CreateGroup( aType, theName );
1377 if ( aResGrp->_is_nil() )
1378 return SMESH::SMESH_Group::_nil();
1380 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1381 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1383 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1384 if ( !CORBA::is_nil( aGrp ) )
1386 aResGrp->AddFrom( aGrp );
1387 if ( g > 0 ) pyDump << ", ";
1391 pyDump << " ], '" << theName << "' )";
1393 SMESH_CATCH( SMESH::throwCorbaException );
1395 return aResGrp._retn();
1398 //=============================================================================
1400 * New group is created. All mesh elements that are
1401 * present in both initial groups are added to the new one.
1403 //=============================================================================
1405 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1406 SMESH::SMESH_GroupBase_ptr theGroup2,
1407 const char* theName )
1408 throw (SALOME::SALOME_Exception)
1410 SMESH::SMESH_Group_var aResGrp;
1415 _preMeshInfo->FullLoadFromFile();
1417 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1418 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1420 if ( theGroup1->GetType() != theGroup2->GetType() )
1421 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1425 // Create Intersection
1426 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1427 if ( aResGrp->_is_nil() )
1428 return aResGrp._retn();
1430 SMESHDS_GroupBase* groupDS1 = 0;
1431 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1432 groupDS1 = grp_i->GetGroupDS();
1434 SMESHDS_GroupBase* groupDS2 = 0;
1435 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1436 groupDS2 = grp_i->GetGroupDS();
1438 SMESHDS_Group* resGroupDS = 0;
1439 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1440 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1442 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1444 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1445 while ( elemIt1->more() )
1447 const SMDS_MeshElement* e = elemIt1->next();
1448 if ( groupDS2->Contains( e ))
1449 resGroupDS->SMDSGroup().Add( e );
1452 // Update Python script
1453 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1454 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1456 SMESH_CATCH( SMESH::throwCorbaException );
1458 return aResGrp._retn();
1461 //=============================================================================
1463 \brief Intersect list of groups. New group is created. All mesh elements that
1464 are present in all initial groups simultaneously are added to the new one.
1465 \param theGroups list of groups
1466 \param theName name of group to be created
1467 \return pointer on the group
1469 //=============================================================================
1470 SMESH::SMESH_Group_ptr
1471 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1472 const char* theName )
1473 throw (SALOME::SALOME_Exception)
1475 SMESH::SMESH_Group_var aResGrp;
1480 _preMeshInfo->FullLoadFromFile();
1483 return SMESH::SMESH_Group::_nil();
1485 // check types and get SMESHDS_GroupBase's
1486 SMESH::ElementType aType = SMESH::ALL;
1487 vector< SMESHDS_GroupBase* > groupVec;
1488 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1490 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1491 if ( CORBA::is_nil( aGrp ) )
1493 if ( aType == SMESH::ALL )
1494 aType = aGrp->GetType();
1495 else if ( aType != aGrp->GetType() )
1496 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1499 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1500 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1502 if ( grpDS->IsEmpty() )
1507 groupVec.push_back( grpDS );
1510 if ( aType == SMESH::ALL ) // all groups are nil
1511 return SMESH::SMESH_Group::_nil();
1516 aResGrp = CreateGroup( aType, theName );
1518 SMESHDS_Group* resGroupDS = 0;
1519 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1520 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1521 if ( !resGroupDS || groupVec.empty() )
1522 return aResGrp._retn();
1525 size_t i, nb = groupVec.size();
1526 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1527 while ( elemIt1->more() )
1529 const SMDS_MeshElement* e = elemIt1->next();
1531 for ( i = 1; ( i < nb && inAll ); ++i )
1532 inAll = groupVec[i]->Contains( e );
1535 resGroupDS->SMDSGroup().Add( e );
1538 // Update Python script
1539 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1540 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1542 SMESH_CATCH( SMESH::throwCorbaException );
1544 return aResGrp._retn();
1547 //=============================================================================
1549 * New group is created. All mesh elements that are present in
1550 * a main group but is not present in a tool group are added to the new one
1552 //=============================================================================
1554 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1555 SMESH::SMESH_GroupBase_ptr theGroup2,
1556 const char* theName )
1557 throw (SALOME::SALOME_Exception)
1559 SMESH::SMESH_Group_var aResGrp;
1564 _preMeshInfo->FullLoadFromFile();
1566 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1567 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1569 if ( theGroup1->GetType() != theGroup2->GetType() )
1570 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1574 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1575 if ( aResGrp->_is_nil() )
1576 return aResGrp._retn();
1578 SMESHDS_GroupBase* groupDS1 = 0;
1579 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1580 groupDS1 = grp_i->GetGroupDS();
1582 SMESHDS_GroupBase* groupDS2 = 0;
1583 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1584 groupDS2 = grp_i->GetGroupDS();
1586 SMESHDS_Group* resGroupDS = 0;
1587 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1588 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1590 if ( groupDS1 && groupDS2 && resGroupDS )
1592 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1593 while ( elemIt1->more() )
1595 const SMDS_MeshElement* e = elemIt1->next();
1596 if ( !groupDS2->Contains( e ))
1597 resGroupDS->SMDSGroup().Add( e );
1600 // Update Python script
1601 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1602 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1604 SMESH_CATCH( SMESH::throwCorbaException );
1606 return aResGrp._retn();
1609 //=============================================================================
1611 \brief Cut lists of groups. New group is created. All mesh elements that are
1612 present in main groups but do not present in tool groups are added to the new one
1613 \param theMainGroups list of main groups
1614 \param theToolGroups list of tool groups
1615 \param theName name of group to be created
1616 \return pointer on the group
1618 //=============================================================================
1619 SMESH::SMESH_Group_ptr
1620 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1621 const SMESH::ListOfGroups& theToolGroups,
1622 const char* theName )
1623 throw (SALOME::SALOME_Exception)
1625 SMESH::SMESH_Group_var aResGrp;
1630 _preMeshInfo->FullLoadFromFile();
1633 return SMESH::SMESH_Group::_nil();
1635 // check types and get SMESHDS_GroupBase's
1636 SMESH::ElementType aType = SMESH::ALL;
1637 vector< SMESHDS_GroupBase* > toolGroupVec;
1638 vector< SMDS_ElemIteratorPtr > mainIterVec;
1640 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1642 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1643 if ( CORBA::is_nil( aGrp ) )
1645 if ( aType == SMESH::ALL )
1646 aType = aGrp->GetType();
1647 else if ( aType != aGrp->GetType() )
1648 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1650 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1651 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1652 if ( !grpDS->IsEmpty() )
1653 mainIterVec.push_back( grpDS->GetElements() );
1655 if ( aType == SMESH::ALL ) // all main groups are nil
1656 return SMESH::SMESH_Group::_nil();
1657 if ( mainIterVec.empty() ) // all main groups are empty
1658 return aResGrp._retn();
1660 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1662 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1663 if ( CORBA::is_nil( aGrp ) )
1665 if ( aType != aGrp->GetType() )
1666 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1668 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1669 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1670 toolGroupVec.push_back( grpDS );
1676 aResGrp = CreateGroup( aType, theName );
1678 SMESHDS_Group* resGroupDS = 0;
1679 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1680 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1682 return aResGrp._retn();
1685 size_t i, nb = toolGroupVec.size();
1686 SMDS_ElemIteratorPtr mainElemIt
1687 ( new SMDS_IteratorOnIterators
1688 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1689 while ( mainElemIt->more() )
1691 const SMDS_MeshElement* e = mainElemIt->next();
1693 for ( i = 0; ( i < nb && !isIn ); ++i )
1694 isIn = toolGroupVec[i]->Contains( e );
1697 resGroupDS->SMDSGroup().Add( e );
1700 // Update Python script
1701 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1702 << ".CutListOfGroups( " << theMainGroups << ", "
1703 << theToolGroups << ", '" << theName << "' )";
1705 SMESH_CATCH( SMESH::throwCorbaException );
1707 return aResGrp._retn();
1710 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1712 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1713 bool & toStopChecking )
1715 toStopChecking = ( nbCommon < nbChecked );
1716 return nbCommon == nbNodes;
1718 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1719 bool & toStopChecking )
1721 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1722 return nbCommon == nbCorners;
1724 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1725 bool & toStopChecking )
1727 return nbCommon > 0;
1729 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1730 bool & toStopChecking )
1732 return nbCommon >= (nbNodes+1) / 2;
1736 //=============================================================================
1738 * Create a group of entities basing on nodes of other groups.
1739 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1740 * \param [in] anElemType - a type of elements to include to the new group.
1741 * \param [in] theName - a name of the new group.
1742 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1743 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1744 * new group provided that it is based on nodes of an element of \a aListOfGroups
1745 * \return SMESH_Group - the created group
1747 // IMP 19939, bug 22010, IMP 22635
1748 //=============================================================================
1750 SMESH::SMESH_Group_ptr
1751 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1752 SMESH::ElementType theElemType,
1753 const char* theName,
1754 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1755 CORBA::Boolean theUnderlyingOnly)
1756 throw (SALOME::SALOME_Exception)
1758 SMESH::SMESH_Group_var aResGrp;
1762 _preMeshInfo->FullLoadFromFile();
1764 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1766 if ( !theName || !aMeshDS )
1767 return SMESH::SMESH_Group::_nil();
1769 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1771 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1772 SMESH_Comment nbCoNoStr( "SMESH.");
1773 switch ( theNbCommonNodes ) {
1774 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1775 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1776 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1777 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1778 default: return aResGrp._retn();
1780 int nbChecked, nbCommon, nbNodes, nbCorners;
1786 aResGrp = CreateGroup( theElemType, theName );
1787 if ( aResGrp->_is_nil() )
1788 return SMESH::SMESH_Group::_nil();
1790 SMESHDS_GroupBase* groupBaseDS =
1791 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1792 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1794 vector<bool> isNodeInGroups;
1796 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1798 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1799 if ( CORBA::is_nil( aGrp ) )
1801 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1802 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1805 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1806 if ( !elIt ) continue;
1808 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1810 while ( elIt->more() ) {
1811 const SMDS_MeshElement* el = elIt->next();
1812 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1813 while ( nIt->more() )
1814 resGroupCore.Add( nIt->next() );
1817 // get elements of theElemType based on nodes of every element of group
1818 else if ( theUnderlyingOnly )
1820 while ( elIt->more() )
1822 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1823 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1824 TIDSortedElemSet checkedElems;
1825 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1826 while ( nIt->more() )
1828 const SMDS_MeshNode* n = nIt->next();
1829 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1830 // check nodes of elements of theElemType around el
1831 while ( elOfTypeIt->more() )
1833 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1834 if ( !checkedElems.insert( elOfType ).second ) continue;
1835 nbNodes = elOfType->NbNodes();
1836 nbCorners = elOfType->NbCornerNodes();
1838 bool toStopChecking = false;
1839 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1840 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1841 if ( elNodes.count( nIt2->next() ) &&
1842 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1844 resGroupCore.Add( elOfType );
1851 // get all nodes of elements of groups
1854 while ( elIt->more() )
1856 const SMDS_MeshElement* el = elIt->next(); // an element of group
1857 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1858 while ( nIt->more() )
1860 const SMDS_MeshNode* n = nIt->next();
1861 if ( n->GetID() >= (int) isNodeInGroups.size() )
1862 isNodeInGroups.resize( n->GetID() + 1, false );
1863 isNodeInGroups[ n->GetID() ] = true;
1869 // Get elements of theElemType based on a certain number of nodes of elements of groups
1870 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1872 const SMDS_MeshNode* n;
1873 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1874 const int isNodeInGroupsSize = isNodeInGroups.size();
1875 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1877 if ( !isNodeInGroups[ iN ] ||
1878 !( n = aMeshDS->FindNode( iN )))
1881 // check nodes of elements of theElemType around n
1882 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1883 while ( elOfTypeIt->more() )
1885 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1886 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1891 nbNodes = elOfType->NbNodes();
1892 nbCorners = elOfType->NbCornerNodes();
1894 bool toStopChecking = false;
1895 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1896 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1898 const int nID = nIt->next()->GetID();
1899 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1900 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1902 resGroupCore.Add( elOfType );
1910 // Update Python script
1911 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1912 << ".CreateDimGroup( "
1913 << theGroups << ", " << theElemType << ", '" << theName << "', "
1914 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1916 SMESH_CATCH( SMESH::throwCorbaException );
1918 return aResGrp._retn();
1921 //================================================================================
1923 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1924 * existing 1D elements as group boundaries.
1925 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1926 * adjacent faces is more than \a sharpAngle in degrees.
1927 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1928 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1929 * \return ListOfGroups - the created groups
1931 //================================================================================
1933 SMESH::ListOfGroups*
1934 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1935 CORBA::Boolean theCreateEdges,
1936 CORBA::Boolean theUseExistingEdges )
1937 throw (SALOME::SALOME_Exception)
1939 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1940 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1943 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1949 _preMeshInfo->FullLoadFromFile();
1951 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1953 std::vector< SMESH_MeshAlgos::Edge > edges =
1954 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1956 if ( theCreateEdges )
1958 std::vector<const SMDS_MeshNode *> nodes(2);
1959 for ( size_t i = 0; i < edges.size(); ++i )
1961 nodes[0] = edges[i]._node1;
1962 nodes[1] = edges[i]._node2;
1963 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1965 if ( edges[i]._medium )
1966 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1968 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1972 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1973 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1975 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1977 resultGroups->length( faceGroups.size() );
1978 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1980 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1981 _editor->GenerateGroupName("Group").c_str());
1982 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1984 SMESHDS_GroupBase* groupBaseDS =
1985 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1986 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1988 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1989 for ( size_t i = 0; i < faces.size(); ++i )
1990 groupCore.Add( faces[i] );
1993 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1994 << ".FaceGroupsSeparatedByEdges( "
1995 << TVar( theSharpAngle ) << ", "
1996 << theCreateEdges << ", "
1997 << theUseExistingEdges << " )";
1999 SMESH_CATCH( SMESH::throwCorbaException );
2000 return resultGroups._retn();
2004 //================================================================================
2006 * \brief Remember GEOM group data
2008 //================================================================================
2010 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
2011 CORBA::Object_ptr theSmeshObj)
2013 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2016 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2017 if ( groupSO->_is_nil() )
2020 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2021 GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
2022 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2025 _geomGroupData.push_back( TGeomGroupData() );
2026 TGeomGroupData & groupData = _geomGroupData.back();
2028 CORBA::String_var entry = groupSO->GetID();
2029 groupData._groupEntry = entry.in();
2031 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2032 groupData._indices.insert( ids[i] );
2034 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2035 // shape index in SMESHDS
2036 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2037 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2040 //================================================================================
2042 * Remove GEOM group data relating to removed smesh object
2044 //================================================================================
2046 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2048 list<TGeomGroupData>::iterator
2049 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2050 for ( ; data != dataEnd; ++data ) {
2051 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2052 _geomGroupData.erase( data );
2058 //================================================================================
2060 * \brief Return new group contents if it has been changed and update group data
2062 //================================================================================
2063 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2065 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2067 TopoDS_Shape newShape;
2069 if ( how == IS_BREAK_LINK )
2071 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2072 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2073 if ( !meshSO->_is_nil() &&
2074 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2075 geomRefSO->ReferencedObject( geomSO.inout() ))
2077 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2078 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2079 newShape = _gen_i->GeomObjectToShape( geom );
2085 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2086 if ( !groupSO->_is_nil() )
2088 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2089 if ( CORBA::is_nil( groupObj )) return newShape;
2090 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2092 // get indices of group items
2093 set<int> curIndices;
2094 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2095 GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
2096 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2097 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2098 curIndices.insert( ids[i] );
2100 if ( how == ONLY_IF_CHANGED && groupData._indices == curIndices )
2101 return newShape; // group not changed
2104 groupData._indices = curIndices;
2106 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2107 if ( !geomClient ) return newShape;
2108 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2109 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2110 newShape = _gen_i->GeomObjectToShape( geomGroup );
2113 if ( newShape.IsNull() ) {
2114 // geom group becomes empty - return empty compound
2115 TopoDS_Compound compound;
2116 BRep_Builder().MakeCompound(compound);
2117 newShape = compound;
2124 //-----------------------------------------------------------------------------
2126 * \brief Storage of shape and index used in CheckGeomGroupModif()
2128 struct TIndexedShape
2131 TopoDS_Shape _shape;
2132 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2134 //-----------------------------------------------------------------------------
2136 * \brief Data to re-create a group on geometry
2138 struct TGroupOnGeomData
2141 TopoDS_Shape _shape;
2142 SMDSAbs_ElementType _type;
2144 Quantity_Color _color;
2146 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2148 _oldID = group->GetID();
2149 _type = group->GetType();
2150 _name = group->GetStoreName();
2151 _color = group->GetColor();
2155 //-----------------------------------------------------------------------------
2157 * \brief Check if a filter is still valid after geometry removal
2159 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2161 if ( theFilter->_is_nil() )
2163 SMESH::Filter::Criteria_var criteria;
2164 theFilter->GetCriteria( criteria.out() );
2166 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2168 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2170 switch ( criteria[ iCr ].Type )
2172 case SMESH::FT_BelongToGeom:
2173 case SMESH::FT_BelongToPlane:
2174 case SMESH::FT_BelongToCylinder:
2175 case SMESH::FT_BelongToGenSurface:
2176 case SMESH::FT_LyingOnGeom:
2177 entry = thresholdID;
2179 case SMESH::FT_ConnectedElements:
2182 entry = thresholdID;
2188 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2189 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2190 if ( so->_is_nil() )
2192 CORBA::Object_var obj = so->GetObject();
2193 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2194 if ( gen->GeomObjectToShape( geom ).IsNull() )
2197 } // loop on criteria
2203 //=============================================================================
2205 * \brief Update data if geometry changes
2209 //=============================================================================
2211 void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
2213 SMESH::SMESH_Mesh_var me = _this();
2214 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2216 TPythonDump dumpNothing; // prevent any dump
2218 //bool removedFromClient = false;
2220 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2222 //removedFromClient = _impl->HasShapeToMesh();
2224 // try to find geometry by study reference
2225 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2226 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2227 if ( !meshSO->_is_nil() &&
2228 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2229 geomRefSO->ReferencedObject( geomSO.inout() ))
2231 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2232 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2235 if ( mainGO->_is_nil() && // geometry removed ==>
2236 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2238 // convert geom dependent groups into standalone ones
2239 CheckGeomGroupModif();
2241 _impl->ShapeToMesh( TopoDS_Shape() );
2243 // remove sub-meshes
2244 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2245 while ( i_sm != _mapSubMeshIor.end() )
2247 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2249 RemoveSubMesh( sm );
2251 // remove all children except groups in the study
2252 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2253 SALOMEDS::SObject_wrap so;
2254 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2255 if ( meshSO->FindSubObject( tag, so.inout() ))
2256 builder->RemoveObjectWithChildren( so );
2258 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2264 if ( !_impl->HasShapeToMesh() ) return;
2267 // Update after group modification
2269 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2270 mainGO->GetTick() == _mainShapeTick )
2272 int nb = NbNodes() + NbElements();
2273 CheckGeomGroupModif();
2274 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2275 _gen_i->UpdateIcons( me );
2279 // Update after shape modification
2281 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2282 if ( !geomClient ) return;
2283 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2284 if ( geomGen->_is_nil() ) return;
2286 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2287 geomClient->RemoveShapeFromBuffer( ior.in() );
2289 // Update data taking into account that if topology doesn't change
2290 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2293 _preMeshInfo->ForgetAllData();
2298 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2299 if ( newShape.IsNull() )
2302 _mainShapeTick = mainGO->GetTick();
2304 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2306 // store data of groups on geometry
2307 std::vector< TGroupOnGeomData > groupsData;
2308 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2309 groupsData.reserve( groups.size() );
2310 TopTools_DataMapOfShapeShape old2newShapeMap;
2311 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2312 for ( ; g != groups.end(); ++g )
2314 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2316 groupsData.push_back( TGroupOnGeomData( group ));
2319 SMESH::SMESH_GroupOnGeom_var gog;
2320 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2321 if ( i_grp != _mapGroups.end() )
2322 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2324 GEOM::GEOM_Object_var geom;
2325 if ( !gog->_is_nil() )
2329 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2330 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2331 if ( !grpSO->_is_nil() &&
2332 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2333 geomRefSO->ReferencedObject( geomSO.inout() ))
2335 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2336 geom = GEOM::GEOM_Object::_narrow( geomObj );
2341 geom = gog->GetShape();
2344 if ( !geom->_is_nil() )
2346 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2347 geomClient->RemoveShapeFromBuffer( ior.in() );
2348 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2349 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2351 else if ( old2newShapeMap.IsBound( group->GetShape() ))
2353 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2357 // store assigned hypotheses
2358 std::vector< pair< int, THypList > > ids2Hyps;
2359 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2360 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2362 const TopoDS_Shape& s = s2hyps.Key();
2363 const THypList& hyps = s2hyps.ChangeValue();
2364 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2367 std::map< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2369 // count shapes excluding compounds corresponding to geom groups
2370 int oldNbSubShapes = meshDS->MaxShapeIndex();
2371 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2373 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2374 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2377 std::set<int> subIds;
2378 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2379 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2380 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2383 // check if shape topology changes - save shape type per shape ID
2384 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2385 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2386 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2388 // change shape to mesh
2389 _impl->ShapeToMesh( TopoDS_Shape() );
2390 _impl->ShapeToMesh( newShape );
2392 // check if shape topology changes - check new shape types
2393 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2394 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2396 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2397 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2400 // re-add shapes (compounds) of geom groups
2401 std::map< int, int > old2newIDs; // group IDs
2402 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2403 for ( ; data != _geomGroupData.end(); ++data )
2406 std::map< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2407 if ( ii2i != ii2iMap.end() )
2408 oldID = ii2i->second;
2410 TopoDS_Shape newShape = newGroupShape( *data, isBreakLink ? IS_BREAK_LINK : MAIN_TRANSFORMED );
2411 if ( !newShape.IsNull() )
2413 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2415 TopoDS_Compound compound;
2416 BRep_Builder().MakeCompound( compound );
2417 BRep_Builder().Add( compound, newShape );
2418 newShape = compound;
2420 int newID = _impl->GetSubMesh( newShape )->GetId();
2421 if ( oldID && oldID != newID )
2422 old2newIDs.insert( std::make_pair( oldID, newID ));
2426 // re-assign hypotheses
2427 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2429 if ( !sameTopology && ids2Hyps[i].first != 1 )
2430 continue; // assign only global hypos
2431 int sID = ids2Hyps[i].first;
2432 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2433 if ( o2n != old2newIDs.end() )
2435 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2436 const THypList& hyps = ids2Hyps[i].second;
2437 THypList::const_iterator h = hyps.begin();
2438 for ( ; h != hyps.end(); ++h )
2439 _impl->AddHypothesis( s, (*h)->GetID() );
2442 if ( !sameTopology )
2444 // remove invalid study sub-objects
2445 CheckGeomGroupModif();
2449 // restore groups on geometry
2450 for ( size_t i = 0; i < groupsData.size(); ++i )
2452 const TGroupOnGeomData& data = groupsData[i];
2453 if ( data._shape.IsNull() )
2456 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2457 if ( i2g == _mapGroups.end() ) continue;
2459 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2460 if ( !gr_i ) continue;
2462 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2464 _mapGroups.erase( i2g );
2466 g->GetGroupDS()->SetColor( data._color );
2469 std::map< int, int >::iterator o2n = old2newIDs.begin();
2470 for ( ; o2n != old2newIDs.end(); ++o2n )
2472 int newID = o2n->second, oldID = o2n->first;
2473 if ( !_mapSubMesh.count( oldID ))
2475 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2476 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2477 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2478 _mapSubMesh. erase(oldID);
2479 _mapSubMesh_i. erase(oldID);
2480 _mapSubMeshIor.erase(oldID);
2481 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2484 // update _mapSubMesh
2485 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2486 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2487 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2490 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
2494 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2495 if ( !meshSO->_is_nil() )
2496 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2500 //=============================================================================
2502 * \brief Update objects depending on changed geom groups
2504 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2505 * issue 0020210: Update of a smesh group after modification of the associated geom group
2507 //=============================================================================
2509 void SMESH_Mesh_i::CheckGeomGroupModif()
2511 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2512 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2513 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2514 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2515 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2517 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2518 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2519 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2521 int nbValid = 0, nbRemoved = 0;
2522 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2523 for ( ; chItr->More(); chItr->Next() )
2525 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2526 if ( !smSO->_is_nil() &&
2527 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2528 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2530 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2531 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2532 if ( !geom->_non_existent() )
2535 continue; // keep the sub-mesh
2538 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2539 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2540 if ( !sm->_is_nil() && !sm->_non_existent() )
2542 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2543 if ( smGeom->_is_nil() )
2545 RemoveSubMesh( sm );
2552 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2553 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2557 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2558 builder->RemoveObjectWithChildren( rootSO );
2562 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2563 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2564 while ( i_gr != _mapGroups.end())
2566 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2568 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2569 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2570 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2571 bool isValidGeom = false;
2572 if ( !onGeom->_is_nil() )
2574 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2576 else if ( !onFilt->_is_nil() )
2578 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2582 isValidGeom = ( !groupSO->_is_nil() &&
2583 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2587 if ( !IsLoaded() || group->IsEmpty() )
2589 RemoveGroup( group );
2591 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2593 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2595 else // is it possible?
2597 builder->RemoveObjectWithChildren( refSO );
2603 if ( !_impl->HasShapeToMesh() ) return;
2605 CORBA::Long nbEntities = NbNodes() + NbElements();
2607 // Check if group contents changed
2609 typedef map< string, TopoDS_Shape > TEntry2Geom;
2610 TEntry2Geom newGroupContents;
2612 list<TGeomGroupData>::iterator
2613 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2614 for ( ; data != dataEnd; ++data )
2616 pair< TEntry2Geom::iterator, bool > it_new =
2617 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2618 bool processedGroup = !it_new.second;
2619 TopoDS_Shape& newShape = it_new.first->second;
2620 if ( !processedGroup )
2621 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2622 if ( newShape.IsNull() )
2623 continue; // no changes
2626 _preMeshInfo->ForgetOrLoad();
2628 if ( processedGroup ) { // update group indices
2629 list<TGeomGroupData>::iterator data2 = data;
2630 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2631 data->_indices = data2->_indices;
2634 // Update SMESH objects according to new GEOM group contents
2636 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2637 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2639 int oldID = submesh->GetId();
2640 if ( !_mapSubMeshIor.count( oldID ))
2642 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2644 // update hypotheses
2645 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2646 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2647 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2649 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2650 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2652 // care of submeshes
2653 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2654 int newID = newSubmesh->GetId();
2655 if ( newID != oldID ) {
2656 _mapSubMesh [ newID ] = newSubmesh;
2657 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2658 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2659 _mapSubMesh. erase(oldID);
2660 _mapSubMesh_i. erase(oldID);
2661 _mapSubMeshIor.erase(oldID);
2662 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2667 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2668 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2669 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2671 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2673 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2674 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2675 ds->SetShape( newShape );
2680 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2681 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2683 // Remove groups and submeshes basing on removed sub-shapes
2685 TopTools_MapOfShape newShapeMap;
2686 TopoDS_Iterator shapeIt( newShape );
2687 for ( ; shapeIt.More(); shapeIt.Next() )
2688 newShapeMap.Add( shapeIt.Value() );
2690 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2691 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2693 if ( newShapeMap.Contains( shapeIt.Value() ))
2695 TopTools_IndexedMapOfShape oldShapeMap;
2696 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2697 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2699 const TopoDS_Shape& oldShape = oldShapeMap(i);
2700 int oldInd = meshDS->ShapeToIndex( oldShape );
2702 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2703 if ( i_smIor != _mapSubMeshIor.end() ) {
2704 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2707 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2708 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2710 // check if a group bases on oldInd shape
2711 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2712 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2713 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2714 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2716 RemoveGroup( i_grp->second ); // several groups can base on same shape
2717 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2722 // Reassign hypotheses and update groups after setting the new shape to mesh
2724 // collect anassigned hypotheses
2725 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2726 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2727 TShapeHypList assignedHyps;
2728 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2730 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2731 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2732 if ( !hyps.empty() ) {
2733 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2734 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2735 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2738 // collect shapes supporting groups
2739 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2740 TShapeTypeList groupData;
2741 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2742 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2743 for ( ; grIt != groups.end(); ++grIt )
2745 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2747 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2749 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2751 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2752 _impl->ShapeToMesh( newShape );
2754 // reassign hypotheses
2755 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2756 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2758 TIndexedShape& geom = indS_hyps->first;
2759 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2760 int oldID = geom._index;
2761 int newID = meshDS->ShapeToIndex( geom._shape );
2762 if ( oldID == 1 ) { // main shape
2764 geom._shape = newShape;
2768 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2769 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2770 // care of sub-meshes
2771 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2772 if ( newID != oldID ) {
2773 _mapSubMesh [ newID ] = newSubmesh;
2774 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2775 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2776 _mapSubMesh. erase(oldID);
2777 _mapSubMesh_i. erase(oldID);
2778 _mapSubMeshIor.erase(oldID);
2779 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2783 TShapeTypeList::iterator geomType = groupData.begin();
2784 for ( ; geomType != groupData.end(); ++geomType )
2786 const TIndexedShape& geom = geomType->first;
2787 int oldID = geom._index;
2788 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2791 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2792 CORBA::String_var name = groupSO->GetName();
2794 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2795 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2796 /*id=*/-1, geom._shape ))
2797 group_i->changeLocalId( group->GetID() );
2800 break; // everything has been updated
2803 } // loop on group data
2807 CORBA::Long newNbEntities = NbNodes() + NbElements();
2808 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2809 if ( newNbEntities != nbEntities )
2811 // Add all SObjects with icons to soToUpdateIcons
2812 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2814 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2815 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2816 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2818 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2819 i_gr != _mapGroups.end(); ++i_gr ) // groups
2820 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2823 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2824 for ( ; so != soToUpdateIcons.end(); ++so )
2825 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2828 //=============================================================================
2830 * \brief Create standalone group from a group on geometry or filter
2832 //=============================================================================
2834 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2835 throw (SALOME::SALOME_Exception)
2837 SMESH::SMESH_Group_var aGroup;
2842 _preMeshInfo->FullLoadFromFile();
2844 if ( theGroup->_is_nil() )
2845 return aGroup._retn();
2847 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2849 return aGroup._retn();
2851 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2853 const int anId = aGroupToRem->GetLocalID();
2854 if ( !_impl->ConvertToStandalone( anId ) )
2855 return aGroup._retn();
2856 removeGeomGroupData( theGroup );
2858 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2860 // remove old instance of group from own map
2861 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2862 _mapGroups.erase( anId );
2864 SALOMEDS::StudyBuilder_var builder;
2865 SALOMEDS::SObject_wrap aGroupSO;
2866 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2867 if ( !aStudy->_is_nil() ) {
2868 builder = aStudy->NewBuilder();
2869 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2870 if ( !aGroupSO->_is_nil() )
2872 // remove reference to geometry
2873 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2874 for ( ; chItr->More(); chItr->Next() )
2876 // Remove group's child SObject
2877 SALOMEDS::SObject_wrap so = chItr->Value();
2878 builder->RemoveObject( so );
2880 // Update Python script
2881 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2882 << ".ConvertToStandalone( " << aGroupSO << " )";
2884 // change icon of Group on Filter
2887 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2888 // const int isEmpty = ( elemTypes->length() == 0 );
2891 SALOMEDS::GenericAttribute_wrap anAttr =
2892 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2893 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2894 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2900 // remember new group in own map
2901 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2902 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2904 // register CORBA object for persistence
2905 _gen_i->RegisterObject( aGroup );
2907 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2908 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2909 //aGroup->Register();
2910 aGroupToRem->UnRegister();
2912 SMESH_CATCH( SMESH::throwCorbaException );
2914 return aGroup._retn();
2917 //=============================================================================
2921 //=============================================================================
2923 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2925 if(MYDEBUG) MESSAGE( "createSubMesh" );
2926 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2927 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2930 SMESH_subMesh_i * subMeshServant;
2933 subMeshId = mySubMesh->GetId();
2934 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2936 else // "invalid sub-mesh"
2938 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2939 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2940 if ( _mapSubMesh.empty() )
2943 subMeshId = _mapSubMesh.begin()->first - 1;
2944 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2947 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2949 _mapSubMesh [subMeshId] = mySubMesh;
2950 _mapSubMesh_i [subMeshId] = subMeshServant;
2951 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2953 subMeshServant->Register();
2955 // register CORBA object for persistence
2956 int nextId = _gen_i->RegisterObject( subMesh );
2957 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2958 else { nextId = 0; } // avoid "unused variable" warning
2960 // to track changes of GEOM groups
2961 if ( subMeshId > 0 )
2962 addGeomGroupData( theSubShapeObject, subMesh );
2964 return subMesh._retn();
2967 //=======================================================================
2968 //function : getSubMesh
2970 //=======================================================================
2972 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2974 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2975 if ( it == _mapSubMeshIor.end() )
2976 return SMESH::SMESH_subMesh::_nil();
2978 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2981 //=============================================================================
2985 //=============================================================================
2987 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2988 GEOM::GEOM_Object_ptr theSubShapeObject )
2990 bool isHypChanged = false;
2991 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2992 return isHypChanged;
2994 const int subMeshId = theSubMesh->GetId();
2996 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2999 if (( _mapSubMesh.count( subMeshId )) &&
3000 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3002 TopoDS_Shape S = sm->GetSubShape();
3005 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3006 isHypChanged = !hyps.empty();
3007 if ( isHypChanged && _preMeshInfo )
3008 _preMeshInfo->ForgetOrLoad();
3009 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3010 for ( ; hyp != hyps.end(); ++hyp )
3011 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3018 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3019 isHypChanged = ( aHypList->length() > 0 );
3020 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3021 removeHypothesis( theSubShapeObject, aHypList[i] );
3024 catch( const SALOME::SALOME_Exception& ) {
3025 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3027 removeGeomGroupData( theSubShapeObject );
3031 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3032 if ( id_smi != _mapSubMesh_i.end() )
3033 id_smi->second->UnRegister();
3035 // remove a CORBA object
3036 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3037 if ( id_smptr != _mapSubMeshIor.end() )
3038 SMESH::SMESH_subMesh_var( id_smptr->second );
3040 _mapSubMesh.erase(subMeshId);
3041 _mapSubMesh_i.erase(subMeshId);
3042 _mapSubMeshIor.erase(subMeshId);
3044 return isHypChanged;
3047 //=============================================================================
3051 //=============================================================================
3053 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3054 const char* theName,
3056 const TopoDS_Shape& theShape,
3057 const SMESH_PredicatePtr& thePredicate )
3059 std::string newName;
3060 if ( !theName || !theName[0] )
3062 std::set< std::string > presentNames;
3063 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3064 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3066 CORBA::String_var name = i_gr->second->GetName();
3067 presentNames.insert( name.in() );
3070 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3071 } while ( !presentNames.insert( newName ).second );
3072 theName = newName.c_str();
3074 SMESH::SMESH_GroupBase_var aGroup;
3075 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3076 theID, theShape, thePredicate ))
3078 int anId = g->GetID();
3079 SMESH_GroupBase_i* aGroupImpl;
3080 if ( !theShape.IsNull() )
3081 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3082 else if ( thePredicate )
3083 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3085 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3087 aGroup = aGroupImpl->_this();
3088 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3089 aGroupImpl->Register();
3091 // register CORBA object for persistence
3092 int nextId = _gen_i->RegisterObject( aGroup );
3093 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3094 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3096 // to track changes of GEOM groups
3097 if ( !theShape.IsNull() ) {
3098 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3099 addGeomGroupData( geom, aGroup );
3102 return aGroup._retn();
3105 //=============================================================================
3107 * SMESH_Mesh_i::removeGroup
3109 * Should be called by ~SMESH_Group_i()
3111 //=============================================================================
3113 void SMESH_Mesh_i::removeGroup( const int theId )
3115 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3116 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3117 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3118 _mapGroups.erase( theId );
3119 removeGeomGroupData( group );
3120 if ( !_impl->RemoveGroup( theId ))
3122 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3123 RemoveGroup( group );
3125 group->UnRegister();
3129 //=============================================================================
3133 //=============================================================================
3135 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3136 throw(SALOME::SALOME_Exception)
3138 SMESH::log_array_var aLog;
3142 _preMeshInfo->FullLoadFromFile();
3144 list < SMESHDS_Command * >logDS = _impl->GetLog();
3145 aLog = new SMESH::log_array;
3147 int lg = logDS.size();
3150 list < SMESHDS_Command * >::iterator its = logDS.begin();
3151 while(its != logDS.end()){
3152 SMESHDS_Command *com = *its;
3153 int comType = com->GetType();
3155 int lgcom = com->GetNumber();
3157 const list < int >&intList = com->GetIndexes();
3158 int inum = intList.size();
3160 list < int >::const_iterator ii = intList.begin();
3161 const list < double >&coordList = com->GetCoords();
3162 int rnum = coordList.size();
3164 list < double >::const_iterator ir = coordList.begin();
3165 aLog[indexLog].commandType = comType;
3166 aLog[indexLog].number = lgcom;
3167 aLog[indexLog].coords.length(rnum);
3168 aLog[indexLog].indexes.length(inum);
3169 for(int i = 0; i < rnum; i++){
3170 aLog[indexLog].coords[i] = *ir;
3171 //MESSAGE(" "<<i<<" "<<ir.Value());
3174 for(int i = 0; i < inum; i++){
3175 aLog[indexLog].indexes[i] = *ii;
3176 //MESSAGE(" "<<i<<" "<<ii.Value());
3185 SMESH_CATCH( SMESH::throwCorbaException );
3187 return aLog._retn();
3191 //=============================================================================
3195 //=============================================================================
3197 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3201 SMESH_CATCH( SMESH::throwCorbaException );
3204 //=============================================================================
3208 //=============================================================================
3210 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3215 //=============================================================================
3218 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3219 // issue 0020918: groups removal is caused by hyp modification
3220 // issue 0021208: to forget not loaded mesh data at hyp modification
3221 struct TCallUp_i : public SMESH_Mesh::TCallUp
3223 SMESH_Mesh_i* _mesh;
3224 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3225 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3226 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3227 virtual void Load () { _mesh->Load(); }
3231 //================================================================================
3233 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3235 //================================================================================
3237 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3240 _preMeshInfo->ForgetOrLoad();
3242 SMESH::SMESH_Mesh_var mesh = _this();
3243 _gen_i->UpdateIcons( mesh );
3245 // mark a hypothesis as valid after edition
3246 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3247 SALOMEDS::SObject_wrap hypRoot;
3248 if ( !smeshComp->_is_nil() &&
3249 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3251 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3252 for ( ; anIter->More(); anIter->Next() )
3254 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3255 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3256 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3257 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3258 _gen_i->HighLightInvalid( hyp, false );
3263 //=============================================================================
3267 //=============================================================================
3269 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3271 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3274 _impl->SetCallUp( new TCallUp_i(this));
3277 //=============================================================================
3281 //=============================================================================
3283 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3285 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3289 //=============================================================================
3291 * Return mesh editor
3293 //=============================================================================
3295 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3296 throw (SALOME::SALOME_Exception)
3298 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3302 _preMeshInfo->FullLoadFromFile();
3304 // Create MeshEditor
3306 _editor = new SMESH_MeshEditor_i( this, false );
3307 aMeshEdVar = _editor->_this();
3309 // Update Python script
3310 TPythonDump() << _editor << " = "
3311 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3313 SMESH_CATCH( SMESH::throwCorbaException );
3315 return aMeshEdVar._retn();
3318 //=============================================================================
3320 * Return mesh edition previewer
3322 //=============================================================================
3324 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3325 throw (SALOME::SALOME_Exception)
3327 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3331 _preMeshInfo->FullLoadFromFile();
3333 if ( !_previewEditor )
3334 _previewEditor = new SMESH_MeshEditor_i( this, true );
3335 aMeshEdVar = _previewEditor->_this();
3337 SMESH_CATCH( SMESH::throwCorbaException );
3339 return aMeshEdVar._retn();
3342 //================================================================================
3344 * \brief Return true if the mesh has been edited since a last total re-compute
3345 * and those modifications may prevent successful partial re-compute
3347 //================================================================================
3349 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3351 Unexpect aCatch(SALOME_SalomeException);
3352 return _impl->HasModificationsToDiscard();
3355 //================================================================================
3357 * \brief Returns a random unique color
3359 //================================================================================
3361 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3363 const int MAX_ATTEMPTS = 100;
3365 double tolerance = 0.5;
3366 SALOMEDS::Color col;
3370 // generate random color
3371 double red = (double)rand() / RAND_MAX;
3372 double green = (double)rand() / RAND_MAX;
3373 double blue = (double)rand() / RAND_MAX;
3374 // check existence in the list of the existing colors
3375 bool matched = false;
3376 std::list<SALOMEDS::Color>::const_iterator it;
3377 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3378 SALOMEDS::Color color = *it;
3379 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3380 matched = tol < tolerance;
3382 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3383 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3391 //=============================================================================
3393 * Sets auto-color mode. If it is on, groups get unique random colors
3395 //=============================================================================
3397 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3399 Unexpect aCatch(SALOME_SalomeException);
3400 _impl->SetAutoColor(theAutoColor);
3402 TPythonDump pyDump; // not to dump group->SetColor() from below code
3403 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3405 std::list<SALOMEDS::Color> aReservedColors;
3406 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3407 for ( ; it != _mapGroups.end(); it++ ) {
3408 if ( CORBA::is_nil( it->second )) continue;
3409 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3410 it->second->SetColor( aColor );
3411 aReservedColors.push_back( aColor );
3415 //=============================================================================
3417 * Returns true if auto-color mode is on
3419 //=============================================================================
3421 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3423 Unexpect aCatch(SALOME_SalomeException);
3424 return _impl->GetAutoColor();
3427 //=============================================================================
3429 * Checks if there are groups with equal names
3431 //=============================================================================
3433 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3435 return _impl->HasDuplicatedGroupNamesMED();
3438 //================================================================================
3440 * \brief Care of a file before exporting mesh into it
3442 //================================================================================
3444 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3446 SMESH_File aFile( file, false );
3448 if ( aFile.exists() ) {
3449 // existing filesystem node
3450 if ( !aFile.isDirectory() ) {
3451 if ( aFile.openForWriting() ) {
3452 if ( overwrite && ! aFile.remove()) {
3453 msg << "Can't replace " << aFile.getName();
3456 msg << "Can't write into " << aFile.getName();
3459 msg << "Location " << aFile.getName() << " is not a file";
3463 // nonexisting file; check if it can be created
3464 if ( !aFile.openForWriting() ) {
3465 msg << "You cannot create the file "
3467 << ". Check the directory existence and access rights";
3475 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3479 //================================================================================
3481 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3482 * \param file - file name
3483 * \param overwrite - to erase the file or not
3484 * \retval string - mesh name
3486 //================================================================================
3488 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3489 CORBA::Boolean overwrite)
3492 PrepareForWriting(file, overwrite);
3493 string aMeshName = "Mesh";
3494 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3495 if ( !aStudy->_is_nil() ) {
3496 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3497 if ( !aMeshSO->_is_nil() ) {
3498 CORBA::String_var name = aMeshSO->GetName();
3500 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3501 if ( !aStudy->GetProperties()->IsLocked() )
3503 SALOMEDS::GenericAttribute_wrap anAttr;
3504 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3505 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3506 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3507 ASSERT(!aFileName->_is_nil());
3508 aFileName->SetValue(file);
3509 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3510 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3511 ASSERT(!aFileType->_is_nil());
3512 aFileType->SetValue("FICHIERMED");
3516 // Update Python script
3517 // set name of mesh before export
3518 TPythonDump() << _gen_i << ".SetName("
3519 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3521 // check names of groups
3527 //================================================================================
3529 * \brief Export to MED file
3531 //================================================================================
3533 void SMESH_Mesh_i::ExportMED(const char* file,
3534 CORBA::Boolean auto_groups,
3535 CORBA::Long version,
3536 CORBA::Boolean overwrite,
3537 CORBA::Boolean autoDimension)
3538 throw(SALOME::SALOME_Exception)
3540 //MESSAGE("MED minor version: "<< minor);
3543 _preMeshInfo->FullLoadFromFile();
3545 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3546 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3548 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3550 << "auto_groups=" <<auto_groups << ", "
3551 << "minor=" << version << ", "
3552 << "overwrite=" << overwrite << ", "
3553 << "meshPart=None, "
3554 << "autoDimension=" << autoDimension << " )";
3556 SMESH_CATCH( SMESH::throwCorbaException );
3559 //================================================================================
3561 * \brief Export a mesh to a SAUV file
3563 //================================================================================
3565 void SMESH_Mesh_i::ExportSAUV (const char* file,
3566 CORBA::Boolean auto_groups)
3567 throw(SALOME::SALOME_Exception)
3569 Unexpect aCatch(SALOME_SalomeException);
3571 _preMeshInfo->FullLoadFromFile();
3573 string aMeshName = prepareMeshNameAndGroups(file, true);
3574 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3575 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3576 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3580 //================================================================================
3582 * \brief Export a mesh to a DAT file
3584 //================================================================================
3586 void SMESH_Mesh_i::ExportDAT (const char *file)
3587 throw(SALOME::SALOME_Exception)
3589 Unexpect aCatch(SALOME_SalomeException);
3591 _preMeshInfo->FullLoadFromFile();
3593 // Update Python script
3594 // check names of groups
3596 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3599 PrepareForWriting(file);
3600 _impl->ExportDAT(file);
3603 //================================================================================
3605 * \brief Export a mesh to an UNV file
3607 //================================================================================
3609 void SMESH_Mesh_i::ExportUNV (const char *file)
3610 throw(SALOME::SALOME_Exception)
3612 Unexpect aCatch(SALOME_SalomeException);
3614 _preMeshInfo->FullLoadFromFile();
3616 // Update Python script
3617 // check names of groups
3619 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3622 PrepareForWriting(file);
3623 _impl->ExportUNV(file);
3626 //================================================================================
3628 * \brief Export a mesh to an STL file
3630 //================================================================================
3632 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3633 throw(SALOME::SALOME_Exception)
3635 Unexpect aCatch(SALOME_SalomeException);
3637 _preMeshInfo->FullLoadFromFile();
3639 // Update Python script
3640 // check names of groups
3642 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3643 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3645 CORBA::String_var name;
3646 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3647 if ( !so->_is_nil() )
3648 name = so->GetName();
3651 PrepareForWriting( file );
3652 _impl->ExportSTL( file, isascii, name.in() );
3655 //================================================================================
3657 * \brief Export a part of mesh to a med file
3659 //================================================================================
3661 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3663 CORBA::Boolean auto_groups,
3664 CORBA::Long version,
3665 CORBA::Boolean overwrite,
3666 CORBA::Boolean autoDimension,
3667 const GEOM::ListOfFields& fields,
3668 const char* geomAssocFields,
3669 CORBA::Double ZTolerance)
3670 throw (SALOME::SALOME_Exception)
3672 MESSAGE("MED version: "<< version);
3675 _preMeshInfo->FullLoadFromFile();
3678 bool have0dField = false;
3679 if ( fields.length() > 0 )
3681 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3682 if ( shapeToMesh->_is_nil() )
3683 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3685 for ( size_t i = 0; i < fields.length(); ++i )
3687 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3688 THROW_SALOME_CORBA_EXCEPTION
3689 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3690 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3691 if ( fieldShape->_is_nil() )
3692 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3693 if ( !fieldShape->IsSame( shapeToMesh ) )
3694 THROW_SALOME_CORBA_EXCEPTION
3695 ( "Field defined not on shape", SALOME::BAD_PARAM);
3696 if ( fields[i]->GetDimension() == 0 )
3699 if ( geomAssocFields )
3700 for ( int i = 0; geomAssocFields[i]; ++i )
3701 switch ( geomAssocFields[i] ) {
3702 case 'v':case 'e':case 'f':case 's': break;
3703 case 'V':case 'E':case 'F':case 'S': break;
3704 default: THROW_SALOME_CORBA_EXCEPTION
3705 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3709 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3713 string aMeshName = "Mesh";
3714 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3715 if ( CORBA::is_nil( meshPart ) ||
3716 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3718 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3719 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3720 0, autoDimension, /*addODOnVertices=*/have0dField,
3722 meshDS = _impl->GetMeshDS();
3727 _preMeshInfo->FullLoadFromFile();
3729 PrepareForWriting(file, overwrite);
3731 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3732 if ( !SO->_is_nil() ) {
3733 CORBA::String_var name = SO->GetName();
3737 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3738 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3739 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3740 meshDS = tmpDSDeleter._obj = partDS;
3745 if ( _impl->HasShapeToMesh() )
3747 DriverMED_W_Field fieldWriter;
3748 fieldWriter.SetFile( file );
3749 fieldWriter.SetMeshName( aMeshName );
3750 fieldWriter.AddODOnVertices( have0dField );
3752 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3756 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3757 goList->length( fields.length() );
3758 for ( size_t i = 0; i < fields.length(); ++i )
3760 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3763 TPythonDump() << _this() << ".ExportPartToMED( "
3764 << meshPart << ", r'"
3766 << auto_groups << ", "
3768 << overwrite << ", "
3769 << autoDimension << ", "
3771 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3772 << TVar( ZTolerance )
3775 SMESH_CATCH( SMESH::throwCorbaException );
3778 //================================================================================
3780 * Write GEOM fields to MED file
3782 //================================================================================
3784 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3785 SMESHDS_Mesh* meshDS,
3786 const GEOM::ListOfFields& fields,
3787 const char* geomAssocFields)
3789 #define METH "SMESH_Mesh_i::exportMEDFields() "
3791 if (( fields.length() < 1 ) &&
3792 ( !geomAssocFields || !geomAssocFields[0] ))
3795 std::vector< std::vector< double > > dblVals;
3796 std::vector< std::vector< int > > intVals;
3797 std::vector< int > subIdsByDim[ 4 ];
3798 const double noneDblValue = 0.;
3799 const double noneIntValue = 0;
3801 for ( size_t iF = 0; iF < fields.length(); ++iF )
3805 int dim = fields[ iF ]->GetDimension();
3806 SMDSAbs_ElementType elemType;
3807 TopAbs_ShapeEnum shapeType;
3809 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3810 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3811 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3812 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3814 continue; // skip fields on whole shape
3816 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3817 if ( dataType == GEOM::FDT_String )
3819 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3820 if ( stepIDs->length() < 1 )
3822 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3823 if ( comps->length() < 1 )
3825 CORBA::String_var name = fields[ iF ]->GetName();
3827 if ( !fieldWriter.Set( meshDS,
3831 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3834 for ( size_t iC = 0; iC < comps->length(); ++iC )
3835 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3837 dblVals.resize( comps->length() );
3838 intVals.resize( comps->length() );
3840 // find sub-shape IDs
3842 std::vector< int >& subIds = subIdsByDim[ dim ];
3843 if ( subIds.empty() )
3844 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3845 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3846 subIds.push_back( id );
3850 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3854 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3856 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3857 if ( step->_is_nil() )
3860 CORBA::Long stamp = step->GetStamp();
3861 CORBA::Long id = step->GetID();
3862 fieldWriter.SetDtIt( int( stamp ), int( id ));
3864 // fill dblVals or intVals
3865 for ( size_t iC = 0; iC < comps->length(); ++iC )
3866 if ( dataType == GEOM::FDT_Double )
3868 dblVals[ iC ].clear();
3869 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3873 intVals[ iC ].clear();
3874 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3878 case GEOM::FDT_Double:
3880 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3881 if ( dblStep->_is_nil() ) continue;
3882 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3883 if ( vv->length() != subIds.size() * comps->length() )
3884 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3885 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3886 for ( size_t iC = 0; iC < comps->length(); ++iC )
3887 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3892 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3893 if ( intStep->_is_nil() ) continue;
3894 GEOM::ListOfLong_var vv = intStep->GetValues();
3895 if ( vv->length() != subIds.size() * comps->length() )
3896 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3897 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3898 for ( size_t iC = 0; iC < comps->length(); ++iC )
3899 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3902 case GEOM::FDT_Bool:
3904 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3905 if ( boolStep->_is_nil() ) continue;
3906 GEOM::short_array_var vv = boolStep->GetValues();
3907 if ( vv->length() != subIds.size() * comps->length() )
3908 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3909 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3910 for ( size_t iC = 0; iC < comps->length(); ++iC )
3911 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3917 // pass values to fieldWriter
3918 elemIt = fieldWriter.GetOrderedElems();
3919 if ( dataType == GEOM::FDT_Double )
3920 while ( elemIt->more() )
3922 const SMDS_MeshElement* e = elemIt->next();
3923 const int shapeID = e->getshapeId();
3924 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3925 for ( size_t iC = 0; iC < comps->length(); ++iC )
3926 fieldWriter.AddValue( noneDblValue );
3928 for ( size_t iC = 0; iC < comps->length(); ++iC )
3929 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3932 while ( elemIt->more() )
3934 const SMDS_MeshElement* e = elemIt->next();
3935 const int shapeID = e->getshapeId();
3936 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3937 for ( size_t iC = 0; iC < comps->length(); ++iC )
3938 fieldWriter.AddValue( (double) noneIntValue );
3940 for ( size_t iC = 0; iC < comps->length(); ++iC )
3941 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3945 fieldWriter.Perform();
3946 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3947 if ( res && res->IsKO() )
3949 if ( res->myComment.empty() )
3950 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3952 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3958 if ( !geomAssocFields || !geomAssocFields[0] )
3961 // write geomAssocFields
3963 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3964 shapeDim[ TopAbs_COMPOUND ] = 3;
3965 shapeDim[ TopAbs_COMPSOLID ] = 3;
3966 shapeDim[ TopAbs_SOLID ] = 3;
3967 shapeDim[ TopAbs_SHELL ] = 2;
3968 shapeDim[ TopAbs_FACE ] = 2;
3969 shapeDim[ TopAbs_WIRE ] = 1;
3970 shapeDim[ TopAbs_EDGE ] = 1;
3971 shapeDim[ TopAbs_VERTEX ] = 0;
3972 shapeDim[ TopAbs_SHAPE ] = 3;
3974 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3976 std::vector< std::string > compNames;
3977 switch ( geomAssocFields[ iF ]) {
3979 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3980 compNames.push_back( "dim" );
3983 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3986 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3989 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3993 compNames.push_back( "id" );
3994 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3995 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3997 fieldWriter.SetDtIt( -1, -1 );
3999 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4003 if ( compNames.size() == 2 ) // _vertices_
4004 while ( elemIt->more() )
4006 const SMDS_MeshElement* e = elemIt->next();
4007 const int shapeID = e->getshapeId();
4010 fieldWriter.AddValue( (double) -1 );
4011 fieldWriter.AddValue( (double) -1 );
4015 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4016 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4017 fieldWriter.AddValue( (double) shapeID );
4021 while ( elemIt->more() )
4023 const SMDS_MeshElement* e = elemIt->next();
4024 const int shapeID = e->getshapeId();
4026 fieldWriter.AddValue( (double) -1 );
4028 fieldWriter.AddValue( (double) shapeID );
4032 fieldWriter.Perform();
4033 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4034 if ( res && res->IsKO() )
4036 if ( res->myComment.empty() )
4037 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4039 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4042 } // loop on geomAssocFields
4047 //================================================================================
4049 * \brief Export a part of mesh to a DAT file
4051 //================================================================================
4053 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4055 throw (SALOME::SALOME_Exception)
4057 Unexpect aCatch(SALOME_SalomeException);
4059 _preMeshInfo->FullLoadFromFile();
4061 PrepareForWriting(file);
4063 SMESH_MeshPartDS partDS( meshPart );
4064 _impl->ExportDAT(file,&partDS);
4066 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4067 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4069 //================================================================================
4071 * \brief Export a part of mesh to an UNV file
4073 //================================================================================
4075 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4077 throw (SALOME::SALOME_Exception)
4079 Unexpect aCatch(SALOME_SalomeException);
4081 _preMeshInfo->FullLoadFromFile();
4083 PrepareForWriting(file);
4085 SMESH_MeshPartDS partDS( meshPart );
4086 _impl->ExportUNV(file, &partDS);
4088 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4089 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4091 //================================================================================
4093 * \brief Export a part of mesh to an STL file
4095 //================================================================================
4097 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4099 ::CORBA::Boolean isascii)
4100 throw (SALOME::SALOME_Exception)
4102 Unexpect aCatch(SALOME_SalomeException);
4104 _preMeshInfo->FullLoadFromFile();
4106 PrepareForWriting(file);
4108 CORBA::String_var name;
4109 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4110 if ( !so->_is_nil() )
4111 name = so->GetName();
4113 SMESH_MeshPartDS partDS( meshPart );
4114 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4116 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4117 << meshPart<< ", r'" << file << "', " << isascii << ")";
4120 //================================================================================
4122 * \brief Export a part of mesh to an STL file
4124 //================================================================================
4126 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4128 CORBA::Boolean overwrite,
4129 CORBA::Boolean groupElemsByType)
4130 throw (SALOME::SALOME_Exception)
4133 Unexpect aCatch(SALOME_SalomeException);
4135 _preMeshInfo->FullLoadFromFile();
4137 PrepareForWriting(file,overwrite);
4139 std::string meshName("");
4140 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4141 if ( !so->_is_nil() )
4143 CORBA::String_var name = so->GetName();
4144 meshName = name.in();
4148 SMESH_MeshPartDS partDS( meshPart );
4149 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4151 SMESH_CATCH( SMESH::throwCorbaException );
4153 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4154 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4156 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4160 //================================================================================
4162 * \brief Export a part of mesh to a GMF file
4164 //================================================================================
4166 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4168 bool withRequiredGroups)
4169 throw (SALOME::SALOME_Exception)
4171 Unexpect aCatch(SALOME_SalomeException);
4173 _preMeshInfo->FullLoadFromFile();
4175 PrepareForWriting(file,/*overwrite=*/true);
4177 SMESH_MeshPartDS partDS( meshPart );
4178 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4180 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4181 << meshPart<< ", r'"
4183 << withRequiredGroups << ")";
4186 //=============================================================================
4188 * Return computation progress [0.,1]
4190 //=============================================================================
4192 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4196 return _impl->GetComputeProgress();
4198 SMESH_CATCH( SMESH::doNothing );
4202 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4204 Unexpect aCatch(SALOME_SalomeException);
4206 return _preMeshInfo->NbNodes();
4208 return _impl->NbNodes();
4211 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4213 Unexpect aCatch(SALOME_SalomeException);
4215 return _preMeshInfo->NbElements();
4217 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4220 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4222 Unexpect aCatch(SALOME_SalomeException);
4224 return _preMeshInfo->Nb0DElements();
4226 return _impl->Nb0DElements();
4229 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4231 Unexpect aCatch(SALOME_SalomeException);
4233 return _preMeshInfo->NbBalls();
4235 return _impl->NbBalls();
4238 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4240 Unexpect aCatch(SALOME_SalomeException);
4242 return _preMeshInfo->NbEdges();
4244 return _impl->NbEdges();
4247 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4248 throw(SALOME::SALOME_Exception)
4250 Unexpect aCatch(SALOME_SalomeException);
4252 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4254 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4257 //=============================================================================
4259 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4261 Unexpect aCatch(SALOME_SalomeException);
4263 return _preMeshInfo->NbFaces();
4265 return _impl->NbFaces();
4268 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4270 Unexpect aCatch(SALOME_SalomeException);
4272 return _preMeshInfo->NbTriangles();
4274 return _impl->NbTriangles();
4277 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4279 Unexpect aCatch(SALOME_SalomeException);
4281 return _preMeshInfo->NbBiQuadTriangles();
4283 return _impl->NbBiQuadTriangles();
4286 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4288 Unexpect aCatch(SALOME_SalomeException);
4290 return _preMeshInfo->NbQuadrangles();
4292 return _impl->NbQuadrangles();
4295 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4297 Unexpect aCatch(SALOME_SalomeException);
4299 return _preMeshInfo->NbBiQuadQuadrangles();
4301 return _impl->NbBiQuadQuadrangles();
4304 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4306 Unexpect aCatch(SALOME_SalomeException);
4308 return _preMeshInfo->NbPolygons();
4310 return _impl->NbPolygons();
4313 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4315 Unexpect aCatch(SALOME_SalomeException);
4317 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4319 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4322 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4323 throw(SALOME::SALOME_Exception)
4325 Unexpect aCatch(SALOME_SalomeException);
4327 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4329 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4332 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4333 throw(SALOME::SALOME_Exception)
4335 Unexpect aCatch(SALOME_SalomeException);
4337 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4339 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4342 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4343 throw(SALOME::SALOME_Exception)
4345 Unexpect aCatch(SALOME_SalomeException);
4347 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4349 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4352 //=============================================================================
4354 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4356 Unexpect aCatch(SALOME_SalomeException);
4358 return _preMeshInfo->NbVolumes();
4360 return _impl->NbVolumes();
4363 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4365 Unexpect aCatch(SALOME_SalomeException);
4367 return _preMeshInfo->NbTetras();
4369 return _impl->NbTetras();
4372 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4374 Unexpect aCatch(SALOME_SalomeException);
4376 return _preMeshInfo->NbHexas();
4378 return _impl->NbHexas();
4381 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4383 Unexpect aCatch(SALOME_SalomeException);
4385 return _preMeshInfo->NbTriQuadHexas();
4387 return _impl->NbTriQuadraticHexas();
4390 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4392 Unexpect aCatch(SALOME_SalomeException);
4394 return _preMeshInfo->NbPyramids();
4396 return _impl->NbPyramids();
4399 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4401 Unexpect aCatch(SALOME_SalomeException);
4403 return _preMeshInfo->NbPrisms();
4405 return _impl->NbPrisms();
4408 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4410 Unexpect aCatch(SALOME_SalomeException);
4412 return _preMeshInfo->NbHexPrisms();
4414 return _impl->NbHexagonalPrisms();
4417 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4419 Unexpect aCatch(SALOME_SalomeException);
4421 return _preMeshInfo->NbPolyhedrons();
4423 return _impl->NbPolyhedrons();
4426 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4427 throw(SALOME::SALOME_Exception)
4429 Unexpect aCatch(SALOME_SalomeException);
4431 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4433 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4436 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4437 throw(SALOME::SALOME_Exception)
4439 Unexpect aCatch(SALOME_SalomeException);
4441 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4443 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4446 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4447 throw(SALOME::SALOME_Exception)
4449 Unexpect aCatch(SALOME_SalomeException);
4451 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4453 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4456 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4457 throw(SALOME::SALOME_Exception)
4459 Unexpect aCatch(SALOME_SalomeException);
4461 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4463 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4466 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4467 throw(SALOME::SALOME_Exception)
4469 Unexpect aCatch(SALOME_SalomeException);
4471 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4473 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4476 //=============================================================================
4478 * Returns nb of published sub-meshes
4480 //=============================================================================
4482 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4484 Unexpect aCatch(SALOME_SalomeException);
4485 return _mapSubMesh_i.size();
4488 //=============================================================================
4490 * Dumps mesh into a string
4492 //=============================================================================
4494 char* SMESH_Mesh_i::Dump()
4498 return CORBA::string_dup( os.str().c_str() );
4501 //=============================================================================
4503 * Method of SMESH_IDSource interface
4505 //=============================================================================
4507 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4509 return GetElementsId();
4512 //=============================================================================
4514 * Returns ids of all elements
4516 //=============================================================================
4518 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4519 throw (SALOME::SALOME_Exception)
4521 Unexpect aCatch(SALOME_SalomeException);
4523 _preMeshInfo->FullLoadFromFile();
4525 SMESH::long_array_var aResult = new SMESH::long_array();
4526 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4528 if ( aSMESHDS_Mesh == NULL )
4529 return aResult._retn();
4531 long nbElements = NbElements();
4532 aResult->length( nbElements );
4533 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4534 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4535 aResult[i] = anIt->next()->GetID();
4537 return aResult._retn();
4541 //=============================================================================
4543 * Returns ids of all elements of given type
4545 //=============================================================================
4547 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4548 throw (SALOME::SALOME_Exception)
4550 Unexpect aCatch(SALOME_SalomeException);
4552 _preMeshInfo->FullLoadFromFile();
4554 SMESH::long_array_var aResult = new SMESH::long_array();
4555 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4557 if ( aSMESHDS_Mesh == NULL )
4558 return aResult._retn();
4560 long nbElements = NbElements();
4562 // No sense in returning ids of elements along with ids of nodes:
4563 // when theElemType == SMESH::ALL, return node ids only if
4564 // there are no elements
4565 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4566 return GetNodesId();
4568 aResult->length( nbElements );
4572 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4573 while ( i < nbElements && anIt->more() )
4574 aResult[i++] = anIt->next()->GetID();
4576 aResult->length( i );
4578 return aResult._retn();
4581 //=============================================================================
4583 * Returns ids of all nodes
4585 //=============================================================================
4587 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4588 throw (SALOME::SALOME_Exception)
4590 Unexpect aCatch(SALOME_SalomeException);
4592 _preMeshInfo->FullLoadFromFile();
4594 SMESH::long_array_var aResult = new SMESH::long_array();
4595 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4597 if ( aMeshDS == NULL )
4598 return aResult._retn();
4600 long nbNodes = NbNodes();
4601 aResult->length( nbNodes );
4602 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4603 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4604 aResult[i] = anIt->next()->GetID();
4606 return aResult._retn();
4609 //=============================================================================
4613 //=============================================================================
4615 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4616 throw (SALOME::SALOME_Exception)
4618 SMESH::ElementType type = SMESH::ALL;
4622 _preMeshInfo->FullLoadFromFile();
4624 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4626 SMESH_CATCH( SMESH::throwCorbaException );
4631 //=============================================================================
4635 //=============================================================================
4637 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4638 throw (SALOME::SALOME_Exception)
4641 _preMeshInfo->FullLoadFromFile();
4643 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4645 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4647 return ( SMESH::EntityType ) e->GetEntityType();
4650 //=============================================================================
4654 //=============================================================================
4656 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4657 throw (SALOME::SALOME_Exception)
4660 _preMeshInfo->FullLoadFromFile();
4662 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4664 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4666 return ( SMESH::GeometryType ) e->GetGeomType();
4669 //=============================================================================
4671 * Returns ID of elements for given submesh
4673 //=============================================================================
4674 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4675 throw (SALOME::SALOME_Exception)
4677 SMESH::long_array_var aResult = new SMESH::long_array();
4681 _preMeshInfo->FullLoadFromFile();
4683 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4684 if(!SM) return aResult._retn();
4686 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4687 if(!SDSM) return aResult._retn();
4689 aResult->length(SDSM->NbElements());
4691 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4693 while ( eIt->more() ) {
4694 aResult[i++] = eIt->next()->GetID();
4697 SMESH_CATCH( SMESH::throwCorbaException );
4699 return aResult._retn();
4702 //=============================================================================
4704 * Returns ID of nodes for given submesh
4705 * If param all==true - returns all nodes, else -
4706 * returns only nodes on shapes.
4708 //=============================================================================
4710 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4712 throw (SALOME::SALOME_Exception)
4714 SMESH::long_array_var aResult = new SMESH::long_array();
4718 _preMeshInfo->FullLoadFromFile();
4720 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4721 if(!SM) return aResult._retn();
4723 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4724 if(!SDSM) return aResult._retn();
4727 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4728 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4729 while ( nIt->more() ) {
4730 const SMDS_MeshNode* elem = nIt->next();
4731 theElems.insert( elem->GetID() );
4734 else { // all nodes of submesh elements
4735 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4736 while ( eIt->more() ) {
4737 const SMDS_MeshElement* anElem = eIt->next();
4738 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4739 while ( nIt->more() ) {
4740 const SMDS_MeshElement* elem = nIt->next();
4741 theElems.insert( elem->GetID() );
4746 aResult->length(theElems.size());
4747 set<int>::iterator itElem;
4749 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4750 aResult[i++] = *itElem;
4752 SMESH_CATCH( SMESH::throwCorbaException );
4754 return aResult._retn();
4757 //=============================================================================
4759 * Returns type of elements for given submesh
4761 //=============================================================================
4763 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4764 throw (SALOME::SALOME_Exception)
4766 SMESH::ElementType type = SMESH::ALL;
4770 _preMeshInfo->FullLoadFromFile();
4772 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4773 if(!SM) return SMESH::ALL;
4775 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4776 if(!SDSM) return SMESH::ALL;
4778 if(SDSM->NbElements()==0)
4779 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4781 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4782 const SMDS_MeshElement* anElem = eIt->next();
4784 type = ( SMESH::ElementType ) anElem->GetType();
4786 SMESH_CATCH( SMESH::throwCorbaException );
4792 //=============================================================================
4794 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4796 //=============================================================================
4798 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4801 _preMeshInfo->FullLoadFromFile();
4803 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4804 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4809 //=============================================================================
4811 * Get XYZ coordinates of node as list of double
4812 * If there is not node for given ID - returns empty list
4814 //=============================================================================
4816 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4819 _preMeshInfo->FullLoadFromFile();
4821 SMESH::double_array_var aResult = new SMESH::double_array();
4822 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4823 if ( aMeshDS == NULL )
4824 return aResult._retn();
4827 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4829 return aResult._retn();
4833 aResult[0] = aNode->X();
4834 aResult[1] = aNode->Y();
4835 aResult[2] = aNode->Z();
4836 return aResult._retn();
4840 //=============================================================================
4842 * For given node returns list of IDs of inverse elements
4843 * If there is not node for given ID - returns empty list
4845 //=============================================================================
4847 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4848 SMESH::ElementType elemType)
4851 _preMeshInfo->FullLoadFromFile();
4853 SMESH::long_array_var aResult = new SMESH::long_array();
4854 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4855 if ( aMeshDS == NULL )
4856 return aResult._retn();
4859 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4861 return aResult._retn();
4863 // find inverse elements
4864 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4865 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4866 aResult->length( aNode->NbInverseElements( type ));
4867 for( int i = 0; eIt->more(); ++i )
4869 const SMDS_MeshElement* elem = eIt->next();
4870 aResult[ i ] = elem->GetID();
4872 return aResult._retn();
4875 //=============================================================================
4877 * \brief Return position of a node on shape
4879 //=============================================================================
4881 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4884 _preMeshInfo->FullLoadFromFile();
4886 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4887 aNodePosition->shapeID = 0;
4888 aNodePosition->shapeType = GEOM::SHAPE;
4890 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4891 if ( !mesh ) return aNodePosition;
4893 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4895 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4897 aNodePosition->shapeID = aNode->getshapeId();
4898 switch ( pos->GetTypeOfPosition() ) {
4900 aNodePosition->shapeType = GEOM::EDGE;
4901 aNodePosition->params.length(1);
4902 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4904 case SMDS_TOP_FACE: {
4905 SMDS_FacePositionPtr fPos = pos;
4906 aNodePosition->shapeType = GEOM::FACE;
4907 aNodePosition->params.length(2);
4908 aNodePosition->params[0] = fPos->GetUParameter();
4909 aNodePosition->params[1] = fPos->GetVParameter();
4912 case SMDS_TOP_VERTEX:
4913 aNodePosition->shapeType = GEOM::VERTEX;
4915 case SMDS_TOP_3DSPACE:
4916 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4917 aNodePosition->shapeType = GEOM::SOLID;
4918 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4919 aNodePosition->shapeType = GEOM::SHELL;
4925 return aNodePosition;
4928 //=============================================================================
4930 * \brief Return position of an element on shape
4932 //=============================================================================
4934 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4937 _preMeshInfo->FullLoadFromFile();
4939 SMESH::ElementPosition anElementPosition;
4940 anElementPosition.shapeID = 0;
4941 anElementPosition.shapeType = GEOM::SHAPE;
4943 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4944 if ( !mesh ) return anElementPosition;
4946 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4948 anElementPosition.shapeID = anElem->getshapeId();
4949 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4950 if ( !aSp.IsNull() ) {
4951 switch ( aSp.ShapeType() ) {
4953 anElementPosition.shapeType = GEOM::EDGE;
4956 anElementPosition.shapeType = GEOM::FACE;
4959 anElementPosition.shapeType = GEOM::VERTEX;
4962 anElementPosition.shapeType = GEOM::SOLID;
4965 anElementPosition.shapeType = GEOM::SHELL;
4971 return anElementPosition;
4974 //=============================================================================
4976 * If given element is node returns IDs of shape from position
4977 * If there is not node for given ID - returns -1
4979 //=============================================================================
4981 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4984 _preMeshInfo->FullLoadFromFile();
4986 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4987 if ( aMeshDS == NULL )
4991 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4993 return aNode->getshapeId();
5000 //=============================================================================
5002 * For given element returns ID of result shape after
5003 * ::FindShape() from SMESH_MeshEditor
5004 * If there is not element for given ID - returns -1
5006 //=============================================================================
5008 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5011 _preMeshInfo->FullLoadFromFile();
5013 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5014 if ( aMeshDS == NULL )
5017 // try to find element
5018 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5022 ::SMESH_MeshEditor aMeshEditor(_impl);
5023 int index = aMeshEditor.FindShape( elem );
5031 //=============================================================================
5033 * Returns number of nodes for given element
5034 * If there is not element for given ID - returns -1
5036 //=============================================================================
5038 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5041 _preMeshInfo->FullLoadFromFile();
5043 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5044 if ( aMeshDS == NULL ) return -1;
5045 // try to find element
5046 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5047 if(!elem) return -1;
5048 return elem->NbNodes();
5052 //=============================================================================
5054 * Returns ID of node by given index for given element
5055 * If there is not element for given ID - returns -1
5056 * If there is not node for given index - returns -2
5058 //=============================================================================
5060 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5063 _preMeshInfo->FullLoadFromFile();
5065 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5066 if ( aMeshDS == NULL ) return -1;
5067 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5068 if(!elem) return -1;
5069 if( index>=elem->NbNodes() || index<0 ) return -1;
5070 return elem->GetNode(index)->GetID();
5073 //=============================================================================
5075 * Returns IDs of nodes of given element
5077 //=============================================================================
5079 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5082 _preMeshInfo->FullLoadFromFile();
5084 SMESH::long_array_var aResult = new SMESH::long_array();
5085 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5087 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5089 aResult->length( elem->NbNodes() );
5090 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5091 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5092 aResult[ i ] = n->GetID();
5095 return aResult._retn();
5098 //=============================================================================
5100 * Returns true if given node is medium node
5101 * in given quadratic element
5103 //=============================================================================
5105 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5108 _preMeshInfo->FullLoadFromFile();
5110 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5111 if ( aMeshDS == NULL ) return false;
5113 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5114 if(!aNode) return false;
5115 // try to find element
5116 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5117 if(!elem) return false;
5119 return elem->IsMediumNode(aNode);
5123 //=============================================================================
5125 * Returns true if given node is medium node
5126 * in one of quadratic elements
5128 //=============================================================================
5130 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5131 SMESH::ElementType theElemType)
5134 _preMeshInfo->FullLoadFromFile();
5136 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5137 if ( aMeshDS == NULL ) return false;
5140 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5141 if(!aNode) return false;
5143 SMESH_MesherHelper aHelper( *(_impl) );
5145 SMDSAbs_ElementType aType;
5146 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5147 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5148 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5149 else aType = SMDSAbs_All;
5151 return aHelper.IsMedium(aNode,aType);
5155 //=============================================================================
5157 * Returns number of edges for given element
5159 //=============================================================================
5161 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5164 _preMeshInfo->FullLoadFromFile();
5166 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5167 if ( aMeshDS == NULL ) return -1;
5168 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5169 if(!elem) return -1;
5170 return elem->NbEdges();
5174 //=============================================================================
5176 * Returns number of faces for given element
5178 //=============================================================================
5180 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5183 _preMeshInfo->FullLoadFromFile();
5185 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5186 if ( aMeshDS == NULL ) return -1;
5187 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5188 if(!elem) return -1;
5189 return elem->NbFaces();
5192 //=======================================================================
5193 //function : GetElemFaceNodes
5194 //purpose : Returns nodes of given face (counted from zero) for given element.
5195 //=======================================================================
5197 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5198 CORBA::Short faceIndex)
5201 _preMeshInfo->FullLoadFromFile();
5203 SMESH::long_array_var aResult = new SMESH::long_array();
5204 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5206 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5208 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5209 if ( faceIndex < vtool.NbFaces() )
5211 aResult->length( vtool.NbFaceNodes( faceIndex ));
5212 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5213 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5214 aResult[ i ] = nn[ i ]->GetID();
5218 return aResult._retn();
5221 //=======================================================================
5222 //function : GetFaceNormal
5223 //purpose : Returns three components of normal of given mesh face.
5224 //=======================================================================
5226 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5227 CORBA::Boolean normalized)
5230 _preMeshInfo->FullLoadFromFile();
5232 SMESH::double_array_var aResult = new SMESH::double_array();
5234 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5237 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5239 aResult->length( 3 );
5240 aResult[ 0 ] = normal.X();
5241 aResult[ 1 ] = normal.Y();
5242 aResult[ 2 ] = normal.Z();
5245 return aResult._retn();
5248 //=======================================================================
5249 //function : FindElementByNodes
5250 //purpose : Returns an element based on all given nodes.
5251 //=======================================================================
5253 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5256 _preMeshInfo->FullLoadFromFile();
5258 CORBA::Long elemID(0);
5259 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5261 vector< const SMDS_MeshNode * > nn( nodes.length() );
5262 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5263 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5266 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5267 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5268 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5269 _impl->NbVolumes( ORDER_QUADRATIC )))
5270 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5272 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5277 //================================================================================
5279 * \brief Return elements including all given nodes.
5281 //================================================================================
5283 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5284 SMESH::ElementType elemType)
5287 _preMeshInfo->FullLoadFromFile();
5289 SMESH::long_array_var result = new SMESH::long_array();
5291 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5293 vector< const SMDS_MeshNode * > nn( nodes.length() );
5294 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5295 nn[i] = mesh->FindNode( nodes[i] );
5297 std::vector<const SMDS_MeshElement *> elems;
5298 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5299 result->length( elems.size() );
5300 for ( size_t i = 0; i < elems.size(); ++i )
5301 result[i] = elems[i]->GetID();
5303 return result._retn();
5306 //=============================================================================
5308 * Returns true if given element is polygon
5310 //=============================================================================
5312 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5315 _preMeshInfo->FullLoadFromFile();
5317 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5318 if ( aMeshDS == NULL ) return false;
5319 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5320 if(!elem) return false;
5321 return elem->IsPoly();
5325 //=============================================================================
5327 * Returns true if given element is quadratic
5329 //=============================================================================
5331 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5334 _preMeshInfo->FullLoadFromFile();
5336 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5337 if ( aMeshDS == NULL ) return false;
5338 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5339 if(!elem) return false;
5340 return elem->IsQuadratic();
5343 //=============================================================================
5345 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5347 //=============================================================================
5349 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5352 _preMeshInfo->FullLoadFromFile();
5354 if ( const SMDS_BallElement* ball =
5355 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5356 return ball->GetDiameter();
5361 //=============================================================================
5363 * Returns bary center for given element
5365 //=============================================================================
5367 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5370 _preMeshInfo->FullLoadFromFile();
5372 SMESH::double_array_var aResult = new SMESH::double_array();
5373 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5374 if ( aMeshDS == NULL )
5375 return aResult._retn();
5377 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5379 return aResult._retn();
5381 if(elem->GetType()==SMDSAbs_Volume) {
5382 SMDS_VolumeTool aTool;
5383 if(aTool.Set(elem)) {
5385 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5390 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5392 double x=0., y=0., z=0.;
5393 for(; anIt->more(); ) {
5395 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5409 return aResult._retn();
5412 //================================================================================
5414 * \brief Create a group of elements preventing computation of a sub-shape
5416 //================================================================================
5418 SMESH::ListOfGroups*
5419 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5420 const char* theGroupName )
5421 throw ( SALOME::SALOME_Exception )
5423 Unexpect aCatch(SALOME_SalomeException);
5425 if ( !theGroupName || strlen( theGroupName) == 0 )
5426 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5428 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5429 ::SMESH_MeshEditor::ElemFeatures elemType;
5431 // submesh by subshape id
5432 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5433 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5436 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5437 if ( error && error->HasBadElems() )
5439 // sort bad elements by type
5440 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5441 const list<const SMDS_MeshElement*>& badElems =
5442 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5443 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5444 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5445 for ( ; elemIt != elemEnd; ++elemIt )
5447 const SMDS_MeshElement* elem = *elemIt;
5448 if ( !elem ) continue;
5450 if ( elem->GetID() < 1 )
5452 // elem is a temporary element, make a real element
5453 vector< const SMDS_MeshNode* > nodes;
5454 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5455 while ( nIt->more() && elem )
5457 nodes.push_back( nIt->next() );
5458 if ( nodes.back()->GetID() < 1 )
5459 elem = 0; // a temporary element on temporary nodes
5463 ::SMESH_MeshEditor editor( _impl );
5464 elem = editor.AddElement( nodes, elemType.Init( elem ));
5468 elemsByType[ elem->GetType() ].push_back( elem );
5471 // how many groups to create?
5473 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5474 nbTypes += int( !elemsByType[ i ].empty() );
5475 groups->length( nbTypes );
5478 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5480 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5481 if ( elems.empty() ) continue;
5483 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5484 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5486 SMESH::SMESH_Mesh_var mesh = _this();
5487 SALOMEDS::SObject_wrap aSO =
5488 _gen_i->PublishGroup( mesh, groups[ iG ],
5489 GEOM::GEOM_Object::_nil(), theGroupName);
5491 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5492 if ( !grp_i ) continue;
5494 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5495 for ( size_t iE = 0; iE < elems.size(); ++iE )
5496 grpDS->SMDSGroup().Add( elems[ iE ]);
5501 return groups._retn();
5504 //=============================================================================
5506 * Create and publish group servants if any groups were imported or created anyhow
5508 //=============================================================================
5510 void SMESH_Mesh_i::CreateGroupServants()
5512 SMESH::SMESH_Mesh_var aMesh = _this();
5515 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5516 while ( groupIt->more() )
5518 ::SMESH_Group* group = groupIt->next();
5519 int anId = group->GetID();
5521 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5522 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5524 addedIDs.insert( anId );
5526 SMESH_GroupBase_i* aGroupImpl;
5528 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5529 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5531 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5532 shape = groupOnGeom->GetShape();
5535 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5538 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5539 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5540 aGroupImpl->Register();
5542 // register CORBA object for persistence
5543 int nextId = _gen_i->RegisterObject( groupVar );
5544 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5545 else { nextId = 0; } // avoid "unused variable" warning in release mode
5547 // publishing the groups in the study
5548 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5549 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5551 if ( !addedIDs.empty() )
5554 set<int>::iterator id = addedIDs.begin();
5555 for ( ; id != addedIDs.end(); ++id )
5557 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5558 int i = std::distance( _mapGroups.begin(), it );
5559 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5564 //=============================================================================
5566 * \brief Return true if all sub-meshes are computed OK - to update an icon
5568 //=============================================================================
5570 bool SMESH_Mesh_i::IsComputedOK()
5572 return _impl->IsComputedOK();
5575 //=============================================================================
5577 * \brief Return groups cantained in _mapGroups by their IDs
5579 //=============================================================================
5581 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5583 int nbGroups = groupIDs.size();
5584 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5585 aList->length( nbGroups );
5587 list<int>::const_iterator ids = groupIDs.begin();
5588 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5590 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5591 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5592 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5594 aList->length( nbGroups );
5595 return aList._retn();
5598 //=============================================================================
5600 * \brief Return information about imported file
5602 //=============================================================================
5604 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5606 SMESH::MedFileInfo_var res( _medFileInfo );
5607 if ( !res.operator->() ) {
5608 res = new SMESH::MedFileInfo;
5610 res->fileSize = res->major = res->minor = res->release = -1;
5615 //=======================================================================
5616 //function : FileInfoToString
5617 //purpose : Persistence of file info
5618 //=======================================================================
5620 std::string SMESH_Mesh_i::FileInfoToString()
5623 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5625 s = SMESH_Comment( _medFileInfo->fileSize )
5626 << " " << _medFileInfo->major
5627 << " " << _medFileInfo->minor
5628 << " " << _medFileInfo->release
5629 << " " << _medFileInfo->fileName;
5634 //=======================================================================
5635 //function : FileInfoFromString
5636 //purpose : Persistence of file info
5637 //=======================================================================
5639 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5641 std::string size, major, minor, release, fileName;
5642 std::istringstream is(info);
5643 is >> size >> major >> minor >> release;
5644 fileName = info.data() + ( size.size() + 1 +
5647 release.size()+ 1 );
5649 _medFileInfo = new SMESH::MedFileInfo();
5650 _medFileInfo->fileName = fileName.c_str();
5651 _medFileInfo->fileSize = atoi( size.c_str() );
5652 _medFileInfo->major = atoi( major.c_str() );
5653 _medFileInfo->minor = atoi( minor.c_str() );
5654 _medFileInfo->release = atoi( release.c_str() );
5657 //=============================================================================
5659 * \brief Pass names of mesh groups from study to mesh DS
5661 //=============================================================================
5663 void SMESH_Mesh_i::checkGroupNames()
5665 int nbGrp = NbGroups();
5669 SMESH::ListOfGroups* grpList = 0;
5670 // avoid dump of "GetGroups"
5672 // store python dump into a local variable inside local scope
5673 SMESH::TPythonDump pDump; // do not delete this line of code
5674 grpList = GetGroups();
5677 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5678 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5681 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5682 if ( aGrpSO->_is_nil() )
5684 // correct name of the mesh group if necessary
5685 const char* guiName = aGrpSO->GetName();
5686 if ( strcmp(guiName, aGrp->GetName()) )
5687 aGrp->SetName( guiName );
5691 //=============================================================================
5693 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5695 //=============================================================================
5696 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5698 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5702 //=============================================================================
5704 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5706 //=============================================================================
5708 char* SMESH_Mesh_i::GetParameters()
5710 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5713 //=============================================================================
5715 * \brief Returns list of notebook variables used for last Mesh operation
5717 //=============================================================================
5718 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5720 SMESH::string_array_var aResult = new SMESH::string_array();
5721 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5723 CORBA::String_var aParameters = GetParameters();
5724 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5725 if ( aSections->length() > 0 ) {
5726 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5727 aResult->length( aVars.length() );
5728 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5729 aResult[i] = CORBA::string_dup( aVars[i] );
5732 return aResult._retn();
5735 //=======================================================================
5736 //function : GetTypes
5737 //purpose : Returns types of elements it contains
5738 //=======================================================================
5740 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5743 return _preMeshInfo->GetTypes();
5745 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5749 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5750 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5751 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5752 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5753 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5754 if (_impl->NbNodes() &&
5755 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5756 types->length( nbTypes );
5758 return types._retn();
5761 //=======================================================================
5762 //function : GetMesh
5763 //purpose : Returns self
5764 //=======================================================================
5766 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5768 return SMESH::SMESH_Mesh::_duplicate( _this() );
5771 //=======================================================================
5772 //function : IsMeshInfoCorrect
5773 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5774 // * happen if mesh data is not yet fully loaded from the file of study.
5775 //=======================================================================
5777 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5779 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5782 //=============================================================================
5784 * \brief Returns number of mesh elements per each \a EntityType
5786 //=============================================================================
5788 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5791 return _preMeshInfo->GetMeshInfo();
5793 SMESH::long_array_var aRes = new SMESH::long_array();
5794 aRes->length(SMESH::Entity_Last);
5795 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5797 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5799 return aRes._retn();
5800 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5801 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5802 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5803 return aRes._retn();
5806 //=============================================================================
5808 * \brief Returns number of mesh elements per each \a ElementType
5810 //=============================================================================
5812 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5814 SMESH::long_array_var aRes = new SMESH::long_array();
5815 aRes->length(SMESH::NB_ELEMENT_TYPES);
5816 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5819 const SMDS_MeshInfo* meshInfo = 0;
5821 meshInfo = _preMeshInfo;
5822 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5823 meshInfo = & meshDS->GetMeshInfo();
5826 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5827 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5829 return aRes._retn();
5832 //=============================================================================
5834 * Collect statistic of mesh elements given by iterator
5836 //=============================================================================
5838 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5839 SMESH::long_array& theInfo)
5841 if (!theItr) return;
5842 while (theItr->more())
5843 theInfo[ theItr->next()->GetEntityType() ]++;
5845 //=============================================================================
5847 * Returns mesh unstructed grid information.
5849 //=============================================================================
5851 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5853 SALOMEDS::TMPFile_var SeqFile;
5854 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5855 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5857 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5858 aWriter->WriteToOutputStringOn();
5859 aWriter->SetInputData(aGrid);
5860 aWriter->SetFileTypeToBinary();
5862 char* str = aWriter->GetOutputString();
5863 int size = aWriter->GetOutputStringLength();
5865 //Allocate octet buffer of required size
5866 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5867 //Copy ostrstream content to the octet buffer
5868 memcpy(OctetBuf, str, size);
5869 //Create and return TMPFile
5870 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5874 return SeqFile._retn();
5877 //=============================================================================
5878 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5879 * SMESH::ElementType type) */
5881 using namespace SMESH::Controls;
5882 //-----------------------------------------------------------------------------
5883 struct PredicateIterator : public SMDS_ElemIterator
5885 SMDS_ElemIteratorPtr _elemIter;
5886 PredicatePtr _predicate;
5887 const SMDS_MeshElement* _elem;
5888 SMDSAbs_ElementType _type;
5890 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5891 PredicatePtr predicate,
5892 SMDSAbs_ElementType type):
5893 _elemIter(iterator), _predicate(predicate), _type(type)
5901 virtual const SMDS_MeshElement* next()
5903 const SMDS_MeshElement* res = _elem;
5905 while ( _elemIter->more() && !_elem )
5907 if ((_elem = _elemIter->next()) &&
5908 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5909 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5916 //-----------------------------------------------------------------------------
5917 struct IDSourceIterator : public SMDS_ElemIterator
5919 const CORBA::Long* _idPtr;
5920 const CORBA::Long* _idEndPtr;
5921 SMESH::long_array_var _idArray;
5922 const SMDS_Mesh* _mesh;
5923 const SMDSAbs_ElementType _type;
5924 const SMDS_MeshElement* _elem;
5926 IDSourceIterator( const SMDS_Mesh* mesh,
5927 const CORBA::Long* ids,
5929 SMDSAbs_ElementType type):
5930 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5932 if ( _idPtr && nbIds && _mesh )
5935 IDSourceIterator( const SMDS_Mesh* mesh,
5936 SMESH::long_array* idArray,
5937 SMDSAbs_ElementType type):
5938 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5940 if ( idArray && _mesh )
5942 _idPtr = &_idArray[0];
5943 _idEndPtr = _idPtr + _idArray->length();
5951 virtual const SMDS_MeshElement* next()
5953 const SMDS_MeshElement* res = _elem;
5955 while ( _idPtr < _idEndPtr && !_elem )
5957 if ( _type == SMDSAbs_Node )
5959 _elem = _mesh->FindNode( *_idPtr++ );
5961 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5962 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5970 //-----------------------------------------------------------------------------
5972 struct NodeOfElemIterator : public SMDS_ElemIterator
5974 TColStd_MapOfInteger _checkedNodeIDs;
5975 SMDS_ElemIteratorPtr _elemIter;
5976 SMDS_ElemIteratorPtr _nodeIter;
5977 const SMDS_MeshElement* _node;
5979 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5981 if ( _elemIter && _elemIter->more() )
5983 _nodeIter = _elemIter->next()->nodesIterator();
5991 virtual const SMDS_MeshElement* next()
5993 const SMDS_MeshElement* res = _node;
5995 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5997 if ( _nodeIter->more() )
5999 _node = _nodeIter->next();
6000 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6005 _nodeIter = _elemIter->next()->nodesIterator();
6013 //=============================================================================
6015 * Return iterator on elements of given type in given object
6017 //=============================================================================
6019 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6020 SMESH::ElementType theType)
6022 SMDS_ElemIteratorPtr elemIt;
6023 bool typeOK = ( theType == SMESH::ALL );
6024 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6026 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6027 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6028 if ( !mesh_i ) return elemIt;
6029 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6031 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6033 elemIt = meshDS->elementsIterator( elemType );
6036 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6038 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6041 elemIt = sm->GetElements();
6042 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6044 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6045 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6049 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6051 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6052 if ( groupDS && ( elemType == groupDS->GetType() ||
6053 elemType == SMDSAbs_Node ||
6054 elemType == SMDSAbs_All ))
6056 elemIt = groupDS->GetElements();
6057 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6060 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6062 if ( filter_i->GetElementType() == theType ||
6063 filter_i->GetElementType() == SMESH::ALL ||
6064 elemType == SMDSAbs_Node ||
6065 elemType == SMDSAbs_All)
6067 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6068 if ( pred_i && pred_i->GetPredicate() )
6070 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6071 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6072 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6073 elemIt = SMDS_ElemIteratorPtr
6074 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6075 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6081 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6082 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6083 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6085 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6086 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6089 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6090 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6094 SMESH::long_array_var ids = theObject->GetIDs();
6095 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6097 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6100 if ( elemIt && elemIt->more() && !typeOK )
6102 if ( elemType == SMDSAbs_Node )
6104 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6108 elemIt = SMDS_ElemIteratorPtr();
6114 //=============================================================================
6115 namespace // Finding concurrent hypotheses
6116 //=============================================================================
6120 * \brief mapping of mesh dimension into shape type
6122 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6124 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6126 case 0: aType = TopAbs_VERTEX; break;
6127 case 1: aType = TopAbs_EDGE; break;
6128 case 2: aType = TopAbs_FACE; break;
6130 default:aType = TopAbs_SOLID; break;
6135 //-----------------------------------------------------------------------------
6137 * \brief Internal structure used to find concurrent submeshes
6139 * It represents a pair < submesh, concurrent dimension >, where
6140 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6141 * with another submesh. In other words, it is dimension of a hypothesis assigned
6148 int _dim; //!< a dimension the algo can build (concurrent dimension)
6149 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6150 TopTools_MapOfShape _shapeMap;
6151 SMESH_subMesh* _subMesh;
6152 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6154 //-----------------------------------------------------------------------------
6155 // Return the algorithm
6156 const SMESH_Algo* GetAlgo() const
6157 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6159 //-----------------------------------------------------------------------------
6161 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6163 const TopoDS_Shape& theShape)
6165 _subMesh = (SMESH_subMesh*)theSubMesh;
6166 SetShape( theDim, theShape );
6169 //-----------------------------------------------------------------------------
6171 void SetShape(const int theDim,
6172 const TopoDS_Shape& theShape)
6175 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6176 if (_dim >= _ownDim)
6177 _shapeMap.Add( theShape );
6179 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6180 for( ; anExp.More(); anExp.Next() )
6181 _shapeMap.Add( anExp.Current() );
6185 //-----------------------------------------------------------------------------
6186 //! Check sharing of sub-shapes
6187 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6188 const TopTools_MapOfShape& theToFind,
6189 const TopAbs_ShapeEnum theType)
6191 bool isShared = false;
6192 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6193 for (; !isShared && anItr.More(); anItr.Next() )
6195 const TopoDS_Shape aSubSh = anItr.Key();
6196 // check for case when concurrent dimensions are same
6197 isShared = theToFind.Contains( aSubSh );
6198 // check for sub-shape with concurrent dimension
6199 TopExp_Explorer anExp( aSubSh, theType );
6200 for ( ; !isShared && anExp.More(); anExp.Next() )
6201 isShared = theToFind.Contains( anExp.Current() );
6206 //-----------------------------------------------------------------------------
6207 //! check algorithms
6208 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6209 const SMESHDS_Hypothesis* theA2)
6211 if ( !theA1 || !theA2 ||
6212 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6213 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6214 return false; // one of the hypothesis is not algorithm
6215 // check algorithm names (should be equal)
6216 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6220 //-----------------------------------------------------------------------------
6221 //! Check if sub-shape hypotheses are concurrent
6222 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6224 if ( _subMesh == theOther->_subMesh )
6225 return false; // same sub-shape - should not be
6227 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6228 // any of the two submeshes is not on COMPOUND shape )
6229 // -> no concurrency
6230 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6231 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6232 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6233 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6234 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6237 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6238 if ( !checkSubShape )
6241 // check algorithms to be same
6242 const SMESH_Algo* a1 = this->GetAlgo();
6243 const SMESH_Algo* a2 = theOther->GetAlgo();
6244 bool isSame = checkAlgo( a1, a2 );
6248 return false; // pb?
6249 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6252 // check hypothesises for concurrence (skip first as algorithm)
6254 // pointers should be same, because it is referened from mesh hypothesis partition
6255 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6256 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6257 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6258 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6260 // the submeshes are concurrent if their algorithms has different parameters
6261 return nbSame != theOther->_hypotheses.size() - 1;
6264 // Return true if algorithm of this SMESH_DimHyp is used if no
6265 // sub-mesh order is imposed by the user
6266 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6268 // NeedDiscreteBoundary() algo has a higher priority
6269 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6270 theOther->GetAlgo()->NeedDiscreteBoundary() )
6271 return !this->GetAlgo()->NeedDiscreteBoundary();
6273 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6276 }; // end of SMESH_DimHyp
6277 //-----------------------------------------------------------------------------
6279 typedef list<const SMESH_DimHyp*> TDimHypList;
6281 //-----------------------------------------------------------------------------
6283 void addDimHypInstance(const int theDim,
6284 const TopoDS_Shape& theShape,
6285 const SMESH_Algo* theAlgo,
6286 const SMESH_subMesh* theSubMesh,
6287 const list <const SMESHDS_Hypothesis*>& theHypList,
6288 TDimHypList* theDimHypListArr )
6290 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6291 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6292 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6293 dimHyp->_hypotheses.push_front(theAlgo);
6294 listOfdimHyp.push_back( dimHyp );
6297 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6298 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6299 theHypList.begin(), theHypList.end() );
6302 //-----------------------------------------------------------------------------
6303 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6304 TDimHypList& theListOfConcurr)
6306 if ( theListOfConcurr.empty() )
6308 theListOfConcurr.push_back( theDimHyp );
6312 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6313 while ( hypIt != theListOfConcurr.end() &&
6314 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6316 theListOfConcurr.insert( hypIt, theDimHyp );
6320 //-----------------------------------------------------------------------------
6321 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6322 const TDimHypList& theListOfDimHyp,
6323 TDimHypList& theListOfConcurrHyp,
6324 set<int>& theSetOfConcurrId )
6326 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6327 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6329 const SMESH_DimHyp* curDimHyp = *rIt;
6330 if ( curDimHyp == theDimHyp )
6331 break; // meet own dimHyp pointer in same dimension
6333 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6334 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6336 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6341 //-----------------------------------------------------------------------------
6342 void unionLists(TListOfInt& theListOfId,
6343 TListOfListOfInt& theListOfListOfId,
6346 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6347 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6349 continue; //skip already treated lists
6350 // check if other list has any same submesh object
6351 TListOfInt& otherListOfId = *it;
6352 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6353 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6356 // union two lists (from source into target)
6357 TListOfInt::iterator it2 = otherListOfId.begin();
6358 for ( ; it2 != otherListOfId.end(); it2++ ) {
6359 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6360 theListOfId.push_back(*it2);
6362 // clear source list
6363 otherListOfId.clear();
6366 //-----------------------------------------------------------------------------
6368 //! free memory allocated for dimension-hypothesis objects
6369 void removeDimHyps( TDimHypList* theArrOfList )
6371 for (int i = 0; i < 4; i++ ) {
6372 TDimHypList& listOfdimHyp = theArrOfList[i];
6373 TDimHypList::const_iterator it = listOfdimHyp.begin();
6374 for ( ; it != listOfdimHyp.end(); it++ )
6379 //-----------------------------------------------------------------------------
6381 * \brief find common submeshes with given submesh
6382 * \param theSubMeshList list of already collected submesh to check
6383 * \param theSubMesh given submesh to intersect with other
6384 * \param theCommonSubMeshes collected common submeshes
6386 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6387 const SMESH_subMesh* theSubMesh,
6388 set<const SMESH_subMesh*>& theCommon )
6392 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6393 for ( ; it != theSubMeshList.end(); it++ )
6394 theSubMesh->FindIntersection( *it, theCommon );
6395 theSubMeshList.push_back( theSubMesh );
6396 //theCommon.insert( theSubMesh );
6399 //-----------------------------------------------------------------------------
6400 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6402 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6403 for ( ; listsIt != smLists.end(); ++listsIt )
6405 const TListOfInt& smIDs = *listsIt;
6406 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6414 //=============================================================================
6416 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6418 //=============================================================================
6420 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6422 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6423 if ( isSubMeshInList( submeshID, anOrder ))
6426 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6427 return isSubMeshInList( submeshID, allConurrent );
6430 //=============================================================================
6432 * \brief Return submesh objects list in meshing order
6434 //=============================================================================
6436 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6438 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6440 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6442 return aResult._retn();
6444 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6445 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6446 anOrder.splice( anOrder.end(), allConurrent );
6449 TListOfListOfInt::iterator listIt = anOrder.begin();
6450 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6451 unionLists( *listIt, anOrder, listIndx + 1 );
6453 // convert submesh ids into interface instances
6454 // and dump command into python
6455 convertMeshOrder( anOrder, aResult, false );
6457 return aResult._retn();
6460 //=============================================================================
6462 * \brief Finds concurrent sub-meshes
6464 //=============================================================================
6466 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6468 TListOfListOfInt anOrder;
6469 ::SMESH_Mesh& mesh = GetImpl();
6471 // collect submeshes and detect concurrent algorithms and hypothesises
6472 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6474 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6475 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6476 ::SMESH_subMesh* sm = (*i_sm).second;
6478 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6480 // list of assigned hypothesises
6481 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6482 // Find out dimensions where the submesh can be concurrent.
6483 // We define the dimensions by algo of each of hypotheses in hypList
6484 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6485 for( ; hypIt != hypList.end(); hypIt++ ) {
6486 SMESH_Algo* anAlgo = 0;
6487 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6488 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6489 // hyp it-self is algo
6490 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6492 // try to find algorithm with help of sub-shapes
6493 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6494 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6495 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6498 continue; // no algorithm assigned to a current submesh
6500 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6501 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6503 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6504 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6505 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6507 } // end iterations on submesh
6509 // iterate on created dimension-hypotheses and check for concurrents
6510 for ( int i = 0; i < 4; i++ ) {
6511 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6512 // check for concurrents in own and other dimensions (step-by-step)
6513 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6514 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6515 const SMESH_DimHyp* dimHyp = *dhIt;
6516 TDimHypList listOfConcurr;
6517 set<int> setOfConcurrIds;
6518 // looking for concurrents and collect into own list
6519 for ( int j = i; j < 4; j++ )
6520 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6521 // check if any concurrents found
6522 if ( listOfConcurr.size() > 0 ) {
6523 // add own submesh to list of concurrent
6524 addInOrderOfPriority( dimHyp, listOfConcurr );
6525 list<int> listOfConcurrIds;
6526 TDimHypList::iterator hypIt = listOfConcurr.begin();
6527 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6528 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6529 anOrder.push_back( listOfConcurrIds );
6534 removeDimHyps(dimHypListArr);
6536 // now, minimize the number of concurrent groups
6537 // Here we assume that lists of submeshes can have same submesh
6538 // in case of multi-dimension algorithms, as result
6539 // list with common submesh has to be united into one list
6541 TListOfListOfInt::iterator listIt = anOrder.begin();
6542 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6543 unionLists( *listIt, anOrder, listIndx + 1 );
6549 //=============================================================================
6551 * \brief Set submesh object order
6552 * \param theSubMeshArray submesh array order
6554 //=============================================================================
6556 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6559 _preMeshInfo->ForgetOrLoad();
6562 ::SMESH_Mesh& mesh = GetImpl();
6564 TPythonDump aPythonDump; // prevent dump of called methods
6565 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6567 TListOfListOfInt subMeshOrder;
6568 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6570 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6571 TListOfInt subMeshIds;
6573 aPythonDump << ", ";
6574 aPythonDump << "[ ";
6575 // Collect subMeshes which should be clear
6576 // do it list-by-list, because modification of submesh order
6577 // take effect between concurrent submeshes only
6578 set<const SMESH_subMesh*> subMeshToClear;
6579 list<const SMESH_subMesh*> subMeshList;
6580 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6582 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6584 aPythonDump << ", ";
6585 aPythonDump << subMesh;
6586 subMeshIds.push_back( subMesh->GetId() );
6587 // detect common parts of submeshes
6588 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6589 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6591 aPythonDump << " ]";
6592 subMeshOrder.push_back( subMeshIds );
6594 // clear collected sub-meshes
6595 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6596 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6597 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6599 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6600 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6601 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6604 aPythonDump << " ])";
6606 mesh.SetMeshOrder( subMeshOrder );
6609 SMESH::SMESH_Mesh_var me = _this();
6610 _gen_i->UpdateIcons( me );
6615 //=============================================================================
6617 * \brief Convert submesh ids into submesh interfaces
6619 //=============================================================================
6621 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6622 SMESH::submesh_array_array& theResOrder,
6623 const bool theIsDump)
6625 int nbSet = theIdsOrder.size();
6626 TPythonDump aPythonDump; // prevent dump of called methods
6628 aPythonDump << "[ ";
6629 theResOrder.length(nbSet);
6630 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6632 for( ; it != theIdsOrder.end(); it++ ) {
6633 // translate submesh identificators into submesh objects
6634 // takeing into account real number of concurrent lists
6635 const TListOfInt& aSubOrder = (*it);
6636 if (!aSubOrder.size())
6639 aPythonDump << "[ ";
6640 // convert shape indices into interfaces
6641 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6642 aResSubSet->length(aSubOrder.size());
6643 TListOfInt::const_iterator subIt = aSubOrder.begin();
6645 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6646 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6648 SMESH::SMESH_subMesh_var subMesh =
6649 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6652 aPythonDump << ", ";
6653 aPythonDump << subMesh;
6655 aResSubSet[ j++ ] = subMesh;
6658 aPythonDump << " ]";
6660 theResOrder[ listIndx++ ] = aResSubSet;
6662 // correct number of lists
6663 theResOrder.length( listIndx );
6666 // finilise python dump
6667 aPythonDump << " ]";
6668 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6672 namespace // utils used by SMESH_MeshPartDS
6675 * \brief Class used to access to protected data of SMDS_MeshInfo
6677 struct TMeshInfo : public SMDS_MeshInfo
6679 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6682 * \brief Element holing its ID only
6684 struct TElemID : public SMDS_LinearEdge
6686 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6690 //================================================================================
6692 // Implementation of SMESH_MeshPartDS
6694 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6695 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6697 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6698 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6701 _meshDS = mesh_i->GetImpl().GetMeshDS();
6703 SetPersistentId( _meshDS->GetPersistentId() );
6705 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6707 // <meshPart> is the whole mesh
6708 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6710 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6711 myGroupSet = _meshDS->GetGroups();
6716 SMESH::long_array_var anIDs = meshPart->GetIDs();
6717 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6718 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6720 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6721 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6722 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6727 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6728 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6729 if ( _elements[ e->GetType() ].insert( e ).second )
6732 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6733 while ( nIt->more() )
6735 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6736 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6743 ShapeToMesh( _meshDS->ShapeToMesh() );
6745 _meshDS = 0; // to enforce iteration on _elements and _nodes
6748 // -------------------------------------------------------------------------------------
6749 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6750 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6753 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6754 for ( ; partIt != meshPart.end(); ++partIt )
6755 if ( const SMDS_MeshElement * e = *partIt )
6756 if ( _elements[ e->GetType() ].insert( e ).second )
6759 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6760 while ( nIt->more() )
6762 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6763 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6769 // -------------------------------------------------------------------------------------
6770 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6772 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6774 TElemID elem( IDelem );
6775 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6776 if ( !_elements[ iType ].empty() )
6778 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6779 if ( it != _elements[ iType ].end() )
6784 // -------------------------------------------------------------------------------------
6785 bool SMESH_MeshPartDS::HasNumerationHoles()
6787 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6789 return ( MinNodeID() != 1 ||
6790 MaxNodeID() != NbNodes() ||
6791 MinElementID() != 1 ||
6792 MaxElementID() != NbElements() );
6794 // -------------------------------------------------------------------------------------
6795 int SMESH_MeshPartDS::MaxNodeID() const
6797 if ( _meshDS ) return _meshDS->MaxNodeID();
6798 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6800 // -------------------------------------------------------------------------------------
6801 int SMESH_MeshPartDS::MinNodeID() const
6803 if ( _meshDS ) return _meshDS->MinNodeID();
6804 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6806 // -------------------------------------------------------------------------------------
6807 int SMESH_MeshPartDS::MaxElementID() const
6809 if ( _meshDS ) return _meshDS->MaxElementID();
6811 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6812 if ( !_elements[ iType ].empty() )
6813 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6816 // -------------------------------------------------------------------------------------
6817 int SMESH_MeshPartDS::MinElementID() const
6819 if ( _meshDS ) return _meshDS->MinElementID();
6821 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6822 if ( !_elements[ iType ].empty() )
6823 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6826 // -------------------------------------------------------------------------------------
6827 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6829 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6831 typedef SMDS_SetIterator
6832 <const SMDS_MeshElement*,
6833 TIDSortedElemSet::const_iterator,
6834 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6835 SMDS_MeshElement::GeomFilter
6838 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6840 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6841 _elements[type].end(),
6842 SMDS_MeshElement::GeomFilter( geomType )));
6844 // -------------------------------------------------------------------------------------
6845 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6847 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6849 typedef SMDS_SetIterator
6850 <const SMDS_MeshElement*,
6851 TIDSortedElemSet::const_iterator,
6852 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6853 SMDS_MeshElement::EntityFilter
6856 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6858 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6859 _elements[type].end(),
6860 SMDS_MeshElement::EntityFilter( entity )));
6862 // -------------------------------------------------------------------------------------
6863 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6865 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6866 if ( type == SMDSAbs_All && !_meshDS )
6868 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6870 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6871 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6873 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6875 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6876 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6878 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6879 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6881 // -------------------------------------------------------------------------------------
6882 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6883 iterType SMESH_MeshPartDS::methName() const \
6885 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6886 return _meshDS ? _meshDS->methName() : iterType \
6887 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6889 // -------------------------------------------------------------------------------------
6890 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6891 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6892 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6893 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6894 #undef _GET_ITER_DEFINE
6896 // END Implementation of SMESH_MeshPartDS
6898 //================================================================================