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_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
101 int SMESH_Mesh_i::_idGenerator = 0;
103 //=============================================================================
107 //=============================================================================
109 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
111 : SALOME::GenericObj_i( thePOA )
115 _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 Return false if the mesh is not yet fully loaded from the study file
262 //================================================================================
264 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
266 Unexpect aCatch(SALOME_SalomeException);
267 return !_preMeshInfo;
270 //================================================================================
272 * \brief Load full mesh data from the study file
274 //================================================================================
276 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
278 Unexpect aCatch(SALOME_SalomeException);
280 _preMeshInfo->FullLoadFromFile();
283 //================================================================================
285 * \brief Remove all nodes and elements
287 //================================================================================
289 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
291 Unexpect aCatch(SALOME_SalomeException);
293 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
297 //CheckGeomGroupModif(); // issue 20145
299 catch(SALOME_Exception & S_ex) {
300 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
303 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
305 SMESH::SMESH_Mesh_var mesh = _this();
306 _gen_i->UpdateIcons( mesh );
309 //================================================================================
311 * \brief Remove all nodes and elements for indicated shape
313 //================================================================================
315 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
316 throw (SALOME::SALOME_Exception)
318 Unexpect aCatch(SALOME_SalomeException);
320 _preMeshInfo->FullLoadFromFile();
323 _impl->ClearSubMesh( ShapeID );
325 catch(SALOME_Exception & S_ex) {
326 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
328 _impl->GetMeshDS()->Modified();
330 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
333 //=============================================================================
335 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
337 //=============================================================================
339 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
341 SMESH::DriverMED_ReadStatus res;
344 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
345 res = SMESH::DRS_OK; break;
346 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
347 res = SMESH::DRS_EMPTY; break;
348 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
349 res = SMESH::DRS_WARN_RENUMBER; break;
350 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
351 res = SMESH::DRS_WARN_SKIP_ELEM; break;
352 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
353 res = SMESH::DRS_WARN_DESCENDING; break;
354 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
356 res = SMESH::DRS_FAIL; break;
361 //=============================================================================
363 * Convert ::SMESH_ComputeError to SMESH::ComputeError
365 //=============================================================================
367 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
369 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
370 errVar->subShapeID = -1;
371 errVar->hasBadMesh = false;
373 if ( !errorPtr || errorPtr->IsOK() )
375 errVar->code = SMESH::COMPERR_OK;
379 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
380 errVar->comment = errorPtr->myComment.c_str();
382 return errVar._retn();
385 //=============================================================================
389 * Imports mesh data from MED file
391 //=============================================================================
393 SMESH::DriverMED_ReadStatus
394 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
395 throw ( SALOME::SALOME_Exception )
397 Unexpect aCatch(SALOME_SalomeException);
400 status = _impl->MEDToMesh( theFileName, theMeshName );
402 catch( SALOME_Exception& S_ex ) {
403 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
406 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
409 CreateGroupServants();
411 int major, minor, release;
412 major = minor = release = 0;
413 MED::GetMEDVersion(theFileName, major, minor, release);
414 _medFileInfo = new SMESH::MedFileInfo();
415 _medFileInfo->fileName = theFileName;
416 _medFileInfo->fileSize = 0;
417 _medFileInfo->major = major;
418 _medFileInfo->minor = minor;
419 _medFileInfo->release = release;
420 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
422 return ConvertDriverMEDReadStatus(status);
425 //================================================================================
427 * \brief Imports mesh data from the CGNS file
429 //================================================================================
431 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
432 const int theMeshIndex,
433 std::string& theMeshName )
434 throw ( SALOME::SALOME_Exception )
436 Unexpect aCatch(SALOME_SalomeException);
439 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
441 catch( SALOME_Exception& S_ex ) {
442 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
445 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
448 CreateGroupServants();
450 _medFileInfo = new SMESH::MedFileInfo();
451 _medFileInfo->fileName = theFileName;
452 _medFileInfo->major = 0;
453 _medFileInfo->minor = 0;
454 _medFileInfo->release = 0;
455 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
457 return ConvertDriverMEDReadStatus(status);
460 //================================================================================
462 * \brief Return string representation of a MED file version comprising nbDigits
464 //================================================================================
466 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
468 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
470 return CORBA::string_dup( ver.c_str() );
473 //================================================================================
475 * Return the list of med versions compatibles for write/append,
476 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
478 //================================================================================
479 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
481 SMESH::long_array_var aResult = new SMESH::long_array();
482 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
483 long nbver = mvok.size();
484 aResult->length( nbver );
485 for ( int i = 0; i < nbver; i++ )
486 aResult[i] = mvok[i];
487 return aResult._retn();
490 //=============================================================================
494 * Imports mesh data from MED file
496 //=============================================================================
498 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
499 throw ( SALOME::SALOME_Exception )
503 // Read mesh with name = <theMeshName> into SMESH_Mesh
504 _impl->UNVToMesh( theFileName );
506 CreateGroupServants();
508 _medFileInfo = new SMESH::MedFileInfo();
509 _medFileInfo->fileName = theFileName;
510 _medFileInfo->major = 0;
511 _medFileInfo->minor = 0;
512 _medFileInfo->release = 0;
513 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
515 SMESH_CATCH( SMESH::throwCorbaException );
520 //=============================================================================
524 * Imports mesh data from STL file
526 //=============================================================================
527 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
528 throw ( SALOME::SALOME_Exception )
532 // Read mesh with name = <theMeshName> into SMESH_Mesh
533 std::string name = _impl->STLToMesh( theFileName );
536 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
537 _gen_i->SetName( meshSO, name.c_str() );
539 _medFileInfo = new SMESH::MedFileInfo();
540 _medFileInfo->fileName = theFileName;
541 _medFileInfo->major = 0;
542 _medFileInfo->minor = 0;
543 _medFileInfo->release = 0;
544 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
546 SMESH_CATCH( SMESH::throwCorbaException );
551 //================================================================================
553 * \brief Function used in SMESH_CATCH by ImportGMFFile()
555 //================================================================================
559 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
561 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
565 //================================================================================
567 * \brief Imports data from a GMF file and returns an error description
569 //================================================================================
571 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
572 bool theMakeRequiredGroups )
573 throw (SALOME::SALOME_Exception)
575 SMESH_ComputeErrorPtr error;
578 #define SMESH_CAUGHT error =
581 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
583 _medFileInfo = new SMESH::MedFileInfo();
584 _medFileInfo->fileName = theFileName;
585 _medFileInfo->major = 0;
586 _medFileInfo->minor = 0;
587 _medFileInfo->release = 0;
588 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
590 SMESH_CATCH( exceptionToComputeError );
594 CreateGroupServants();
596 return ConvertComputeError( error );
599 //=============================================================================
603 //=============================================================================
605 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
607 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
608 (SMESH_Hypothesis::Hypothesis_Status theStatus)
611 RETURNCASE( HYP_OK );
612 RETURNCASE( HYP_MISSING );
613 RETURNCASE( HYP_CONCURRENT );
614 RETURNCASE( HYP_BAD_PARAMETER );
615 RETURNCASE( HYP_HIDDEN_ALGO );
616 RETURNCASE( HYP_HIDING_ALGO );
617 RETURNCASE( HYP_UNKNOWN_FATAL );
618 RETURNCASE( HYP_INCOMPATIBLE );
619 RETURNCASE( HYP_NOTCONFORM );
620 RETURNCASE( HYP_ALREADY_EXIST );
621 RETURNCASE( HYP_BAD_DIM );
622 RETURNCASE( HYP_BAD_SUBSHAPE );
623 RETURNCASE( HYP_BAD_GEOMETRY );
624 RETURNCASE( HYP_NEED_SHAPE );
625 RETURNCASE( HYP_INCOMPAT_HYPS );
628 return SMESH::HYP_UNKNOWN_FATAL;
631 //=============================================================================
635 * calls internal addHypothesis() and then adds a reference to <anHyp> under
636 * the SObject actually having a reference to <aSubShape>.
637 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
639 //=============================================================================
641 SMESH::Hypothesis_Status
642 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
643 SMESH::SMESH_Hypothesis_ptr anHyp,
644 CORBA::String_out anErrorText)
645 throw(SALOME::SALOME_Exception)
647 Unexpect aCatch(SALOME_SalomeException);
649 _preMeshInfo->ForgetOrLoad();
651 const int prevNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
654 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
655 anErrorText = error.c_str();
657 SMESH::SMESH_Mesh_var mesh( _this() );
658 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
660 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
662 int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
663 if ( newNbMeshEnt != prevNbMeshEnt )
664 _gen_i->UpdateIcons( mesh );
666 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
668 // Update Python script
669 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
670 << aSubShape << ", " << anHyp << " )";
672 return ConvertHypothesisStatus(status);
675 //=============================================================================
679 //=============================================================================
681 SMESH_Hypothesis::Hypothesis_Status
682 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
683 SMESH::SMESH_Hypothesis_ptr anHyp,
684 std::string* anErrorText)
686 if(MYDEBUG) MESSAGE("addHypothesis");
688 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
689 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
691 if (CORBA::is_nil( anHyp ))
692 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
694 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
697 TopoDS_Shape myLocSubShape;
698 //use PseudoShape in case if mesh has no shape
700 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
702 myLocSubShape = _impl->GetShapeToMesh();
704 const int hypId = anHyp->GetId();
706 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
707 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
709 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
711 // assure there is a corresponding submesh
712 if ( !_impl->IsMainShape( myLocSubShape )) {
713 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
714 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
715 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
718 else if ( anErrorText )
720 *anErrorText = error;
723 catch(SALOME_Exception & S_ex)
725 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
730 //=============================================================================
734 //=============================================================================
736 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
737 SMESH::SMESH_Hypothesis_ptr anHyp)
738 throw(SALOME::SALOME_Exception)
740 Unexpect aCatch(SALOME_SalomeException);
742 _preMeshInfo->ForgetOrLoad();
744 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
745 SMESH::SMESH_Mesh_var mesh = _this();
747 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
749 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
750 _gen_i->UpdateIcons( mesh );
752 // Update Python script
753 if(_impl->HasShapeToMesh())
754 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
755 << aSubShape << ", " << anHyp << " )";
757 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
760 return ConvertHypothesisStatus(status);
763 //=============================================================================
767 //=============================================================================
769 SMESH_Hypothesis::Hypothesis_Status
770 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
771 SMESH::SMESH_Hypothesis_ptr anHyp)
773 if(MYDEBUG) MESSAGE("removeHypothesis()");
775 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
776 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
778 if (CORBA::is_nil( anHyp ))
779 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
782 _preMeshInfo->ForgetOrLoad();
784 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
787 TopoDS_Shape myLocSubShape;
788 //use PseudoShape in case if mesh has no shape
789 if( _impl->HasShapeToMesh() )
790 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
792 myLocSubShape = _impl->GetShapeToMesh();
794 const int hypId = anHyp->GetId();
795 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
796 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
798 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
802 catch(SALOME_Exception & S_ex)
804 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
809 //=============================================================================
813 //=============================================================================
815 SMESH::ListOfHypothesis *
816 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
817 throw(SALOME::SALOME_Exception)
819 Unexpect aCatch(SALOME_SalomeException);
820 if (MYDEBUG) MESSAGE("GetHypothesisList");
821 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
822 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
824 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
827 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
828 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
829 myLocSubShape = _impl->GetShapeToMesh();
830 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
831 int i = 0, n = aLocalList.size();
834 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
835 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
836 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
838 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
839 if ( id_hypptr != _mapHypo.end() )
840 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
844 catch(SALOME_Exception & S_ex) {
845 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
848 return aList._retn();
851 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
853 Unexpect aCatch(SALOME_SalomeException);
854 if (MYDEBUG) MESSAGE("GetSubMeshes");
856 SMESH::submesh_array_var aList = new SMESH::submesh_array();
859 TPythonDump aPythonDump;
860 if ( !_mapSubMeshIor.empty() )
864 aList->length( _mapSubMeshIor.size() );
866 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
867 for ( ; it != _mapSubMeshIor.end(); it++ ) {
868 if ( CORBA::is_nil( it->second )) continue;
869 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
871 if (i > 1) aPythonDump << ", ";
872 aPythonDump << it->second;
876 catch(SALOME_Exception & S_ex) {
877 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
880 // Update Python script
881 if ( !_mapSubMeshIor.empty() )
882 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
884 return aList._retn();
887 //=============================================================================
891 //=============================================================================
893 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
894 const char* theName )
895 throw(SALOME::SALOME_Exception)
897 Unexpect aCatch(SALOME_SalomeException);
898 if (CORBA::is_nil(aSubShape))
899 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
901 SMESH::SMESH_subMesh_var subMesh;
902 SMESH::SMESH_Mesh_var aMesh = _this();
904 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
906 //Get or Create the SMESH_subMesh object implementation
908 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
910 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
912 TopoDS_Iterator it( myLocSubShape );
914 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
916 subMesh = getSubMesh( subMeshId );
918 // create a new subMesh object servant if there is none for the shape
919 if ( subMesh->_is_nil() )
920 subMesh = createSubMesh( aSubShape );
921 if ( _gen_i->CanPublishInStudy( subMesh ))
923 SALOMEDS::SObject_wrap aSO =
924 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
925 if ( !aSO->_is_nil()) {
926 // Update Python script
927 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
928 << aSubShape << ", '" << theName << "' )";
932 catch(SALOME_Exception & S_ex) {
933 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
935 return subMesh._retn();
938 //=============================================================================
942 //=============================================================================
944 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
945 throw (SALOME::SALOME_Exception)
949 if ( theSubMesh->_is_nil() )
952 GEOM::GEOM_Object_var aSubShape;
953 // Remove submesh's SObject
954 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
955 if ( !anSO->_is_nil() ) {
956 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
957 SALOMEDS::SObject_wrap anObj, aRef;
958 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
959 anObj->ReferencedObject( aRef.inout() ))
961 CORBA::Object_var obj = aRef->GetObject();
962 aSubShape = GEOM::GEOM_Object::_narrow( obj );
964 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
965 // aSubShape = theSubMesh->GetSubShape();
967 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
968 builder->RemoveObjectWithChildren( anSO );
970 // Update Python script
971 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
974 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
976 _preMeshInfo->ForgetOrLoad();
978 SMESH_CATCH( SMESH::throwCorbaException );
981 //=============================================================================
985 //=============================================================================
987 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
988 const char* theName )
989 throw(SALOME::SALOME_Exception)
991 Unexpect aCatch(SALOME_SalomeException);
993 _preMeshInfo->FullLoadFromFile();
995 SMESH::SMESH_Group_var aNewGroup =
996 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
998 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1000 SMESH::SMESH_Mesh_var mesh = _this();
1001 SALOMEDS::SObject_wrap aSO =
1002 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1003 if ( !aSO->_is_nil())
1004 // Update Python script
1005 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1006 << theElemType << ", '" << theName << "' )";
1008 return aNewGroup._retn();
1011 //=============================================================================
1015 //=============================================================================
1016 SMESH::SMESH_GroupOnGeom_ptr
1017 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1018 const char* theName,
1019 GEOM::GEOM_Object_ptr theGeomObj)
1020 throw(SALOME::SALOME_Exception)
1022 Unexpect aCatch(SALOME_SalomeException);
1024 _preMeshInfo->FullLoadFromFile();
1026 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1028 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1029 if ( !aShape.IsNull() )
1032 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1034 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1036 SMESH::SMESH_Mesh_var mesh = _this();
1037 SALOMEDS::SObject_wrap aSO =
1038 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1039 if ( !aSO->_is_nil())
1040 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1041 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1045 return aNewGroup._retn();
1048 //================================================================================
1050 * \brief Creates a group whose contents is defined by filter
1051 * \param theElemType - group type
1052 * \param theName - group name
1053 * \param theFilter - the filter
1054 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1056 //================================================================================
1058 SMESH::SMESH_GroupOnFilter_ptr
1059 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1060 const char* theName,
1061 SMESH::Filter_ptr theFilter )
1062 throw (SALOME::SALOME_Exception)
1064 Unexpect aCatch(SALOME_SalomeException);
1066 _preMeshInfo->FullLoadFromFile();
1068 if ( CORBA::is_nil( theFilter ))
1069 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1071 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1073 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1075 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1076 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1079 if ( !aNewGroup->_is_nil() )
1080 aNewGroup->SetFilter( theFilter );
1082 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1084 SMESH::SMESH_Mesh_var mesh = _this();
1085 SALOMEDS::SObject_wrap aSO =
1086 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1088 if ( !aSO->_is_nil())
1089 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1090 << theElemType << ", '" << theName << "', " << theFilter << " )";
1092 return aNewGroup._retn();
1095 //=============================================================================
1099 //=============================================================================
1101 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1102 throw (SALOME::SALOME_Exception)
1104 if ( theGroup->_is_nil() )
1109 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1113 if ( aGroup->GetMeshServant() != this )
1114 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1115 SALOME::BAD_PARAM );
1117 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1118 if ( !aGroupSO->_is_nil() )
1120 // Update Python script
1121 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1123 // Remove group's SObject
1124 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1125 builder->RemoveObjectWithChildren( aGroupSO );
1127 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1129 // Remove the group from SMESH data structures
1130 removeGroup( aGroup->GetLocalID() );
1132 SMESH_CATCH( SMESH::throwCorbaException );
1135 //=============================================================================
1137 * Remove group with its contents
1139 //=============================================================================
1141 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1142 throw (SALOME::SALOME_Exception)
1146 _preMeshInfo->FullLoadFromFile();
1148 if ( theGroup->_is_nil() )
1151 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1152 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1153 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1156 vector<int> nodeIds; // to remove nodes becoming free
1157 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1158 if ( !isNodal && !theGroup->IsEmpty() )
1160 CORBA::Long elemID = theGroup->GetID( 1 );
1161 int nbElemNodes = GetElemNbNodes( elemID );
1162 if ( nbElemNodes > 0 )
1163 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1166 // Retrieve contents
1167 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1168 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1169 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1170 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1171 elems.assign( elemBeg, elemEnd );
1173 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1176 RemoveGroup( theGroup );
1179 for ( size_t i = 0; i < elems.size(); ++i )
1181 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1185 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1186 nodeIds.push_back( nIt->next()->GetID() );
1188 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1192 _impl->GetMeshDS()->RemoveElement( elems[i] );
1196 // Remove free nodes
1197 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1198 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1199 if ( n->NbInverseElements() == 0 )
1200 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1202 // Update Python script (theGroup must be alive for this)
1203 pyDump << SMESH::SMESH_Mesh_var(_this())
1204 << ".RemoveGroupWithContents( " << theGroup << " )";
1206 SMESH_CATCH( SMESH::throwCorbaException );
1209 //================================================================================
1211 * \brief Get the list of groups existing in the mesh
1212 * \retval SMESH::ListOfGroups * - list of groups
1214 //================================================================================
1216 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1218 Unexpect aCatch(SALOME_SalomeException);
1219 if (MYDEBUG) MESSAGE("GetGroups");
1221 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1224 TPythonDump aPythonDump;
1225 if ( !_mapGroups.empty() )
1227 aPythonDump << "[ ";
1229 aList->length( _mapGroups.size() );
1231 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1232 for ( ; it != _mapGroups.end(); it++ ) {
1233 if ( CORBA::is_nil( it->second )) continue;
1234 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1236 if (i > 1) aPythonDump << ", ";
1237 aPythonDump << it->second;
1241 catch(SALOME_Exception & S_ex) {
1242 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1244 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1246 return aList._retn();
1249 //=============================================================================
1251 * Get number of groups existing in the mesh
1253 //=============================================================================
1255 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1257 Unexpect aCatch(SALOME_SalomeException);
1258 return _mapGroups.size();
1261 //=============================================================================
1263 * New group including all mesh elements present in initial groups is created.
1265 //=============================================================================
1267 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1268 SMESH::SMESH_GroupBase_ptr theGroup2,
1269 const char* theName )
1270 throw (SALOME::SALOME_Exception)
1272 SMESH::SMESH_Group_var aResGrp;
1276 _preMeshInfo->FullLoadFromFile();
1278 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1279 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1281 if ( theGroup1->GetType() != theGroup2->GetType() )
1282 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1287 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1288 if ( aResGrp->_is_nil() )
1289 return SMESH::SMESH_Group::_nil();
1291 aResGrp->AddFrom( theGroup1 );
1292 aResGrp->AddFrom( theGroup2 );
1294 // Update Python script
1295 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1296 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1298 SMESH_CATCH( SMESH::throwCorbaException );
1300 return aResGrp._retn();
1303 //=============================================================================
1305 * \brief New group including all mesh elements present in initial groups is created.
1306 * \param theGroups list of groups
1307 * \param theName name of group to be created
1308 * \return pointer to the new group
1310 //=============================================================================
1312 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1313 const char* theName )
1314 throw (SALOME::SALOME_Exception)
1316 SMESH::SMESH_Group_var aResGrp;
1319 _preMeshInfo->FullLoadFromFile();
1322 return SMESH::SMESH_Group::_nil();
1327 SMESH::ElementType aType = SMESH::ALL;
1328 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1330 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1331 if ( CORBA::is_nil( aGrp ) )
1333 if ( aType == SMESH::ALL )
1334 aType = aGrp->GetType();
1335 else if ( aType != aGrp->GetType() )
1336 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1339 if ( aType == SMESH::ALL )
1340 return SMESH::SMESH_Group::_nil();
1345 aResGrp = CreateGroup( aType, theName );
1346 if ( aResGrp->_is_nil() )
1347 return SMESH::SMESH_Group::_nil();
1349 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1350 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1352 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1353 if ( !CORBA::is_nil( aGrp ) )
1355 aResGrp->AddFrom( aGrp );
1356 if ( g > 0 ) pyDump << ", ";
1360 pyDump << " ], '" << theName << "' )";
1362 SMESH_CATCH( SMESH::throwCorbaException );
1364 return aResGrp._retn();
1367 //=============================================================================
1369 * New group is created. All mesh elements that are
1370 * present in both initial groups are added to the new one.
1372 //=============================================================================
1374 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1375 SMESH::SMESH_GroupBase_ptr theGroup2,
1376 const char* theName )
1377 throw (SALOME::SALOME_Exception)
1379 SMESH::SMESH_Group_var aResGrp;
1384 _preMeshInfo->FullLoadFromFile();
1386 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1387 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1389 if ( theGroup1->GetType() != theGroup2->GetType() )
1390 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1394 // Create Intersection
1395 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1396 if ( aResGrp->_is_nil() )
1397 return aResGrp._retn();
1399 SMESHDS_GroupBase* groupDS1 = 0;
1400 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1401 groupDS1 = grp_i->GetGroupDS();
1403 SMESHDS_GroupBase* groupDS2 = 0;
1404 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1405 groupDS2 = grp_i->GetGroupDS();
1407 SMESHDS_Group* resGroupDS = 0;
1408 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1409 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1411 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1413 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1414 while ( elemIt1->more() )
1416 const SMDS_MeshElement* e = elemIt1->next();
1417 if ( groupDS2->Contains( e ))
1418 resGroupDS->SMDSGroup().Add( e );
1421 // Update Python script
1422 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1423 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1425 SMESH_CATCH( SMESH::throwCorbaException );
1427 return aResGrp._retn();
1430 //=============================================================================
1432 \brief Intersect list of groups. New group is created. All mesh elements that
1433 are present in all initial groups simultaneously are added to the new one.
1434 \param theGroups list of groups
1435 \param theName name of group to be created
1436 \return pointer on the group
1438 //=============================================================================
1439 SMESH::SMESH_Group_ptr
1440 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1441 const char* theName )
1442 throw (SALOME::SALOME_Exception)
1444 SMESH::SMESH_Group_var aResGrp;
1449 _preMeshInfo->FullLoadFromFile();
1452 return SMESH::SMESH_Group::_nil();
1454 // check types and get SMESHDS_GroupBase's
1455 SMESH::ElementType aType = SMESH::ALL;
1456 vector< SMESHDS_GroupBase* > groupVec;
1457 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1459 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1460 if ( CORBA::is_nil( aGrp ) )
1462 if ( aType == SMESH::ALL )
1463 aType = aGrp->GetType();
1464 else if ( aType != aGrp->GetType() )
1465 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1468 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1469 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1471 if ( grpDS->IsEmpty() )
1476 groupVec.push_back( grpDS );
1479 if ( aType == SMESH::ALL ) // all groups are nil
1480 return SMESH::SMESH_Group::_nil();
1485 aResGrp = CreateGroup( aType, theName );
1487 SMESHDS_Group* resGroupDS = 0;
1488 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1489 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1490 if ( !resGroupDS || groupVec.empty() )
1491 return aResGrp._retn();
1494 size_t i, nb = groupVec.size();
1495 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1496 while ( elemIt1->more() )
1498 const SMDS_MeshElement* e = elemIt1->next();
1500 for ( i = 1; ( i < nb && inAll ); ++i )
1501 inAll = groupVec[i]->Contains( e );
1504 resGroupDS->SMDSGroup().Add( e );
1507 // Update Python script
1508 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1509 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1511 SMESH_CATCH( SMESH::throwCorbaException );
1513 return aResGrp._retn();
1516 //=============================================================================
1518 * New group is created. All mesh elements that are present in
1519 * a main group but is not present in a tool group are added to the new one
1521 //=============================================================================
1523 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1524 SMESH::SMESH_GroupBase_ptr theGroup2,
1525 const char* theName )
1526 throw (SALOME::SALOME_Exception)
1528 SMESH::SMESH_Group_var aResGrp;
1533 _preMeshInfo->FullLoadFromFile();
1535 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1536 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1538 if ( theGroup1->GetType() != theGroup2->GetType() )
1539 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1543 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1544 if ( aResGrp->_is_nil() )
1545 return aResGrp._retn();
1547 SMESHDS_GroupBase* groupDS1 = 0;
1548 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1549 groupDS1 = grp_i->GetGroupDS();
1551 SMESHDS_GroupBase* groupDS2 = 0;
1552 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1553 groupDS2 = grp_i->GetGroupDS();
1555 SMESHDS_Group* resGroupDS = 0;
1556 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1557 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1559 if ( groupDS1 && groupDS2 && resGroupDS )
1561 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1562 while ( elemIt1->more() )
1564 const SMDS_MeshElement* e = elemIt1->next();
1565 if ( !groupDS2->Contains( e ))
1566 resGroupDS->SMDSGroup().Add( e );
1569 // Update Python script
1570 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1571 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1573 SMESH_CATCH( SMESH::throwCorbaException );
1575 return aResGrp._retn();
1578 //=============================================================================
1580 \brief Cut lists of groups. New group is created. All mesh elements that are
1581 present in main groups but do not present in tool groups are added to the new one
1582 \param theMainGroups list of main groups
1583 \param theToolGroups list of tool groups
1584 \param theName name of group to be created
1585 \return pointer on the group
1587 //=============================================================================
1588 SMESH::SMESH_Group_ptr
1589 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1590 const SMESH::ListOfGroups& theToolGroups,
1591 const char* theName )
1592 throw (SALOME::SALOME_Exception)
1594 SMESH::SMESH_Group_var aResGrp;
1599 _preMeshInfo->FullLoadFromFile();
1602 return SMESH::SMESH_Group::_nil();
1604 // check types and get SMESHDS_GroupBase's
1605 SMESH::ElementType aType = SMESH::ALL;
1606 vector< SMESHDS_GroupBase* > toolGroupVec;
1607 vector< SMDS_ElemIteratorPtr > mainIterVec;
1609 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1611 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1612 if ( CORBA::is_nil( aGrp ) )
1614 if ( aType == SMESH::ALL )
1615 aType = aGrp->GetType();
1616 else if ( aType != aGrp->GetType() )
1617 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1619 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1620 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1621 if ( !grpDS->IsEmpty() )
1622 mainIterVec.push_back( grpDS->GetElements() );
1624 if ( aType == SMESH::ALL ) // all main groups are nil
1625 return SMESH::SMESH_Group::_nil();
1626 if ( mainIterVec.empty() ) // all main groups are empty
1627 return aResGrp._retn();
1629 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1631 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1632 if ( CORBA::is_nil( aGrp ) )
1634 if ( aType != aGrp->GetType() )
1635 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1637 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1638 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1639 toolGroupVec.push_back( grpDS );
1645 aResGrp = CreateGroup( aType, theName );
1647 SMESHDS_Group* resGroupDS = 0;
1648 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1649 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1651 return aResGrp._retn();
1654 size_t i, nb = toolGroupVec.size();
1655 SMDS_ElemIteratorPtr mainElemIt
1656 ( new SMDS_IteratorOnIterators
1657 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1658 while ( mainElemIt->more() )
1660 const SMDS_MeshElement* e = mainElemIt->next();
1662 for ( i = 0; ( i < nb && !isIn ); ++i )
1663 isIn = toolGroupVec[i]->Contains( e );
1666 resGroupDS->SMDSGroup().Add( e );
1669 // Update Python script
1670 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1671 << ".CutListOfGroups( " << theMainGroups << ", "
1672 << theToolGroups << ", '" << theName << "' )";
1674 SMESH_CATCH( SMESH::throwCorbaException );
1676 return aResGrp._retn();
1679 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1681 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1682 bool & toStopChecking )
1684 toStopChecking = ( nbCommon < nbChecked );
1685 return nbCommon == nbNodes;
1687 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1688 bool & toStopChecking )
1690 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1691 return nbCommon == nbCorners;
1693 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1694 bool & toStopChecking )
1696 return nbCommon > 0;
1698 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1699 bool & toStopChecking )
1701 return nbCommon >= (nbNodes+1) / 2;
1705 //=============================================================================
1707 * Create a group of entities basing on nodes of other groups.
1708 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1709 * \param [in] anElemType - a type of elements to include to the new group.
1710 * \param [in] theName - a name of the new group.
1711 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1712 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1713 * new group provided that it is based on nodes of an element of \a aListOfGroups
1714 * \return SMESH_Group - the created group
1716 // IMP 19939, bug 22010, IMP 22635
1717 //=============================================================================
1719 SMESH::SMESH_Group_ptr
1720 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1721 SMESH::ElementType theElemType,
1722 const char* theName,
1723 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1724 CORBA::Boolean theUnderlyingOnly)
1725 throw (SALOME::SALOME_Exception)
1727 SMESH::SMESH_Group_var aResGrp;
1731 _preMeshInfo->FullLoadFromFile();
1733 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1735 if ( !theName || !aMeshDS )
1736 return SMESH::SMESH_Group::_nil();
1738 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1740 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1741 SMESH_Comment nbCoNoStr( "SMESH.");
1742 switch ( theNbCommonNodes ) {
1743 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1744 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1745 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1746 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1747 default: return aResGrp._retn();
1749 int nbChecked, nbCommon, nbNodes, nbCorners;
1755 aResGrp = CreateGroup( theElemType, theName );
1756 if ( aResGrp->_is_nil() )
1757 return SMESH::SMESH_Group::_nil();
1759 SMESHDS_GroupBase* groupBaseDS =
1760 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1761 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1763 vector<bool> isNodeInGroups;
1765 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1767 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1768 if ( CORBA::is_nil( aGrp ) )
1770 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1771 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1774 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1775 if ( !elIt ) continue;
1777 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1779 while ( elIt->more() ) {
1780 const SMDS_MeshElement* el = elIt->next();
1781 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1782 while ( nIt->more() )
1783 resGroupCore.Add( nIt->next() );
1786 // get elements of theElemType based on nodes of every element of group
1787 else if ( theUnderlyingOnly )
1789 while ( elIt->more() )
1791 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1792 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1793 TIDSortedElemSet checkedElems;
1794 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1795 while ( nIt->more() )
1797 const SMDS_MeshNode* n = nIt->next();
1798 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1799 // check nodes of elements of theElemType around el
1800 while ( elOfTypeIt->more() )
1802 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1803 if ( !checkedElems.insert( elOfType ).second ) continue;
1804 nbNodes = elOfType->NbNodes();
1805 nbCorners = elOfType->NbCornerNodes();
1807 bool toStopChecking = false;
1808 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1809 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1810 if ( elNodes.count( nIt2->next() ) &&
1811 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1813 resGroupCore.Add( elOfType );
1820 // get all nodes of elements of groups
1823 while ( elIt->more() )
1825 const SMDS_MeshElement* el = elIt->next(); // an element of group
1826 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1827 while ( nIt->more() )
1829 const SMDS_MeshNode* n = nIt->next();
1830 if ( n->GetID() >= (int) isNodeInGroups.size() )
1831 isNodeInGroups.resize( n->GetID() + 1, false );
1832 isNodeInGroups[ n->GetID() ] = true;
1838 // Get elements of theElemType based on a certain number of nodes of elements of groups
1839 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1841 const SMDS_MeshNode* n;
1842 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1843 const int isNodeInGroupsSize = isNodeInGroups.size();
1844 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1846 if ( !isNodeInGroups[ iN ] ||
1847 !( n = aMeshDS->FindNode( iN )))
1850 // check nodes of elements of theElemType around n
1851 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1852 while ( elOfTypeIt->more() )
1854 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1855 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1860 nbNodes = elOfType->NbNodes();
1861 nbCorners = elOfType->NbCornerNodes();
1863 bool toStopChecking = false;
1864 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1865 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1867 const int nID = nIt->next()->GetID();
1868 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1869 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1871 resGroupCore.Add( elOfType );
1879 // Update Python script
1880 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1881 << ".CreateDimGroup( "
1882 << theGroups << ", " << theElemType << ", '" << theName << "', "
1883 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1885 SMESH_CATCH( SMESH::throwCorbaException );
1887 return aResGrp._retn();
1890 //================================================================================
1892 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1893 * existing 1D elements as group boundaries.
1894 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1895 * adjacent faces is more than \a sharpAngle in degrees.
1896 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1897 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1898 * \return ListOfGroups - the created groups
1900 //================================================================================
1902 SMESH::ListOfGroups*
1903 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1904 CORBA::Boolean theCreateEdges,
1905 CORBA::Boolean theUseExistingEdges )
1906 throw (SALOME::SALOME_Exception)
1908 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1909 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1912 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1918 _preMeshInfo->FullLoadFromFile();
1920 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1922 std::vector< SMESH_MeshAlgos::Edge > edges =
1923 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1925 if ( theCreateEdges )
1927 std::vector<const SMDS_MeshNode *> nodes(2);
1928 for ( size_t i = 0; i < edges.size(); ++i )
1930 nodes[0] = edges[i]._node1;
1931 nodes[1] = edges[i]._node2;
1932 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1934 if ( edges[i]._medium )
1935 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1937 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1941 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1942 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1944 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1946 resultGroups->length( faceGroups.size() );
1947 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1949 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1950 _editor->GenerateGroupName("Group").c_str());
1951 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1953 SMESHDS_GroupBase* groupBaseDS =
1954 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1955 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1957 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1958 for ( size_t i = 0; i < faces.size(); ++i )
1959 groupCore.Add( faces[i] );
1962 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1963 << ".FaceGroupsSeparatedByEdges( "
1964 << TVar( theSharpAngle ) << ", "
1965 << theCreateEdges << ", "
1966 << theUseExistingEdges << " )";
1968 SMESH_CATCH( SMESH::throwCorbaException );
1969 return resultGroups._retn();
1973 //================================================================================
1975 * \brief Remember GEOM group data
1977 //================================================================================
1979 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1980 CORBA::Object_ptr theSmeshObj)
1982 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1985 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1986 if ( groupSO->_is_nil() )
1989 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1990 GEOM::GEOM_IGroupOperations_wrap groupOp =
1991 geomGen->GetIGroupOperations();
1992 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1995 _geomGroupData.push_back( TGeomGroupData() );
1996 TGeomGroupData & groupData = _geomGroupData.back();
1998 CORBA::String_var entry = groupSO->GetID();
1999 groupData._groupEntry = entry.in();
2001 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2002 groupData._indices.insert( ids[i] );
2004 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2005 // shape index in SMESHDS
2006 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2007 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2010 //================================================================================
2012 * Remove GEOM group data relating to removed smesh object
2014 //================================================================================
2016 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2018 list<TGeomGroupData>::iterator
2019 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2020 for ( ; data != dataEnd; ++data ) {
2021 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2022 _geomGroupData.erase( data );
2028 //================================================================================
2030 * \brief Return new group contents if it has been changed and update group data
2032 //================================================================================
2034 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
2036 TopoDS_Shape newShape;
2039 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2040 if ( !groupSO->_is_nil() )
2042 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2043 if ( CORBA::is_nil( groupObj )) return newShape;
2044 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2046 // get indices of group items
2047 set<int> curIndices;
2048 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2049 GEOM::GEOM_IGroupOperations_wrap groupOp =
2050 geomGen->GetIGroupOperations();
2051 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2052 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2053 curIndices.insert( ids[i] );
2055 if ( groupData._indices == curIndices )
2056 return newShape; // group not changed
2059 groupData._indices = curIndices;
2061 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2062 if ( !geomClient ) return newShape;
2063 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2064 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2065 newShape = _gen_i->GeomObjectToShape( geomGroup );
2068 if ( newShape.IsNull() ) {
2069 // geom group becomes empty - return empty compound
2070 TopoDS_Compound compound;
2071 BRep_Builder().MakeCompound(compound);
2072 newShape = compound;
2079 //-----------------------------------------------------------------------------
2081 * \brief Storage of shape and index used in CheckGeomGroupModif()
2083 struct TIndexedShape
2086 TopoDS_Shape _shape;
2087 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2089 //-----------------------------------------------------------------------------
2091 * \brief Data to re-create a group on geometry
2093 struct TGroupOnGeomData
2096 TopoDS_Shape _shape;
2097 SMDSAbs_ElementType _type;
2099 Quantity_Color _color;
2101 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2103 _oldID = group->GetID();
2104 _type = group->GetType();
2105 _name = group->GetStoreName();
2106 _color = group->GetColor();
2110 //-----------------------------------------------------------------------------
2112 * \brief Check if a filter is still valid after geometry removal
2114 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2116 if ( theFilter->_is_nil() )
2118 SMESH::Filter::Criteria_var criteria;
2119 theFilter->GetCriteria( criteria.out() );
2121 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2123 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2125 switch ( criteria[ iCr ].Type )
2127 case SMESH::FT_BelongToGeom:
2128 case SMESH::FT_BelongToPlane:
2129 case SMESH::FT_BelongToCylinder:
2130 case SMESH::FT_BelongToGenSurface:
2131 case SMESH::FT_LyingOnGeom:
2132 entry = thresholdID;
2134 case SMESH::FT_ConnectedElements:
2137 entry = thresholdID;
2143 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2144 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2145 if ( so->_is_nil() )
2147 CORBA::Object_var obj = so->GetObject();
2148 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2149 if ( gen->GeomObjectToShape( geom ).IsNull() )
2152 } // loop on criteria
2158 //=============================================================================
2160 * \brief Update data if geometry changes
2164 //=============================================================================
2166 void SMESH_Mesh_i::CheckGeomModif()
2168 SMESH::SMESH_Mesh_var me = _this();
2169 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2171 //bool removedFromClient = false;
2173 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2175 //removedFromClient = _impl->HasShapeToMesh();
2177 // try to find geometry by study reference
2178 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2179 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2180 if ( !meshSO->_is_nil() &&
2181 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2182 geomRefSO->ReferencedObject( geomSO.inout() ))
2184 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2185 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2188 if ( mainGO->_is_nil() && // geometry removed ==>
2189 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2191 // convert geom dependent groups into standalone ones
2192 CheckGeomGroupModif();
2194 _impl->ShapeToMesh( TopoDS_Shape() );
2196 // remove sub-meshes
2197 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2198 while ( i_sm != _mapSubMeshIor.end() )
2200 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2202 RemoveSubMesh( sm );
2204 // remove all children except groups in the study
2205 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2206 SALOMEDS::SObject_wrap so;
2207 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2208 if ( meshSO->FindSubObject( tag, so.inout() ))
2209 builder->RemoveObjectWithChildren( so );
2211 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2217 if ( !_impl->HasShapeToMesh() ) return;
2220 // Update after group modification
2222 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2223 mainGO->GetTick() == _mainShapeTick )
2225 int nb = NbNodes() + NbElements();
2226 CheckGeomGroupModif();
2227 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2228 _gen_i->UpdateIcons( me );
2232 // Update after shape transformation like Translate
2234 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2235 if ( !geomClient ) return;
2236 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2237 if ( geomGen->_is_nil() ) return;
2239 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2240 geomClient->RemoveShapeFromBuffer( ior.in() );
2242 // Update data taking into account that
2243 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2246 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2247 if ( newShape.IsNull() )
2250 _mainShapeTick = mainGO->GetTick();
2252 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2254 // store data of groups on geometry
2255 std::vector< TGroupOnGeomData > groupsData;
2256 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2257 groupsData.reserve( groups.size() );
2258 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2259 for ( ; g != groups.end(); ++g )
2261 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2263 groupsData.push_back( TGroupOnGeomData( group ));
2266 SMESH::SMESH_GroupOnGeom_var gog;
2267 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2268 if ( i_grp != _mapGroups.end() )
2269 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2271 GEOM::GEOM_Object_var geom;
2272 if ( !gog->_is_nil() )
2273 geom = gog->GetShape();
2274 if ( !geom->_is_nil() )
2276 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2277 geomClient->RemoveShapeFromBuffer( ior.in() );
2278 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2282 // store assigned hypotheses
2283 std::vector< pair< int, THypList > > ids2Hyps;
2284 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2285 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2287 const TopoDS_Shape& s = s2hyps.Key();
2288 const THypList& hyps = s2hyps.ChangeValue();
2289 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2292 // change shape to mesh
2293 int oldNbSubShapes = meshDS->MaxShapeIndex();
2294 _impl->ShapeToMesh( TopoDS_Shape() );
2295 _impl->ShapeToMesh( newShape );
2297 // re-add shapes of geom groups
2298 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2299 for ( ; data != _geomGroupData.end(); ++data )
2301 TopoDS_Shape newShape = newGroupShape( *data );
2302 if ( !newShape.IsNull() )
2304 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2306 TopoDS_Compound compound;
2307 BRep_Builder().MakeCompound( compound );
2308 BRep_Builder().Add( compound, newShape );
2309 newShape = compound;
2311 _impl->GetSubMesh( newShape );
2314 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2315 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2316 SALOME::INTERNAL_ERROR );
2318 // re-assign hypotheses
2319 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2321 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2322 const THypList& hyps = ids2Hyps[i].second;
2323 THypList::const_iterator h = hyps.begin();
2324 for ( ; h != hyps.end(); ++h )
2325 _impl->AddHypothesis( s, (*h)->GetID() );
2328 // restore groups on geometry
2329 for ( size_t i = 0; i < groupsData.size(); ++i )
2331 const TGroupOnGeomData& data = groupsData[i];
2332 if ( data._shape.IsNull() )
2335 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2336 if ( i2g == _mapGroups.end() ) continue;
2338 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2339 if ( !gr_i ) continue;
2341 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2343 _mapGroups.erase( i2g );
2345 g->GetGroupDS()->SetColor( data._color );
2348 // update _mapSubMesh
2349 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2350 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2351 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2355 //=============================================================================
2357 * \brief Update objects depending on changed geom groups
2359 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2360 * issue 0020210: Update of a smesh group after modification of the associated geom group
2362 //=============================================================================
2364 void SMESH_Mesh_i::CheckGeomGroupModif()
2366 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2367 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2368 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2369 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2370 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2372 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2373 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2374 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2376 int nbValid = 0, nbRemoved = 0;
2377 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2378 for ( ; chItr->More(); chItr->Next() )
2380 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2381 if ( !smSO->_is_nil() &&
2382 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2383 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2385 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2386 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2387 if ( !geom->_non_existent() )
2390 continue; // keep the sub-mesh
2393 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2394 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2395 if ( !sm->_is_nil() && !sm->_non_existent() )
2397 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2398 if ( smGeom->_is_nil() )
2400 RemoveSubMesh( sm );
2407 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2408 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2412 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2413 builder->RemoveObjectWithChildren( rootSO );
2417 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2418 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2419 while ( i_gr != _mapGroups.end())
2421 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2423 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2424 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2425 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2426 bool isValidGeom = false;
2427 if ( !onGeom->_is_nil() )
2429 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2431 else if ( !onFilt->_is_nil() )
2433 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2437 isValidGeom = ( !groupSO->_is_nil() &&
2438 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2442 if ( !IsLoaded() || group->IsEmpty() )
2444 RemoveGroup( group );
2446 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2448 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2450 else // is it possible?
2452 builder->RemoveObjectWithChildren( refSO );
2458 if ( !_impl->HasShapeToMesh() ) return;
2460 CORBA::Long nbEntities = NbNodes() + NbElements();
2462 // Check if group contents changed
2464 typedef map< string, TopoDS_Shape > TEntry2Geom;
2465 TEntry2Geom newGroupContents;
2467 list<TGeomGroupData>::iterator
2468 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2469 for ( ; data != dataEnd; ++data )
2471 pair< TEntry2Geom::iterator, bool > it_new =
2472 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2473 bool processedGroup = !it_new.second;
2474 TopoDS_Shape& newShape = it_new.first->second;
2475 if ( !processedGroup )
2476 newShape = newGroupShape( *data );
2477 if ( newShape.IsNull() )
2478 continue; // no changes
2481 _preMeshInfo->ForgetOrLoad();
2483 if ( processedGroup ) { // update group indices
2484 list<TGeomGroupData>::iterator data2 = data;
2485 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2486 data->_indices = data2->_indices;
2489 // Update SMESH objects according to new GEOM group contents
2491 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2492 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2494 int oldID = submesh->GetId();
2495 if ( !_mapSubMeshIor.count( oldID ))
2497 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2499 // update hypotheses
2500 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2501 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2502 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2504 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2505 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2507 // care of submeshes
2508 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2509 int newID = newSubmesh->GetId();
2510 if ( newID != oldID ) {
2511 _mapSubMesh [ newID ] = newSubmesh;
2512 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2513 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2514 _mapSubMesh. erase(oldID);
2515 _mapSubMesh_i. erase(oldID);
2516 _mapSubMeshIor.erase(oldID);
2517 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2522 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2523 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2524 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2526 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2528 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2529 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2530 ds->SetShape( newShape );
2535 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2536 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2538 // Remove groups and submeshes basing on removed sub-shapes
2540 TopTools_MapOfShape newShapeMap;
2541 TopoDS_Iterator shapeIt( newShape );
2542 for ( ; shapeIt.More(); shapeIt.Next() )
2543 newShapeMap.Add( shapeIt.Value() );
2545 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2546 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2548 if ( newShapeMap.Contains( shapeIt.Value() ))
2550 TopTools_IndexedMapOfShape oldShapeMap;
2551 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2552 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2554 const TopoDS_Shape& oldShape = oldShapeMap(i);
2555 int oldInd = meshDS->ShapeToIndex( oldShape );
2557 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2558 if ( i_smIor != _mapSubMeshIor.end() ) {
2559 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2562 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2563 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2565 // check if a group bases on oldInd shape
2566 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2567 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2568 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2569 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2571 RemoveGroup( i_grp->second ); // several groups can base on same shape
2572 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2577 // Reassign hypotheses and update groups after setting the new shape to mesh
2579 // collect anassigned hypotheses
2580 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2581 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2582 TShapeHypList assignedHyps;
2583 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2585 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2586 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2587 if ( !hyps.empty() ) {
2588 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2589 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2590 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2593 // collect shapes supporting groups
2594 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2595 TShapeTypeList groupData;
2596 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2597 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2598 for ( ; grIt != groups.end(); ++grIt )
2600 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2602 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2604 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2606 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2607 _impl->ShapeToMesh( newShape );
2609 // reassign hypotheses
2610 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2611 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2613 TIndexedShape& geom = indS_hyps->first;
2614 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2615 int oldID = geom._index;
2616 int newID = meshDS->ShapeToIndex( geom._shape );
2617 if ( oldID == 1 ) { // main shape
2619 geom._shape = newShape;
2623 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2624 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2625 // care of sub-meshes
2626 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2627 if ( newID != oldID ) {
2628 _mapSubMesh [ newID ] = newSubmesh;
2629 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2630 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2631 _mapSubMesh. erase(oldID);
2632 _mapSubMesh_i. erase(oldID);
2633 _mapSubMeshIor.erase(oldID);
2634 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2638 TShapeTypeList::iterator geomType = groupData.begin();
2639 for ( ; geomType != groupData.end(); ++geomType )
2641 const TIndexedShape& geom = geomType->first;
2642 int oldID = geom._index;
2643 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2646 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2647 CORBA::String_var name = groupSO->GetName();
2649 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2650 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2651 /*id=*/-1, geom._shape ))
2652 group_i->changeLocalId( group->GetID() );
2655 break; // everything has been updated
2658 } // loop on group data
2662 CORBA::Long newNbEntities = NbNodes() + NbElements();
2663 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2664 if ( newNbEntities != nbEntities )
2666 // Add all SObjects with icons to soToUpdateIcons
2667 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2669 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2670 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2671 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2673 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2674 i_gr != _mapGroups.end(); ++i_gr ) // groups
2675 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2678 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2679 for ( ; so != soToUpdateIcons.end(); ++so )
2680 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2683 //=============================================================================
2685 * \brief Create standalone group from a group on geometry or filter
2687 //=============================================================================
2689 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2690 throw (SALOME::SALOME_Exception)
2692 SMESH::SMESH_Group_var aGroup;
2697 _preMeshInfo->FullLoadFromFile();
2699 if ( theGroup->_is_nil() )
2700 return aGroup._retn();
2702 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2704 return aGroup._retn();
2706 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2708 const int anId = aGroupToRem->GetLocalID();
2709 if ( !_impl->ConvertToStandalone( anId ) )
2710 return aGroup._retn();
2711 removeGeomGroupData( theGroup );
2713 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2715 // remove old instance of group from own map
2716 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2717 _mapGroups.erase( anId );
2719 SALOMEDS::StudyBuilder_var builder;
2720 SALOMEDS::SObject_wrap aGroupSO;
2721 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2722 if ( !aStudy->_is_nil() ) {
2723 builder = aStudy->NewBuilder();
2724 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2725 if ( !aGroupSO->_is_nil() )
2727 // remove reference to geometry
2728 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2729 for ( ; chItr->More(); chItr->Next() )
2731 // Remove group's child SObject
2732 SALOMEDS::SObject_wrap so = chItr->Value();
2733 builder->RemoveObject( so );
2735 // Update Python script
2736 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2737 << ".ConvertToStandalone( " << aGroupSO << " )";
2739 // change icon of Group on Filter
2742 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2743 // const int isEmpty = ( elemTypes->length() == 0 );
2746 SALOMEDS::GenericAttribute_wrap anAttr =
2747 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2748 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2749 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2755 // remember new group in own map
2756 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2757 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2759 // register CORBA object for persistence
2760 _gen_i->RegisterObject( aGroup );
2762 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2763 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2764 //aGroup->Register();
2765 aGroupToRem->UnRegister();
2767 SMESH_CATCH( SMESH::throwCorbaException );
2769 return aGroup._retn();
2772 //=============================================================================
2776 //=============================================================================
2778 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2780 if(MYDEBUG) MESSAGE( "createSubMesh" );
2781 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2782 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2785 SMESH_subMesh_i * subMeshServant;
2788 subMeshId = mySubMesh->GetId();
2789 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2791 else // "invalid sub-mesh"
2793 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2794 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2795 if ( _mapSubMesh.empty() )
2798 subMeshId = _mapSubMesh.begin()->first - 1;
2799 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2802 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2804 _mapSubMesh [subMeshId] = mySubMesh;
2805 _mapSubMesh_i [subMeshId] = subMeshServant;
2806 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2808 subMeshServant->Register();
2810 // register CORBA object for persistence
2811 int nextId = _gen_i->RegisterObject( subMesh );
2812 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2813 else { nextId = 0; } // avoid "unused variable" warning
2815 // to track changes of GEOM groups
2816 if ( subMeshId > 0 )
2817 addGeomGroupData( theSubShapeObject, subMesh );
2819 return subMesh._retn();
2822 //=======================================================================
2823 //function : getSubMesh
2825 //=======================================================================
2827 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2829 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2830 if ( it == _mapSubMeshIor.end() )
2831 return SMESH::SMESH_subMesh::_nil();
2833 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2836 //=============================================================================
2840 //=============================================================================
2842 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2843 GEOM::GEOM_Object_ptr theSubShapeObject )
2845 bool isHypChanged = false;
2846 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2847 return isHypChanged;
2849 const int subMeshId = theSubMesh->GetId();
2851 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2854 if (( _mapSubMesh.count( subMeshId )) &&
2855 ( sm = _impl->GetSubMeshContaining( subMeshId )))
2857 TopoDS_Shape S = sm->GetSubShape();
2860 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2861 isHypChanged = !hyps.empty();
2862 if ( isHypChanged && _preMeshInfo )
2863 _preMeshInfo->ForgetOrLoad();
2864 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2865 for ( ; hyp != hyps.end(); ++hyp )
2866 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2873 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2874 isHypChanged = ( aHypList->length() > 0 );
2875 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2876 removeHypothesis( theSubShapeObject, aHypList[i] );
2879 catch( const SALOME::SALOME_Exception& ) {
2880 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2882 removeGeomGroupData( theSubShapeObject );
2886 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2887 if ( id_smi != _mapSubMesh_i.end() )
2888 id_smi->second->UnRegister();
2890 // remove a CORBA object
2891 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2892 if ( id_smptr != _mapSubMeshIor.end() )
2893 SMESH::SMESH_subMesh_var( id_smptr->second );
2895 _mapSubMesh.erase(subMeshId);
2896 _mapSubMesh_i.erase(subMeshId);
2897 _mapSubMeshIor.erase(subMeshId);
2899 return isHypChanged;
2902 //=============================================================================
2906 //=============================================================================
2908 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2909 const char* theName,
2911 const TopoDS_Shape& theShape,
2912 const SMESH_PredicatePtr& thePredicate )
2914 std::string newName;
2915 if ( !theName || !theName[0] )
2917 std::set< std::string > presentNames;
2918 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2919 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2921 CORBA::String_var name = i_gr->second->GetName();
2922 presentNames.insert( name.in() );
2925 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2926 } while ( !presentNames.insert( newName ).second );
2927 theName = newName.c_str();
2929 SMESH::SMESH_GroupBase_var aGroup;
2930 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
2931 theID, theShape, thePredicate ))
2933 int anId = g->GetID();
2934 SMESH_GroupBase_i* aGroupImpl;
2935 if ( !theShape.IsNull() )
2936 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2937 else if ( thePredicate )
2938 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2940 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2942 aGroup = aGroupImpl->_this();
2943 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2944 aGroupImpl->Register();
2946 // register CORBA object for persistence
2947 int nextId = _gen_i->RegisterObject( aGroup );
2948 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2949 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
2951 // to track changes of GEOM groups
2952 if ( !theShape.IsNull() ) {
2953 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2954 addGeomGroupData( geom, aGroup );
2957 return aGroup._retn();
2960 //=============================================================================
2962 * SMESH_Mesh_i::removeGroup
2964 * Should be called by ~SMESH_Group_i()
2966 //=============================================================================
2968 void SMESH_Mesh_i::removeGroup( const int theId )
2970 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2971 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2972 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2973 _mapGroups.erase( theId );
2974 removeGeomGroupData( group );
2975 if ( !_impl->RemoveGroup( theId ))
2977 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2978 RemoveGroup( group );
2980 group->UnRegister();
2984 //=============================================================================
2988 //=============================================================================
2990 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2991 throw(SALOME::SALOME_Exception)
2993 SMESH::log_array_var aLog;
2997 _preMeshInfo->FullLoadFromFile();
2999 list < SMESHDS_Command * >logDS = _impl->GetLog();
3000 aLog = new SMESH::log_array;
3002 int lg = logDS.size();
3005 list < SMESHDS_Command * >::iterator its = logDS.begin();
3006 while(its != logDS.end()){
3007 SMESHDS_Command *com = *its;
3008 int comType = com->GetType();
3010 int lgcom = com->GetNumber();
3012 const list < int >&intList = com->GetIndexes();
3013 int inum = intList.size();
3015 list < int >::const_iterator ii = intList.begin();
3016 const list < double >&coordList = com->GetCoords();
3017 int rnum = coordList.size();
3019 list < double >::const_iterator ir = coordList.begin();
3020 aLog[indexLog].commandType = comType;
3021 aLog[indexLog].number = lgcom;
3022 aLog[indexLog].coords.length(rnum);
3023 aLog[indexLog].indexes.length(inum);
3024 for(int i = 0; i < rnum; i++){
3025 aLog[indexLog].coords[i] = *ir;
3026 //MESSAGE(" "<<i<<" "<<ir.Value());
3029 for(int i = 0; i < inum; i++){
3030 aLog[indexLog].indexes[i] = *ii;
3031 //MESSAGE(" "<<i<<" "<<ii.Value());
3040 SMESH_CATCH( SMESH::throwCorbaException );
3042 return aLog._retn();
3046 //=============================================================================
3050 //=============================================================================
3052 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3056 SMESH_CATCH( SMESH::throwCorbaException );
3059 //=============================================================================
3063 //=============================================================================
3065 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3070 //=============================================================================
3073 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3074 // issue 0020918: groups removal is caused by hyp modification
3075 // issue 0021208: to forget not loaded mesh data at hyp modification
3076 struct TCallUp_i : public SMESH_Mesh::TCallUp
3078 SMESH_Mesh_i* _mesh;
3079 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3080 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3081 virtual void HypothesisModified( int hypID,
3082 bool updIcons) { _mesh->onHypothesisModified( hypID,
3084 virtual void Load () { _mesh->Load(); }
3085 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3089 //================================================================================
3091 * \brief callback from _impl to
3092 * 1) forget not loaded mesh data (issue 0021208)
3093 * 2) mark hypothesis as valid
3095 //================================================================================
3097 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3100 _preMeshInfo->ForgetOrLoad();
3102 if ( theUpdateIcons )
3104 SMESH::SMESH_Mesh_var mesh = _this();
3105 _gen_i->UpdateIcons( mesh );
3108 if ( _nbInvalidHypos != 0 )
3110 // mark a hypothesis as valid after edition
3112 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3113 SALOMEDS::SObject_wrap hypRoot;
3114 if ( !smeshComp->_is_nil() &&
3115 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3117 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3118 for ( ; anIter->More(); anIter->Next() )
3120 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3121 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3122 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3123 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3124 _gen_i->HighLightInvalid( hyp, false );
3126 nbInvalid += _gen_i->IsInvalid( hypSO );
3129 _nbInvalidHypos = nbInvalid;
3133 //=============================================================================
3137 //=============================================================================
3139 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3141 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3144 _impl->SetCallUp( new TCallUp_i(this));
3147 //=============================================================================
3151 //=============================================================================
3153 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3155 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3159 //=============================================================================
3161 * Return mesh editor
3163 //=============================================================================
3165 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3166 throw (SALOME::SALOME_Exception)
3168 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3172 _preMeshInfo->FullLoadFromFile();
3174 // Create MeshEditor
3176 _editor = new SMESH_MeshEditor_i( this, false );
3177 aMeshEdVar = _editor->_this();
3179 // Update Python script
3180 TPythonDump() << _editor << " = "
3181 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3183 SMESH_CATCH( SMESH::throwCorbaException );
3185 return aMeshEdVar._retn();
3188 //=============================================================================
3190 * Return mesh edition previewer
3192 //=============================================================================
3194 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3195 throw (SALOME::SALOME_Exception)
3197 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3201 _preMeshInfo->FullLoadFromFile();
3203 if ( !_previewEditor )
3204 _previewEditor = new SMESH_MeshEditor_i( this, true );
3205 aMeshEdVar = _previewEditor->_this();
3207 SMESH_CATCH( SMESH::throwCorbaException );
3209 return aMeshEdVar._retn();
3212 //================================================================================
3214 * \brief Return true if the mesh has been edited since a last total re-compute
3215 * and those modifications may prevent successful partial re-compute
3217 //================================================================================
3219 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3221 Unexpect aCatch(SALOME_SalomeException);
3222 return _impl->HasModificationsToDiscard();
3225 //================================================================================
3227 * \brief Returns a random unique color
3229 //================================================================================
3231 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3233 const int MAX_ATTEMPTS = 100;
3235 double tolerance = 0.5;
3236 SALOMEDS::Color col;
3240 // generate random color
3241 double red = (double)rand() / RAND_MAX;
3242 double green = (double)rand() / RAND_MAX;
3243 double blue = (double)rand() / RAND_MAX;
3244 // check existence in the list of the existing colors
3245 bool matched = false;
3246 std::list<SALOMEDS::Color>::const_iterator it;
3247 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3248 SALOMEDS::Color color = *it;
3249 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3250 matched = tol < tolerance;
3252 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3253 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3261 //=============================================================================
3263 * Sets auto-color mode. If it is on, groups get unique random colors
3265 //=============================================================================
3267 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3269 Unexpect aCatch(SALOME_SalomeException);
3270 _impl->SetAutoColor(theAutoColor);
3272 TPythonDump pyDump; // not to dump group->SetColor() from below code
3273 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3275 std::list<SALOMEDS::Color> aReservedColors;
3276 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3277 for ( ; it != _mapGroups.end(); it++ ) {
3278 if ( CORBA::is_nil( it->second )) continue;
3279 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3280 it->second->SetColor( aColor );
3281 aReservedColors.push_back( aColor );
3285 //=============================================================================
3287 * Returns true if auto-color mode is on
3289 //=============================================================================
3291 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3293 Unexpect aCatch(SALOME_SalomeException);
3294 return _impl->GetAutoColor();
3297 //=============================================================================
3299 * Checks if there are groups with equal names
3301 //=============================================================================
3303 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3305 return _impl->HasDuplicatedGroupNamesMED();
3308 //================================================================================
3310 * \brief Care of a file before exporting mesh into it
3312 //================================================================================
3314 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3316 SMESH_File aFile( file, false );
3318 if ( aFile.exists() ) {
3319 // existing filesystem node
3320 if ( !aFile.isDirectory() ) {
3321 if ( aFile.openForWriting() ) {
3322 if ( overwrite && ! aFile.remove()) {
3323 msg << "Can't replace " << aFile.getName();
3326 msg << "Can't write into " << aFile.getName();
3329 msg << "Location " << aFile.getName() << " is not a file";
3333 // nonexisting file; check if it can be created
3334 if ( !aFile.openForWriting() ) {
3335 msg << "You cannot create the file "
3337 << ". Check the directory existence and access rights";
3345 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3349 //================================================================================
3351 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3352 * \param file - file name
3353 * \param overwrite - to erase the file or not
3354 * \retval string - mesh name
3356 //================================================================================
3358 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3359 CORBA::Boolean overwrite)
3362 PrepareForWriting(file, overwrite);
3363 string aMeshName = "Mesh";
3364 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3365 if ( !aStudy->_is_nil() ) {
3366 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3367 if ( !aMeshSO->_is_nil() ) {
3368 CORBA::String_var name = aMeshSO->GetName();
3370 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3371 if ( !aStudy->GetProperties()->IsLocked() )
3373 SALOMEDS::GenericAttribute_wrap anAttr;
3374 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3375 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3376 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3377 ASSERT(!aFileName->_is_nil());
3378 aFileName->SetValue(file);
3379 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3380 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3381 ASSERT(!aFileType->_is_nil());
3382 aFileType->SetValue("FICHIERMED");
3386 // Update Python script
3387 // set name of mesh before export
3388 TPythonDump() << _gen_i << ".SetName("
3389 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3391 // check names of groups
3397 //================================================================================
3399 * \brief Export to MED file
3401 //================================================================================
3403 void SMESH_Mesh_i::ExportMED(const char* file,
3404 CORBA::Boolean auto_groups,
3405 CORBA::Long version,
3406 CORBA::Boolean overwrite,
3407 CORBA::Boolean autoDimension)
3408 throw(SALOME::SALOME_Exception)
3410 //MESSAGE("MED minor version: "<< minor);
3413 _preMeshInfo->FullLoadFromFile();
3415 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3416 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3418 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3420 << "auto_groups=" <<auto_groups << ", "
3421 << "minor=" << version << ", "
3422 << "overwrite=" << overwrite << ", "
3423 << "meshPart=None, "
3424 << "autoDimension=" << autoDimension << " )";
3426 SMESH_CATCH( SMESH::throwCorbaException );
3429 //================================================================================
3431 * \brief Export a mesh to a SAUV file
3433 //================================================================================
3435 void SMESH_Mesh_i::ExportSAUV (const char* file,
3436 CORBA::Boolean auto_groups)
3437 throw(SALOME::SALOME_Exception)
3439 Unexpect aCatch(SALOME_SalomeException);
3441 _preMeshInfo->FullLoadFromFile();
3443 string aMeshName = prepareMeshNameAndGroups(file, true);
3444 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3445 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3446 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3450 //================================================================================
3452 * \brief Export a mesh to a DAT file
3454 //================================================================================
3456 void SMESH_Mesh_i::ExportDAT (const char *file)
3457 throw(SALOME::SALOME_Exception)
3459 Unexpect aCatch(SALOME_SalomeException);
3461 _preMeshInfo->FullLoadFromFile();
3463 // Update Python script
3464 // check names of groups
3466 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3469 PrepareForWriting(file);
3470 _impl->ExportDAT(file);
3473 //================================================================================
3475 * \brief Export a mesh to an UNV file
3477 //================================================================================
3479 void SMESH_Mesh_i::ExportUNV (const char *file)
3480 throw(SALOME::SALOME_Exception)
3482 Unexpect aCatch(SALOME_SalomeException);
3484 _preMeshInfo->FullLoadFromFile();
3486 // Update Python script
3487 // check names of groups
3489 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3492 PrepareForWriting(file);
3493 _impl->ExportUNV(file);
3496 //================================================================================
3498 * \brief Export a mesh to an STL file
3500 //================================================================================
3502 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3503 throw(SALOME::SALOME_Exception)
3505 Unexpect aCatch(SALOME_SalomeException);
3507 _preMeshInfo->FullLoadFromFile();
3509 // Update Python script
3510 // check names of groups
3512 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3513 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3515 CORBA::String_var name;
3516 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3517 if ( !so->_is_nil() )
3518 name = so->GetName();
3521 PrepareForWriting( file );
3522 _impl->ExportSTL( file, isascii, name.in() );
3525 //================================================================================
3527 * \brief Export a part of mesh to a med file
3529 //================================================================================
3531 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3533 CORBA::Boolean auto_groups,
3534 CORBA::Long version,
3535 CORBA::Boolean overwrite,
3536 CORBA::Boolean autoDimension,
3537 const GEOM::ListOfFields& fields,
3538 const char* geomAssocFields,
3539 CORBA::Double ZTolerance)
3540 throw (SALOME::SALOME_Exception)
3542 MESSAGE("MED version: "<< version);
3545 _preMeshInfo->FullLoadFromFile();
3548 bool have0dField = false;
3549 if ( fields.length() > 0 )
3551 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3552 if ( shapeToMesh->_is_nil() )
3553 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3555 for ( size_t i = 0; i < fields.length(); ++i )
3557 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3558 THROW_SALOME_CORBA_EXCEPTION
3559 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3560 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3561 if ( fieldShape->_is_nil() )
3562 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3563 if ( !fieldShape->IsSame( shapeToMesh ) )
3564 THROW_SALOME_CORBA_EXCEPTION
3565 ( "Field defined not on shape", SALOME::BAD_PARAM);
3566 if ( fields[i]->GetDimension() == 0 )
3569 if ( geomAssocFields )
3570 for ( int i = 0; geomAssocFields[i]; ++i )
3571 switch ( geomAssocFields[i] ) {
3572 case 'v':case 'e':case 'f':case 's': break;
3573 case 'V':case 'E':case 'F':case 'S': break;
3574 default: THROW_SALOME_CORBA_EXCEPTION
3575 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3579 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3583 string aMeshName = "Mesh";
3584 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3585 if ( CORBA::is_nil( meshPart ) ||
3586 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3588 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3589 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3590 0, autoDimension, /*addODOnVertices=*/have0dField,
3592 meshDS = _impl->GetMeshDS();
3597 _preMeshInfo->FullLoadFromFile();
3599 PrepareForWriting(file, overwrite);
3601 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3602 if ( !SO->_is_nil() ) {
3603 CORBA::String_var name = SO->GetName();
3607 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3608 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3609 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3610 meshDS = tmpDSDeleter._obj = partDS;
3615 if ( _impl->HasShapeToMesh() )
3617 DriverMED_W_Field fieldWriter;
3618 fieldWriter.SetFile( file );
3619 fieldWriter.SetMeshName( aMeshName );
3620 fieldWriter.AddODOnVertices( have0dField );
3622 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3626 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3627 goList->length( fields.length() );
3628 for ( size_t i = 0; i < fields.length(); ++i )
3630 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3633 TPythonDump() << _this() << ".ExportPartToMED( "
3634 << meshPart << ", r'"
3636 << auto_groups << ", "
3638 << overwrite << ", "
3639 << autoDimension << ", "
3641 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3642 << TVar( ZTolerance )
3645 SMESH_CATCH( SMESH::throwCorbaException );
3648 //================================================================================
3650 * Write GEOM fields to MED file
3652 //================================================================================
3654 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3655 SMESHDS_Mesh* meshDS,
3656 const GEOM::ListOfFields& fields,
3657 const char* geomAssocFields)
3659 #define METH "SMESH_Mesh_i::exportMEDFields() "
3661 if (( fields.length() < 1 ) &&
3662 ( !geomAssocFields || !geomAssocFields[0] ))
3665 std::vector< std::vector< double > > dblVals;
3666 std::vector< std::vector< int > > intVals;
3667 std::vector< int > subIdsByDim[ 4 ];
3668 const double noneDblValue = 0.;
3669 const double noneIntValue = 0;
3671 for ( size_t iF = 0; iF < fields.length(); ++iF )
3675 int dim = fields[ iF ]->GetDimension();
3676 SMDSAbs_ElementType elemType;
3677 TopAbs_ShapeEnum shapeType;
3679 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3680 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3681 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3682 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3684 continue; // skip fields on whole shape
3686 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3687 if ( dataType == GEOM::FDT_String )
3689 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3690 if ( stepIDs->length() < 1 )
3692 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3693 if ( comps->length() < 1 )
3695 CORBA::String_var name = fields[ iF ]->GetName();
3697 if ( !fieldWriter.Set( meshDS,
3701 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3704 for ( size_t iC = 0; iC < comps->length(); ++iC )
3705 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3707 dblVals.resize( comps->length() );
3708 intVals.resize( comps->length() );
3710 // find sub-shape IDs
3712 std::vector< int >& subIds = subIdsByDim[ dim ];
3713 if ( subIds.empty() )
3714 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3715 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3716 subIds.push_back( id );
3720 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3724 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3726 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3727 if ( step->_is_nil() )
3730 CORBA::Long stamp = step->GetStamp();
3731 CORBA::Long id = step->GetID();
3732 fieldWriter.SetDtIt( int( stamp ), int( id ));
3734 // fill dblVals or intVals
3735 for ( size_t iC = 0; iC < comps->length(); ++iC )
3736 if ( dataType == GEOM::FDT_Double )
3738 dblVals[ iC ].clear();
3739 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3743 intVals[ iC ].clear();
3744 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3748 case GEOM::FDT_Double:
3750 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3751 if ( dblStep->_is_nil() ) continue;
3752 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3753 if ( vv->length() != subIds.size() * comps->length() )
3754 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3755 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3756 for ( size_t iC = 0; iC < comps->length(); ++iC )
3757 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3762 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3763 if ( intStep->_is_nil() ) continue;
3764 GEOM::ListOfLong_var vv = intStep->GetValues();
3765 if ( vv->length() != subIds.size() * comps->length() )
3766 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3767 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3768 for ( size_t iC = 0; iC < comps->length(); ++iC )
3769 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3772 case GEOM::FDT_Bool:
3774 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3775 if ( boolStep->_is_nil() ) continue;
3776 GEOM::short_array_var vv = boolStep->GetValues();
3777 if ( vv->length() != subIds.size() * comps->length() )
3778 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3779 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3780 for ( size_t iC = 0; iC < comps->length(); ++iC )
3781 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3787 // pass values to fieldWriter
3788 elemIt = fieldWriter.GetOrderedElems();
3789 if ( dataType == GEOM::FDT_Double )
3790 while ( elemIt->more() )
3792 const SMDS_MeshElement* e = elemIt->next();
3793 const int shapeID = e->getshapeId();
3794 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3795 for ( size_t iC = 0; iC < comps->length(); ++iC )
3796 fieldWriter.AddValue( noneDblValue );
3798 for ( size_t iC = 0; iC < comps->length(); ++iC )
3799 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3802 while ( elemIt->more() )
3804 const SMDS_MeshElement* e = elemIt->next();
3805 const int shapeID = e->getshapeId();
3806 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3807 for ( size_t iC = 0; iC < comps->length(); ++iC )
3808 fieldWriter.AddValue( (double) noneIntValue );
3810 for ( size_t iC = 0; iC < comps->length(); ++iC )
3811 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3815 fieldWriter.Perform();
3816 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3817 if ( res && res->IsKO() )
3819 if ( res->myComment.empty() )
3820 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3822 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3828 if ( !geomAssocFields || !geomAssocFields[0] )
3831 // write geomAssocFields
3833 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3834 shapeDim[ TopAbs_COMPOUND ] = 3;
3835 shapeDim[ TopAbs_COMPSOLID ] = 3;
3836 shapeDim[ TopAbs_SOLID ] = 3;
3837 shapeDim[ TopAbs_SHELL ] = 2;
3838 shapeDim[ TopAbs_FACE ] = 2;
3839 shapeDim[ TopAbs_WIRE ] = 1;
3840 shapeDim[ TopAbs_EDGE ] = 1;
3841 shapeDim[ TopAbs_VERTEX ] = 0;
3842 shapeDim[ TopAbs_SHAPE ] = 3;
3844 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3846 std::vector< std::string > compNames;
3847 switch ( geomAssocFields[ iF ]) {
3849 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3850 compNames.push_back( "dim" );
3853 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3856 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3859 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3863 compNames.push_back( "id" );
3864 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3865 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3867 fieldWriter.SetDtIt( -1, -1 );
3869 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3873 if ( compNames.size() == 2 ) // _vertices_
3874 while ( elemIt->more() )
3876 const SMDS_MeshElement* e = elemIt->next();
3877 const int shapeID = e->getshapeId();
3880 fieldWriter.AddValue( (double) -1 );
3881 fieldWriter.AddValue( (double) -1 );
3885 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3886 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3887 fieldWriter.AddValue( (double) shapeID );
3891 while ( elemIt->more() )
3893 const SMDS_MeshElement* e = elemIt->next();
3894 const int shapeID = e->getshapeId();
3896 fieldWriter.AddValue( (double) -1 );
3898 fieldWriter.AddValue( (double) shapeID );
3902 fieldWriter.Perform();
3903 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3904 if ( res && res->IsKO() )
3906 if ( res->myComment.empty() )
3907 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3909 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3912 } // loop on geomAssocFields
3917 //================================================================================
3919 * \brief Export a part of mesh to a DAT file
3921 //================================================================================
3923 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3925 throw (SALOME::SALOME_Exception)
3927 Unexpect aCatch(SALOME_SalomeException);
3929 _preMeshInfo->FullLoadFromFile();
3931 PrepareForWriting(file);
3933 SMESH_MeshPartDS partDS( meshPart );
3934 _impl->ExportDAT(file,&partDS);
3936 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3937 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3939 //================================================================================
3941 * \brief Export a part of mesh to an UNV file
3943 //================================================================================
3945 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3947 throw (SALOME::SALOME_Exception)
3949 Unexpect aCatch(SALOME_SalomeException);
3951 _preMeshInfo->FullLoadFromFile();
3953 PrepareForWriting(file);
3955 SMESH_MeshPartDS partDS( meshPart );
3956 _impl->ExportUNV(file, &partDS);
3958 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3959 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3961 //================================================================================
3963 * \brief Export a part of mesh to an STL file
3965 //================================================================================
3967 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3969 ::CORBA::Boolean isascii)
3970 throw (SALOME::SALOME_Exception)
3972 Unexpect aCatch(SALOME_SalomeException);
3974 _preMeshInfo->FullLoadFromFile();
3976 PrepareForWriting(file);
3978 CORBA::String_var name;
3979 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3980 if ( !so->_is_nil() )
3981 name = so->GetName();
3983 SMESH_MeshPartDS partDS( meshPart );
3984 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3986 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3987 << meshPart<< ", r'" << file << "', " << isascii << ")";
3990 //================================================================================
3992 * \brief Export a part of mesh to an STL file
3994 //================================================================================
3996 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3998 CORBA::Boolean overwrite,
3999 CORBA::Boolean groupElemsByType)
4000 throw (SALOME::SALOME_Exception)
4003 Unexpect aCatch(SALOME_SalomeException);
4005 _preMeshInfo->FullLoadFromFile();
4007 PrepareForWriting(file,overwrite);
4009 std::string meshName("");
4010 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4011 if ( !so->_is_nil() )
4013 CORBA::String_var name = so->GetName();
4014 meshName = name.in();
4018 SMESH_MeshPartDS partDS( meshPart );
4019 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4021 SMESH_CATCH( SMESH::throwCorbaException );
4023 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4024 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4026 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4030 //================================================================================
4032 * \brief Export a part of mesh to a GMF file
4034 //================================================================================
4036 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4038 bool withRequiredGroups)
4039 throw (SALOME::SALOME_Exception)
4041 Unexpect aCatch(SALOME_SalomeException);
4043 _preMeshInfo->FullLoadFromFile();
4045 PrepareForWriting(file,/*overwrite=*/true);
4047 SMESH_MeshPartDS partDS( meshPart );
4048 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4050 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4051 << meshPart<< ", r'"
4053 << withRequiredGroups << ")";
4056 //=============================================================================
4058 * Return computation progress [0.,1]
4060 //=============================================================================
4062 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4066 return _impl->GetComputeProgress();
4068 SMESH_CATCH( SMESH::doNothing );
4072 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4074 Unexpect aCatch(SALOME_SalomeException);
4076 return _preMeshInfo->NbNodes();
4078 return _impl->NbNodes();
4081 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4083 Unexpect aCatch(SALOME_SalomeException);
4085 return _preMeshInfo->NbElements();
4087 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4090 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4092 Unexpect aCatch(SALOME_SalomeException);
4094 return _preMeshInfo->Nb0DElements();
4096 return _impl->Nb0DElements();
4099 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4101 Unexpect aCatch(SALOME_SalomeException);
4103 return _preMeshInfo->NbBalls();
4105 return _impl->NbBalls();
4108 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4110 Unexpect aCatch(SALOME_SalomeException);
4112 return _preMeshInfo->NbEdges();
4114 return _impl->NbEdges();
4117 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4118 throw(SALOME::SALOME_Exception)
4120 Unexpect aCatch(SALOME_SalomeException);
4122 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4124 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4127 //=============================================================================
4129 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4131 Unexpect aCatch(SALOME_SalomeException);
4133 return _preMeshInfo->NbFaces();
4135 return _impl->NbFaces();
4138 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4140 Unexpect aCatch(SALOME_SalomeException);
4142 return _preMeshInfo->NbTriangles();
4144 return _impl->NbTriangles();
4147 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4149 Unexpect aCatch(SALOME_SalomeException);
4151 return _preMeshInfo->NbBiQuadTriangles();
4153 return _impl->NbBiQuadTriangles();
4156 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4158 Unexpect aCatch(SALOME_SalomeException);
4160 return _preMeshInfo->NbQuadrangles();
4162 return _impl->NbQuadrangles();
4165 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4167 Unexpect aCatch(SALOME_SalomeException);
4169 return _preMeshInfo->NbBiQuadQuadrangles();
4171 return _impl->NbBiQuadQuadrangles();
4174 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4176 Unexpect aCatch(SALOME_SalomeException);
4178 return _preMeshInfo->NbPolygons();
4180 return _impl->NbPolygons();
4183 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4185 Unexpect aCatch(SALOME_SalomeException);
4187 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4189 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4192 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4193 throw(SALOME::SALOME_Exception)
4195 Unexpect aCatch(SALOME_SalomeException);
4197 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4199 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4202 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4203 throw(SALOME::SALOME_Exception)
4205 Unexpect aCatch(SALOME_SalomeException);
4207 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4209 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4212 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4213 throw(SALOME::SALOME_Exception)
4215 Unexpect aCatch(SALOME_SalomeException);
4217 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4219 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4222 //=============================================================================
4224 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4226 Unexpect aCatch(SALOME_SalomeException);
4228 return _preMeshInfo->NbVolumes();
4230 return _impl->NbVolumes();
4233 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4235 Unexpect aCatch(SALOME_SalomeException);
4237 return _preMeshInfo->NbTetras();
4239 return _impl->NbTetras();
4242 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4244 Unexpect aCatch(SALOME_SalomeException);
4246 return _preMeshInfo->NbHexas();
4248 return _impl->NbHexas();
4251 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4253 Unexpect aCatch(SALOME_SalomeException);
4255 return _preMeshInfo->NbTriQuadHexas();
4257 return _impl->NbTriQuadraticHexas();
4260 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4262 Unexpect aCatch(SALOME_SalomeException);
4264 return _preMeshInfo->NbPyramids();
4266 return _impl->NbPyramids();
4269 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4271 Unexpect aCatch(SALOME_SalomeException);
4273 return _preMeshInfo->NbPrisms();
4275 return _impl->NbPrisms();
4278 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4280 Unexpect aCatch(SALOME_SalomeException);
4282 return _preMeshInfo->NbHexPrisms();
4284 return _impl->NbHexagonalPrisms();
4287 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4289 Unexpect aCatch(SALOME_SalomeException);
4291 return _preMeshInfo->NbPolyhedrons();
4293 return _impl->NbPolyhedrons();
4296 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4297 throw(SALOME::SALOME_Exception)
4299 Unexpect aCatch(SALOME_SalomeException);
4301 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4303 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4306 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4307 throw(SALOME::SALOME_Exception)
4309 Unexpect aCatch(SALOME_SalomeException);
4311 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4313 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4316 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4317 throw(SALOME::SALOME_Exception)
4319 Unexpect aCatch(SALOME_SalomeException);
4321 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4323 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4326 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4327 throw(SALOME::SALOME_Exception)
4329 Unexpect aCatch(SALOME_SalomeException);
4331 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4333 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4336 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4337 throw(SALOME::SALOME_Exception)
4339 Unexpect aCatch(SALOME_SalomeException);
4341 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4343 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4346 //=============================================================================
4348 * Returns nb of published sub-meshes
4350 //=============================================================================
4352 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4354 Unexpect aCatch(SALOME_SalomeException);
4355 return _mapSubMesh_i.size();
4358 //=============================================================================
4360 * Dumps mesh into a string
4362 //=============================================================================
4364 char* SMESH_Mesh_i::Dump()
4368 return CORBA::string_dup( os.str().c_str() );
4371 //=============================================================================
4373 * Method of SMESH_IDSource interface
4375 //=============================================================================
4377 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4379 return GetElementsId();
4382 //=============================================================================
4384 * Returns ids of all elements
4386 //=============================================================================
4388 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4389 throw (SALOME::SALOME_Exception)
4391 Unexpect aCatch(SALOME_SalomeException);
4393 _preMeshInfo->FullLoadFromFile();
4395 SMESH::long_array_var aResult = new SMESH::long_array();
4396 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4398 if ( aSMESHDS_Mesh == NULL )
4399 return aResult._retn();
4401 long nbElements = NbElements();
4402 aResult->length( nbElements );
4403 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4404 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4405 aResult[i] = anIt->next()->GetID();
4407 return aResult._retn();
4411 //=============================================================================
4413 * Returns ids of all elements of given type
4415 //=============================================================================
4417 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4418 throw (SALOME::SALOME_Exception)
4420 Unexpect aCatch(SALOME_SalomeException);
4422 _preMeshInfo->FullLoadFromFile();
4424 SMESH::long_array_var aResult = new SMESH::long_array();
4425 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4427 if ( aSMESHDS_Mesh == NULL )
4428 return aResult._retn();
4430 long nbElements = NbElements();
4432 // No sense in returning ids of elements along with ids of nodes:
4433 // when theElemType == SMESH::ALL, return node ids only if
4434 // there are no elements
4435 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4436 return GetNodesId();
4438 aResult->length( nbElements );
4442 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4443 while ( i < nbElements && anIt->more() )
4444 aResult[i++] = anIt->next()->GetID();
4446 aResult->length( i );
4448 return aResult._retn();
4451 //=============================================================================
4453 * Returns ids of all nodes
4455 //=============================================================================
4457 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4458 throw (SALOME::SALOME_Exception)
4460 Unexpect aCatch(SALOME_SalomeException);
4462 _preMeshInfo->FullLoadFromFile();
4464 SMESH::long_array_var aResult = new SMESH::long_array();
4465 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4467 if ( aMeshDS == NULL )
4468 return aResult._retn();
4470 long nbNodes = NbNodes();
4471 aResult->length( nbNodes );
4472 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4473 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4474 aResult[i] = anIt->next()->GetID();
4476 return aResult._retn();
4479 //=============================================================================
4483 //=============================================================================
4485 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4486 throw (SALOME::SALOME_Exception)
4488 SMESH::ElementType type = SMESH::ALL;
4492 _preMeshInfo->FullLoadFromFile();
4494 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4496 SMESH_CATCH( SMESH::throwCorbaException );
4501 //=============================================================================
4505 //=============================================================================
4507 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4508 throw (SALOME::SALOME_Exception)
4511 _preMeshInfo->FullLoadFromFile();
4513 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4515 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4517 return ( SMESH::EntityType ) e->GetEntityType();
4520 //=============================================================================
4524 //=============================================================================
4526 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4527 throw (SALOME::SALOME_Exception)
4530 _preMeshInfo->FullLoadFromFile();
4532 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4534 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4536 return ( SMESH::GeometryType ) e->GetGeomType();
4539 //=============================================================================
4541 * Returns ID of elements for given submesh
4543 //=============================================================================
4544 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4545 throw (SALOME::SALOME_Exception)
4547 SMESH::long_array_var aResult = new SMESH::long_array();
4551 _preMeshInfo->FullLoadFromFile();
4553 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4554 if(!SM) return aResult._retn();
4556 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4557 if(!SDSM) return aResult._retn();
4559 aResult->length(SDSM->NbElements());
4561 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4563 while ( eIt->more() ) {
4564 aResult[i++] = eIt->next()->GetID();
4567 SMESH_CATCH( SMESH::throwCorbaException );
4569 return aResult._retn();
4572 //=============================================================================
4574 * Returns ID of nodes for given submesh
4575 * If param all==true - returns all nodes, else -
4576 * returns only nodes on shapes.
4578 //=============================================================================
4580 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4582 throw (SALOME::SALOME_Exception)
4584 SMESH::long_array_var aResult = new SMESH::long_array();
4588 _preMeshInfo->FullLoadFromFile();
4590 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4591 if(!SM) return aResult._retn();
4593 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4594 if(!SDSM) return aResult._retn();
4597 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4598 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4599 while ( nIt->more() ) {
4600 const SMDS_MeshNode* elem = nIt->next();
4601 theElems.insert( elem->GetID() );
4604 else { // all nodes of submesh elements
4605 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4606 while ( eIt->more() ) {
4607 const SMDS_MeshElement* anElem = eIt->next();
4608 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4609 while ( nIt->more() ) {
4610 const SMDS_MeshElement* elem = nIt->next();
4611 theElems.insert( elem->GetID() );
4616 aResult->length(theElems.size());
4617 set<int>::iterator itElem;
4619 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4620 aResult[i++] = *itElem;
4622 SMESH_CATCH( SMESH::throwCorbaException );
4624 return aResult._retn();
4627 //=============================================================================
4629 * Returns type of elements for given submesh
4631 //=============================================================================
4633 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4634 throw (SALOME::SALOME_Exception)
4636 SMESH::ElementType type = SMESH::ALL;
4640 _preMeshInfo->FullLoadFromFile();
4642 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4643 if(!SM) return SMESH::ALL;
4645 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4646 if(!SDSM) return SMESH::ALL;
4648 if(SDSM->NbElements()==0)
4649 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4651 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4652 const SMDS_MeshElement* anElem = eIt->next();
4654 type = ( SMESH::ElementType ) anElem->GetType();
4656 SMESH_CATCH( SMESH::throwCorbaException );
4662 //=============================================================================
4664 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4666 //=============================================================================
4668 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4671 _preMeshInfo->FullLoadFromFile();
4673 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4674 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4679 //=============================================================================
4681 * Get XYZ coordinates of node as list of double
4682 * If there is not node for given ID - returns empty list
4684 //=============================================================================
4686 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4689 _preMeshInfo->FullLoadFromFile();
4691 SMESH::double_array_var aResult = new SMESH::double_array();
4692 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4693 if ( aMeshDS == NULL )
4694 return aResult._retn();
4697 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4699 return aResult._retn();
4703 aResult[0] = aNode->X();
4704 aResult[1] = aNode->Y();
4705 aResult[2] = aNode->Z();
4706 return aResult._retn();
4710 //=============================================================================
4712 * For given node returns list of IDs of inverse elements
4713 * If there is not node for given ID - returns empty list
4715 //=============================================================================
4717 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4718 SMESH::ElementType elemType)
4721 _preMeshInfo->FullLoadFromFile();
4723 SMESH::long_array_var aResult = new SMESH::long_array();
4724 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4725 if ( aMeshDS == NULL )
4726 return aResult._retn();
4729 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4731 return aResult._retn();
4733 // find inverse elements
4734 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4735 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4736 aResult->length( aNode->NbInverseElements( type ));
4737 for( int i = 0; eIt->more(); ++i )
4739 const SMDS_MeshElement* elem = eIt->next();
4740 aResult[ i ] = elem->GetID();
4742 return aResult._retn();
4745 //=============================================================================
4747 * \brief Return position of a node on shape
4749 //=============================================================================
4751 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4754 _preMeshInfo->FullLoadFromFile();
4756 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4757 aNodePosition->shapeID = 0;
4758 aNodePosition->shapeType = GEOM::SHAPE;
4760 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4761 if ( !mesh ) return aNodePosition;
4763 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4765 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4767 aNodePosition->shapeID = aNode->getshapeId();
4768 switch ( pos->GetTypeOfPosition() ) {
4770 aNodePosition->shapeType = GEOM::EDGE;
4771 aNodePosition->params.length(1);
4772 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4774 case SMDS_TOP_FACE: {
4775 SMDS_FacePositionPtr fPos = pos;
4776 aNodePosition->shapeType = GEOM::FACE;
4777 aNodePosition->params.length(2);
4778 aNodePosition->params[0] = fPos->GetUParameter();
4779 aNodePosition->params[1] = fPos->GetVParameter();
4782 case SMDS_TOP_VERTEX:
4783 aNodePosition->shapeType = GEOM::VERTEX;
4785 case SMDS_TOP_3DSPACE:
4786 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4787 aNodePosition->shapeType = GEOM::SOLID;
4788 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4789 aNodePosition->shapeType = GEOM::SHELL;
4795 return aNodePosition;
4798 //=============================================================================
4800 * \brief Return position of an element on shape
4802 //=============================================================================
4804 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4807 _preMeshInfo->FullLoadFromFile();
4809 SMESH::ElementPosition anElementPosition;
4810 anElementPosition.shapeID = 0;
4811 anElementPosition.shapeType = GEOM::SHAPE;
4813 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4814 if ( !mesh ) return anElementPosition;
4816 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4818 anElementPosition.shapeID = anElem->getshapeId();
4819 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4820 if ( !aSp.IsNull() ) {
4821 switch ( aSp.ShapeType() ) {
4823 anElementPosition.shapeType = GEOM::EDGE;
4826 anElementPosition.shapeType = GEOM::FACE;
4829 anElementPosition.shapeType = GEOM::VERTEX;
4832 anElementPosition.shapeType = GEOM::SOLID;
4835 anElementPosition.shapeType = GEOM::SHELL;
4841 return anElementPosition;
4844 //=============================================================================
4846 * If given element is node returns IDs of shape from position
4847 * If there is not node for given ID - returns -1
4849 //=============================================================================
4851 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4854 _preMeshInfo->FullLoadFromFile();
4856 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4857 if ( aMeshDS == NULL )
4861 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4863 return aNode->getshapeId();
4870 //=============================================================================
4872 * For given element returns ID of result shape after
4873 * ::FindShape() from SMESH_MeshEditor
4874 * If there is not element for given ID - returns -1
4876 //=============================================================================
4878 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4881 _preMeshInfo->FullLoadFromFile();
4883 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4884 if ( aMeshDS == NULL )
4887 // try to find element
4888 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4892 ::SMESH_MeshEditor aMeshEditor(_impl);
4893 int index = aMeshEditor.FindShape( elem );
4901 //=============================================================================
4903 * Returns number of nodes for given element
4904 * If there is not element for given ID - returns -1
4906 //=============================================================================
4908 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4911 _preMeshInfo->FullLoadFromFile();
4913 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4914 if ( aMeshDS == NULL ) return -1;
4915 // try to find element
4916 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4917 if(!elem) return -1;
4918 return elem->NbNodes();
4922 //=============================================================================
4924 * Returns ID of node by given index for given element
4925 * If there is not element for given ID - returns -1
4926 * If there is not node for given index - returns -2
4928 //=============================================================================
4930 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4933 _preMeshInfo->FullLoadFromFile();
4935 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4936 if ( aMeshDS == NULL ) return -1;
4937 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4938 if(!elem) return -1;
4939 if( index>=elem->NbNodes() || index<0 ) return -1;
4940 return elem->GetNode(index)->GetID();
4943 //=============================================================================
4945 * Returns IDs of nodes of given element
4947 //=============================================================================
4949 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4952 _preMeshInfo->FullLoadFromFile();
4954 SMESH::long_array_var aResult = new SMESH::long_array();
4955 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4957 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4959 aResult->length( elem->NbNodes() );
4960 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4961 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
4962 aResult[ i ] = n->GetID();
4965 return aResult._retn();
4968 //=============================================================================
4970 * Returns true if given node is medium node
4971 * in given quadratic element
4973 //=============================================================================
4975 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4978 _preMeshInfo->FullLoadFromFile();
4980 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4981 if ( aMeshDS == NULL ) return false;
4983 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4984 if(!aNode) return false;
4985 // try to find element
4986 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4987 if(!elem) return false;
4989 return elem->IsMediumNode(aNode);
4993 //=============================================================================
4995 * Returns true if given node is medium node
4996 * in one of quadratic elements
4998 //=============================================================================
5000 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5001 SMESH::ElementType theElemType)
5004 _preMeshInfo->FullLoadFromFile();
5006 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5007 if ( aMeshDS == NULL ) return false;
5010 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5011 if(!aNode) return false;
5013 SMESH_MesherHelper aHelper( *(_impl) );
5015 SMDSAbs_ElementType aType;
5016 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5017 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5018 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5019 else aType = SMDSAbs_All;
5021 return aHelper.IsMedium(aNode,aType);
5025 //=============================================================================
5027 * Returns number of edges for given element
5029 //=============================================================================
5031 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5034 _preMeshInfo->FullLoadFromFile();
5036 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5037 if ( aMeshDS == NULL ) return -1;
5038 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5039 if(!elem) return -1;
5040 return elem->NbEdges();
5044 //=============================================================================
5046 * Returns number of faces for given element
5048 //=============================================================================
5050 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5053 _preMeshInfo->FullLoadFromFile();
5055 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5056 if ( aMeshDS == NULL ) return -1;
5057 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5058 if(!elem) return -1;
5059 return elem->NbFaces();
5062 //=======================================================================
5063 //function : GetElemFaceNodes
5064 //purpose : Returns nodes of given face (counted from zero) for given element.
5065 //=======================================================================
5067 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5068 CORBA::Short faceIndex)
5071 _preMeshInfo->FullLoadFromFile();
5073 SMESH::long_array_var aResult = new SMESH::long_array();
5074 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5076 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5078 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5079 if ( faceIndex < vtool.NbFaces() )
5081 aResult->length( vtool.NbFaceNodes( faceIndex ));
5082 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5083 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5084 aResult[ i ] = nn[ i ]->GetID();
5088 return aResult._retn();
5091 //=======================================================================
5092 //function : GetFaceNormal
5093 //purpose : Returns three components of normal of given mesh face.
5094 //=======================================================================
5096 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5097 CORBA::Boolean normalized)
5100 _preMeshInfo->FullLoadFromFile();
5102 SMESH::double_array_var aResult = new SMESH::double_array();
5104 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5107 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5109 aResult->length( 3 );
5110 aResult[ 0 ] = normal.X();
5111 aResult[ 1 ] = normal.Y();
5112 aResult[ 2 ] = normal.Z();
5115 return aResult._retn();
5118 //=======================================================================
5119 //function : FindElementByNodes
5120 //purpose : Returns an element based on all given nodes.
5121 //=======================================================================
5123 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5126 _preMeshInfo->FullLoadFromFile();
5128 CORBA::Long elemID(0);
5129 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5131 vector< const SMDS_MeshNode * > nn( nodes.length() );
5132 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5133 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5136 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5137 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5138 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5139 _impl->NbVolumes( ORDER_QUADRATIC )))
5140 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5142 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5147 //================================================================================
5149 * \brief Return elements including all given nodes.
5151 //================================================================================
5153 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5154 SMESH::ElementType elemType)
5157 _preMeshInfo->FullLoadFromFile();
5159 SMESH::long_array_var result = new SMESH::long_array();
5161 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5163 vector< const SMDS_MeshNode * > nn( nodes.length() );
5164 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5165 nn[i] = mesh->FindNode( nodes[i] );
5167 std::vector<const SMDS_MeshElement *> elems;
5168 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5169 result->length( elems.size() );
5170 for ( size_t i = 0; i < elems.size(); ++i )
5171 result[i] = elems[i]->GetID();
5173 return result._retn();
5176 //=============================================================================
5178 * Returns true if given element is polygon
5180 //=============================================================================
5182 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5185 _preMeshInfo->FullLoadFromFile();
5187 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5188 if ( aMeshDS == NULL ) return false;
5189 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5190 if(!elem) return false;
5191 return elem->IsPoly();
5195 //=============================================================================
5197 * Returns true if given element is quadratic
5199 //=============================================================================
5201 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5204 _preMeshInfo->FullLoadFromFile();
5206 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5207 if ( aMeshDS == NULL ) return false;
5208 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5209 if(!elem) return false;
5210 return elem->IsQuadratic();
5213 //=============================================================================
5215 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5217 //=============================================================================
5219 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5222 _preMeshInfo->FullLoadFromFile();
5224 if ( const SMDS_BallElement* ball =
5225 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5226 return ball->GetDiameter();
5231 //=============================================================================
5233 * Returns bary center for given element
5235 //=============================================================================
5237 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5240 _preMeshInfo->FullLoadFromFile();
5242 SMESH::double_array_var aResult = new SMESH::double_array();
5243 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5244 if ( aMeshDS == NULL )
5245 return aResult._retn();
5247 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5249 return aResult._retn();
5251 if(elem->GetType()==SMDSAbs_Volume) {
5252 SMDS_VolumeTool aTool;
5253 if(aTool.Set(elem)) {
5255 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5260 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5262 double x=0., y=0., z=0.;
5263 for(; anIt->more(); ) {
5265 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5279 return aResult._retn();
5282 //================================================================================
5284 * \brief Create a group of elements preventing computation of a sub-shape
5286 //================================================================================
5288 SMESH::ListOfGroups*
5289 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5290 const char* theGroupName )
5291 throw ( SALOME::SALOME_Exception )
5293 Unexpect aCatch(SALOME_SalomeException);
5295 if ( !theGroupName || strlen( theGroupName) == 0 )
5296 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5298 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5299 ::SMESH_MeshEditor::ElemFeatures elemType;
5301 // submesh by subshape id
5302 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5303 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5306 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5307 if ( error && error->HasBadElems() )
5309 // sort bad elements by type
5310 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5311 const list<const SMDS_MeshElement*>& badElems =
5312 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5313 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5314 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5315 for ( ; elemIt != elemEnd; ++elemIt )
5317 const SMDS_MeshElement* elem = *elemIt;
5318 if ( !elem ) continue;
5320 if ( elem->GetID() < 1 )
5322 // elem is a temporary element, make a real element
5323 vector< const SMDS_MeshNode* > nodes;
5324 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5325 while ( nIt->more() && elem )
5327 nodes.push_back( nIt->next() );
5328 if ( nodes.back()->GetID() < 1 )
5329 elem = 0; // a temporary element on temporary nodes
5333 ::SMESH_MeshEditor editor( _impl );
5334 elem = editor.AddElement( nodes, elemType.Init( elem ));
5338 elemsByType[ elem->GetType() ].push_back( elem );
5341 // how many groups to create?
5343 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5344 nbTypes += int( !elemsByType[ i ].empty() );
5345 groups->length( nbTypes );
5348 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5350 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5351 if ( elems.empty() ) continue;
5353 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5354 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5356 SMESH::SMESH_Mesh_var mesh = _this();
5357 SALOMEDS::SObject_wrap aSO =
5358 _gen_i->PublishGroup( mesh, groups[ iG ],
5359 GEOM::GEOM_Object::_nil(), theGroupName);
5361 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5362 if ( !grp_i ) continue;
5364 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5365 for ( size_t iE = 0; iE < elems.size(); ++iE )
5366 grpDS->SMDSGroup().Add( elems[ iE ]);
5371 return groups._retn();
5374 //=============================================================================
5376 * Create and publish group servants if any groups were imported or created anyhow
5378 //=============================================================================
5380 void SMESH_Mesh_i::CreateGroupServants()
5382 SMESH::SMESH_Mesh_var aMesh = _this();
5385 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5386 while ( groupIt->more() )
5388 ::SMESH_Group* group = groupIt->next();
5389 int anId = group->GetID();
5391 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5392 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5394 addedIDs.insert( anId );
5396 SMESH_GroupBase_i* aGroupImpl;
5398 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5399 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5401 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5402 shape = groupOnGeom->GetShape();
5405 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5408 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5409 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5410 aGroupImpl->Register();
5412 // register CORBA object for persistence
5413 int nextId = _gen_i->RegisterObject( groupVar );
5414 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5415 else { nextId = 0; } // avoid "unused variable" warning in release mode
5417 // publishing the groups in the study
5418 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5419 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5421 if ( !addedIDs.empty() )
5424 set<int>::iterator id = addedIDs.begin();
5425 for ( ; id != addedIDs.end(); ++id )
5427 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5428 int i = std::distance( _mapGroups.begin(), it );
5429 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5434 //=============================================================================
5436 * \brief Return true if all sub-meshes are computed OK - to update an icon
5438 //=============================================================================
5440 bool SMESH_Mesh_i::IsComputedOK()
5442 return _impl->IsComputedOK();
5445 //=============================================================================
5447 * \brief Return groups cantained in _mapGroups by their IDs
5449 //=============================================================================
5451 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5453 int nbGroups = groupIDs.size();
5454 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5455 aList->length( nbGroups );
5457 list<int>::const_iterator ids = groupIDs.begin();
5458 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5460 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5461 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5462 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5464 aList->length( nbGroups );
5465 return aList._retn();
5468 //=============================================================================
5470 * \brief Return information about imported file
5472 //=============================================================================
5474 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5476 SMESH::MedFileInfo_var res( _medFileInfo );
5477 if ( !res.operator->() ) {
5478 res = new SMESH::MedFileInfo;
5480 res->fileSize = res->major = res->minor = res->release = -1;
5485 //=======================================================================
5486 //function : FileInfoToString
5487 //purpose : Persistence of file info
5488 //=======================================================================
5490 std::string SMESH_Mesh_i::FileInfoToString()
5493 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5495 s = SMESH_Comment( _medFileInfo->fileSize )
5496 << " " << _medFileInfo->major
5497 << " " << _medFileInfo->minor
5498 << " " << _medFileInfo->release
5499 << " " << _medFileInfo->fileName;
5504 //=======================================================================
5505 //function : FileInfoFromString
5506 //purpose : Persistence of file info
5507 //=======================================================================
5509 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5511 std::string size, major, minor, release, fileName;
5512 std::istringstream is(info);
5513 is >> size >> major >> minor >> release;
5514 fileName = info.data() + ( size.size() + 1 +
5517 release.size()+ 1 );
5519 _medFileInfo = new SMESH::MedFileInfo();
5520 _medFileInfo->fileName = fileName.c_str();
5521 _medFileInfo->fileSize = atoi( size.c_str() );
5522 _medFileInfo->major = atoi( major.c_str() );
5523 _medFileInfo->minor = atoi( minor.c_str() );
5524 _medFileInfo->release = atoi( release.c_str() );
5527 //=============================================================================
5529 * \brief Pass names of mesh groups from study to mesh DS
5531 //=============================================================================
5533 void SMESH_Mesh_i::checkGroupNames()
5535 int nbGrp = NbGroups();
5539 SMESH::ListOfGroups* grpList = 0;
5540 // avoid dump of "GetGroups"
5542 // store python dump into a local variable inside local scope
5543 SMESH::TPythonDump pDump; // do not delete this line of code
5544 grpList = GetGroups();
5547 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5548 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5551 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5552 if ( aGrpSO->_is_nil() )
5554 // correct name of the mesh group if necessary
5555 const char* guiName = aGrpSO->GetName();
5556 if ( strcmp(guiName, aGrp->GetName()) )
5557 aGrp->SetName( guiName );
5561 //=============================================================================
5563 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5565 //=============================================================================
5566 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5568 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5572 //=============================================================================
5574 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5576 //=============================================================================
5578 char* SMESH_Mesh_i::GetParameters()
5580 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5583 //=============================================================================
5585 * \brief Returns list of notebook variables used for last Mesh operation
5587 //=============================================================================
5588 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5590 SMESH::string_array_var aResult = new SMESH::string_array();
5591 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5593 CORBA::String_var aParameters = GetParameters();
5594 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5595 if ( aSections->length() > 0 ) {
5596 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5597 aResult->length( aVars.length() );
5598 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5599 aResult[i] = CORBA::string_dup( aVars[i] );
5602 return aResult._retn();
5605 //=======================================================================
5606 //function : GetTypes
5607 //purpose : Returns types of elements it contains
5608 //=======================================================================
5610 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5613 return _preMeshInfo->GetTypes();
5615 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5619 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5620 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5621 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5622 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5623 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5624 if (_impl->NbNodes() &&
5625 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5626 types->length( nbTypes );
5628 return types._retn();
5631 //=======================================================================
5632 //function : GetMesh
5633 //purpose : Returns self
5634 //=======================================================================
5636 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5638 return SMESH::SMESH_Mesh::_duplicate( _this() );
5641 //=======================================================================
5642 //function : IsMeshInfoCorrect
5643 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5644 // * happen if mesh data is not yet fully loaded from the file of study.
5645 //=======================================================================
5647 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5649 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5652 //=============================================================================
5654 * \brief Returns number of mesh elements per each \a EntityType
5656 //=============================================================================
5658 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5661 return _preMeshInfo->GetMeshInfo();
5663 SMESH::long_array_var aRes = new SMESH::long_array();
5664 aRes->length(SMESH::Entity_Last);
5665 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5667 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5669 return aRes._retn();
5670 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5671 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5672 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5673 return aRes._retn();
5676 //=============================================================================
5678 * \brief Returns number of mesh elements per each \a ElementType
5680 //=============================================================================
5682 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5684 SMESH::long_array_var aRes = new SMESH::long_array();
5685 aRes->length(SMESH::NB_ELEMENT_TYPES);
5686 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5689 const SMDS_MeshInfo* meshInfo = 0;
5691 meshInfo = _preMeshInfo;
5692 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5693 meshInfo = & meshDS->GetMeshInfo();
5696 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5697 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5699 return aRes._retn();
5702 //=============================================================================
5704 * Collect statistic of mesh elements given by iterator
5706 //=============================================================================
5708 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5709 SMESH::long_array& theInfo)
5711 if (!theItr) return;
5712 while (theItr->more())
5713 theInfo[ theItr->next()->GetEntityType() ]++;
5715 //=============================================================================
5717 * Returns mesh unstructed grid information.
5719 //=============================================================================
5721 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5723 SALOMEDS::TMPFile_var SeqFile;
5724 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5725 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5727 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5728 aWriter->WriteToOutputStringOn();
5729 aWriter->SetInputData(aGrid);
5730 aWriter->SetFileTypeToBinary();
5732 char* str = aWriter->GetOutputString();
5733 int size = aWriter->GetOutputStringLength();
5735 //Allocate octet buffer of required size
5736 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5737 //Copy ostrstream content to the octet buffer
5738 memcpy(OctetBuf, str, size);
5739 //Create and return TMPFile
5740 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5744 return SeqFile._retn();
5747 //=============================================================================
5748 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5749 * SMESH::ElementType type) */
5751 using namespace SMESH::Controls;
5752 //-----------------------------------------------------------------------------
5753 struct PredicateIterator : public SMDS_ElemIterator
5755 SMDS_ElemIteratorPtr _elemIter;
5756 PredicatePtr _predicate;
5757 const SMDS_MeshElement* _elem;
5758 SMDSAbs_ElementType _type;
5760 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5761 PredicatePtr predicate,
5762 SMDSAbs_ElementType type):
5763 _elemIter(iterator), _predicate(predicate), _type(type)
5771 virtual const SMDS_MeshElement* next()
5773 const SMDS_MeshElement* res = _elem;
5775 while ( _elemIter->more() && !_elem )
5777 if ((_elem = _elemIter->next()) &&
5778 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5779 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5786 //-----------------------------------------------------------------------------
5787 struct IDSourceIterator : public SMDS_ElemIterator
5789 const CORBA::Long* _idPtr;
5790 const CORBA::Long* _idEndPtr;
5791 SMESH::long_array_var _idArray;
5792 const SMDS_Mesh* _mesh;
5793 const SMDSAbs_ElementType _type;
5794 const SMDS_MeshElement* _elem;
5796 IDSourceIterator( const SMDS_Mesh* mesh,
5797 const CORBA::Long* ids,
5799 SMDSAbs_ElementType type):
5800 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5802 if ( _idPtr && nbIds && _mesh )
5805 IDSourceIterator( const SMDS_Mesh* mesh,
5806 SMESH::long_array* idArray,
5807 SMDSAbs_ElementType type):
5808 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5810 if ( idArray && _mesh )
5812 _idPtr = &_idArray[0];
5813 _idEndPtr = _idPtr + _idArray->length();
5821 virtual const SMDS_MeshElement* next()
5823 const SMDS_MeshElement* res = _elem;
5825 while ( _idPtr < _idEndPtr && !_elem )
5827 if ( _type == SMDSAbs_Node )
5829 _elem = _mesh->FindNode( *_idPtr++ );
5831 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5832 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5840 //-----------------------------------------------------------------------------
5842 struct NodeOfElemIterator : public SMDS_ElemIterator
5844 TColStd_MapOfInteger _checkedNodeIDs;
5845 SMDS_ElemIteratorPtr _elemIter;
5846 SMDS_ElemIteratorPtr _nodeIter;
5847 const SMDS_MeshElement* _node;
5849 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5851 if ( _elemIter && _elemIter->more() )
5853 _nodeIter = _elemIter->next()->nodesIterator();
5861 virtual const SMDS_MeshElement* next()
5863 const SMDS_MeshElement* res = _node;
5865 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5867 if ( _nodeIter->more() )
5869 _node = _nodeIter->next();
5870 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5875 _nodeIter = _elemIter->next()->nodesIterator();
5883 //=============================================================================
5885 * Return iterator on elements of given type in given object
5887 //=============================================================================
5889 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5890 SMESH::ElementType theType)
5892 SMDS_ElemIteratorPtr elemIt;
5893 bool typeOK = ( theType == SMESH::ALL );
5894 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5896 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5897 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5898 if ( !mesh_i ) return elemIt;
5899 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5901 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5903 elemIt = meshDS->elementsIterator( elemType );
5906 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5908 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5911 elemIt = sm->GetElements();
5912 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5914 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5915 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5919 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5921 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5922 if ( groupDS && ( elemType == groupDS->GetType() ||
5923 elemType == SMDSAbs_Node ||
5924 elemType == SMDSAbs_All ))
5926 elemIt = groupDS->GetElements();
5927 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5930 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5932 if ( filter_i->GetElementType() == theType ||
5933 filter_i->GetElementType() == SMESH::ALL ||
5934 elemType == SMDSAbs_Node ||
5935 elemType == SMDSAbs_All)
5937 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5938 if ( pred_i && pred_i->GetPredicate() )
5940 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5941 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5942 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
5943 elemIt = SMDS_ElemIteratorPtr
5944 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
5945 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
5951 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5952 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5953 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5955 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
5956 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5959 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5960 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
5964 SMESH::long_array_var ids = theObject->GetIDs();
5965 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
5967 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5970 if ( elemIt && elemIt->more() && !typeOK )
5972 if ( elemType == SMDSAbs_Node )
5974 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5978 elemIt = SMDS_ElemIteratorPtr();
5984 //=============================================================================
5985 namespace // Finding concurrent hypotheses
5986 //=============================================================================
5990 * \brief mapping of mesh dimension into shape type
5992 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5994 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5996 case 0: aType = TopAbs_VERTEX; break;
5997 case 1: aType = TopAbs_EDGE; break;
5998 case 2: aType = TopAbs_FACE; break;
6000 default:aType = TopAbs_SOLID; break;
6005 //-----------------------------------------------------------------------------
6007 * \brief Internal structure used to find concurrent submeshes
6009 * It represents a pair < submesh, concurrent dimension >, where
6010 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6011 * with another submesh. In other words, it is dimension of a hypothesis assigned
6018 int _dim; //!< a dimension the algo can build (concurrent dimension)
6019 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6020 TopTools_MapOfShape _shapeMap;
6021 SMESH_subMesh* _subMesh;
6022 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6024 //-----------------------------------------------------------------------------
6025 // Return the algorithm
6026 const SMESH_Algo* GetAlgo() const
6027 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6029 //-----------------------------------------------------------------------------
6031 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6033 const TopoDS_Shape& theShape)
6035 _subMesh = (SMESH_subMesh*)theSubMesh;
6036 SetShape( theDim, theShape );
6039 //-----------------------------------------------------------------------------
6041 void SetShape(const int theDim,
6042 const TopoDS_Shape& theShape)
6045 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6046 if (_dim >= _ownDim)
6047 _shapeMap.Add( theShape );
6049 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6050 for( ; anExp.More(); anExp.Next() )
6051 _shapeMap.Add( anExp.Current() );
6055 //-----------------------------------------------------------------------------
6056 //! Check sharing of sub-shapes
6057 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6058 const TopTools_MapOfShape& theToFind,
6059 const TopAbs_ShapeEnum theType)
6061 bool isShared = false;
6062 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6063 for (; !isShared && anItr.More(); anItr.Next() )
6065 const TopoDS_Shape aSubSh = anItr.Key();
6066 // check for case when concurrent dimensions are same
6067 isShared = theToFind.Contains( aSubSh );
6068 // check for sub-shape with concurrent dimension
6069 TopExp_Explorer anExp( aSubSh, theType );
6070 for ( ; !isShared && anExp.More(); anExp.Next() )
6071 isShared = theToFind.Contains( anExp.Current() );
6076 //-----------------------------------------------------------------------------
6077 //! check algorithms
6078 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6079 const SMESHDS_Hypothesis* theA2)
6081 if ( !theA1 || !theA2 ||
6082 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6083 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6084 return false; // one of the hypothesis is not algorithm
6085 // check algorithm names (should be equal)
6086 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6090 //-----------------------------------------------------------------------------
6091 //! Check if sub-shape hypotheses are concurrent
6092 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6094 if ( _subMesh == theOther->_subMesh )
6095 return false; // same sub-shape - should not be
6097 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6098 // any of the two submeshes is not on COMPOUND shape )
6099 // -> no concurrency
6100 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6101 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6102 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6103 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6104 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6107 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6108 if ( !checkSubShape )
6111 // check algorithms to be same
6112 const SMESH_Algo* a1 = this->GetAlgo();
6113 const SMESH_Algo* a2 = theOther->GetAlgo();
6114 bool isSame = checkAlgo( a1, a2 );
6118 return false; // pb?
6119 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6122 // check hypothesises for concurrence (skip first as algorithm)
6124 // pointers should be same, because it is referened from mesh hypothesis partition
6125 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6126 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6127 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6128 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6130 // the submeshes are concurrent if their algorithms has different parameters
6131 return nbSame != theOther->_hypotheses.size() - 1;
6134 // Return true if algorithm of this SMESH_DimHyp is used if no
6135 // sub-mesh order is imposed by the user
6136 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6138 // NeedDiscreteBoundary() algo has a higher priority
6139 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6140 theOther->GetAlgo()->NeedDiscreteBoundary() )
6141 return !this->GetAlgo()->NeedDiscreteBoundary();
6143 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6146 }; // end of SMESH_DimHyp
6147 //-----------------------------------------------------------------------------
6149 typedef list<const SMESH_DimHyp*> TDimHypList;
6151 //-----------------------------------------------------------------------------
6153 void addDimHypInstance(const int theDim,
6154 const TopoDS_Shape& theShape,
6155 const SMESH_Algo* theAlgo,
6156 const SMESH_subMesh* theSubMesh,
6157 const list <const SMESHDS_Hypothesis*>& theHypList,
6158 TDimHypList* theDimHypListArr )
6160 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6161 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6162 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6163 dimHyp->_hypotheses.push_front(theAlgo);
6164 listOfdimHyp.push_back( dimHyp );
6167 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6168 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6169 theHypList.begin(), theHypList.end() );
6172 //-----------------------------------------------------------------------------
6173 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6174 TDimHypList& theListOfConcurr)
6176 if ( theListOfConcurr.empty() )
6178 theListOfConcurr.push_back( theDimHyp );
6182 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6183 while ( hypIt != theListOfConcurr.end() &&
6184 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6186 theListOfConcurr.insert( hypIt, theDimHyp );
6190 //-----------------------------------------------------------------------------
6191 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6192 const TDimHypList& theListOfDimHyp,
6193 TDimHypList& theListOfConcurrHyp,
6194 set<int>& theSetOfConcurrId )
6196 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6197 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6199 const SMESH_DimHyp* curDimHyp = *rIt;
6200 if ( curDimHyp == theDimHyp )
6201 break; // meet own dimHyp pointer in same dimension
6203 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6204 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6206 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6211 //-----------------------------------------------------------------------------
6212 void unionLists(TListOfInt& theListOfId,
6213 TListOfListOfInt& theListOfListOfId,
6216 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6217 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6219 continue; //skip already treated lists
6220 // check if other list has any same submesh object
6221 TListOfInt& otherListOfId = *it;
6222 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6223 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6226 // union two lists (from source into target)
6227 TListOfInt::iterator it2 = otherListOfId.begin();
6228 for ( ; it2 != otherListOfId.end(); it2++ ) {
6229 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6230 theListOfId.push_back(*it2);
6232 // clear source list
6233 otherListOfId.clear();
6236 //-----------------------------------------------------------------------------
6238 //! free memory allocated for dimension-hypothesis objects
6239 void removeDimHyps( TDimHypList* theArrOfList )
6241 for (int i = 0; i < 4; i++ ) {
6242 TDimHypList& listOfdimHyp = theArrOfList[i];
6243 TDimHypList::const_iterator it = listOfdimHyp.begin();
6244 for ( ; it != listOfdimHyp.end(); it++ )
6249 //-----------------------------------------------------------------------------
6251 * \brief find common submeshes with given submesh
6252 * \param theSubMeshList list of already collected submesh to check
6253 * \param theSubMesh given submesh to intersect with other
6254 * \param theCommonSubMeshes collected common submeshes
6256 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6257 const SMESH_subMesh* theSubMesh,
6258 set<const SMESH_subMesh*>& theCommon )
6262 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6263 for ( ; it != theSubMeshList.end(); it++ )
6264 theSubMesh->FindIntersection( *it, theCommon );
6265 theSubMeshList.push_back( theSubMesh );
6266 //theCommon.insert( theSubMesh );
6269 //-----------------------------------------------------------------------------
6270 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6272 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6273 for ( ; listsIt != smLists.end(); ++listsIt )
6275 const TListOfInt& smIDs = *listsIt;
6276 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6284 //=============================================================================
6286 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6288 //=============================================================================
6290 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6292 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6293 if ( isSubMeshInList( submeshID, anOrder ))
6296 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6297 return isSubMeshInList( submeshID, allConurrent );
6300 //=============================================================================
6302 * \brief Return submesh objects list in meshing order
6304 //=============================================================================
6306 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6308 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6310 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6312 return aResult._retn();
6314 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6315 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6316 anOrder.splice( anOrder.end(), allConurrent );
6319 TListOfListOfInt::iterator listIt = anOrder.begin();
6320 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6321 unionLists( *listIt, anOrder, listIndx + 1 );
6323 // convert submesh ids into interface instances
6324 // and dump command into python
6325 convertMeshOrder( anOrder, aResult, false );
6327 return aResult._retn();
6330 //=============================================================================
6332 * \brief Finds concurrent sub-meshes
6334 //=============================================================================
6336 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6338 TListOfListOfInt anOrder;
6339 ::SMESH_Mesh& mesh = GetImpl();
6341 // collect submeshes and detect concurrent algorithms and hypothesises
6342 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6344 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6345 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6346 ::SMESH_subMesh* sm = (*i_sm).second;
6348 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6350 // list of assigned hypothesises
6351 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6352 // Find out dimensions where the submesh can be concurrent.
6353 // We define the dimensions by algo of each of hypotheses in hypList
6354 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6355 for( ; hypIt != hypList.end(); hypIt++ ) {
6356 SMESH_Algo* anAlgo = 0;
6357 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6358 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6359 // hyp it-self is algo
6360 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6362 // try to find algorithm with help of sub-shapes
6363 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6364 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6365 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6368 continue; // no algorithm assigned to a current submesh
6370 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6371 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6373 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6374 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6375 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6377 } // end iterations on submesh
6379 // iterate on created dimension-hypotheses and check for concurrents
6380 for ( int i = 0; i < 4; i++ ) {
6381 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6382 // check for concurrents in own and other dimensions (step-by-step)
6383 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6384 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6385 const SMESH_DimHyp* dimHyp = *dhIt;
6386 TDimHypList listOfConcurr;
6387 set<int> setOfConcurrIds;
6388 // looking for concurrents and collect into own list
6389 for ( int j = i; j < 4; j++ )
6390 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6391 // check if any concurrents found
6392 if ( listOfConcurr.size() > 0 ) {
6393 // add own submesh to list of concurrent
6394 addInOrderOfPriority( dimHyp, listOfConcurr );
6395 list<int> listOfConcurrIds;
6396 TDimHypList::iterator hypIt = listOfConcurr.begin();
6397 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6398 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6399 anOrder.push_back( listOfConcurrIds );
6404 removeDimHyps(dimHypListArr);
6406 // now, minimize the number of concurrent groups
6407 // Here we assume that lists of submeshes can have same submesh
6408 // in case of multi-dimension algorithms, as result
6409 // list with common submesh has to be united into one list
6411 TListOfListOfInt::iterator listIt = anOrder.begin();
6412 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6413 unionLists( *listIt, anOrder, listIndx + 1 );
6419 //=============================================================================
6421 * \brief Set submesh object order
6422 * \param theSubMeshArray submesh array order
6424 //=============================================================================
6426 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6429 _preMeshInfo->ForgetOrLoad();
6432 ::SMESH_Mesh& mesh = GetImpl();
6434 TPythonDump aPythonDump; // prevent dump of called methods
6435 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6437 TListOfListOfInt subMeshOrder;
6438 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6440 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6441 TListOfInt subMeshIds;
6443 aPythonDump << ", ";
6444 aPythonDump << "[ ";
6445 // Collect subMeshes which should be clear
6446 // do it list-by-list, because modification of submesh order
6447 // take effect between concurrent submeshes only
6448 set<const SMESH_subMesh*> subMeshToClear;
6449 list<const SMESH_subMesh*> subMeshList;
6450 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6452 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6454 aPythonDump << ", ";
6455 aPythonDump << subMesh;
6456 subMeshIds.push_back( subMesh->GetId() );
6457 // detect common parts of submeshes
6458 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6459 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6461 aPythonDump << " ]";
6462 subMeshOrder.push_back( subMeshIds );
6464 // clear collected sub-meshes
6465 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6466 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6467 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6469 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6470 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6471 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6474 aPythonDump << " ])";
6476 mesh.SetMeshOrder( subMeshOrder );
6479 SMESH::SMESH_Mesh_var me = _this();
6480 _gen_i->UpdateIcons( me );
6485 //=============================================================================
6487 * \brief Convert submesh ids into submesh interfaces
6489 //=============================================================================
6491 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6492 SMESH::submesh_array_array& theResOrder,
6493 const bool theIsDump)
6495 int nbSet = theIdsOrder.size();
6496 TPythonDump aPythonDump; // prevent dump of called methods
6498 aPythonDump << "[ ";
6499 theResOrder.length(nbSet);
6500 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6502 for( ; it != theIdsOrder.end(); it++ ) {
6503 // translate submesh identificators into submesh objects
6504 // takeing into account real number of concurrent lists
6505 const TListOfInt& aSubOrder = (*it);
6506 if (!aSubOrder.size())
6509 aPythonDump << "[ ";
6510 // convert shape indices into interfaces
6511 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6512 aResSubSet->length(aSubOrder.size());
6513 TListOfInt::const_iterator subIt = aSubOrder.begin();
6515 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6516 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6518 SMESH::SMESH_subMesh_var subMesh =
6519 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6522 aPythonDump << ", ";
6523 aPythonDump << subMesh;
6525 aResSubSet[ j++ ] = subMesh;
6528 aPythonDump << " ]";
6530 theResOrder[ listIndx++ ] = aResSubSet;
6532 // correct number of lists
6533 theResOrder.length( listIndx );
6536 // finilise python dump
6537 aPythonDump << " ]";
6538 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6542 namespace // utils used by SMESH_MeshPartDS
6545 * \brief Class used to access to protected data of SMDS_MeshInfo
6547 struct TMeshInfo : public SMDS_MeshInfo
6549 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6552 * \brief Element holing its ID only
6554 struct TElemID : public SMDS_LinearEdge
6556 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6560 //================================================================================
6562 // Implementation of SMESH_MeshPartDS
6564 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6565 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6567 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6568 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6571 _meshDS = mesh_i->GetImpl().GetMeshDS();
6573 SetPersistentId( _meshDS->GetPersistentId() );
6575 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6577 // <meshPart> is the whole mesh
6578 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6580 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6581 myGroupSet = _meshDS->GetGroups();
6586 SMESH::long_array_var anIDs = meshPart->GetIDs();
6587 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6588 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6590 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6591 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6592 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6597 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6598 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6599 if ( _elements[ e->GetType() ].insert( e ).second )
6602 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6603 while ( nIt->more() )
6605 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6606 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6613 ShapeToMesh( _meshDS->ShapeToMesh() );
6615 _meshDS = 0; // to enforce iteration on _elements and _nodes
6618 // -------------------------------------------------------------------------------------
6619 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6620 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6623 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6624 for ( ; partIt != meshPart.end(); ++partIt )
6625 if ( const SMDS_MeshElement * e = *partIt )
6626 if ( _elements[ e->GetType() ].insert( e ).second )
6629 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6630 while ( nIt->more() )
6632 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6633 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6639 // -------------------------------------------------------------------------------------
6640 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6642 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6644 TElemID elem( IDelem );
6645 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6646 if ( !_elements[ iType ].empty() )
6648 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6649 if ( it != _elements[ iType ].end() )
6654 // -------------------------------------------------------------------------------------
6655 bool SMESH_MeshPartDS::HasNumerationHoles()
6657 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6659 return ( MinNodeID() != 1 ||
6660 MaxNodeID() != NbNodes() ||
6661 MinElementID() != 1 ||
6662 MaxElementID() != NbElements() );
6664 // -------------------------------------------------------------------------------------
6665 int SMESH_MeshPartDS::MaxNodeID() const
6667 if ( _meshDS ) return _meshDS->MaxNodeID();
6668 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6670 // -------------------------------------------------------------------------------------
6671 int SMESH_MeshPartDS::MinNodeID() const
6673 if ( _meshDS ) return _meshDS->MinNodeID();
6674 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6676 // -------------------------------------------------------------------------------------
6677 int SMESH_MeshPartDS::MaxElementID() const
6679 if ( _meshDS ) return _meshDS->MaxElementID();
6681 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6682 if ( !_elements[ iType ].empty() )
6683 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6686 // -------------------------------------------------------------------------------------
6687 int SMESH_MeshPartDS::MinElementID() const
6689 if ( _meshDS ) return _meshDS->MinElementID();
6691 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6692 if ( !_elements[ iType ].empty() )
6693 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6696 // -------------------------------------------------------------------------------------
6697 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6699 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6701 typedef SMDS_SetIterator
6702 <const SMDS_MeshElement*,
6703 TIDSortedElemSet::const_iterator,
6704 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6705 SMDS_MeshElement::GeomFilter
6708 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6710 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6711 _elements[type].end(),
6712 SMDS_MeshElement::GeomFilter( geomType )));
6714 // -------------------------------------------------------------------------------------
6715 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6717 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6719 typedef SMDS_SetIterator
6720 <const SMDS_MeshElement*,
6721 TIDSortedElemSet::const_iterator,
6722 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6723 SMDS_MeshElement::EntityFilter
6726 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6728 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6729 _elements[type].end(),
6730 SMDS_MeshElement::EntityFilter( entity )));
6732 // -------------------------------------------------------------------------------------
6733 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6735 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6736 if ( type == SMDSAbs_All && !_meshDS )
6738 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6740 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6741 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6743 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6745 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6746 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6748 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6749 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6751 // -------------------------------------------------------------------------------------
6752 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6753 iterType SMESH_MeshPartDS::methName() const \
6755 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6756 return _meshDS ? _meshDS->methName() : iterType \
6757 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6759 // -------------------------------------------------------------------------------------
6760 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6761 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6762 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6763 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6764 #undef _GET_ITER_DEFINE
6766 // END Implementation of SMESH_MeshPartDS
6768 //================================================================================