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( " << theNewGeom->GetStudyEntry() << " )";
290 //================================================================================
292 * \brief Return false if the mesh is not yet fully loaded from the study file
294 //================================================================================
296 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
298 Unexpect aCatch(SALOME_SalomeException);
299 return !_preMeshInfo;
302 //================================================================================
304 * \brief Load full mesh data from the study file
306 //================================================================================
308 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
310 Unexpect aCatch(SALOME_SalomeException);
312 _preMeshInfo->FullLoadFromFile();
315 //================================================================================
317 * \brief Remove all nodes and elements
319 //================================================================================
321 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
323 Unexpect aCatch(SALOME_SalomeException);
325 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
329 //CheckGeomGroupModif(); // issue 20145
331 catch(SALOME_Exception & S_ex) {
332 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
335 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
337 SMESH::SMESH_Mesh_var mesh = _this();
338 _gen_i->UpdateIcons( mesh );
341 //================================================================================
343 * \brief Remove all nodes and elements for indicated shape
345 //================================================================================
347 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
348 throw (SALOME::SALOME_Exception)
350 Unexpect aCatch(SALOME_SalomeException);
352 _preMeshInfo->FullLoadFromFile();
355 _impl->ClearSubMesh( ShapeID );
357 catch(SALOME_Exception & S_ex) {
358 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
360 _impl->GetMeshDS()->Modified();
362 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
365 //=============================================================================
367 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
369 //=============================================================================
371 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
373 SMESH::DriverMED_ReadStatus res;
376 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
377 res = SMESH::DRS_OK; break;
378 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
379 res = SMESH::DRS_EMPTY; break;
380 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
381 res = SMESH::DRS_WARN_RENUMBER; break;
382 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
383 res = SMESH::DRS_WARN_SKIP_ELEM; break;
384 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
385 res = SMESH::DRS_WARN_DESCENDING; break;
386 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
388 res = SMESH::DRS_FAIL; break;
393 //=============================================================================
395 * Convert ::SMESH_ComputeError to SMESH::ComputeError
397 //=============================================================================
399 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
401 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
402 errVar->subShapeID = -1;
403 errVar->hasBadMesh = false;
405 if ( !errorPtr || errorPtr->IsOK() )
407 errVar->code = SMESH::COMPERR_OK;
411 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
412 errVar->comment = errorPtr->myComment.c_str();
414 return errVar._retn();
417 //=============================================================================
421 * Imports mesh data from MED file
423 //=============================================================================
425 SMESH::DriverMED_ReadStatus
426 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
427 throw ( SALOME::SALOME_Exception )
429 Unexpect aCatch(SALOME_SalomeException);
432 status = _impl->MEDToMesh( theFileName, theMeshName );
434 catch( SALOME_Exception& S_ex ) {
435 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
438 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
441 CreateGroupServants();
443 int major, minor, release;
444 major = minor = release = 0;
445 MED::GetMEDVersion(theFileName, major, minor, release);
446 _medFileInfo = new SMESH::MedFileInfo();
447 _medFileInfo->fileName = theFileName;
448 _medFileInfo->fileSize = 0;
449 _medFileInfo->major = major;
450 _medFileInfo->minor = minor;
451 _medFileInfo->release = release;
452 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
454 return ConvertDriverMEDReadStatus(status);
457 //================================================================================
459 * \brief Imports mesh data from the CGNS file
461 //================================================================================
463 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
464 const int theMeshIndex,
465 std::string& theMeshName )
466 throw ( SALOME::SALOME_Exception )
468 Unexpect aCatch(SALOME_SalomeException);
471 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
473 catch( SALOME_Exception& S_ex ) {
474 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
477 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
480 CreateGroupServants();
482 _medFileInfo = new SMESH::MedFileInfo();
483 _medFileInfo->fileName = theFileName;
484 _medFileInfo->major = 0;
485 _medFileInfo->minor = 0;
486 _medFileInfo->release = 0;
487 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
489 return ConvertDriverMEDReadStatus(status);
492 //================================================================================
494 * \brief Return string representation of a MED file version comprising nbDigits
496 //================================================================================
498 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
500 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
502 return CORBA::string_dup( ver.c_str() );
505 //================================================================================
507 * Return the list of med versions compatibles for write/append,
508 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
510 //================================================================================
511 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
513 SMESH::long_array_var aResult = new SMESH::long_array();
514 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
515 long nbver = mvok.size();
516 aResult->length( nbver );
517 for ( int i = 0; i < nbver; i++ )
518 aResult[i] = mvok[i];
519 return aResult._retn();
522 //=============================================================================
526 * Imports mesh data from MED file
528 //=============================================================================
530 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
531 throw ( SALOME::SALOME_Exception )
535 // Read mesh with name = <theMeshName> into SMESH_Mesh
536 _impl->UNVToMesh( theFileName );
538 CreateGroupServants();
540 _medFileInfo = new SMESH::MedFileInfo();
541 _medFileInfo->fileName = theFileName;
542 _medFileInfo->major = 0;
543 _medFileInfo->minor = 0;
544 _medFileInfo->release = 0;
545 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
547 SMESH_CATCH( SMESH::throwCorbaException );
552 //=============================================================================
556 * Imports mesh data from STL file
558 //=============================================================================
559 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
560 throw ( SALOME::SALOME_Exception )
564 // Read mesh with name = <theMeshName> into SMESH_Mesh
565 std::string name = _impl->STLToMesh( theFileName );
568 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
569 _gen_i->SetName( meshSO, name.c_str() );
571 _medFileInfo = new SMESH::MedFileInfo();
572 _medFileInfo->fileName = theFileName;
573 _medFileInfo->major = 0;
574 _medFileInfo->minor = 0;
575 _medFileInfo->release = 0;
576 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
578 SMESH_CATCH( SMESH::throwCorbaException );
583 //================================================================================
585 * \brief Function used in SMESH_CATCH by ImportGMFFile()
587 //================================================================================
591 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
593 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
597 //================================================================================
599 * \brief Imports data from a GMF file and returns an error description
601 //================================================================================
603 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
604 bool theMakeRequiredGroups )
605 throw (SALOME::SALOME_Exception)
607 SMESH_ComputeErrorPtr error;
610 #define SMESH_CAUGHT error =
613 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
615 _medFileInfo = new SMESH::MedFileInfo();
616 _medFileInfo->fileName = theFileName;
617 _medFileInfo->major = 0;
618 _medFileInfo->minor = 0;
619 _medFileInfo->release = 0;
620 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
622 SMESH_CATCH( exceptionToComputeError );
626 CreateGroupServants();
628 return ConvertComputeError( error );
631 //=============================================================================
635 //=============================================================================
637 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
639 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
640 (SMESH_Hypothesis::Hypothesis_Status theStatus)
643 RETURNCASE( HYP_OK );
644 RETURNCASE( HYP_MISSING );
645 RETURNCASE( HYP_CONCURRENT );
646 RETURNCASE( HYP_BAD_PARAMETER );
647 RETURNCASE( HYP_HIDDEN_ALGO );
648 RETURNCASE( HYP_HIDING_ALGO );
649 RETURNCASE( HYP_UNKNOWN_FATAL );
650 RETURNCASE( HYP_INCOMPATIBLE );
651 RETURNCASE( HYP_NOTCONFORM );
652 RETURNCASE( HYP_ALREADY_EXIST );
653 RETURNCASE( HYP_BAD_DIM );
654 RETURNCASE( HYP_BAD_SUBSHAPE );
655 RETURNCASE( HYP_BAD_GEOMETRY );
656 RETURNCASE( HYP_NEED_SHAPE );
657 RETURNCASE( HYP_INCOMPAT_HYPS );
660 return SMESH::HYP_UNKNOWN_FATAL;
663 //=============================================================================
667 * calls internal addHypothesis() and then adds a reference to <anHyp> under
668 * the SObject actually having a reference to <aSubShape>.
669 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
671 //=============================================================================
673 SMESH::Hypothesis_Status
674 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
675 SMESH::SMESH_Hypothesis_ptr anHyp,
676 CORBA::String_out anErrorText)
677 throw(SALOME::SALOME_Exception)
679 Unexpect aCatch(SALOME_SalomeException);
681 _preMeshInfo->ForgetOrLoad();
684 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
685 anErrorText = error.c_str();
687 SMESH::SMESH_Mesh_var mesh( _this() );
688 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
690 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
691 _gen_i->UpdateIcons( mesh );
693 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
695 // Update Python script
696 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
697 << aSubShape << ", " << anHyp << " )";
699 return ConvertHypothesisStatus(status);
702 //=============================================================================
706 //=============================================================================
708 SMESH_Hypothesis::Hypothesis_Status
709 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
710 SMESH::SMESH_Hypothesis_ptr anHyp,
711 std::string* anErrorText)
713 if(MYDEBUG) MESSAGE("addHypothesis");
715 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
716 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
718 if (CORBA::is_nil( anHyp ))
719 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
721 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
724 TopoDS_Shape myLocSubShape;
725 //use PseudoShape in case if mesh has no shape
727 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
729 myLocSubShape = _impl->GetShapeToMesh();
731 const int hypId = anHyp->GetId();
733 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
734 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
736 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
738 // assure there is a corresponding submesh
739 if ( !_impl->IsMainShape( myLocSubShape )) {
740 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
741 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
742 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
745 else if ( anErrorText )
747 *anErrorText = error;
750 catch(SALOME_Exception & S_ex)
752 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
757 //=============================================================================
761 //=============================================================================
763 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
764 SMESH::SMESH_Hypothesis_ptr anHyp)
765 throw(SALOME::SALOME_Exception)
767 Unexpect aCatch(SALOME_SalomeException);
769 _preMeshInfo->ForgetOrLoad();
771 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
772 SMESH::SMESH_Mesh_var mesh = _this();
774 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
776 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
777 _gen_i->UpdateIcons( mesh );
779 // Update Python script
780 if(_impl->HasShapeToMesh())
781 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
782 << aSubShape << ", " << anHyp << " )";
784 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
787 return ConvertHypothesisStatus(status);
790 //=============================================================================
794 //=============================================================================
796 SMESH_Hypothesis::Hypothesis_Status
797 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
798 SMESH::SMESH_Hypothesis_ptr anHyp)
800 if(MYDEBUG) MESSAGE("removeHypothesis()");
802 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
803 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
805 if (CORBA::is_nil( anHyp ))
806 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
809 _preMeshInfo->ForgetOrLoad();
811 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
814 TopoDS_Shape myLocSubShape;
815 //use PseudoShape in case if mesh has no shape
816 if( _impl->HasShapeToMesh() )
817 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
819 myLocSubShape = _impl->GetShapeToMesh();
821 const int hypId = anHyp->GetId();
822 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
823 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
825 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
829 catch(SALOME_Exception & S_ex)
831 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
836 //=============================================================================
840 //=============================================================================
842 SMESH::ListOfHypothesis *
843 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
844 throw(SALOME::SALOME_Exception)
846 Unexpect aCatch(SALOME_SalomeException);
847 if (MYDEBUG) MESSAGE("GetHypothesisList");
848 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
849 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
851 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
854 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
855 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
856 myLocSubShape = _impl->GetShapeToMesh();
857 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
858 int i = 0, n = aLocalList.size();
861 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
862 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
863 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
865 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
866 if ( id_hypptr != _mapHypo.end() )
867 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
871 catch(SALOME_Exception & S_ex) {
872 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
875 return aList._retn();
878 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
880 Unexpect aCatch(SALOME_SalomeException);
881 if (MYDEBUG) MESSAGE("GetSubMeshes");
883 SMESH::submesh_array_var aList = new SMESH::submesh_array();
886 TPythonDump aPythonDump;
887 if ( !_mapSubMeshIor.empty() )
891 aList->length( _mapSubMeshIor.size() );
893 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
894 for ( ; it != _mapSubMeshIor.end(); it++ ) {
895 if ( CORBA::is_nil( it->second )) continue;
896 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
898 if (i > 1) aPythonDump << ", ";
899 aPythonDump << it->second;
903 catch(SALOME_Exception & S_ex) {
904 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
907 // Update Python script
908 if ( !_mapSubMeshIor.empty() )
909 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
911 return aList._retn();
914 //=============================================================================
918 //=============================================================================
920 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
921 const char* theName )
922 throw(SALOME::SALOME_Exception)
924 Unexpect aCatch(SALOME_SalomeException);
925 if (CORBA::is_nil(aSubShape))
926 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
928 SMESH::SMESH_subMesh_var subMesh;
929 SMESH::SMESH_Mesh_var aMesh = _this();
931 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
933 //Get or Create the SMESH_subMesh object implementation
935 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
937 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
939 TopoDS_Iterator it( myLocSubShape );
941 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
943 subMesh = getSubMesh( subMeshId );
945 // create a new subMesh object servant if there is none for the shape
946 if ( subMesh->_is_nil() )
947 subMesh = createSubMesh( aSubShape );
948 if ( _gen_i->CanPublishInStudy( subMesh ))
950 SALOMEDS::SObject_wrap aSO =
951 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
952 if ( !aSO->_is_nil()) {
953 // Update Python script
954 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
955 << aSubShape << ", '" << theName << "' )";
959 catch(SALOME_Exception & S_ex) {
960 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
962 return subMesh._retn();
965 //=============================================================================
969 //=============================================================================
971 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
972 throw (SALOME::SALOME_Exception)
976 if ( theSubMesh->_is_nil() )
979 GEOM::GEOM_Object_var aSubShape;
980 // Remove submesh's SObject
981 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
982 if ( !anSO->_is_nil() ) {
983 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
984 SALOMEDS::SObject_wrap anObj, aRef;
985 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
986 anObj->ReferencedObject( aRef.inout() ))
988 CORBA::Object_var obj = aRef->GetObject();
989 aSubShape = GEOM::GEOM_Object::_narrow( obj );
991 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
992 // aSubShape = theSubMesh->GetSubShape();
994 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
995 builder->RemoveObjectWithChildren( anSO );
997 // Update Python script
998 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
1001 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
1003 _preMeshInfo->ForgetOrLoad();
1005 SMESH_CATCH( SMESH::throwCorbaException );
1008 //=============================================================================
1012 //=============================================================================
1014 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1015 const char* theName )
1016 throw(SALOME::SALOME_Exception)
1018 Unexpect aCatch(SALOME_SalomeException);
1020 _preMeshInfo->FullLoadFromFile();
1022 SMESH::SMESH_Group_var aNewGroup =
1023 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1025 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1027 SMESH::SMESH_Mesh_var mesh = _this();
1028 SALOMEDS::SObject_wrap aSO =
1029 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1030 if ( !aSO->_is_nil())
1031 // Update Python script
1032 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1033 << theElemType << ", '" << theName << "' )";
1035 return aNewGroup._retn();
1038 //=============================================================================
1042 //=============================================================================
1043 SMESH::SMESH_GroupOnGeom_ptr
1044 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1045 const char* theName,
1046 GEOM::GEOM_Object_ptr theGeomObj)
1047 throw(SALOME::SALOME_Exception)
1049 Unexpect aCatch(SALOME_SalomeException);
1051 _preMeshInfo->FullLoadFromFile();
1053 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1055 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1056 if ( !aShape.IsNull() )
1059 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1061 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1063 SMESH::SMESH_Mesh_var mesh = _this();
1064 SALOMEDS::SObject_wrap aSO =
1065 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1066 if ( !aSO->_is_nil())
1067 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1068 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1072 return aNewGroup._retn();
1075 //================================================================================
1077 * \brief Creates a group whose contents is defined by filter
1078 * \param theElemType - group type
1079 * \param theName - group name
1080 * \param theFilter - the filter
1081 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1083 //================================================================================
1085 SMESH::SMESH_GroupOnFilter_ptr
1086 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1087 const char* theName,
1088 SMESH::Filter_ptr theFilter )
1089 throw (SALOME::SALOME_Exception)
1091 Unexpect aCatch(SALOME_SalomeException);
1093 _preMeshInfo->FullLoadFromFile();
1095 if ( CORBA::is_nil( theFilter ))
1096 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1098 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1100 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1102 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1103 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1106 if ( !aNewGroup->_is_nil() )
1107 aNewGroup->SetFilter( theFilter );
1109 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1111 SMESH::SMESH_Mesh_var mesh = _this();
1112 SALOMEDS::SObject_wrap aSO =
1113 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1115 if ( !aSO->_is_nil())
1116 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1117 << theElemType << ", '" << theName << "', " << theFilter << " )";
1119 return aNewGroup._retn();
1122 //=============================================================================
1126 //=============================================================================
1128 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1129 throw (SALOME::SALOME_Exception)
1131 if ( theGroup->_is_nil() )
1136 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1140 if ( aGroup->GetMeshServant() != this )
1141 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1142 SALOME::BAD_PARAM );
1144 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1145 if ( !aGroupSO->_is_nil() )
1147 // Update Python script
1148 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1150 // Remove group's SObject
1151 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1152 builder->RemoveObjectWithChildren( aGroupSO );
1154 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1156 // Remove the group from SMESH data structures
1157 removeGroup( aGroup->GetLocalID() );
1159 SMESH_CATCH( SMESH::throwCorbaException );
1162 //=============================================================================
1164 * Remove group with its contents
1166 //=============================================================================
1168 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1169 throw (SALOME::SALOME_Exception)
1173 _preMeshInfo->FullLoadFromFile();
1175 if ( theGroup->_is_nil() )
1178 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1179 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1180 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1183 vector<int> nodeIds; // to remove nodes becoming free
1184 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1185 if ( !isNodal && !theGroup->IsEmpty() )
1187 CORBA::Long elemID = theGroup->GetID( 1 );
1188 int nbElemNodes = GetElemNbNodes( elemID );
1189 if ( nbElemNodes > 0 )
1190 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1193 // Retrieve contents
1194 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1195 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1196 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1197 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1198 elems.assign( elemBeg, elemEnd );
1200 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1203 RemoveGroup( theGroup );
1206 for ( size_t i = 0; i < elems.size(); ++i )
1208 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1212 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1213 nodeIds.push_back( nIt->next()->GetID() );
1215 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1219 _impl->GetMeshDS()->RemoveElement( elems[i] );
1223 // Remove free nodes
1224 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1225 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1226 if ( n->NbInverseElements() == 0 )
1227 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1229 // Update Python script (theGroup must be alive for this)
1230 pyDump << SMESH::SMESH_Mesh_var(_this())
1231 << ".RemoveGroupWithContents( " << theGroup << " )";
1233 SMESH_CATCH( SMESH::throwCorbaException );
1236 //================================================================================
1238 * \brief Get the list of groups existing in the mesh
1239 * \retval SMESH::ListOfGroups * - list of groups
1241 //================================================================================
1243 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1245 Unexpect aCatch(SALOME_SalomeException);
1246 if (MYDEBUG) MESSAGE("GetGroups");
1248 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1251 TPythonDump aPythonDump;
1252 if ( !_mapGroups.empty() )
1254 aPythonDump << "[ ";
1256 aList->length( _mapGroups.size() );
1258 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1259 for ( ; it != _mapGroups.end(); it++ ) {
1260 if ( CORBA::is_nil( it->second )) continue;
1261 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1263 if (i > 1) aPythonDump << ", ";
1264 aPythonDump << it->second;
1268 catch(SALOME_Exception & S_ex) {
1269 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1271 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1273 return aList._retn();
1276 //=============================================================================
1278 * Get number of groups existing in the mesh
1280 //=============================================================================
1282 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1284 Unexpect aCatch(SALOME_SalomeException);
1285 return _mapGroups.size();
1288 //=============================================================================
1290 * New group including all mesh elements present in initial groups is created.
1292 //=============================================================================
1294 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1295 SMESH::SMESH_GroupBase_ptr theGroup2,
1296 const char* theName )
1297 throw (SALOME::SALOME_Exception)
1299 SMESH::SMESH_Group_var aResGrp;
1303 _preMeshInfo->FullLoadFromFile();
1305 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1306 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1308 if ( theGroup1->GetType() != theGroup2->GetType() )
1309 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1314 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1315 if ( aResGrp->_is_nil() )
1316 return SMESH::SMESH_Group::_nil();
1318 aResGrp->AddFrom( theGroup1 );
1319 aResGrp->AddFrom( theGroup2 );
1321 // Update Python script
1322 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1323 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1325 SMESH_CATCH( SMESH::throwCorbaException );
1327 return aResGrp._retn();
1330 //=============================================================================
1332 * \brief New group including all mesh elements present in initial groups is created.
1333 * \param theGroups list of groups
1334 * \param theName name of group to be created
1335 * \return pointer to the new group
1337 //=============================================================================
1339 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1340 const char* theName )
1341 throw (SALOME::SALOME_Exception)
1343 SMESH::SMESH_Group_var aResGrp;
1346 _preMeshInfo->FullLoadFromFile();
1349 return SMESH::SMESH_Group::_nil();
1354 SMESH::ElementType aType = SMESH::ALL;
1355 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1357 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1358 if ( CORBA::is_nil( aGrp ) )
1360 if ( aType == SMESH::ALL )
1361 aType = aGrp->GetType();
1362 else if ( aType != aGrp->GetType() )
1363 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1366 if ( aType == SMESH::ALL )
1367 return SMESH::SMESH_Group::_nil();
1372 aResGrp = CreateGroup( aType, theName );
1373 if ( aResGrp->_is_nil() )
1374 return SMESH::SMESH_Group::_nil();
1376 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1377 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1379 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1380 if ( !CORBA::is_nil( aGrp ) )
1382 aResGrp->AddFrom( aGrp );
1383 if ( g > 0 ) pyDump << ", ";
1387 pyDump << " ], '" << theName << "' )";
1389 SMESH_CATCH( SMESH::throwCorbaException );
1391 return aResGrp._retn();
1394 //=============================================================================
1396 * New group is created. All mesh elements that are
1397 * present in both initial groups are added to the new one.
1399 //=============================================================================
1401 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1402 SMESH::SMESH_GroupBase_ptr theGroup2,
1403 const char* theName )
1404 throw (SALOME::SALOME_Exception)
1406 SMESH::SMESH_Group_var aResGrp;
1411 _preMeshInfo->FullLoadFromFile();
1413 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1414 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1416 if ( theGroup1->GetType() != theGroup2->GetType() )
1417 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1421 // Create Intersection
1422 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1423 if ( aResGrp->_is_nil() )
1424 return aResGrp._retn();
1426 SMESHDS_GroupBase* groupDS1 = 0;
1427 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1428 groupDS1 = grp_i->GetGroupDS();
1430 SMESHDS_GroupBase* groupDS2 = 0;
1431 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1432 groupDS2 = grp_i->GetGroupDS();
1434 SMESHDS_Group* resGroupDS = 0;
1435 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1436 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1438 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1440 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1441 while ( elemIt1->more() )
1443 const SMDS_MeshElement* e = elemIt1->next();
1444 if ( groupDS2->Contains( e ))
1445 resGroupDS->SMDSGroup().Add( e );
1448 // Update Python script
1449 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1450 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1452 SMESH_CATCH( SMESH::throwCorbaException );
1454 return aResGrp._retn();
1457 //=============================================================================
1459 \brief Intersect list of groups. New group is created. All mesh elements that
1460 are present in all initial groups simultaneously are added to the new one.
1461 \param theGroups list of groups
1462 \param theName name of group to be created
1463 \return pointer on the group
1465 //=============================================================================
1466 SMESH::SMESH_Group_ptr
1467 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1468 const char* theName )
1469 throw (SALOME::SALOME_Exception)
1471 SMESH::SMESH_Group_var aResGrp;
1476 _preMeshInfo->FullLoadFromFile();
1479 return SMESH::SMESH_Group::_nil();
1481 // check types and get SMESHDS_GroupBase's
1482 SMESH::ElementType aType = SMESH::ALL;
1483 vector< SMESHDS_GroupBase* > groupVec;
1484 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1486 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1487 if ( CORBA::is_nil( aGrp ) )
1489 if ( aType == SMESH::ALL )
1490 aType = aGrp->GetType();
1491 else if ( aType != aGrp->GetType() )
1492 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1495 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1496 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1498 if ( grpDS->IsEmpty() )
1503 groupVec.push_back( grpDS );
1506 if ( aType == SMESH::ALL ) // all groups are nil
1507 return SMESH::SMESH_Group::_nil();
1512 aResGrp = CreateGroup( aType, theName );
1514 SMESHDS_Group* resGroupDS = 0;
1515 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1516 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1517 if ( !resGroupDS || groupVec.empty() )
1518 return aResGrp._retn();
1521 size_t i, nb = groupVec.size();
1522 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1523 while ( elemIt1->more() )
1525 const SMDS_MeshElement* e = elemIt1->next();
1527 for ( i = 1; ( i < nb && inAll ); ++i )
1528 inAll = groupVec[i]->Contains( e );
1531 resGroupDS->SMDSGroup().Add( e );
1534 // Update Python script
1535 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1536 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1538 SMESH_CATCH( SMESH::throwCorbaException );
1540 return aResGrp._retn();
1543 //=============================================================================
1545 * New group is created. All mesh elements that are present in
1546 * a main group but is not present in a tool group are added to the new one
1548 //=============================================================================
1550 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1551 SMESH::SMESH_GroupBase_ptr theGroup2,
1552 const char* theName )
1553 throw (SALOME::SALOME_Exception)
1555 SMESH::SMESH_Group_var aResGrp;
1560 _preMeshInfo->FullLoadFromFile();
1562 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1563 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1565 if ( theGroup1->GetType() != theGroup2->GetType() )
1566 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1570 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1571 if ( aResGrp->_is_nil() )
1572 return aResGrp._retn();
1574 SMESHDS_GroupBase* groupDS1 = 0;
1575 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1576 groupDS1 = grp_i->GetGroupDS();
1578 SMESHDS_GroupBase* groupDS2 = 0;
1579 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1580 groupDS2 = grp_i->GetGroupDS();
1582 SMESHDS_Group* resGroupDS = 0;
1583 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1584 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1586 if ( groupDS1 && groupDS2 && resGroupDS )
1588 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1589 while ( elemIt1->more() )
1591 const SMDS_MeshElement* e = elemIt1->next();
1592 if ( !groupDS2->Contains( e ))
1593 resGroupDS->SMDSGroup().Add( e );
1596 // Update Python script
1597 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1598 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1600 SMESH_CATCH( SMESH::throwCorbaException );
1602 return aResGrp._retn();
1605 //=============================================================================
1607 \brief Cut lists of groups. New group is created. All mesh elements that are
1608 present in main groups but do not present in tool groups are added to the new one
1609 \param theMainGroups list of main groups
1610 \param theToolGroups list of tool groups
1611 \param theName name of group to be created
1612 \return pointer on the group
1614 //=============================================================================
1615 SMESH::SMESH_Group_ptr
1616 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1617 const SMESH::ListOfGroups& theToolGroups,
1618 const char* theName )
1619 throw (SALOME::SALOME_Exception)
1621 SMESH::SMESH_Group_var aResGrp;
1626 _preMeshInfo->FullLoadFromFile();
1629 return SMESH::SMESH_Group::_nil();
1631 // check types and get SMESHDS_GroupBase's
1632 SMESH::ElementType aType = SMESH::ALL;
1633 vector< SMESHDS_GroupBase* > toolGroupVec;
1634 vector< SMDS_ElemIteratorPtr > mainIterVec;
1636 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1638 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1639 if ( CORBA::is_nil( aGrp ) )
1641 if ( aType == SMESH::ALL )
1642 aType = aGrp->GetType();
1643 else if ( aType != aGrp->GetType() )
1644 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1646 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1647 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1648 if ( !grpDS->IsEmpty() )
1649 mainIterVec.push_back( grpDS->GetElements() );
1651 if ( aType == SMESH::ALL ) // all main groups are nil
1652 return SMESH::SMESH_Group::_nil();
1653 if ( mainIterVec.empty() ) // all main groups are empty
1654 return aResGrp._retn();
1656 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1658 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1659 if ( CORBA::is_nil( aGrp ) )
1661 if ( aType != aGrp->GetType() )
1662 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1664 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1665 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1666 toolGroupVec.push_back( grpDS );
1672 aResGrp = CreateGroup( aType, theName );
1674 SMESHDS_Group* resGroupDS = 0;
1675 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1676 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1678 return aResGrp._retn();
1681 size_t i, nb = toolGroupVec.size();
1682 SMDS_ElemIteratorPtr mainElemIt
1683 ( new SMDS_IteratorOnIterators
1684 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1685 while ( mainElemIt->more() )
1687 const SMDS_MeshElement* e = mainElemIt->next();
1689 for ( i = 0; ( i < nb && !isIn ); ++i )
1690 isIn = toolGroupVec[i]->Contains( e );
1693 resGroupDS->SMDSGroup().Add( e );
1696 // Update Python script
1697 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1698 << ".CutListOfGroups( " << theMainGroups << ", "
1699 << theToolGroups << ", '" << theName << "' )";
1701 SMESH_CATCH( SMESH::throwCorbaException );
1703 return aResGrp._retn();
1706 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1708 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1709 bool & toStopChecking )
1711 toStopChecking = ( nbCommon < nbChecked );
1712 return nbCommon == nbNodes;
1714 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1715 bool & toStopChecking )
1717 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1718 return nbCommon == nbCorners;
1720 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1721 bool & toStopChecking )
1723 return nbCommon > 0;
1725 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1726 bool & toStopChecking )
1728 return nbCommon >= (nbNodes+1) / 2;
1732 //=============================================================================
1734 * Create a group of entities basing on nodes of other groups.
1735 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1736 * \param [in] anElemType - a type of elements to include to the new group.
1737 * \param [in] theName - a name of the new group.
1738 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1739 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1740 * new group provided that it is based on nodes of an element of \a aListOfGroups
1741 * \return SMESH_Group - the created group
1743 // IMP 19939, bug 22010, IMP 22635
1744 //=============================================================================
1746 SMESH::SMESH_Group_ptr
1747 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1748 SMESH::ElementType theElemType,
1749 const char* theName,
1750 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1751 CORBA::Boolean theUnderlyingOnly)
1752 throw (SALOME::SALOME_Exception)
1754 SMESH::SMESH_Group_var aResGrp;
1758 _preMeshInfo->FullLoadFromFile();
1760 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1762 if ( !theName || !aMeshDS )
1763 return SMESH::SMESH_Group::_nil();
1765 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1767 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1768 SMESH_Comment nbCoNoStr( "SMESH.");
1769 switch ( theNbCommonNodes ) {
1770 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1771 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1772 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1773 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1774 default: return aResGrp._retn();
1776 int nbChecked, nbCommon, nbNodes, nbCorners;
1782 aResGrp = CreateGroup( theElemType, theName );
1783 if ( aResGrp->_is_nil() )
1784 return SMESH::SMESH_Group::_nil();
1786 SMESHDS_GroupBase* groupBaseDS =
1787 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1788 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1790 vector<bool> isNodeInGroups;
1792 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1794 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1795 if ( CORBA::is_nil( aGrp ) )
1797 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1798 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1801 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1802 if ( !elIt ) continue;
1804 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1806 while ( elIt->more() ) {
1807 const SMDS_MeshElement* el = elIt->next();
1808 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1809 while ( nIt->more() )
1810 resGroupCore.Add( nIt->next() );
1813 // get elements of theElemType based on nodes of every element of group
1814 else if ( theUnderlyingOnly )
1816 while ( elIt->more() )
1818 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1819 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1820 TIDSortedElemSet checkedElems;
1821 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1822 while ( nIt->more() )
1824 const SMDS_MeshNode* n = nIt->next();
1825 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1826 // check nodes of elements of theElemType around el
1827 while ( elOfTypeIt->more() )
1829 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1830 if ( !checkedElems.insert( elOfType ).second ) continue;
1831 nbNodes = elOfType->NbNodes();
1832 nbCorners = elOfType->NbCornerNodes();
1834 bool toStopChecking = false;
1835 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1836 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1837 if ( elNodes.count( nIt2->next() ) &&
1838 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1840 resGroupCore.Add( elOfType );
1847 // get all nodes of elements of groups
1850 while ( elIt->more() )
1852 const SMDS_MeshElement* el = elIt->next(); // an element of group
1853 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1854 while ( nIt->more() )
1856 const SMDS_MeshNode* n = nIt->next();
1857 if ( n->GetID() >= (int) isNodeInGroups.size() )
1858 isNodeInGroups.resize( n->GetID() + 1, false );
1859 isNodeInGroups[ n->GetID() ] = true;
1865 // Get elements of theElemType based on a certain number of nodes of elements of groups
1866 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1868 const SMDS_MeshNode* n;
1869 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1870 const int isNodeInGroupsSize = isNodeInGroups.size();
1871 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1873 if ( !isNodeInGroups[ iN ] ||
1874 !( n = aMeshDS->FindNode( iN )))
1877 // check nodes of elements of theElemType around n
1878 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1879 while ( elOfTypeIt->more() )
1881 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1882 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1887 nbNodes = elOfType->NbNodes();
1888 nbCorners = elOfType->NbCornerNodes();
1890 bool toStopChecking = false;
1891 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1892 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1894 const int nID = nIt->next()->GetID();
1895 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1896 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1898 resGroupCore.Add( elOfType );
1906 // Update Python script
1907 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1908 << ".CreateDimGroup( "
1909 << theGroups << ", " << theElemType << ", '" << theName << "', "
1910 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1912 SMESH_CATCH( SMESH::throwCorbaException );
1914 return aResGrp._retn();
1917 //================================================================================
1919 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1920 * existing 1D elements as group boundaries.
1921 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1922 * adjacent faces is more than \a sharpAngle in degrees.
1923 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1924 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1925 * \return ListOfGroups - the created groups
1927 //================================================================================
1929 SMESH::ListOfGroups*
1930 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1931 CORBA::Boolean theCreateEdges,
1932 CORBA::Boolean theUseExistingEdges )
1933 throw (SALOME::SALOME_Exception)
1935 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1936 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1939 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1945 _preMeshInfo->FullLoadFromFile();
1947 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1949 std::vector< SMESH_MeshAlgos::Edge > edges =
1950 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1952 if ( theCreateEdges )
1954 std::vector<const SMDS_MeshNode *> nodes(2);
1955 for ( size_t i = 0; i < edges.size(); ++i )
1957 nodes[0] = edges[i]._node1;
1958 nodes[1] = edges[i]._node2;
1959 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1961 if ( edges[i]._medium )
1962 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1964 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1968 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1969 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1971 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1973 resultGroups->length( faceGroups.size() );
1974 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1976 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1977 _editor->GenerateGroupName("Group").c_str());
1978 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1980 SMESHDS_GroupBase* groupBaseDS =
1981 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1982 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1984 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1985 for ( size_t i = 0; i < faces.size(); ++i )
1986 groupCore.Add( faces[i] );
1989 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1990 << ".FaceGroupsSeparatedByEdges( "
1991 << TVar( theSharpAngle ) << ", "
1992 << theCreateEdges << ", "
1993 << theUseExistingEdges << " )";
1995 SMESH_CATCH( SMESH::throwCorbaException );
1996 return resultGroups._retn();
2000 //================================================================================
2002 * \brief Remember GEOM group data
2004 //================================================================================
2006 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
2007 CORBA::Object_ptr theSmeshObj)
2009 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2012 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2013 if ( groupSO->_is_nil() )
2016 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2017 GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
2018 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2021 _geomGroupData.push_back( TGeomGroupData() );
2022 TGeomGroupData & groupData = _geomGroupData.back();
2024 CORBA::String_var entry = groupSO->GetID();
2025 groupData._groupEntry = entry.in();
2027 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2028 groupData._indices.insert( ids[i] );
2030 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2031 // shape index in SMESHDS
2032 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2033 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2036 //================================================================================
2038 * Remove GEOM group data relating to removed smesh object
2040 //================================================================================
2042 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2044 list<TGeomGroupData>::iterator
2045 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2046 for ( ; data != dataEnd; ++data ) {
2047 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2048 _geomGroupData.erase( data );
2054 //================================================================================
2056 * \brief Return new group contents if it has been changed and update group data
2058 //================================================================================
2059 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2061 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2063 TopoDS_Shape newShape;
2065 if ( how == IS_BREAK_LINK )
2067 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2068 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2069 if ( !meshSO->_is_nil() &&
2070 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2071 geomRefSO->ReferencedObject( geomSO.inout() ))
2073 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2074 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2075 newShape = _gen_i->GeomObjectToShape( geom );
2081 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2082 if ( !groupSO->_is_nil() )
2084 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2085 if ( CORBA::is_nil( groupObj )) return newShape;
2086 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2088 // get indices of group items
2089 set<int> curIndices;
2090 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2091 GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
2092 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2093 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2094 curIndices.insert( ids[i] );
2096 if ( how == ONLY_IF_CHANGED && groupData._indices == curIndices )
2097 return newShape; // group not changed
2100 groupData._indices = curIndices;
2102 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2103 if ( !geomClient ) return newShape;
2104 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2105 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2106 newShape = _gen_i->GeomObjectToShape( geomGroup );
2109 if ( newShape.IsNull() ) {
2110 // geom group becomes empty - return empty compound
2111 TopoDS_Compound compound;
2112 BRep_Builder().MakeCompound(compound);
2113 newShape = compound;
2120 //-----------------------------------------------------------------------------
2122 * \brief Storage of shape and index used in CheckGeomGroupModif()
2124 struct TIndexedShape
2127 TopoDS_Shape _shape;
2128 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2130 //-----------------------------------------------------------------------------
2132 * \brief Data to re-create a group on geometry
2134 struct TGroupOnGeomData
2137 TopoDS_Shape _shape;
2138 SMDSAbs_ElementType _type;
2140 Quantity_Color _color;
2142 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2144 _oldID = group->GetID();
2145 _type = group->GetType();
2146 _name = group->GetStoreName();
2147 _color = group->GetColor();
2151 //-----------------------------------------------------------------------------
2153 * \brief Check if a filter is still valid after geometry removal
2155 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2157 if ( theFilter->_is_nil() )
2159 SMESH::Filter::Criteria_var criteria;
2160 theFilter->GetCriteria( criteria.out() );
2162 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2164 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2166 switch ( criteria[ iCr ].Type )
2168 case SMESH::FT_BelongToGeom:
2169 case SMESH::FT_BelongToPlane:
2170 case SMESH::FT_BelongToCylinder:
2171 case SMESH::FT_BelongToGenSurface:
2172 case SMESH::FT_LyingOnGeom:
2173 entry = thresholdID;
2175 case SMESH::FT_ConnectedElements:
2178 entry = thresholdID;
2184 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2185 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2186 if ( so->_is_nil() )
2188 CORBA::Object_var obj = so->GetObject();
2189 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2190 if ( gen->GeomObjectToShape( geom ).IsNull() )
2193 } // loop on criteria
2199 //=============================================================================
2201 * \brief Update data if geometry changes
2205 //=============================================================================
2207 void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
2209 SMESH::SMESH_Mesh_var me = _this();
2210 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2212 TPythonDump dumpNothing; // prevent any dump
2214 //bool removedFromClient = false;
2216 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2218 //removedFromClient = _impl->HasShapeToMesh();
2220 // try to find geometry by study reference
2221 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2222 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2223 if ( !meshSO->_is_nil() &&
2224 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2225 geomRefSO->ReferencedObject( geomSO.inout() ))
2227 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2228 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2231 if ( mainGO->_is_nil() && // geometry removed ==>
2232 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2234 // convert geom dependent groups into standalone ones
2235 CheckGeomGroupModif();
2237 _impl->ShapeToMesh( TopoDS_Shape() );
2239 // remove sub-meshes
2240 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2241 while ( i_sm != _mapSubMeshIor.end() )
2243 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2245 RemoveSubMesh( sm );
2247 // remove all children except groups in the study
2248 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2249 SALOMEDS::SObject_wrap so;
2250 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2251 if ( meshSO->FindSubObject( tag, so.inout() ))
2252 builder->RemoveObjectWithChildren( so );
2254 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2260 if ( !_impl->HasShapeToMesh() ) return;
2263 // Update after group modification
2265 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2266 mainGO->GetTick() == _mainShapeTick )
2268 int nb = NbNodes() + NbElements();
2269 CheckGeomGroupModif();
2270 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2271 _gen_i->UpdateIcons( me );
2275 // Update after shape modification
2277 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2278 if ( !geomClient ) return;
2279 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2280 if ( geomGen->_is_nil() ) return;
2282 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2283 geomClient->RemoveShapeFromBuffer( ior.in() );
2285 // Update data taking into account that if topology doesn't change
2286 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2289 _preMeshInfo->ForgetAllData();
2292 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2293 if ( newShape.IsNull() )
2296 _mainShapeTick = mainGO->GetTick();
2298 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2300 // store data of groups on geometry
2301 std::vector< TGroupOnGeomData > groupsData;
2302 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2303 groupsData.reserve( groups.size() );
2304 TopTools_DataMapOfShapeShape old2newShapeMap;
2305 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2306 for ( ; g != groups.end(); ++g )
2308 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2310 groupsData.push_back( TGroupOnGeomData( group ));
2313 SMESH::SMESH_GroupOnGeom_var gog;
2314 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2315 if ( i_grp != _mapGroups.end() )
2316 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2318 GEOM::GEOM_Object_var geom;
2319 if ( !gog->_is_nil() )
2323 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2324 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2325 if ( !grpSO->_is_nil() &&
2326 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2327 geomRefSO->ReferencedObject( geomSO.inout() ))
2329 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2330 geom = GEOM::GEOM_Object::_narrow( geomObj );
2335 geom = gog->GetShape();
2338 if ( !geom->_is_nil() )
2340 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2341 geomClient->RemoveShapeFromBuffer( ior.in() );
2342 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2343 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2345 else if ( old2newShapeMap.IsBound( group->GetShape() ))
2347 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2351 // store assigned hypotheses
2352 std::vector< pair< int, THypList > > ids2Hyps;
2353 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2354 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2356 const TopoDS_Shape& s = s2hyps.Key();
2357 const THypList& hyps = s2hyps.ChangeValue();
2358 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2361 std::map< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2363 // count shapes excluding compounds corresponding to geom groups
2364 int oldNbSubShapes = meshDS->MaxShapeIndex();
2365 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2367 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2368 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2371 std::set<int> subIds;
2372 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2373 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2374 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2377 // check if shape topology changes - save shape type per shape ID
2378 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2379 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2380 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2382 // change shape to mesh
2383 _impl->ShapeToMesh( TopoDS_Shape() );
2384 _impl->ShapeToMesh( newShape );
2386 // check if shape topology changes - check new shape types
2387 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2388 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2390 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2391 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2394 // re-add shapes (compounds) of geom groups
2395 std::map< int, int > old2newIDs; // group IDs
2396 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2397 for ( ; data != _geomGroupData.end(); ++data )
2400 std::map< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2401 if ( ii2i != ii2iMap.end() )
2402 oldID = ii2i->second;
2404 TopoDS_Shape newShape = newGroupShape( *data, isBreakLink ? IS_BREAK_LINK : MAIN_TRANSFORMED );
2405 if ( !newShape.IsNull() )
2407 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2409 TopoDS_Compound compound;
2410 BRep_Builder().MakeCompound( compound );
2411 BRep_Builder().Add( compound, newShape );
2412 newShape = compound;
2414 int newID = _impl->GetSubMesh( newShape )->GetId();
2415 if ( oldID && oldID != newID )
2416 old2newIDs.insert( std::make_pair( oldID, newID ));
2420 // re-assign hypotheses
2421 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2423 if ( !sameTopology && ids2Hyps[i].first != 1 )
2424 continue; // assign only global hypos
2425 int sID = ids2Hyps[i].first;
2426 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2427 if ( o2n != old2newIDs.end() )
2429 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2430 const THypList& hyps = ids2Hyps[i].second;
2431 THypList::const_iterator h = hyps.begin();
2432 for ( ; h != hyps.end(); ++h )
2433 _impl->AddHypothesis( s, (*h)->GetID() );
2436 if ( !sameTopology )
2438 // remove invalid study sub-objects
2439 CheckGeomGroupModif();
2443 // restore groups on geometry
2444 for ( size_t i = 0; i < groupsData.size(); ++i )
2446 const TGroupOnGeomData& data = groupsData[i];
2447 if ( data._shape.IsNull() )
2450 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2451 if ( i2g == _mapGroups.end() ) continue;
2453 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2454 if ( !gr_i ) continue;
2456 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2458 _mapGroups.erase( i2g );
2460 g->GetGroupDS()->SetColor( data._color );
2463 std::map< int, int >::iterator o2n = old2newIDs.begin();
2464 for ( ; o2n != old2newIDs.end(); ++o2n )
2466 int newID = o2n->second, oldID = o2n->first;
2467 if ( !_mapSubMesh.count( oldID ))
2469 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2470 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2471 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2472 _mapSubMesh. erase(oldID);
2473 _mapSubMesh_i. erase(oldID);
2474 _mapSubMeshIor.erase(oldID);
2475 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2478 // update _mapSubMesh
2479 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2480 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2481 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2484 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
2488 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2489 if ( !meshSO->_is_nil() )
2490 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2494 //=============================================================================
2496 * \brief Update objects depending on changed geom groups
2498 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2499 * issue 0020210: Update of a smesh group after modification of the associated geom group
2501 //=============================================================================
2503 void SMESH_Mesh_i::CheckGeomGroupModif()
2505 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2506 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2507 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2508 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2509 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2511 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2512 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2513 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2515 int nbValid = 0, nbRemoved = 0;
2516 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2517 for ( ; chItr->More(); chItr->Next() )
2519 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2520 if ( !smSO->_is_nil() &&
2521 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2522 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2524 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2525 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2526 if ( !geom->_non_existent() )
2529 continue; // keep the sub-mesh
2532 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2533 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2534 if ( !sm->_is_nil() && !sm->_non_existent() )
2536 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2537 if ( smGeom->_is_nil() )
2539 RemoveSubMesh( sm );
2546 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2547 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2551 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2552 builder->RemoveObjectWithChildren( rootSO );
2556 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2557 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2558 while ( i_gr != _mapGroups.end())
2560 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2562 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2563 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2564 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2565 bool isValidGeom = false;
2566 if ( !onGeom->_is_nil() )
2568 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2570 else if ( !onFilt->_is_nil() )
2572 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2576 isValidGeom = ( !groupSO->_is_nil() &&
2577 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2581 if ( !IsLoaded() || group->IsEmpty() )
2583 RemoveGroup( group );
2585 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2587 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2589 else // is it possible?
2591 builder->RemoveObjectWithChildren( refSO );
2597 if ( !_impl->HasShapeToMesh() ) return;
2599 CORBA::Long nbEntities = NbNodes() + NbElements();
2601 // Check if group contents changed
2603 typedef map< string, TopoDS_Shape > TEntry2Geom;
2604 TEntry2Geom newGroupContents;
2606 list<TGeomGroupData>::iterator
2607 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2608 for ( ; data != dataEnd; ++data )
2610 pair< TEntry2Geom::iterator, bool > it_new =
2611 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2612 bool processedGroup = !it_new.second;
2613 TopoDS_Shape& newShape = it_new.first->second;
2614 if ( !processedGroup )
2615 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2616 if ( newShape.IsNull() )
2617 continue; // no changes
2620 _preMeshInfo->ForgetOrLoad();
2622 if ( processedGroup ) { // update group indices
2623 list<TGeomGroupData>::iterator data2 = data;
2624 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2625 data->_indices = data2->_indices;
2628 // Update SMESH objects according to new GEOM group contents
2630 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2631 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2633 int oldID = submesh->GetId();
2634 if ( !_mapSubMeshIor.count( oldID ))
2636 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2638 // update hypotheses
2639 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2640 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2641 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2643 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2644 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2646 // care of submeshes
2647 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2648 int newID = newSubmesh->GetId();
2649 if ( newID != oldID ) {
2650 _mapSubMesh [ newID ] = newSubmesh;
2651 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2652 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2653 _mapSubMesh. erase(oldID);
2654 _mapSubMesh_i. erase(oldID);
2655 _mapSubMeshIor.erase(oldID);
2656 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2661 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2662 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2663 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2665 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2667 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2668 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2669 ds->SetShape( newShape );
2674 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2675 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2677 // Remove groups and submeshes basing on removed sub-shapes
2679 TopTools_MapOfShape newShapeMap;
2680 TopoDS_Iterator shapeIt( newShape );
2681 for ( ; shapeIt.More(); shapeIt.Next() )
2682 newShapeMap.Add( shapeIt.Value() );
2684 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2685 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2687 if ( newShapeMap.Contains( shapeIt.Value() ))
2689 TopTools_IndexedMapOfShape oldShapeMap;
2690 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2691 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2693 const TopoDS_Shape& oldShape = oldShapeMap(i);
2694 int oldInd = meshDS->ShapeToIndex( oldShape );
2696 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2697 if ( i_smIor != _mapSubMeshIor.end() ) {
2698 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2701 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2702 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2704 // check if a group bases on oldInd shape
2705 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2706 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2707 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2708 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2710 RemoveGroup( i_grp->second ); // several groups can base on same shape
2711 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2716 // Reassign hypotheses and update groups after setting the new shape to mesh
2718 // collect anassigned hypotheses
2719 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2720 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2721 TShapeHypList assignedHyps;
2722 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2724 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2725 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2726 if ( !hyps.empty() ) {
2727 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2728 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2729 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2732 // collect shapes supporting groups
2733 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2734 TShapeTypeList groupData;
2735 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2736 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2737 for ( ; grIt != groups.end(); ++grIt )
2739 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2741 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2743 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2745 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2746 _impl->ShapeToMesh( newShape );
2748 // reassign hypotheses
2749 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2750 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2752 TIndexedShape& geom = indS_hyps->first;
2753 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2754 int oldID = geom._index;
2755 int newID = meshDS->ShapeToIndex( geom._shape );
2756 if ( oldID == 1 ) { // main shape
2758 geom._shape = newShape;
2762 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2763 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2764 // care of sub-meshes
2765 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2766 if ( newID != oldID ) {
2767 _mapSubMesh [ newID ] = newSubmesh;
2768 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2769 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2770 _mapSubMesh. erase(oldID);
2771 _mapSubMesh_i. erase(oldID);
2772 _mapSubMeshIor.erase(oldID);
2773 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2777 TShapeTypeList::iterator geomType = groupData.begin();
2778 for ( ; geomType != groupData.end(); ++geomType )
2780 const TIndexedShape& geom = geomType->first;
2781 int oldID = geom._index;
2782 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2785 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2786 CORBA::String_var name = groupSO->GetName();
2788 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2789 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2790 /*id=*/-1, geom._shape ))
2791 group_i->changeLocalId( group->GetID() );
2794 break; // everything has been updated
2797 } // loop on group data
2801 CORBA::Long newNbEntities = NbNodes() + NbElements();
2802 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2803 if ( newNbEntities != nbEntities )
2805 // Add all SObjects with icons to soToUpdateIcons
2806 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2808 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2809 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2810 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2812 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2813 i_gr != _mapGroups.end(); ++i_gr ) // groups
2814 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2817 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2818 for ( ; so != soToUpdateIcons.end(); ++so )
2819 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2822 //=============================================================================
2824 * \brief Create standalone group from a group on geometry or filter
2826 //=============================================================================
2828 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2829 throw (SALOME::SALOME_Exception)
2831 SMESH::SMESH_Group_var aGroup;
2836 _preMeshInfo->FullLoadFromFile();
2838 if ( theGroup->_is_nil() )
2839 return aGroup._retn();
2841 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2843 return aGroup._retn();
2845 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2847 const int anId = aGroupToRem->GetLocalID();
2848 if ( !_impl->ConvertToStandalone( anId ) )
2849 return aGroup._retn();
2850 removeGeomGroupData( theGroup );
2852 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2854 // remove old instance of group from own map
2855 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2856 _mapGroups.erase( anId );
2858 SALOMEDS::StudyBuilder_var builder;
2859 SALOMEDS::SObject_wrap aGroupSO;
2860 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2861 if ( !aStudy->_is_nil() ) {
2862 builder = aStudy->NewBuilder();
2863 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2864 if ( !aGroupSO->_is_nil() )
2866 // remove reference to geometry
2867 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2868 for ( ; chItr->More(); chItr->Next() )
2870 // Remove group's child SObject
2871 SALOMEDS::SObject_wrap so = chItr->Value();
2872 builder->RemoveObject( so );
2874 // Update Python script
2875 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2876 << ".ConvertToStandalone( " << aGroupSO << " )";
2878 // change icon of Group on Filter
2881 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2882 // const int isEmpty = ( elemTypes->length() == 0 );
2885 SALOMEDS::GenericAttribute_wrap anAttr =
2886 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2887 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2888 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2894 // remember new group in own map
2895 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2896 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2898 // register CORBA object for persistence
2899 _gen_i->RegisterObject( aGroup );
2901 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2902 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2903 //aGroup->Register();
2904 aGroupToRem->UnRegister();
2906 SMESH_CATCH( SMESH::throwCorbaException );
2908 return aGroup._retn();
2911 //=============================================================================
2915 //=============================================================================
2917 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2919 if(MYDEBUG) MESSAGE( "createSubMesh" );
2920 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2921 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2924 SMESH_subMesh_i * subMeshServant;
2927 subMeshId = mySubMesh->GetId();
2928 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2930 else // "invalid sub-mesh"
2932 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2933 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2934 if ( _mapSubMesh.empty() )
2937 subMeshId = _mapSubMesh.begin()->first - 1;
2938 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2941 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2943 _mapSubMesh [subMeshId] = mySubMesh;
2944 _mapSubMesh_i [subMeshId] = subMeshServant;
2945 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2947 subMeshServant->Register();
2949 // register CORBA object for persistence
2950 int nextId = _gen_i->RegisterObject( subMesh );
2951 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2952 else { nextId = 0; } // avoid "unused variable" warning
2954 // to track changes of GEOM groups
2955 if ( subMeshId > 0 )
2956 addGeomGroupData( theSubShapeObject, subMesh );
2958 return subMesh._retn();
2961 //=======================================================================
2962 //function : getSubMesh
2964 //=======================================================================
2966 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2968 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2969 if ( it == _mapSubMeshIor.end() )
2970 return SMESH::SMESH_subMesh::_nil();
2972 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2975 //=============================================================================
2979 //=============================================================================
2981 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2982 GEOM::GEOM_Object_ptr theSubShapeObject )
2984 bool isHypChanged = false;
2985 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2986 return isHypChanged;
2988 const int subMeshId = theSubMesh->GetId();
2990 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2993 if (( _mapSubMesh.count( subMeshId )) &&
2994 ( sm = _impl->GetSubMeshContaining( subMeshId )))
2996 TopoDS_Shape S = sm->GetSubShape();
2999 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3000 isHypChanged = !hyps.empty();
3001 if ( isHypChanged && _preMeshInfo )
3002 _preMeshInfo->ForgetOrLoad();
3003 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3004 for ( ; hyp != hyps.end(); ++hyp )
3005 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3012 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3013 isHypChanged = ( aHypList->length() > 0 );
3014 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3015 removeHypothesis( theSubShapeObject, aHypList[i] );
3018 catch( const SALOME::SALOME_Exception& ) {
3019 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3021 removeGeomGroupData( theSubShapeObject );
3025 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3026 if ( id_smi != _mapSubMesh_i.end() )
3027 id_smi->second->UnRegister();
3029 // remove a CORBA object
3030 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3031 if ( id_smptr != _mapSubMeshIor.end() )
3032 SMESH::SMESH_subMesh_var( id_smptr->second );
3034 _mapSubMesh.erase(subMeshId);
3035 _mapSubMesh_i.erase(subMeshId);
3036 _mapSubMeshIor.erase(subMeshId);
3038 return isHypChanged;
3041 //=============================================================================
3045 //=============================================================================
3047 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3048 const char* theName,
3050 const TopoDS_Shape& theShape,
3051 const SMESH_PredicatePtr& thePredicate )
3053 std::string newName;
3054 if ( !theName || !theName[0] )
3056 std::set< std::string > presentNames;
3057 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3058 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3060 CORBA::String_var name = i_gr->second->GetName();
3061 presentNames.insert( name.in() );
3064 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3065 } while ( !presentNames.insert( newName ).second );
3066 theName = newName.c_str();
3068 SMESH::SMESH_GroupBase_var aGroup;
3069 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3070 theID, theShape, thePredicate ))
3072 int anId = g->GetID();
3073 SMESH_GroupBase_i* aGroupImpl;
3074 if ( !theShape.IsNull() )
3075 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3076 else if ( thePredicate )
3077 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3079 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3081 aGroup = aGroupImpl->_this();
3082 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3083 aGroupImpl->Register();
3085 // register CORBA object for persistence
3086 int nextId = _gen_i->RegisterObject( aGroup );
3087 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3088 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3090 // to track changes of GEOM groups
3091 if ( !theShape.IsNull() ) {
3092 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3093 addGeomGroupData( geom, aGroup );
3096 return aGroup._retn();
3099 //=============================================================================
3101 * SMESH_Mesh_i::removeGroup
3103 * Should be called by ~SMESH_Group_i()
3105 //=============================================================================
3107 void SMESH_Mesh_i::removeGroup( const int theId )
3109 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3110 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3111 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3112 _mapGroups.erase( theId );
3113 removeGeomGroupData( group );
3114 if ( !_impl->RemoveGroup( theId ))
3116 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3117 RemoveGroup( group );
3119 group->UnRegister();
3123 //=============================================================================
3127 //=============================================================================
3129 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3130 throw(SALOME::SALOME_Exception)
3132 SMESH::log_array_var aLog;
3136 _preMeshInfo->FullLoadFromFile();
3138 list < SMESHDS_Command * >logDS = _impl->GetLog();
3139 aLog = new SMESH::log_array;
3141 int lg = logDS.size();
3144 list < SMESHDS_Command * >::iterator its = logDS.begin();
3145 while(its != logDS.end()){
3146 SMESHDS_Command *com = *its;
3147 int comType = com->GetType();
3149 int lgcom = com->GetNumber();
3151 const list < int >&intList = com->GetIndexes();
3152 int inum = intList.size();
3154 list < int >::const_iterator ii = intList.begin();
3155 const list < double >&coordList = com->GetCoords();
3156 int rnum = coordList.size();
3158 list < double >::const_iterator ir = coordList.begin();
3159 aLog[indexLog].commandType = comType;
3160 aLog[indexLog].number = lgcom;
3161 aLog[indexLog].coords.length(rnum);
3162 aLog[indexLog].indexes.length(inum);
3163 for(int i = 0; i < rnum; i++){
3164 aLog[indexLog].coords[i] = *ir;
3165 //MESSAGE(" "<<i<<" "<<ir.Value());
3168 for(int i = 0; i < inum; i++){
3169 aLog[indexLog].indexes[i] = *ii;
3170 //MESSAGE(" "<<i<<" "<<ii.Value());
3179 SMESH_CATCH( SMESH::throwCorbaException );
3181 return aLog._retn();
3185 //=============================================================================
3189 //=============================================================================
3191 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3195 SMESH_CATCH( SMESH::throwCorbaException );
3198 //=============================================================================
3202 //=============================================================================
3204 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3209 //=============================================================================
3212 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3213 // issue 0020918: groups removal is caused by hyp modification
3214 // issue 0021208: to forget not loaded mesh data at hyp modification
3215 struct TCallUp_i : public SMESH_Mesh::TCallUp
3217 SMESH_Mesh_i* _mesh;
3218 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3219 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3220 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3221 virtual void Load () { _mesh->Load(); }
3225 //================================================================================
3227 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3229 //================================================================================
3231 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3234 _preMeshInfo->ForgetOrLoad();
3236 SMESH::SMESH_Mesh_var mesh = _this();
3237 _gen_i->UpdateIcons( mesh );
3239 // mark a hypothesis as valid after edition
3240 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3241 SALOMEDS::SObject_wrap hypRoot;
3242 if ( !smeshComp->_is_nil() &&
3243 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3245 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3246 for ( ; anIter->More(); anIter->Next() )
3248 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3249 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3250 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3251 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3252 _gen_i->HighLightInvalid( hyp, false );
3257 //=============================================================================
3261 //=============================================================================
3263 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3265 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3268 _impl->SetCallUp( new TCallUp_i(this));
3271 //=============================================================================
3275 //=============================================================================
3277 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3279 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3283 //=============================================================================
3285 * Return mesh editor
3287 //=============================================================================
3289 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3290 throw (SALOME::SALOME_Exception)
3292 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3296 _preMeshInfo->FullLoadFromFile();
3298 // Create MeshEditor
3300 _editor = new SMESH_MeshEditor_i( this, false );
3301 aMeshEdVar = _editor->_this();
3303 // Update Python script
3304 TPythonDump() << _editor << " = "
3305 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3307 SMESH_CATCH( SMESH::throwCorbaException );
3309 return aMeshEdVar._retn();
3312 //=============================================================================
3314 * Return mesh edition previewer
3316 //=============================================================================
3318 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3319 throw (SALOME::SALOME_Exception)
3321 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3325 _preMeshInfo->FullLoadFromFile();
3327 if ( !_previewEditor )
3328 _previewEditor = new SMESH_MeshEditor_i( this, true );
3329 aMeshEdVar = _previewEditor->_this();
3331 SMESH_CATCH( SMESH::throwCorbaException );
3333 return aMeshEdVar._retn();
3336 //================================================================================
3338 * \brief Return true if the mesh has been edited since a last total re-compute
3339 * and those modifications may prevent successful partial re-compute
3341 //================================================================================
3343 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3345 Unexpect aCatch(SALOME_SalomeException);
3346 return _impl->HasModificationsToDiscard();
3349 //================================================================================
3351 * \brief Returns a random unique color
3353 //================================================================================
3355 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3357 const int MAX_ATTEMPTS = 100;
3359 double tolerance = 0.5;
3360 SALOMEDS::Color col;
3364 // generate random color
3365 double red = (double)rand() / RAND_MAX;
3366 double green = (double)rand() / RAND_MAX;
3367 double blue = (double)rand() / RAND_MAX;
3368 // check existence in the list of the existing colors
3369 bool matched = false;
3370 std::list<SALOMEDS::Color>::const_iterator it;
3371 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3372 SALOMEDS::Color color = *it;
3373 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3374 matched = tol < tolerance;
3376 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3377 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3385 //=============================================================================
3387 * Sets auto-color mode. If it is on, groups get unique random colors
3389 //=============================================================================
3391 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3393 Unexpect aCatch(SALOME_SalomeException);
3394 _impl->SetAutoColor(theAutoColor);
3396 TPythonDump pyDump; // not to dump group->SetColor() from below code
3397 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3399 std::list<SALOMEDS::Color> aReservedColors;
3400 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3401 for ( ; it != _mapGroups.end(); it++ ) {
3402 if ( CORBA::is_nil( it->second )) continue;
3403 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3404 it->second->SetColor( aColor );
3405 aReservedColors.push_back( aColor );
3409 //=============================================================================
3411 * Returns true if auto-color mode is on
3413 //=============================================================================
3415 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3417 Unexpect aCatch(SALOME_SalomeException);
3418 return _impl->GetAutoColor();
3421 //=============================================================================
3423 * Checks if there are groups with equal names
3425 //=============================================================================
3427 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3429 return _impl->HasDuplicatedGroupNamesMED();
3432 //================================================================================
3434 * \brief Care of a file before exporting mesh into it
3436 //================================================================================
3438 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3440 SMESH_File aFile( file, false );
3442 if ( aFile.exists() ) {
3443 // existing filesystem node
3444 if ( !aFile.isDirectory() ) {
3445 if ( aFile.openForWriting() ) {
3446 if ( overwrite && ! aFile.remove()) {
3447 msg << "Can't replace " << aFile.getName();
3450 msg << "Can't write into " << aFile.getName();
3453 msg << "Location " << aFile.getName() << " is not a file";
3457 // nonexisting file; check if it can be created
3458 if ( !aFile.openForWriting() ) {
3459 msg << "You cannot create the file "
3461 << ". Check the directory existence and access rights";
3469 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3473 //================================================================================
3475 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3476 * \param file - file name
3477 * \param overwrite - to erase the file or not
3478 * \retval string - mesh name
3480 //================================================================================
3482 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3483 CORBA::Boolean overwrite)
3486 PrepareForWriting(file, overwrite);
3487 string aMeshName = "Mesh";
3488 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3489 if ( !aStudy->_is_nil() ) {
3490 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3491 if ( !aMeshSO->_is_nil() ) {
3492 CORBA::String_var name = aMeshSO->GetName();
3494 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3495 if ( !aStudy->GetProperties()->IsLocked() )
3497 SALOMEDS::GenericAttribute_wrap anAttr;
3498 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3499 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3500 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3501 ASSERT(!aFileName->_is_nil());
3502 aFileName->SetValue(file);
3503 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3504 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3505 ASSERT(!aFileType->_is_nil());
3506 aFileType->SetValue("FICHIERMED");
3510 // Update Python script
3511 // set name of mesh before export
3512 TPythonDump() << _gen_i << ".SetName("
3513 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3515 // check names of groups
3521 //================================================================================
3523 * \brief Export to MED file
3525 //================================================================================
3527 void SMESH_Mesh_i::ExportMED(const char* file,
3528 CORBA::Boolean auto_groups,
3529 CORBA::Long version,
3530 CORBA::Boolean overwrite,
3531 CORBA::Boolean autoDimension)
3532 throw(SALOME::SALOME_Exception)
3534 //MESSAGE("MED minor version: "<< minor);
3537 _preMeshInfo->FullLoadFromFile();
3539 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3540 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3542 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3544 << "auto_groups=" <<auto_groups << ", "
3545 << "minor=" << version << ", "
3546 << "overwrite=" << overwrite << ", "
3547 << "meshPart=None, "
3548 << "autoDimension=" << autoDimension << " )";
3550 SMESH_CATCH( SMESH::throwCorbaException );
3553 //================================================================================
3555 * \brief Export a mesh to a SAUV file
3557 //================================================================================
3559 void SMESH_Mesh_i::ExportSAUV (const char* file,
3560 CORBA::Boolean auto_groups)
3561 throw(SALOME::SALOME_Exception)
3563 Unexpect aCatch(SALOME_SalomeException);
3565 _preMeshInfo->FullLoadFromFile();
3567 string aMeshName = prepareMeshNameAndGroups(file, true);
3568 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3569 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3570 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3574 //================================================================================
3576 * \brief Export a mesh to a DAT file
3578 //================================================================================
3580 void SMESH_Mesh_i::ExportDAT (const char *file)
3581 throw(SALOME::SALOME_Exception)
3583 Unexpect aCatch(SALOME_SalomeException);
3585 _preMeshInfo->FullLoadFromFile();
3587 // Update Python script
3588 // check names of groups
3590 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3593 PrepareForWriting(file);
3594 _impl->ExportDAT(file);
3597 //================================================================================
3599 * \brief Export a mesh to an UNV file
3601 //================================================================================
3603 void SMESH_Mesh_i::ExportUNV (const char *file)
3604 throw(SALOME::SALOME_Exception)
3606 Unexpect aCatch(SALOME_SalomeException);
3608 _preMeshInfo->FullLoadFromFile();
3610 // Update Python script
3611 // check names of groups
3613 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3616 PrepareForWriting(file);
3617 _impl->ExportUNV(file);
3620 //================================================================================
3622 * \brief Export a mesh to an STL file
3624 //================================================================================
3626 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3627 throw(SALOME::SALOME_Exception)
3629 Unexpect aCatch(SALOME_SalomeException);
3631 _preMeshInfo->FullLoadFromFile();
3633 // Update Python script
3634 // check names of groups
3636 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3637 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3639 CORBA::String_var name;
3640 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3641 if ( !so->_is_nil() )
3642 name = so->GetName();
3645 PrepareForWriting( file );
3646 _impl->ExportSTL( file, isascii, name.in() );
3649 //================================================================================
3651 * \brief Export a part of mesh to a med file
3653 //================================================================================
3655 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3657 CORBA::Boolean auto_groups,
3658 CORBA::Long version,
3659 CORBA::Boolean overwrite,
3660 CORBA::Boolean autoDimension,
3661 const GEOM::ListOfFields& fields,
3662 const char* geomAssocFields,
3663 CORBA::Double ZTolerance)
3664 throw (SALOME::SALOME_Exception)
3666 MESSAGE("MED version: "<< version);
3669 _preMeshInfo->FullLoadFromFile();
3672 bool have0dField = false;
3673 if ( fields.length() > 0 )
3675 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3676 if ( shapeToMesh->_is_nil() )
3677 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3679 for ( size_t i = 0; i < fields.length(); ++i )
3681 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3682 THROW_SALOME_CORBA_EXCEPTION
3683 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3684 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3685 if ( fieldShape->_is_nil() )
3686 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3687 if ( !fieldShape->IsSame( shapeToMesh ) )
3688 THROW_SALOME_CORBA_EXCEPTION
3689 ( "Field defined not on shape", SALOME::BAD_PARAM);
3690 if ( fields[i]->GetDimension() == 0 )
3693 if ( geomAssocFields )
3694 for ( int i = 0; geomAssocFields[i]; ++i )
3695 switch ( geomAssocFields[i] ) {
3696 case 'v':case 'e':case 'f':case 's': break;
3697 case 'V':case 'E':case 'F':case 'S': break;
3698 default: THROW_SALOME_CORBA_EXCEPTION
3699 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3703 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3707 string aMeshName = "Mesh";
3708 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3709 if ( CORBA::is_nil( meshPart ) ||
3710 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3712 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3713 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3714 0, autoDimension, /*addODOnVertices=*/have0dField,
3716 meshDS = _impl->GetMeshDS();
3721 _preMeshInfo->FullLoadFromFile();
3723 PrepareForWriting(file, overwrite);
3725 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3726 if ( !SO->_is_nil() ) {
3727 CORBA::String_var name = SO->GetName();
3731 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3732 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3733 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3734 meshDS = tmpDSDeleter._obj = partDS;
3739 if ( _impl->HasShapeToMesh() )
3741 DriverMED_W_Field fieldWriter;
3742 fieldWriter.SetFile( file );
3743 fieldWriter.SetMeshName( aMeshName );
3744 fieldWriter.AddODOnVertices( have0dField );
3746 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3750 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3751 goList->length( fields.length() );
3752 for ( size_t i = 0; i < fields.length(); ++i )
3754 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3757 TPythonDump() << _this() << ".ExportPartToMED( "
3758 << meshPart << ", r'"
3760 << auto_groups << ", "
3762 << overwrite << ", "
3763 << autoDimension << ", "
3765 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3766 << TVar( ZTolerance )
3769 SMESH_CATCH( SMESH::throwCorbaException );
3772 //================================================================================
3774 * Write GEOM fields to MED file
3776 //================================================================================
3778 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3779 SMESHDS_Mesh* meshDS,
3780 const GEOM::ListOfFields& fields,
3781 const char* geomAssocFields)
3783 #define METH "SMESH_Mesh_i::exportMEDFields() "
3785 if (( fields.length() < 1 ) &&
3786 ( !geomAssocFields || !geomAssocFields[0] ))
3789 std::vector< std::vector< double > > dblVals;
3790 std::vector< std::vector< int > > intVals;
3791 std::vector< int > subIdsByDim[ 4 ];
3792 const double noneDblValue = 0.;
3793 const double noneIntValue = 0;
3795 for ( size_t iF = 0; iF < fields.length(); ++iF )
3799 int dim = fields[ iF ]->GetDimension();
3800 SMDSAbs_ElementType elemType;
3801 TopAbs_ShapeEnum shapeType;
3803 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3804 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3805 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3806 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3808 continue; // skip fields on whole shape
3810 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3811 if ( dataType == GEOM::FDT_String )
3813 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3814 if ( stepIDs->length() < 1 )
3816 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3817 if ( comps->length() < 1 )
3819 CORBA::String_var name = fields[ iF ]->GetName();
3821 if ( !fieldWriter.Set( meshDS,
3825 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3828 for ( size_t iC = 0; iC < comps->length(); ++iC )
3829 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3831 dblVals.resize( comps->length() );
3832 intVals.resize( comps->length() );
3834 // find sub-shape IDs
3836 std::vector< int >& subIds = subIdsByDim[ dim ];
3837 if ( subIds.empty() )
3838 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3839 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3840 subIds.push_back( id );
3844 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3848 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3850 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3851 if ( step->_is_nil() )
3854 CORBA::Long stamp = step->GetStamp();
3855 CORBA::Long id = step->GetID();
3856 fieldWriter.SetDtIt( int( stamp ), int( id ));
3858 // fill dblVals or intVals
3859 for ( size_t iC = 0; iC < comps->length(); ++iC )
3860 if ( dataType == GEOM::FDT_Double )
3862 dblVals[ iC ].clear();
3863 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3867 intVals[ iC ].clear();
3868 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3872 case GEOM::FDT_Double:
3874 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3875 if ( dblStep->_is_nil() ) continue;
3876 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3877 if ( vv->length() != subIds.size() * comps->length() )
3878 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3879 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3880 for ( size_t iC = 0; iC < comps->length(); ++iC )
3881 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3886 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3887 if ( intStep->_is_nil() ) continue;
3888 GEOM::ListOfLong_var vv = intStep->GetValues();
3889 if ( vv->length() != subIds.size() * comps->length() )
3890 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3891 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3892 for ( size_t iC = 0; iC < comps->length(); ++iC )
3893 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3896 case GEOM::FDT_Bool:
3898 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3899 if ( boolStep->_is_nil() ) continue;
3900 GEOM::short_array_var vv = boolStep->GetValues();
3901 if ( vv->length() != subIds.size() * comps->length() )
3902 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3903 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3904 for ( size_t iC = 0; iC < comps->length(); ++iC )
3905 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3911 // pass values to fieldWriter
3912 elemIt = fieldWriter.GetOrderedElems();
3913 if ( dataType == GEOM::FDT_Double )
3914 while ( elemIt->more() )
3916 const SMDS_MeshElement* e = elemIt->next();
3917 const int shapeID = e->getshapeId();
3918 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3919 for ( size_t iC = 0; iC < comps->length(); ++iC )
3920 fieldWriter.AddValue( noneDblValue );
3922 for ( size_t iC = 0; iC < comps->length(); ++iC )
3923 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3926 while ( elemIt->more() )
3928 const SMDS_MeshElement* e = elemIt->next();
3929 const int shapeID = e->getshapeId();
3930 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3931 for ( size_t iC = 0; iC < comps->length(); ++iC )
3932 fieldWriter.AddValue( (double) noneIntValue );
3934 for ( size_t iC = 0; iC < comps->length(); ++iC )
3935 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3939 fieldWriter.Perform();
3940 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3941 if ( res && res->IsKO() )
3943 if ( res->myComment.empty() )
3944 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3946 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3952 if ( !geomAssocFields || !geomAssocFields[0] )
3955 // write geomAssocFields
3957 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3958 shapeDim[ TopAbs_COMPOUND ] = 3;
3959 shapeDim[ TopAbs_COMPSOLID ] = 3;
3960 shapeDim[ TopAbs_SOLID ] = 3;
3961 shapeDim[ TopAbs_SHELL ] = 2;
3962 shapeDim[ TopAbs_FACE ] = 2;
3963 shapeDim[ TopAbs_WIRE ] = 1;
3964 shapeDim[ TopAbs_EDGE ] = 1;
3965 shapeDim[ TopAbs_VERTEX ] = 0;
3966 shapeDim[ TopAbs_SHAPE ] = 3;
3968 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3970 std::vector< std::string > compNames;
3971 switch ( geomAssocFields[ iF ]) {
3973 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3974 compNames.push_back( "dim" );
3977 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3980 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3983 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3987 compNames.push_back( "id" );
3988 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3989 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3991 fieldWriter.SetDtIt( -1, -1 );
3993 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3997 if ( compNames.size() == 2 ) // _vertices_
3998 while ( elemIt->more() )
4000 const SMDS_MeshElement* e = elemIt->next();
4001 const int shapeID = e->getshapeId();
4004 fieldWriter.AddValue( (double) -1 );
4005 fieldWriter.AddValue( (double) -1 );
4009 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4010 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4011 fieldWriter.AddValue( (double) shapeID );
4015 while ( elemIt->more() )
4017 const SMDS_MeshElement* e = elemIt->next();
4018 const int shapeID = e->getshapeId();
4020 fieldWriter.AddValue( (double) -1 );
4022 fieldWriter.AddValue( (double) shapeID );
4026 fieldWriter.Perform();
4027 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4028 if ( res && res->IsKO() )
4030 if ( res->myComment.empty() )
4031 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4033 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4036 } // loop on geomAssocFields
4041 //================================================================================
4043 * \brief Export a part of mesh to a DAT file
4045 //================================================================================
4047 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4049 throw (SALOME::SALOME_Exception)
4051 Unexpect aCatch(SALOME_SalomeException);
4053 _preMeshInfo->FullLoadFromFile();
4055 PrepareForWriting(file);
4057 SMESH_MeshPartDS partDS( meshPart );
4058 _impl->ExportDAT(file,&partDS);
4060 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4061 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4063 //================================================================================
4065 * \brief Export a part of mesh to an UNV file
4067 //================================================================================
4069 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4071 throw (SALOME::SALOME_Exception)
4073 Unexpect aCatch(SALOME_SalomeException);
4075 _preMeshInfo->FullLoadFromFile();
4077 PrepareForWriting(file);
4079 SMESH_MeshPartDS partDS( meshPart );
4080 _impl->ExportUNV(file, &partDS);
4082 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4083 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4085 //================================================================================
4087 * \brief Export a part of mesh to an STL file
4089 //================================================================================
4091 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4093 ::CORBA::Boolean isascii)
4094 throw (SALOME::SALOME_Exception)
4096 Unexpect aCatch(SALOME_SalomeException);
4098 _preMeshInfo->FullLoadFromFile();
4100 PrepareForWriting(file);
4102 CORBA::String_var name;
4103 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4104 if ( !so->_is_nil() )
4105 name = so->GetName();
4107 SMESH_MeshPartDS partDS( meshPart );
4108 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4110 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4111 << meshPart<< ", r'" << file << "', " << isascii << ")";
4114 //================================================================================
4116 * \brief Export a part of mesh to an STL file
4118 //================================================================================
4120 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4122 CORBA::Boolean overwrite,
4123 CORBA::Boolean groupElemsByType)
4124 throw (SALOME::SALOME_Exception)
4127 Unexpect aCatch(SALOME_SalomeException);
4129 _preMeshInfo->FullLoadFromFile();
4131 PrepareForWriting(file,overwrite);
4133 std::string meshName("");
4134 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4135 if ( !so->_is_nil() )
4137 CORBA::String_var name = so->GetName();
4138 meshName = name.in();
4142 SMESH_MeshPartDS partDS( meshPart );
4143 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4145 SMESH_CATCH( SMESH::throwCorbaException );
4147 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4148 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4150 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4154 //================================================================================
4156 * \brief Export a part of mesh to a GMF file
4158 //================================================================================
4160 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4162 bool withRequiredGroups)
4163 throw (SALOME::SALOME_Exception)
4165 Unexpect aCatch(SALOME_SalomeException);
4167 _preMeshInfo->FullLoadFromFile();
4169 PrepareForWriting(file,/*overwrite=*/true);
4171 SMESH_MeshPartDS partDS( meshPart );
4172 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4174 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4175 << meshPart<< ", r'"
4177 << withRequiredGroups << ")";
4180 //=============================================================================
4182 * Return computation progress [0.,1]
4184 //=============================================================================
4186 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4190 return _impl->GetComputeProgress();
4192 SMESH_CATCH( SMESH::doNothing );
4196 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4198 Unexpect aCatch(SALOME_SalomeException);
4200 return _preMeshInfo->NbNodes();
4202 return _impl->NbNodes();
4205 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4207 Unexpect aCatch(SALOME_SalomeException);
4209 return _preMeshInfo->NbElements();
4211 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4214 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4216 Unexpect aCatch(SALOME_SalomeException);
4218 return _preMeshInfo->Nb0DElements();
4220 return _impl->Nb0DElements();
4223 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4225 Unexpect aCatch(SALOME_SalomeException);
4227 return _preMeshInfo->NbBalls();
4229 return _impl->NbBalls();
4232 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4234 Unexpect aCatch(SALOME_SalomeException);
4236 return _preMeshInfo->NbEdges();
4238 return _impl->NbEdges();
4241 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4242 throw(SALOME::SALOME_Exception)
4244 Unexpect aCatch(SALOME_SalomeException);
4246 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4248 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4251 //=============================================================================
4253 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4255 Unexpect aCatch(SALOME_SalomeException);
4257 return _preMeshInfo->NbFaces();
4259 return _impl->NbFaces();
4262 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4264 Unexpect aCatch(SALOME_SalomeException);
4266 return _preMeshInfo->NbTriangles();
4268 return _impl->NbTriangles();
4271 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4273 Unexpect aCatch(SALOME_SalomeException);
4275 return _preMeshInfo->NbBiQuadTriangles();
4277 return _impl->NbBiQuadTriangles();
4280 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4282 Unexpect aCatch(SALOME_SalomeException);
4284 return _preMeshInfo->NbQuadrangles();
4286 return _impl->NbQuadrangles();
4289 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4291 Unexpect aCatch(SALOME_SalomeException);
4293 return _preMeshInfo->NbBiQuadQuadrangles();
4295 return _impl->NbBiQuadQuadrangles();
4298 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4300 Unexpect aCatch(SALOME_SalomeException);
4302 return _preMeshInfo->NbPolygons();
4304 return _impl->NbPolygons();
4307 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4309 Unexpect aCatch(SALOME_SalomeException);
4311 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4313 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4316 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4317 throw(SALOME::SALOME_Exception)
4319 Unexpect aCatch(SALOME_SalomeException);
4321 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4323 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4326 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4327 throw(SALOME::SALOME_Exception)
4329 Unexpect aCatch(SALOME_SalomeException);
4331 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4333 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4336 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4337 throw(SALOME::SALOME_Exception)
4339 Unexpect aCatch(SALOME_SalomeException);
4341 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4343 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4346 //=============================================================================
4348 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4350 Unexpect aCatch(SALOME_SalomeException);
4352 return _preMeshInfo->NbVolumes();
4354 return _impl->NbVolumes();
4357 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4359 Unexpect aCatch(SALOME_SalomeException);
4361 return _preMeshInfo->NbTetras();
4363 return _impl->NbTetras();
4366 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4368 Unexpect aCatch(SALOME_SalomeException);
4370 return _preMeshInfo->NbHexas();
4372 return _impl->NbHexas();
4375 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4377 Unexpect aCatch(SALOME_SalomeException);
4379 return _preMeshInfo->NbTriQuadHexas();
4381 return _impl->NbTriQuadraticHexas();
4384 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4386 Unexpect aCatch(SALOME_SalomeException);
4388 return _preMeshInfo->NbPyramids();
4390 return _impl->NbPyramids();
4393 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4395 Unexpect aCatch(SALOME_SalomeException);
4397 return _preMeshInfo->NbPrisms();
4399 return _impl->NbPrisms();
4402 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4404 Unexpect aCatch(SALOME_SalomeException);
4406 return _preMeshInfo->NbHexPrisms();
4408 return _impl->NbHexagonalPrisms();
4411 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4413 Unexpect aCatch(SALOME_SalomeException);
4415 return _preMeshInfo->NbPolyhedrons();
4417 return _impl->NbPolyhedrons();
4420 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4421 throw(SALOME::SALOME_Exception)
4423 Unexpect aCatch(SALOME_SalomeException);
4425 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4427 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4430 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4431 throw(SALOME::SALOME_Exception)
4433 Unexpect aCatch(SALOME_SalomeException);
4435 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4437 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4440 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4441 throw(SALOME::SALOME_Exception)
4443 Unexpect aCatch(SALOME_SalomeException);
4445 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4447 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4450 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4451 throw(SALOME::SALOME_Exception)
4453 Unexpect aCatch(SALOME_SalomeException);
4455 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4457 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4460 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4461 throw(SALOME::SALOME_Exception)
4463 Unexpect aCatch(SALOME_SalomeException);
4465 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4467 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4470 //=============================================================================
4472 * Returns nb of published sub-meshes
4474 //=============================================================================
4476 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4478 Unexpect aCatch(SALOME_SalomeException);
4479 return _mapSubMesh_i.size();
4482 //=============================================================================
4484 * Dumps mesh into a string
4486 //=============================================================================
4488 char* SMESH_Mesh_i::Dump()
4492 return CORBA::string_dup( os.str().c_str() );
4495 //=============================================================================
4497 * Method of SMESH_IDSource interface
4499 //=============================================================================
4501 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4503 return GetElementsId();
4506 //=============================================================================
4508 * Returns ids of all elements
4510 //=============================================================================
4512 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4513 throw (SALOME::SALOME_Exception)
4515 Unexpect aCatch(SALOME_SalomeException);
4517 _preMeshInfo->FullLoadFromFile();
4519 SMESH::long_array_var aResult = new SMESH::long_array();
4520 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4522 if ( aSMESHDS_Mesh == NULL )
4523 return aResult._retn();
4525 long nbElements = NbElements();
4526 aResult->length( nbElements );
4527 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4528 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4529 aResult[i] = anIt->next()->GetID();
4531 return aResult._retn();
4535 //=============================================================================
4537 * Returns ids of all elements of given type
4539 //=============================================================================
4541 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4542 throw (SALOME::SALOME_Exception)
4544 Unexpect aCatch(SALOME_SalomeException);
4546 _preMeshInfo->FullLoadFromFile();
4548 SMESH::long_array_var aResult = new SMESH::long_array();
4549 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4551 if ( aSMESHDS_Mesh == NULL )
4552 return aResult._retn();
4554 long nbElements = NbElements();
4556 // No sense in returning ids of elements along with ids of nodes:
4557 // when theElemType == SMESH::ALL, return node ids only if
4558 // there are no elements
4559 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4560 return GetNodesId();
4562 aResult->length( nbElements );
4566 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4567 while ( i < nbElements && anIt->more() )
4568 aResult[i++] = anIt->next()->GetID();
4570 aResult->length( i );
4572 return aResult._retn();
4575 //=============================================================================
4577 * Returns ids of all nodes
4579 //=============================================================================
4581 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4582 throw (SALOME::SALOME_Exception)
4584 Unexpect aCatch(SALOME_SalomeException);
4586 _preMeshInfo->FullLoadFromFile();
4588 SMESH::long_array_var aResult = new SMESH::long_array();
4589 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4591 if ( aMeshDS == NULL )
4592 return aResult._retn();
4594 long nbNodes = NbNodes();
4595 aResult->length( nbNodes );
4596 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4597 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4598 aResult[i] = anIt->next()->GetID();
4600 return aResult._retn();
4603 //=============================================================================
4607 //=============================================================================
4609 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4610 throw (SALOME::SALOME_Exception)
4612 SMESH::ElementType type = SMESH::ALL;
4616 _preMeshInfo->FullLoadFromFile();
4618 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4620 SMESH_CATCH( SMESH::throwCorbaException );
4625 //=============================================================================
4629 //=============================================================================
4631 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4632 throw (SALOME::SALOME_Exception)
4635 _preMeshInfo->FullLoadFromFile();
4637 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4639 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4641 return ( SMESH::EntityType ) e->GetEntityType();
4644 //=============================================================================
4648 //=============================================================================
4650 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4651 throw (SALOME::SALOME_Exception)
4654 _preMeshInfo->FullLoadFromFile();
4656 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4658 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4660 return ( SMESH::GeometryType ) e->GetGeomType();
4663 //=============================================================================
4665 * Returns ID of elements for given submesh
4667 //=============================================================================
4668 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4669 throw (SALOME::SALOME_Exception)
4671 SMESH::long_array_var aResult = new SMESH::long_array();
4675 _preMeshInfo->FullLoadFromFile();
4677 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4678 if(!SM) return aResult._retn();
4680 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4681 if(!SDSM) return aResult._retn();
4683 aResult->length(SDSM->NbElements());
4685 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4687 while ( eIt->more() ) {
4688 aResult[i++] = eIt->next()->GetID();
4691 SMESH_CATCH( SMESH::throwCorbaException );
4693 return aResult._retn();
4696 //=============================================================================
4698 * Returns ID of nodes for given submesh
4699 * If param all==true - returns all nodes, else -
4700 * returns only nodes on shapes.
4702 //=============================================================================
4704 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4706 throw (SALOME::SALOME_Exception)
4708 SMESH::long_array_var aResult = new SMESH::long_array();
4712 _preMeshInfo->FullLoadFromFile();
4714 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4715 if(!SM) return aResult._retn();
4717 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4718 if(!SDSM) return aResult._retn();
4721 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4722 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4723 while ( nIt->more() ) {
4724 const SMDS_MeshNode* elem = nIt->next();
4725 theElems.insert( elem->GetID() );
4728 else { // all nodes of submesh elements
4729 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4730 while ( eIt->more() ) {
4731 const SMDS_MeshElement* anElem = eIt->next();
4732 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4733 while ( nIt->more() ) {
4734 const SMDS_MeshElement* elem = nIt->next();
4735 theElems.insert( elem->GetID() );
4740 aResult->length(theElems.size());
4741 set<int>::iterator itElem;
4743 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4744 aResult[i++] = *itElem;
4746 SMESH_CATCH( SMESH::throwCorbaException );
4748 return aResult._retn();
4751 //=============================================================================
4753 * Returns type of elements for given submesh
4755 //=============================================================================
4757 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4758 throw (SALOME::SALOME_Exception)
4760 SMESH::ElementType type = SMESH::ALL;
4764 _preMeshInfo->FullLoadFromFile();
4766 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4767 if(!SM) return SMESH::ALL;
4769 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4770 if(!SDSM) return SMESH::ALL;
4772 if(SDSM->NbElements()==0)
4773 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4775 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4776 const SMDS_MeshElement* anElem = eIt->next();
4778 type = ( SMESH::ElementType ) anElem->GetType();
4780 SMESH_CATCH( SMESH::throwCorbaException );
4786 //=============================================================================
4788 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4790 //=============================================================================
4792 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4795 _preMeshInfo->FullLoadFromFile();
4797 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4798 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4803 //=============================================================================
4805 * Get XYZ coordinates of node as list of double
4806 * If there is not node for given ID - returns empty list
4808 //=============================================================================
4810 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4813 _preMeshInfo->FullLoadFromFile();
4815 SMESH::double_array_var aResult = new SMESH::double_array();
4816 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4817 if ( aMeshDS == NULL )
4818 return aResult._retn();
4821 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4823 return aResult._retn();
4827 aResult[0] = aNode->X();
4828 aResult[1] = aNode->Y();
4829 aResult[2] = aNode->Z();
4830 return aResult._retn();
4834 //=============================================================================
4836 * For given node returns list of IDs of inverse elements
4837 * If there is not node for given ID - returns empty list
4839 //=============================================================================
4841 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4842 SMESH::ElementType elemType)
4845 _preMeshInfo->FullLoadFromFile();
4847 SMESH::long_array_var aResult = new SMESH::long_array();
4848 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4849 if ( aMeshDS == NULL )
4850 return aResult._retn();
4853 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4855 return aResult._retn();
4857 // find inverse elements
4858 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4859 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4860 aResult->length( aNode->NbInverseElements( type ));
4861 for( int i = 0; eIt->more(); ++i )
4863 const SMDS_MeshElement* elem = eIt->next();
4864 aResult[ i ] = elem->GetID();
4866 return aResult._retn();
4869 //=============================================================================
4871 * \brief Return position of a node on shape
4873 //=============================================================================
4875 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4878 _preMeshInfo->FullLoadFromFile();
4880 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4881 aNodePosition->shapeID = 0;
4882 aNodePosition->shapeType = GEOM::SHAPE;
4884 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4885 if ( !mesh ) return aNodePosition;
4887 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4889 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4891 aNodePosition->shapeID = aNode->getshapeId();
4892 switch ( pos->GetTypeOfPosition() ) {
4894 aNodePosition->shapeType = GEOM::EDGE;
4895 aNodePosition->params.length(1);
4896 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4898 case SMDS_TOP_FACE: {
4899 SMDS_FacePositionPtr fPos = pos;
4900 aNodePosition->shapeType = GEOM::FACE;
4901 aNodePosition->params.length(2);
4902 aNodePosition->params[0] = fPos->GetUParameter();
4903 aNodePosition->params[1] = fPos->GetVParameter();
4906 case SMDS_TOP_VERTEX:
4907 aNodePosition->shapeType = GEOM::VERTEX;
4909 case SMDS_TOP_3DSPACE:
4910 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4911 aNodePosition->shapeType = GEOM::SOLID;
4912 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4913 aNodePosition->shapeType = GEOM::SHELL;
4919 return aNodePosition;
4922 //=============================================================================
4924 * \brief Return position of an element on shape
4926 //=============================================================================
4928 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4931 _preMeshInfo->FullLoadFromFile();
4933 SMESH::ElementPosition anElementPosition;
4934 anElementPosition.shapeID = 0;
4935 anElementPosition.shapeType = GEOM::SHAPE;
4937 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4938 if ( !mesh ) return anElementPosition;
4940 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4942 anElementPosition.shapeID = anElem->getshapeId();
4943 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4944 if ( !aSp.IsNull() ) {
4945 switch ( aSp.ShapeType() ) {
4947 anElementPosition.shapeType = GEOM::EDGE;
4950 anElementPosition.shapeType = GEOM::FACE;
4953 anElementPosition.shapeType = GEOM::VERTEX;
4956 anElementPosition.shapeType = GEOM::SOLID;
4959 anElementPosition.shapeType = GEOM::SHELL;
4965 return anElementPosition;
4968 //=============================================================================
4970 * If given element is node returns IDs of shape from position
4971 * If there is not node for given ID - returns -1
4973 //=============================================================================
4975 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4978 _preMeshInfo->FullLoadFromFile();
4980 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4981 if ( aMeshDS == NULL )
4985 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4987 return aNode->getshapeId();
4994 //=============================================================================
4996 * For given element returns ID of result shape after
4997 * ::FindShape() from SMESH_MeshEditor
4998 * If there is not element for given ID - returns -1
5000 //=============================================================================
5002 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5005 _preMeshInfo->FullLoadFromFile();
5007 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5008 if ( aMeshDS == NULL )
5011 // try to find element
5012 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5016 ::SMESH_MeshEditor aMeshEditor(_impl);
5017 int index = aMeshEditor.FindShape( elem );
5025 //=============================================================================
5027 * Returns number of nodes for given element
5028 * If there is not element for given ID - returns -1
5030 //=============================================================================
5032 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5035 _preMeshInfo->FullLoadFromFile();
5037 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5038 if ( aMeshDS == NULL ) return -1;
5039 // try to find element
5040 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5041 if(!elem) return -1;
5042 return elem->NbNodes();
5046 //=============================================================================
5048 * Returns ID of node by given index for given element
5049 * If there is not element for given ID - returns -1
5050 * If there is not node for given index - returns -2
5052 //=============================================================================
5054 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5057 _preMeshInfo->FullLoadFromFile();
5059 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5060 if ( aMeshDS == NULL ) return -1;
5061 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5062 if(!elem) return -1;
5063 if( index>=elem->NbNodes() || index<0 ) return -1;
5064 return elem->GetNode(index)->GetID();
5067 //=============================================================================
5069 * Returns IDs of nodes of given element
5071 //=============================================================================
5073 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5076 _preMeshInfo->FullLoadFromFile();
5078 SMESH::long_array_var aResult = new SMESH::long_array();
5079 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5081 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5083 aResult->length( elem->NbNodes() );
5084 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5085 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5086 aResult[ i ] = n->GetID();
5089 return aResult._retn();
5092 //=============================================================================
5094 * Returns true if given node is medium node
5095 * in given quadratic element
5097 //=============================================================================
5099 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5102 _preMeshInfo->FullLoadFromFile();
5104 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5105 if ( aMeshDS == NULL ) return false;
5107 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5108 if(!aNode) return false;
5109 // try to find element
5110 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5111 if(!elem) return false;
5113 return elem->IsMediumNode(aNode);
5117 //=============================================================================
5119 * Returns true if given node is medium node
5120 * in one of quadratic elements
5122 //=============================================================================
5124 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5125 SMESH::ElementType theElemType)
5128 _preMeshInfo->FullLoadFromFile();
5130 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5131 if ( aMeshDS == NULL ) return false;
5134 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5135 if(!aNode) return false;
5137 SMESH_MesherHelper aHelper( *(_impl) );
5139 SMDSAbs_ElementType aType;
5140 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5141 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5142 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5143 else aType = SMDSAbs_All;
5145 return aHelper.IsMedium(aNode,aType);
5149 //=============================================================================
5151 * Returns number of edges for given element
5153 //=============================================================================
5155 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5158 _preMeshInfo->FullLoadFromFile();
5160 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5161 if ( aMeshDS == NULL ) return -1;
5162 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5163 if(!elem) return -1;
5164 return elem->NbEdges();
5168 //=============================================================================
5170 * Returns number of faces for given element
5172 //=============================================================================
5174 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5177 _preMeshInfo->FullLoadFromFile();
5179 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5180 if ( aMeshDS == NULL ) return -1;
5181 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5182 if(!elem) return -1;
5183 return elem->NbFaces();
5186 //=======================================================================
5187 //function : GetElemFaceNodes
5188 //purpose : Returns nodes of given face (counted from zero) for given element.
5189 //=======================================================================
5191 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5192 CORBA::Short faceIndex)
5195 _preMeshInfo->FullLoadFromFile();
5197 SMESH::long_array_var aResult = new SMESH::long_array();
5198 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5200 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5202 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5203 if ( faceIndex < vtool.NbFaces() )
5205 aResult->length( vtool.NbFaceNodes( faceIndex ));
5206 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5207 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5208 aResult[ i ] = nn[ i ]->GetID();
5212 return aResult._retn();
5215 //=======================================================================
5216 //function : GetFaceNormal
5217 //purpose : Returns three components of normal of given mesh face.
5218 //=======================================================================
5220 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5221 CORBA::Boolean normalized)
5224 _preMeshInfo->FullLoadFromFile();
5226 SMESH::double_array_var aResult = new SMESH::double_array();
5228 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5231 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5233 aResult->length( 3 );
5234 aResult[ 0 ] = normal.X();
5235 aResult[ 1 ] = normal.Y();
5236 aResult[ 2 ] = normal.Z();
5239 return aResult._retn();
5242 //=======================================================================
5243 //function : FindElementByNodes
5244 //purpose : Returns an element based on all given nodes.
5245 //=======================================================================
5247 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5250 _preMeshInfo->FullLoadFromFile();
5252 CORBA::Long elemID(0);
5253 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5255 vector< const SMDS_MeshNode * > nn( nodes.length() );
5256 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5257 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5260 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5261 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5262 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5263 _impl->NbVolumes( ORDER_QUADRATIC )))
5264 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5266 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5271 //================================================================================
5273 * \brief Return elements including all given nodes.
5275 //================================================================================
5277 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5278 SMESH::ElementType elemType)
5281 _preMeshInfo->FullLoadFromFile();
5283 SMESH::long_array_var result = new SMESH::long_array();
5285 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5287 vector< const SMDS_MeshNode * > nn( nodes.length() );
5288 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5289 nn[i] = mesh->FindNode( nodes[i] );
5291 std::vector<const SMDS_MeshElement *> elems;
5292 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5293 result->length( elems.size() );
5294 for ( size_t i = 0; i < elems.size(); ++i )
5295 result[i] = elems[i]->GetID();
5297 return result._retn();
5300 //=============================================================================
5302 * Returns true if given element is polygon
5304 //=============================================================================
5306 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5309 _preMeshInfo->FullLoadFromFile();
5311 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5312 if ( aMeshDS == NULL ) return false;
5313 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5314 if(!elem) return false;
5315 return elem->IsPoly();
5319 //=============================================================================
5321 * Returns true if given element is quadratic
5323 //=============================================================================
5325 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5328 _preMeshInfo->FullLoadFromFile();
5330 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5331 if ( aMeshDS == NULL ) return false;
5332 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5333 if(!elem) return false;
5334 return elem->IsQuadratic();
5337 //=============================================================================
5339 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5341 //=============================================================================
5343 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5346 _preMeshInfo->FullLoadFromFile();
5348 if ( const SMDS_BallElement* ball =
5349 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5350 return ball->GetDiameter();
5355 //=============================================================================
5357 * Returns bary center for given element
5359 //=============================================================================
5361 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5364 _preMeshInfo->FullLoadFromFile();
5366 SMESH::double_array_var aResult = new SMESH::double_array();
5367 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5368 if ( aMeshDS == NULL )
5369 return aResult._retn();
5371 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5373 return aResult._retn();
5375 if(elem->GetType()==SMDSAbs_Volume) {
5376 SMDS_VolumeTool aTool;
5377 if(aTool.Set(elem)) {
5379 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5384 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5386 double x=0., y=0., z=0.;
5387 for(; anIt->more(); ) {
5389 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5403 return aResult._retn();
5406 //================================================================================
5408 * \brief Create a group of elements preventing computation of a sub-shape
5410 //================================================================================
5412 SMESH::ListOfGroups*
5413 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5414 const char* theGroupName )
5415 throw ( SALOME::SALOME_Exception )
5417 Unexpect aCatch(SALOME_SalomeException);
5419 if ( !theGroupName || strlen( theGroupName) == 0 )
5420 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5422 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5423 ::SMESH_MeshEditor::ElemFeatures elemType;
5425 // submesh by subshape id
5426 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5427 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5430 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5431 if ( error && error->HasBadElems() )
5433 // sort bad elements by type
5434 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5435 const list<const SMDS_MeshElement*>& badElems =
5436 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5437 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5438 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5439 for ( ; elemIt != elemEnd; ++elemIt )
5441 const SMDS_MeshElement* elem = *elemIt;
5442 if ( !elem ) continue;
5444 if ( elem->GetID() < 1 )
5446 // elem is a temporary element, make a real element
5447 vector< const SMDS_MeshNode* > nodes;
5448 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5449 while ( nIt->more() && elem )
5451 nodes.push_back( nIt->next() );
5452 if ( nodes.back()->GetID() < 1 )
5453 elem = 0; // a temporary element on temporary nodes
5457 ::SMESH_MeshEditor editor( _impl );
5458 elem = editor.AddElement( nodes, elemType.Init( elem ));
5462 elemsByType[ elem->GetType() ].push_back( elem );
5465 // how many groups to create?
5467 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5468 nbTypes += int( !elemsByType[ i ].empty() );
5469 groups->length( nbTypes );
5472 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5474 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5475 if ( elems.empty() ) continue;
5477 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5478 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5480 SMESH::SMESH_Mesh_var mesh = _this();
5481 SALOMEDS::SObject_wrap aSO =
5482 _gen_i->PublishGroup( mesh, groups[ iG ],
5483 GEOM::GEOM_Object::_nil(), theGroupName);
5485 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5486 if ( !grp_i ) continue;
5488 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5489 for ( size_t iE = 0; iE < elems.size(); ++iE )
5490 grpDS->SMDSGroup().Add( elems[ iE ]);
5495 return groups._retn();
5498 //=============================================================================
5500 * Create and publish group servants if any groups were imported or created anyhow
5502 //=============================================================================
5504 void SMESH_Mesh_i::CreateGroupServants()
5506 SMESH::SMESH_Mesh_var aMesh = _this();
5509 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5510 while ( groupIt->more() )
5512 ::SMESH_Group* group = groupIt->next();
5513 int anId = group->GetID();
5515 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5516 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5518 addedIDs.insert( anId );
5520 SMESH_GroupBase_i* aGroupImpl;
5522 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5523 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5525 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5526 shape = groupOnGeom->GetShape();
5529 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5532 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5533 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5534 aGroupImpl->Register();
5536 // register CORBA object for persistence
5537 int nextId = _gen_i->RegisterObject( groupVar );
5538 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5539 else { nextId = 0; } // avoid "unused variable" warning in release mode
5541 // publishing the groups in the study
5542 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5543 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5545 if ( !addedIDs.empty() )
5548 set<int>::iterator id = addedIDs.begin();
5549 for ( ; id != addedIDs.end(); ++id )
5551 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5552 int i = std::distance( _mapGroups.begin(), it );
5553 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5558 //=============================================================================
5560 * \brief Return true if all sub-meshes are computed OK - to update an icon
5562 //=============================================================================
5564 bool SMESH_Mesh_i::IsComputedOK()
5566 return _impl->IsComputedOK();
5569 //=============================================================================
5571 * \brief Return groups cantained in _mapGroups by their IDs
5573 //=============================================================================
5575 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5577 int nbGroups = groupIDs.size();
5578 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5579 aList->length( nbGroups );
5581 list<int>::const_iterator ids = groupIDs.begin();
5582 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5584 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5585 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5586 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5588 aList->length( nbGroups );
5589 return aList._retn();
5592 //=============================================================================
5594 * \brief Return information about imported file
5596 //=============================================================================
5598 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5600 SMESH::MedFileInfo_var res( _medFileInfo );
5601 if ( !res.operator->() ) {
5602 res = new SMESH::MedFileInfo;
5604 res->fileSize = res->major = res->minor = res->release = -1;
5609 //=======================================================================
5610 //function : FileInfoToString
5611 //purpose : Persistence of file info
5612 //=======================================================================
5614 std::string SMESH_Mesh_i::FileInfoToString()
5617 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5619 s = SMESH_Comment( _medFileInfo->fileSize )
5620 << " " << _medFileInfo->major
5621 << " " << _medFileInfo->minor
5622 << " " << _medFileInfo->release
5623 << " " << _medFileInfo->fileName;
5628 //=======================================================================
5629 //function : FileInfoFromString
5630 //purpose : Persistence of file info
5631 //=======================================================================
5633 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5635 std::string size, major, minor, release, fileName;
5636 std::istringstream is(info);
5637 is >> size >> major >> minor >> release;
5638 fileName = info.data() + ( size.size() + 1 +
5641 release.size()+ 1 );
5643 _medFileInfo = new SMESH::MedFileInfo();
5644 _medFileInfo->fileName = fileName.c_str();
5645 _medFileInfo->fileSize = atoi( size.c_str() );
5646 _medFileInfo->major = atoi( major.c_str() );
5647 _medFileInfo->minor = atoi( minor.c_str() );
5648 _medFileInfo->release = atoi( release.c_str() );
5651 //=============================================================================
5653 * \brief Pass names of mesh groups from study to mesh DS
5655 //=============================================================================
5657 void SMESH_Mesh_i::checkGroupNames()
5659 int nbGrp = NbGroups();
5663 SMESH::ListOfGroups* grpList = 0;
5664 // avoid dump of "GetGroups"
5666 // store python dump into a local variable inside local scope
5667 SMESH::TPythonDump pDump; // do not delete this line of code
5668 grpList = GetGroups();
5671 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5672 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5675 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5676 if ( aGrpSO->_is_nil() )
5678 // correct name of the mesh group if necessary
5679 const char* guiName = aGrpSO->GetName();
5680 if ( strcmp(guiName, aGrp->GetName()) )
5681 aGrp->SetName( guiName );
5685 //=============================================================================
5687 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5689 //=============================================================================
5690 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5692 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5696 //=============================================================================
5698 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5700 //=============================================================================
5702 char* SMESH_Mesh_i::GetParameters()
5704 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5707 //=============================================================================
5709 * \brief Returns list of notebook variables used for last Mesh operation
5711 //=============================================================================
5712 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5714 SMESH::string_array_var aResult = new SMESH::string_array();
5715 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5717 CORBA::String_var aParameters = GetParameters();
5718 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5719 if ( aSections->length() > 0 ) {
5720 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5721 aResult->length( aVars.length() );
5722 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5723 aResult[i] = CORBA::string_dup( aVars[i] );
5726 return aResult._retn();
5729 //=======================================================================
5730 //function : GetTypes
5731 //purpose : Returns types of elements it contains
5732 //=======================================================================
5734 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5737 return _preMeshInfo->GetTypes();
5739 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5743 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5744 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5745 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5746 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5747 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5748 if (_impl->NbNodes() &&
5749 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5750 types->length( nbTypes );
5752 return types._retn();
5755 //=======================================================================
5756 //function : GetMesh
5757 //purpose : Returns self
5758 //=======================================================================
5760 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5762 return SMESH::SMESH_Mesh::_duplicate( _this() );
5765 //=======================================================================
5766 //function : IsMeshInfoCorrect
5767 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5768 // * happen if mesh data is not yet fully loaded from the file of study.
5769 //=======================================================================
5771 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5773 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5776 //=============================================================================
5778 * \brief Returns number of mesh elements per each \a EntityType
5780 //=============================================================================
5782 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5785 return _preMeshInfo->GetMeshInfo();
5787 SMESH::long_array_var aRes = new SMESH::long_array();
5788 aRes->length(SMESH::Entity_Last);
5789 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5791 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5793 return aRes._retn();
5794 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5795 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5796 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5797 return aRes._retn();
5800 //=============================================================================
5802 * \brief Returns number of mesh elements per each \a ElementType
5804 //=============================================================================
5806 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5808 SMESH::long_array_var aRes = new SMESH::long_array();
5809 aRes->length(SMESH::NB_ELEMENT_TYPES);
5810 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5813 const SMDS_MeshInfo* meshInfo = 0;
5815 meshInfo = _preMeshInfo;
5816 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5817 meshInfo = & meshDS->GetMeshInfo();
5820 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5821 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5823 return aRes._retn();
5826 //=============================================================================
5828 * Collect statistic of mesh elements given by iterator
5830 //=============================================================================
5832 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5833 SMESH::long_array& theInfo)
5835 if (!theItr) return;
5836 while (theItr->more())
5837 theInfo[ theItr->next()->GetEntityType() ]++;
5839 //=============================================================================
5841 * Returns mesh unstructed grid information.
5843 //=============================================================================
5845 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5847 SALOMEDS::TMPFile_var SeqFile;
5848 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5849 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5851 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5852 aWriter->WriteToOutputStringOn();
5853 aWriter->SetInputData(aGrid);
5854 aWriter->SetFileTypeToBinary();
5856 char* str = aWriter->GetOutputString();
5857 int size = aWriter->GetOutputStringLength();
5859 //Allocate octet buffer of required size
5860 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5861 //Copy ostrstream content to the octet buffer
5862 memcpy(OctetBuf, str, size);
5863 //Create and return TMPFile
5864 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5868 return SeqFile._retn();
5871 //=============================================================================
5872 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5873 * SMESH::ElementType type) */
5875 using namespace SMESH::Controls;
5876 //-----------------------------------------------------------------------------
5877 struct PredicateIterator : public SMDS_ElemIterator
5879 SMDS_ElemIteratorPtr _elemIter;
5880 PredicatePtr _predicate;
5881 const SMDS_MeshElement* _elem;
5882 SMDSAbs_ElementType _type;
5884 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5885 PredicatePtr predicate,
5886 SMDSAbs_ElementType type):
5887 _elemIter(iterator), _predicate(predicate), _type(type)
5895 virtual const SMDS_MeshElement* next()
5897 const SMDS_MeshElement* res = _elem;
5899 while ( _elemIter->more() && !_elem )
5901 if ((_elem = _elemIter->next()) &&
5902 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5903 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5910 //-----------------------------------------------------------------------------
5911 struct IDSourceIterator : public SMDS_ElemIterator
5913 const CORBA::Long* _idPtr;
5914 const CORBA::Long* _idEndPtr;
5915 SMESH::long_array_var _idArray;
5916 const SMDS_Mesh* _mesh;
5917 const SMDSAbs_ElementType _type;
5918 const SMDS_MeshElement* _elem;
5920 IDSourceIterator( const SMDS_Mesh* mesh,
5921 const CORBA::Long* ids,
5923 SMDSAbs_ElementType type):
5924 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5926 if ( _idPtr && nbIds && _mesh )
5929 IDSourceIterator( const SMDS_Mesh* mesh,
5930 SMESH::long_array* idArray,
5931 SMDSAbs_ElementType type):
5932 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5934 if ( idArray && _mesh )
5936 _idPtr = &_idArray[0];
5937 _idEndPtr = _idPtr + _idArray->length();
5945 virtual const SMDS_MeshElement* next()
5947 const SMDS_MeshElement* res = _elem;
5949 while ( _idPtr < _idEndPtr && !_elem )
5951 if ( _type == SMDSAbs_Node )
5953 _elem = _mesh->FindNode( *_idPtr++ );
5955 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5956 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5964 //-----------------------------------------------------------------------------
5966 struct NodeOfElemIterator : public SMDS_ElemIterator
5968 TColStd_MapOfInteger _checkedNodeIDs;
5969 SMDS_ElemIteratorPtr _elemIter;
5970 SMDS_ElemIteratorPtr _nodeIter;
5971 const SMDS_MeshElement* _node;
5973 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5975 if ( _elemIter && _elemIter->more() )
5977 _nodeIter = _elemIter->next()->nodesIterator();
5985 virtual const SMDS_MeshElement* next()
5987 const SMDS_MeshElement* res = _node;
5989 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5991 if ( _nodeIter->more() )
5993 _node = _nodeIter->next();
5994 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5999 _nodeIter = _elemIter->next()->nodesIterator();
6007 //=============================================================================
6009 * Return iterator on elements of given type in given object
6011 //=============================================================================
6013 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6014 SMESH::ElementType theType)
6016 SMDS_ElemIteratorPtr elemIt;
6017 bool typeOK = ( theType == SMESH::ALL );
6018 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6020 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6021 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6022 if ( !mesh_i ) return elemIt;
6023 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6025 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6027 elemIt = meshDS->elementsIterator( elemType );
6030 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6032 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6035 elemIt = sm->GetElements();
6036 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6038 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6039 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6043 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6045 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6046 if ( groupDS && ( elemType == groupDS->GetType() ||
6047 elemType == SMDSAbs_Node ||
6048 elemType == SMDSAbs_All ))
6050 elemIt = groupDS->GetElements();
6051 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6054 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6056 if ( filter_i->GetElementType() == theType ||
6057 filter_i->GetElementType() == SMESH::ALL ||
6058 elemType == SMDSAbs_Node ||
6059 elemType == SMDSAbs_All)
6061 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6062 if ( pred_i && pred_i->GetPredicate() )
6064 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6065 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6066 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6067 elemIt = SMDS_ElemIteratorPtr
6068 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6069 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6075 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6076 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6077 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6079 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6080 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6083 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6084 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6088 SMESH::long_array_var ids = theObject->GetIDs();
6089 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6091 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6094 if ( elemIt && elemIt->more() && !typeOK )
6096 if ( elemType == SMDSAbs_Node )
6098 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6102 elemIt = SMDS_ElemIteratorPtr();
6108 //=============================================================================
6109 namespace // Finding concurrent hypotheses
6110 //=============================================================================
6114 * \brief mapping of mesh dimension into shape type
6116 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6118 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6120 case 0: aType = TopAbs_VERTEX; break;
6121 case 1: aType = TopAbs_EDGE; break;
6122 case 2: aType = TopAbs_FACE; break;
6124 default:aType = TopAbs_SOLID; break;
6129 //-----------------------------------------------------------------------------
6131 * \brief Internal structure used to find concurrent submeshes
6133 * It represents a pair < submesh, concurrent dimension >, where
6134 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6135 * with another submesh. In other words, it is dimension of a hypothesis assigned
6142 int _dim; //!< a dimension the algo can build (concurrent dimension)
6143 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6144 TopTools_MapOfShape _shapeMap;
6145 SMESH_subMesh* _subMesh;
6146 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6148 //-----------------------------------------------------------------------------
6149 // Return the algorithm
6150 const SMESH_Algo* GetAlgo() const
6151 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6153 //-----------------------------------------------------------------------------
6155 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6157 const TopoDS_Shape& theShape)
6159 _subMesh = (SMESH_subMesh*)theSubMesh;
6160 SetShape( theDim, theShape );
6163 //-----------------------------------------------------------------------------
6165 void SetShape(const int theDim,
6166 const TopoDS_Shape& theShape)
6169 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6170 if (_dim >= _ownDim)
6171 _shapeMap.Add( theShape );
6173 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6174 for( ; anExp.More(); anExp.Next() )
6175 _shapeMap.Add( anExp.Current() );
6179 //-----------------------------------------------------------------------------
6180 //! Check sharing of sub-shapes
6181 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6182 const TopTools_MapOfShape& theToFind,
6183 const TopAbs_ShapeEnum theType)
6185 bool isShared = false;
6186 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6187 for (; !isShared && anItr.More(); anItr.Next() )
6189 const TopoDS_Shape aSubSh = anItr.Key();
6190 // check for case when concurrent dimensions are same
6191 isShared = theToFind.Contains( aSubSh );
6192 // check for sub-shape with concurrent dimension
6193 TopExp_Explorer anExp( aSubSh, theType );
6194 for ( ; !isShared && anExp.More(); anExp.Next() )
6195 isShared = theToFind.Contains( anExp.Current() );
6200 //-----------------------------------------------------------------------------
6201 //! check algorithms
6202 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6203 const SMESHDS_Hypothesis* theA2)
6205 if ( !theA1 || !theA2 ||
6206 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6207 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6208 return false; // one of the hypothesis is not algorithm
6209 // check algorithm names (should be equal)
6210 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6214 //-----------------------------------------------------------------------------
6215 //! Check if sub-shape hypotheses are concurrent
6216 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6218 if ( _subMesh == theOther->_subMesh )
6219 return false; // same sub-shape - should not be
6221 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6222 // any of the two submeshes is not on COMPOUND shape )
6223 // -> no concurrency
6224 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6225 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6226 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6227 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6228 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6231 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6232 if ( !checkSubShape )
6235 // check algorithms to be same
6236 const SMESH_Algo* a1 = this->GetAlgo();
6237 const SMESH_Algo* a2 = theOther->GetAlgo();
6238 bool isSame = checkAlgo( a1, a2 );
6242 return false; // pb?
6243 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6246 // check hypothesises for concurrence (skip first as algorithm)
6248 // pointers should be same, because it is referened from mesh hypothesis partition
6249 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6250 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6251 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6252 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6254 // the submeshes are concurrent if their algorithms has different parameters
6255 return nbSame != theOther->_hypotheses.size() - 1;
6258 // Return true if algorithm of this SMESH_DimHyp is used if no
6259 // sub-mesh order is imposed by the user
6260 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6262 // NeedDiscreteBoundary() algo has a higher priority
6263 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6264 theOther->GetAlgo()->NeedDiscreteBoundary() )
6265 return !this->GetAlgo()->NeedDiscreteBoundary();
6267 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6270 }; // end of SMESH_DimHyp
6271 //-----------------------------------------------------------------------------
6273 typedef list<const SMESH_DimHyp*> TDimHypList;
6275 //-----------------------------------------------------------------------------
6277 void addDimHypInstance(const int theDim,
6278 const TopoDS_Shape& theShape,
6279 const SMESH_Algo* theAlgo,
6280 const SMESH_subMesh* theSubMesh,
6281 const list <const SMESHDS_Hypothesis*>& theHypList,
6282 TDimHypList* theDimHypListArr )
6284 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6285 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6286 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6287 dimHyp->_hypotheses.push_front(theAlgo);
6288 listOfdimHyp.push_back( dimHyp );
6291 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6292 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6293 theHypList.begin(), theHypList.end() );
6296 //-----------------------------------------------------------------------------
6297 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6298 TDimHypList& theListOfConcurr)
6300 if ( theListOfConcurr.empty() )
6302 theListOfConcurr.push_back( theDimHyp );
6306 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6307 while ( hypIt != theListOfConcurr.end() &&
6308 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6310 theListOfConcurr.insert( hypIt, theDimHyp );
6314 //-----------------------------------------------------------------------------
6315 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6316 const TDimHypList& theListOfDimHyp,
6317 TDimHypList& theListOfConcurrHyp,
6318 set<int>& theSetOfConcurrId )
6320 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6321 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6323 const SMESH_DimHyp* curDimHyp = *rIt;
6324 if ( curDimHyp == theDimHyp )
6325 break; // meet own dimHyp pointer in same dimension
6327 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6328 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6330 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6335 //-----------------------------------------------------------------------------
6336 void unionLists(TListOfInt& theListOfId,
6337 TListOfListOfInt& theListOfListOfId,
6340 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6341 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6343 continue; //skip already treated lists
6344 // check if other list has any same submesh object
6345 TListOfInt& otherListOfId = *it;
6346 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6347 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6350 // union two lists (from source into target)
6351 TListOfInt::iterator it2 = otherListOfId.begin();
6352 for ( ; it2 != otherListOfId.end(); it2++ ) {
6353 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6354 theListOfId.push_back(*it2);
6356 // clear source list
6357 otherListOfId.clear();
6360 //-----------------------------------------------------------------------------
6362 //! free memory allocated for dimension-hypothesis objects
6363 void removeDimHyps( TDimHypList* theArrOfList )
6365 for (int i = 0; i < 4; i++ ) {
6366 TDimHypList& listOfdimHyp = theArrOfList[i];
6367 TDimHypList::const_iterator it = listOfdimHyp.begin();
6368 for ( ; it != listOfdimHyp.end(); it++ )
6373 //-----------------------------------------------------------------------------
6375 * \brief find common submeshes with given submesh
6376 * \param theSubMeshList list of already collected submesh to check
6377 * \param theSubMesh given submesh to intersect with other
6378 * \param theCommonSubMeshes collected common submeshes
6380 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6381 const SMESH_subMesh* theSubMesh,
6382 set<const SMESH_subMesh*>& theCommon )
6386 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6387 for ( ; it != theSubMeshList.end(); it++ )
6388 theSubMesh->FindIntersection( *it, theCommon );
6389 theSubMeshList.push_back( theSubMesh );
6390 //theCommon.insert( theSubMesh );
6393 //-----------------------------------------------------------------------------
6394 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6396 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6397 for ( ; listsIt != smLists.end(); ++listsIt )
6399 const TListOfInt& smIDs = *listsIt;
6400 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6408 //=============================================================================
6410 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6412 //=============================================================================
6414 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6416 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6417 if ( isSubMeshInList( submeshID, anOrder ))
6420 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6421 return isSubMeshInList( submeshID, allConurrent );
6424 //=============================================================================
6426 * \brief Return submesh objects list in meshing order
6428 //=============================================================================
6430 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6432 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6434 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6436 return aResult._retn();
6438 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6439 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6440 anOrder.splice( anOrder.end(), allConurrent );
6443 TListOfListOfInt::iterator listIt = anOrder.begin();
6444 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6445 unionLists( *listIt, anOrder, listIndx + 1 );
6447 // convert submesh ids into interface instances
6448 // and dump command into python
6449 convertMeshOrder( anOrder, aResult, false );
6451 return aResult._retn();
6454 //=============================================================================
6456 * \brief Finds concurrent sub-meshes
6458 //=============================================================================
6460 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6462 TListOfListOfInt anOrder;
6463 ::SMESH_Mesh& mesh = GetImpl();
6465 // collect submeshes and detect concurrent algorithms and hypothesises
6466 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6468 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6469 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6470 ::SMESH_subMesh* sm = (*i_sm).second;
6472 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6474 // list of assigned hypothesises
6475 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6476 // Find out dimensions where the submesh can be concurrent.
6477 // We define the dimensions by algo of each of hypotheses in hypList
6478 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6479 for( ; hypIt != hypList.end(); hypIt++ ) {
6480 SMESH_Algo* anAlgo = 0;
6481 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6482 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6483 // hyp it-self is algo
6484 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6486 // try to find algorithm with help of sub-shapes
6487 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6488 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6489 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6492 continue; // no algorithm assigned to a current submesh
6494 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6495 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6497 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6498 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6499 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6501 } // end iterations on submesh
6503 // iterate on created dimension-hypotheses and check for concurrents
6504 for ( int i = 0; i < 4; i++ ) {
6505 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6506 // check for concurrents in own and other dimensions (step-by-step)
6507 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6508 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6509 const SMESH_DimHyp* dimHyp = *dhIt;
6510 TDimHypList listOfConcurr;
6511 set<int> setOfConcurrIds;
6512 // looking for concurrents and collect into own list
6513 for ( int j = i; j < 4; j++ )
6514 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6515 // check if any concurrents found
6516 if ( listOfConcurr.size() > 0 ) {
6517 // add own submesh to list of concurrent
6518 addInOrderOfPriority( dimHyp, listOfConcurr );
6519 list<int> listOfConcurrIds;
6520 TDimHypList::iterator hypIt = listOfConcurr.begin();
6521 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6522 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6523 anOrder.push_back( listOfConcurrIds );
6528 removeDimHyps(dimHypListArr);
6530 // now, minimize the number of concurrent groups
6531 // Here we assume that lists of submeshes can have same submesh
6532 // in case of multi-dimension algorithms, as result
6533 // list with common submesh has to be united into one list
6535 TListOfListOfInt::iterator listIt = anOrder.begin();
6536 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6537 unionLists( *listIt, anOrder, listIndx + 1 );
6543 //=============================================================================
6545 * \brief Set submesh object order
6546 * \param theSubMeshArray submesh array order
6548 //=============================================================================
6550 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6553 _preMeshInfo->ForgetOrLoad();
6556 ::SMESH_Mesh& mesh = GetImpl();
6558 TPythonDump aPythonDump; // prevent dump of called methods
6559 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6561 TListOfListOfInt subMeshOrder;
6562 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6564 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6565 TListOfInt subMeshIds;
6567 aPythonDump << ", ";
6568 aPythonDump << "[ ";
6569 // Collect subMeshes which should be clear
6570 // do it list-by-list, because modification of submesh order
6571 // take effect between concurrent submeshes only
6572 set<const SMESH_subMesh*> subMeshToClear;
6573 list<const SMESH_subMesh*> subMeshList;
6574 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6576 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6578 aPythonDump << ", ";
6579 aPythonDump << subMesh;
6580 subMeshIds.push_back( subMesh->GetId() );
6581 // detect common parts of submeshes
6582 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6583 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6585 aPythonDump << " ]";
6586 subMeshOrder.push_back( subMeshIds );
6588 // clear collected sub-meshes
6589 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6590 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6591 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6593 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6594 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6595 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6598 aPythonDump << " ])";
6600 mesh.SetMeshOrder( subMeshOrder );
6603 SMESH::SMESH_Mesh_var me = _this();
6604 _gen_i->UpdateIcons( me );
6609 //=============================================================================
6611 * \brief Convert submesh ids into submesh interfaces
6613 //=============================================================================
6615 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6616 SMESH::submesh_array_array& theResOrder,
6617 const bool theIsDump)
6619 int nbSet = theIdsOrder.size();
6620 TPythonDump aPythonDump; // prevent dump of called methods
6622 aPythonDump << "[ ";
6623 theResOrder.length(nbSet);
6624 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6626 for( ; it != theIdsOrder.end(); it++ ) {
6627 // translate submesh identificators into submesh objects
6628 // takeing into account real number of concurrent lists
6629 const TListOfInt& aSubOrder = (*it);
6630 if (!aSubOrder.size())
6633 aPythonDump << "[ ";
6634 // convert shape indices into interfaces
6635 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6636 aResSubSet->length(aSubOrder.size());
6637 TListOfInt::const_iterator subIt = aSubOrder.begin();
6639 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6640 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6642 SMESH::SMESH_subMesh_var subMesh =
6643 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6646 aPythonDump << ", ";
6647 aPythonDump << subMesh;
6649 aResSubSet[ j++ ] = subMesh;
6652 aPythonDump << " ]";
6654 theResOrder[ listIndx++ ] = aResSubSet;
6656 // correct number of lists
6657 theResOrder.length( listIndx );
6660 // finilise python dump
6661 aPythonDump << " ]";
6662 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6666 namespace // utils used by SMESH_MeshPartDS
6669 * \brief Class used to access to protected data of SMDS_MeshInfo
6671 struct TMeshInfo : public SMDS_MeshInfo
6673 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6676 * \brief Element holing its ID only
6678 struct TElemID : public SMDS_LinearEdge
6680 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6684 //================================================================================
6686 // Implementation of SMESH_MeshPartDS
6688 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6689 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6691 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6692 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6695 _meshDS = mesh_i->GetImpl().GetMeshDS();
6697 SetPersistentId( _meshDS->GetPersistentId() );
6699 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6701 // <meshPart> is the whole mesh
6702 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6704 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6705 myGroupSet = _meshDS->GetGroups();
6710 SMESH::long_array_var anIDs = meshPart->GetIDs();
6711 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6712 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6714 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6715 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6716 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6721 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6722 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6723 if ( _elements[ e->GetType() ].insert( e ).second )
6726 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6727 while ( nIt->more() )
6729 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6730 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6737 ShapeToMesh( _meshDS->ShapeToMesh() );
6739 _meshDS = 0; // to enforce iteration on _elements and _nodes
6742 // -------------------------------------------------------------------------------------
6743 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6744 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6747 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6748 for ( ; partIt != meshPart.end(); ++partIt )
6749 if ( const SMDS_MeshElement * e = *partIt )
6750 if ( _elements[ e->GetType() ].insert( e ).second )
6753 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6754 while ( nIt->more() )
6756 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6757 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6763 // -------------------------------------------------------------------------------------
6764 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6766 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6768 TElemID elem( IDelem );
6769 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6770 if ( !_elements[ iType ].empty() )
6772 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6773 if ( it != _elements[ iType ].end() )
6778 // -------------------------------------------------------------------------------------
6779 bool SMESH_MeshPartDS::HasNumerationHoles()
6781 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6783 return ( MinNodeID() != 1 ||
6784 MaxNodeID() != NbNodes() ||
6785 MinElementID() != 1 ||
6786 MaxElementID() != NbElements() );
6788 // -------------------------------------------------------------------------------------
6789 int SMESH_MeshPartDS::MaxNodeID() const
6791 if ( _meshDS ) return _meshDS->MaxNodeID();
6792 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6794 // -------------------------------------------------------------------------------------
6795 int SMESH_MeshPartDS::MinNodeID() const
6797 if ( _meshDS ) return _meshDS->MinNodeID();
6798 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6800 // -------------------------------------------------------------------------------------
6801 int SMESH_MeshPartDS::MaxElementID() const
6803 if ( _meshDS ) return _meshDS->MaxElementID();
6805 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6806 if ( !_elements[ iType ].empty() )
6807 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6810 // -------------------------------------------------------------------------------------
6811 int SMESH_MeshPartDS::MinElementID() const
6813 if ( _meshDS ) return _meshDS->MinElementID();
6815 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6816 if ( !_elements[ iType ].empty() )
6817 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6820 // -------------------------------------------------------------------------------------
6821 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6823 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6825 typedef SMDS_SetIterator
6826 <const SMDS_MeshElement*,
6827 TIDSortedElemSet::const_iterator,
6828 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6829 SMDS_MeshElement::GeomFilter
6832 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6834 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6835 _elements[type].end(),
6836 SMDS_MeshElement::GeomFilter( geomType )));
6838 // -------------------------------------------------------------------------------------
6839 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6841 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6843 typedef SMDS_SetIterator
6844 <const SMDS_MeshElement*,
6845 TIDSortedElemSet::const_iterator,
6846 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6847 SMDS_MeshElement::EntityFilter
6850 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6852 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6853 _elements[type].end(),
6854 SMDS_MeshElement::EntityFilter( entity )));
6856 // -------------------------------------------------------------------------------------
6857 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6859 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6860 if ( type == SMDSAbs_All && !_meshDS )
6862 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6864 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6865 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6867 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6869 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6870 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6872 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6873 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6875 // -------------------------------------------------------------------------------------
6876 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6877 iterType SMESH_MeshPartDS::methName() const \
6879 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6880 return _meshDS ? _meshDS->methName() : iterType \
6881 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6883 // -------------------------------------------------------------------------------------
6884 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6885 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6886 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6887 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6888 #undef _GET_ITER_DEFINE
6890 // END Implementation of SMESH_MeshPartDS
6892 //================================================================================