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++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
131 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
132 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
133 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
135 aGroup->UnRegister();
136 SMESH::SMESH_GroupBase_var( itGr->second );
141 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
142 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
143 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
145 aSubMesh->UnRegister();
146 SMESH::SMESH_subMesh_var( itSM->second );
148 _mapSubMeshIor.clear();
150 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
151 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
152 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
153 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
154 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
155 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
158 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
162 // clear cached shapes if no more meshes remain; (the cache is blame,
163 // together with publishing, of spent time increasing in issue 22874)
164 if ( _impl->NbMeshes() == 1 )
165 _gen_i->GetShapeReader()->ClearClientBuffer();
167 delete _editor; _editor = NULL;
168 delete _previewEditor; _previewEditor = NULL;
169 delete _impl; _impl = NULL;
170 delete _preMeshInfo; _preMeshInfo = NULL;
173 //=============================================================================
177 * Associates <this> mesh with <theShape> and puts a reference
178 * to <theShape> into the current study;
179 * the previous shape is substituted by the new one.
181 //=============================================================================
183 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
184 throw (SALOME::SALOME_Exception)
186 Unexpect aCatch(SALOME_SalomeException);
188 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
190 catch(SALOME_Exception & S_ex) {
191 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
193 // to track changes of GEOM groups
194 SMESH::SMESH_Mesh_var mesh = _this();
195 addGeomGroupData( theShapeObject, mesh );
196 if ( !CORBA::is_nil( theShapeObject ))
197 _mainShapeTick = theShapeObject->GetTick();
200 //================================================================================
202 * \brief return true if mesh has a shape to build a shape on
204 //================================================================================
206 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
207 throw (SALOME::SALOME_Exception)
209 Unexpect aCatch(SALOME_SalomeException);
212 res = _impl->HasShapeToMesh();
214 catch(SALOME_Exception & S_ex) {
215 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
220 //=======================================================================
221 //function : GetShapeToMesh
223 //=======================================================================
225 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
226 throw (SALOME::SALOME_Exception)
228 Unexpect aCatch(SALOME_SalomeException);
229 GEOM::GEOM_Object_var aShapeObj;
231 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
234 aShapeObj = _gen_i->ShapeToGeomObject( S );
235 if ( aShapeObj->_is_nil() )
237 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
238 // find GEOM_Object by entry (IPAL52735)
239 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
240 for ( ; data != _geomGroupData.end(); ++data )
241 if ( data->_smeshObject->_is_equivalent( _this() ))
243 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
244 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
245 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
251 catch(SALOME_Exception & S_ex) {
252 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
254 return aShapeObj._retn();
257 //================================================================================
259 * \brief Return false if the mesh is not yet fully loaded from the study file
261 //================================================================================
263 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
265 Unexpect aCatch(SALOME_SalomeException);
266 return !_preMeshInfo;
269 //================================================================================
271 * \brief Load full mesh data from the study file
273 //================================================================================
275 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
277 Unexpect aCatch(SALOME_SalomeException);
279 _preMeshInfo->FullLoadFromFile();
282 //================================================================================
284 * \brief Remove all nodes and elements
286 //================================================================================
288 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
290 Unexpect aCatch(SALOME_SalomeException);
292 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
296 //CheckGeomGroupModif(); // issue 20145
298 catch(SALOME_Exception & S_ex) {
299 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
302 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
304 SMESH::SMESH_Mesh_var mesh = _this();
305 _gen_i->UpdateIcons( mesh );
308 //================================================================================
310 * \brief Remove all nodes and elements for indicated shape
312 //================================================================================
314 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
315 throw (SALOME::SALOME_Exception)
317 Unexpect aCatch(SALOME_SalomeException);
319 _preMeshInfo->FullLoadFromFile();
322 _impl->ClearSubMesh( ShapeID );
324 catch(SALOME_Exception & S_ex) {
325 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
327 _impl->GetMeshDS()->Modified();
329 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
332 //=============================================================================
334 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
336 //=============================================================================
338 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
340 SMESH::DriverMED_ReadStatus res;
343 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
344 res = SMESH::DRS_OK; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
346 res = SMESH::DRS_EMPTY; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
348 res = SMESH::DRS_WARN_RENUMBER; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
350 res = SMESH::DRS_WARN_SKIP_ELEM; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
352 res = SMESH::DRS_WARN_DESCENDING; break;
353 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
355 res = SMESH::DRS_FAIL; break;
360 //=============================================================================
362 * Convert ::SMESH_ComputeError to SMESH::ComputeError
364 //=============================================================================
366 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
368 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
369 errVar->subShapeID = -1;
370 errVar->hasBadMesh = false;
372 if ( !errorPtr || errorPtr->IsOK() )
374 errVar->code = SMESH::COMPERR_OK;
378 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
379 errVar->comment = errorPtr->myComment.c_str();
381 return errVar._retn();
384 //=============================================================================
388 * Imports mesh data from MED file
390 //=============================================================================
392 SMESH::DriverMED_ReadStatus
393 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
394 throw ( SALOME::SALOME_Exception )
396 Unexpect aCatch(SALOME_SalomeException);
399 status = _impl->MEDToMesh( theFileName, theMeshName );
401 catch( SALOME_Exception& S_ex ) {
402 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
405 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
408 CreateGroupServants();
410 int major, minor, release;
411 major = minor = release = 0;
412 MED::GetMEDVersion(theFileName, major, minor, release);
413 _medFileInfo = new SMESH::MedFileInfo();
414 _medFileInfo->fileName = theFileName;
415 _medFileInfo->fileSize = 0;
416 _medFileInfo->major = major;
417 _medFileInfo->minor = minor;
418 _medFileInfo->release = release;
419 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
421 return ConvertDriverMEDReadStatus(status);
424 //================================================================================
426 * \brief Imports mesh data from the CGNS file
428 //================================================================================
430 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
431 const int theMeshIndex,
432 std::string& theMeshName )
433 throw ( SALOME::SALOME_Exception )
435 Unexpect aCatch(SALOME_SalomeException);
438 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
440 catch( SALOME_Exception& S_ex ) {
441 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
444 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
447 CreateGroupServants();
449 _medFileInfo = new SMESH::MedFileInfo();
450 _medFileInfo->fileName = theFileName;
451 _medFileInfo->major = 0;
452 _medFileInfo->minor = 0;
453 _medFileInfo->release = 0;
454 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
456 return ConvertDriverMEDReadStatus(status);
459 //================================================================================
461 * \brief Return string representation of a MED file version comprising nbDigits
463 //================================================================================
465 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
467 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
469 return CORBA::string_dup( ver.c_str() );
472 //================================================================================
474 * Return the list of med versions compatibles for write/append,
475 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
477 //================================================================================
478 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
480 SMESH::long_array_var aResult = new SMESH::long_array();
481 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
482 long nbver = mvok.size();
483 aResult->length( nbver );
484 for ( int i = 0; i < nbver; i++ )
485 aResult[i] = mvok[i];
486 return aResult._retn();
489 //=============================================================================
493 * Imports mesh data from MED file
495 //=============================================================================
497 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
498 throw ( SALOME::SALOME_Exception )
502 // Read mesh with name = <theMeshName> into SMESH_Mesh
503 _impl->UNVToMesh( theFileName );
505 CreateGroupServants();
507 _medFileInfo = new SMESH::MedFileInfo();
508 _medFileInfo->fileName = theFileName;
509 _medFileInfo->major = 0;
510 _medFileInfo->minor = 0;
511 _medFileInfo->release = 0;
512 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
514 SMESH_CATCH( SMESH::throwCorbaException );
519 //=============================================================================
523 * Imports mesh data from STL file
525 //=============================================================================
526 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
527 throw ( SALOME::SALOME_Exception )
531 // Read mesh with name = <theMeshName> into SMESH_Mesh
532 std::string name = _impl->STLToMesh( theFileName );
535 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
536 _gen_i->SetName( meshSO, name.c_str() );
538 _medFileInfo = new SMESH::MedFileInfo();
539 _medFileInfo->fileName = theFileName;
540 _medFileInfo->major = 0;
541 _medFileInfo->minor = 0;
542 _medFileInfo->release = 0;
543 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
545 SMESH_CATCH( SMESH::throwCorbaException );
550 //================================================================================
552 * \brief Function used in SMESH_CATCH by ImportGMFFile()
554 //================================================================================
558 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
560 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
564 //================================================================================
566 * \brief Imports data from a GMF file and returns an error description
568 //================================================================================
570 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
571 bool theMakeRequiredGroups )
572 throw (SALOME::SALOME_Exception)
574 SMESH_ComputeErrorPtr error;
577 #define SMESH_CAUGHT error =
580 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
582 _medFileInfo = new SMESH::MedFileInfo();
583 _medFileInfo->fileName = theFileName;
584 _medFileInfo->major = 0;
585 _medFileInfo->minor = 0;
586 _medFileInfo->release = 0;
587 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
589 SMESH_CATCH( exceptionToComputeError );
593 CreateGroupServants();
595 return ConvertComputeError( error );
598 //=============================================================================
602 //=============================================================================
604 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
606 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
607 (SMESH_Hypothesis::Hypothesis_Status theStatus)
610 RETURNCASE( HYP_OK );
611 RETURNCASE( HYP_MISSING );
612 RETURNCASE( HYP_CONCURRENT );
613 RETURNCASE( HYP_BAD_PARAMETER );
614 RETURNCASE( HYP_HIDDEN_ALGO );
615 RETURNCASE( HYP_HIDING_ALGO );
616 RETURNCASE( HYP_UNKNOWN_FATAL );
617 RETURNCASE( HYP_INCOMPATIBLE );
618 RETURNCASE( HYP_NOTCONFORM );
619 RETURNCASE( HYP_ALREADY_EXIST );
620 RETURNCASE( HYP_BAD_DIM );
621 RETURNCASE( HYP_BAD_SUBSHAPE );
622 RETURNCASE( HYP_BAD_GEOMETRY );
623 RETURNCASE( HYP_NEED_SHAPE );
624 RETURNCASE( HYP_INCOMPAT_HYPS );
627 return SMESH::HYP_UNKNOWN_FATAL;
630 //=============================================================================
634 * calls internal addHypothesis() and then adds a reference to <anHyp> under
635 * the SObject actually having a reference to <aSubShape>.
636 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
638 //=============================================================================
640 SMESH::Hypothesis_Status
641 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
642 SMESH::SMESH_Hypothesis_ptr anHyp,
643 CORBA::String_out anErrorText)
644 throw(SALOME::SALOME_Exception)
646 Unexpect aCatch(SALOME_SalomeException);
648 _preMeshInfo->ForgetOrLoad();
651 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
652 anErrorText = error.c_str();
654 SMESH::SMESH_Mesh_var mesh( _this() );
655 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
657 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
658 _gen_i->UpdateIcons( mesh );
660 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
662 // Update Python script
663 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
664 << aSubShape << ", " << anHyp << " )";
666 return ConvertHypothesisStatus(status);
669 //=============================================================================
673 //=============================================================================
675 SMESH_Hypothesis::Hypothesis_Status
676 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
677 SMESH::SMESH_Hypothesis_ptr anHyp,
678 std::string* anErrorText)
680 if(MYDEBUG) MESSAGE("addHypothesis");
682 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
683 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
685 if (CORBA::is_nil( anHyp ))
686 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
688 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
691 TopoDS_Shape myLocSubShape;
692 //use PseudoShape in case if mesh has no shape
694 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
696 myLocSubShape = _impl->GetShapeToMesh();
698 const int hypId = anHyp->GetId();
700 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
701 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
703 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
705 // assure there is a corresponding submesh
706 if ( !_impl->IsMainShape( myLocSubShape )) {
707 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
708 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
709 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
712 else if ( anErrorText )
714 *anErrorText = error;
717 catch(SALOME_Exception & S_ex)
719 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
724 //=============================================================================
728 //=============================================================================
730 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
731 SMESH::SMESH_Hypothesis_ptr anHyp)
732 throw(SALOME::SALOME_Exception)
734 Unexpect aCatch(SALOME_SalomeException);
736 _preMeshInfo->ForgetOrLoad();
738 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
739 SMESH::SMESH_Mesh_var mesh = _this();
741 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
743 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
744 _gen_i->UpdateIcons( mesh );
746 // Update Python script
747 if(_impl->HasShapeToMesh())
748 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
749 << aSubShape << ", " << anHyp << " )";
751 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
754 return ConvertHypothesisStatus(status);
757 //=============================================================================
761 //=============================================================================
763 SMESH_Hypothesis::Hypothesis_Status
764 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
765 SMESH::SMESH_Hypothesis_ptr anHyp)
767 if(MYDEBUG) MESSAGE("removeHypothesis()");
769 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
770 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
772 if (CORBA::is_nil( anHyp ))
773 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
776 _preMeshInfo->ForgetOrLoad();
778 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
781 TopoDS_Shape myLocSubShape;
782 //use PseudoShape in case if mesh has no shape
783 if( _impl->HasShapeToMesh() )
784 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
786 myLocSubShape = _impl->GetShapeToMesh();
788 const int hypId = anHyp->GetId();
789 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
790 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
792 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
796 catch(SALOME_Exception & S_ex)
798 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
803 //=============================================================================
807 //=============================================================================
809 SMESH::ListOfHypothesis *
810 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
811 throw(SALOME::SALOME_Exception)
813 Unexpect aCatch(SALOME_SalomeException);
814 if (MYDEBUG) MESSAGE("GetHypothesisList");
815 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
816 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
818 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
821 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
822 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
823 myLocSubShape = _impl->GetShapeToMesh();
824 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
825 int i = 0, n = aLocalList.size();
828 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
829 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
830 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
832 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
833 if ( id_hypptr != _mapHypo.end() )
834 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
838 catch(SALOME_Exception & S_ex) {
839 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
842 return aList._retn();
845 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
847 Unexpect aCatch(SALOME_SalomeException);
848 if (MYDEBUG) MESSAGE("GetSubMeshes");
850 SMESH::submesh_array_var aList = new SMESH::submesh_array();
853 TPythonDump aPythonDump;
854 if ( !_mapSubMeshIor.empty() )
858 aList->length( _mapSubMeshIor.size() );
860 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
861 for ( ; it != _mapSubMeshIor.end(); it++ ) {
862 if ( CORBA::is_nil( it->second )) continue;
863 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
865 if (i > 1) aPythonDump << ", ";
866 aPythonDump << it->second;
870 catch(SALOME_Exception & S_ex) {
871 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
874 // Update Python script
875 if ( !_mapSubMeshIor.empty() )
876 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
878 return aList._retn();
881 //=============================================================================
885 //=============================================================================
887 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
888 const char* theName )
889 throw(SALOME::SALOME_Exception)
891 Unexpect aCatch(SALOME_SalomeException);
892 if (CORBA::is_nil(aSubShape))
893 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
895 SMESH::SMESH_subMesh_var subMesh;
896 SMESH::SMESH_Mesh_var aMesh = _this();
898 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
900 //Get or Create the SMESH_subMesh object implementation
902 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
904 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
906 TopoDS_Iterator it( myLocSubShape );
908 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
910 subMesh = getSubMesh( subMeshId );
912 // create a new subMesh object servant if there is none for the shape
913 if ( subMesh->_is_nil() )
914 subMesh = createSubMesh( aSubShape );
915 if ( _gen_i->CanPublishInStudy( subMesh ))
917 SALOMEDS::SObject_wrap aSO =
918 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
919 if ( !aSO->_is_nil()) {
920 // Update Python script
921 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
922 << aSubShape << ", '" << theName << "' )";
926 catch(SALOME_Exception & S_ex) {
927 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
929 return subMesh._retn();
932 //=============================================================================
936 //=============================================================================
938 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
939 throw (SALOME::SALOME_Exception)
943 if ( theSubMesh->_is_nil() )
946 GEOM::GEOM_Object_var aSubShape;
947 // Remove submesh's SObject
948 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
949 if ( !anSO->_is_nil() ) {
950 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
951 SALOMEDS::SObject_wrap anObj, aRef;
952 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
953 anObj->ReferencedObject( aRef.inout() ))
955 CORBA::Object_var obj = aRef->GetObject();
956 aSubShape = GEOM::GEOM_Object::_narrow( obj );
958 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
959 // aSubShape = theSubMesh->GetSubShape();
961 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
962 builder->RemoveObjectWithChildren( anSO );
964 // Update Python script
965 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
968 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
970 _preMeshInfo->ForgetOrLoad();
972 SMESH_CATCH( SMESH::throwCorbaException );
975 //=============================================================================
979 //=============================================================================
981 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
982 const char* theName )
983 throw(SALOME::SALOME_Exception)
985 Unexpect aCatch(SALOME_SalomeException);
987 _preMeshInfo->FullLoadFromFile();
989 SMESH::SMESH_Group_var aNewGroup =
990 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
992 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
994 SMESH::SMESH_Mesh_var mesh = _this();
995 SALOMEDS::SObject_wrap aSO =
996 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
997 if ( !aSO->_is_nil())
998 // Update Python script
999 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1000 << theElemType << ", '" << theName << "' )";
1002 return aNewGroup._retn();
1005 //=============================================================================
1009 //=============================================================================
1010 SMESH::SMESH_GroupOnGeom_ptr
1011 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1012 const char* theName,
1013 GEOM::GEOM_Object_ptr theGeomObj)
1014 throw(SALOME::SALOME_Exception)
1016 Unexpect aCatch(SALOME_SalomeException);
1018 _preMeshInfo->FullLoadFromFile();
1020 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1022 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1023 if ( !aShape.IsNull() )
1026 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1028 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1030 SMESH::SMESH_Mesh_var mesh = _this();
1031 SALOMEDS::SObject_wrap aSO =
1032 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1033 if ( !aSO->_is_nil())
1034 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1035 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1039 return aNewGroup._retn();
1042 //================================================================================
1044 * \brief Creates a group whose contents is defined by filter
1045 * \param theElemType - group type
1046 * \param theName - group name
1047 * \param theFilter - the filter
1048 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1050 //================================================================================
1052 SMESH::SMESH_GroupOnFilter_ptr
1053 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1054 const char* theName,
1055 SMESH::Filter_ptr theFilter )
1056 throw (SALOME::SALOME_Exception)
1058 Unexpect aCatch(SALOME_SalomeException);
1060 _preMeshInfo->FullLoadFromFile();
1062 if ( CORBA::is_nil( theFilter ))
1063 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1065 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1067 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1069 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1070 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1073 if ( !aNewGroup->_is_nil() )
1074 aNewGroup->SetFilter( theFilter );
1076 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1078 SMESH::SMESH_Mesh_var mesh = _this();
1079 SALOMEDS::SObject_wrap aSO =
1080 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1082 if ( !aSO->_is_nil())
1083 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1084 << theElemType << ", '" << theName << "', " << theFilter << " )";
1086 return aNewGroup._retn();
1089 //=============================================================================
1093 //=============================================================================
1095 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1096 throw (SALOME::SALOME_Exception)
1098 if ( theGroup->_is_nil() )
1103 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1107 if ( aGroup->GetMeshServant() != this )
1108 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1109 SALOME::BAD_PARAM );
1111 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1112 if ( !aGroupSO->_is_nil() )
1114 // Update Python script
1115 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1117 // Remove group's SObject
1118 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1119 builder->RemoveObjectWithChildren( aGroupSO );
1121 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1123 // Remove the group from SMESH data structures
1124 removeGroup( aGroup->GetLocalID() );
1126 SMESH_CATCH( SMESH::throwCorbaException );
1129 //=============================================================================
1131 * Remove group with its contents
1133 //=============================================================================
1135 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1136 throw (SALOME::SALOME_Exception)
1140 _preMeshInfo->FullLoadFromFile();
1142 if ( theGroup->_is_nil() )
1145 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1146 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1147 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1150 vector<int> nodeIds; // to remove nodes becoming free
1151 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1152 if ( !isNodal && !theGroup->IsEmpty() )
1154 CORBA::Long elemID = theGroup->GetID( 1 );
1155 int nbElemNodes = GetElemNbNodes( elemID );
1156 if ( nbElemNodes > 0 )
1157 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1160 // Retrieve contents
1161 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1162 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1163 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1164 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1165 elems.assign( elemBeg, elemEnd );
1167 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1170 RemoveGroup( theGroup );
1173 for ( size_t i = 0; i < elems.size(); ++i )
1175 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1179 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1180 nodeIds.push_back( nIt->next()->GetID() );
1182 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1186 _impl->GetMeshDS()->RemoveElement( elems[i] );
1190 // Remove free nodes
1191 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1192 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1193 if ( n->NbInverseElements() == 0 )
1194 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1196 // Update Python script (theGroup must be alive for this)
1197 pyDump << SMESH::SMESH_Mesh_var(_this())
1198 << ".RemoveGroupWithContents( " << theGroup << " )";
1200 SMESH_CATCH( SMESH::throwCorbaException );
1203 //================================================================================
1205 * \brief Get the list of groups existing in the mesh
1206 * \retval SMESH::ListOfGroups * - list of groups
1208 //================================================================================
1210 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1212 Unexpect aCatch(SALOME_SalomeException);
1213 if (MYDEBUG) MESSAGE("GetGroups");
1215 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1218 TPythonDump aPythonDump;
1219 if ( !_mapGroups.empty() )
1221 aPythonDump << "[ ";
1223 aList->length( _mapGroups.size() );
1225 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1226 for ( ; it != _mapGroups.end(); it++ ) {
1227 if ( CORBA::is_nil( it->second )) continue;
1228 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1230 if (i > 1) aPythonDump << ", ";
1231 aPythonDump << it->second;
1235 catch(SALOME_Exception & S_ex) {
1236 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1238 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1240 return aList._retn();
1243 //=============================================================================
1245 * Get number of groups existing in the mesh
1247 //=============================================================================
1249 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1251 Unexpect aCatch(SALOME_SalomeException);
1252 return _mapGroups.size();
1255 //=============================================================================
1257 * New group including all mesh elements present in initial groups is created.
1259 //=============================================================================
1261 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1262 SMESH::SMESH_GroupBase_ptr theGroup2,
1263 const char* theName )
1264 throw (SALOME::SALOME_Exception)
1266 SMESH::SMESH_Group_var aResGrp;
1270 _preMeshInfo->FullLoadFromFile();
1272 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1273 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1275 if ( theGroup1->GetType() != theGroup2->GetType() )
1276 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1281 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1282 if ( aResGrp->_is_nil() )
1283 return SMESH::SMESH_Group::_nil();
1285 aResGrp->AddFrom( theGroup1 );
1286 aResGrp->AddFrom( theGroup2 );
1288 // Update Python script
1289 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1290 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1292 SMESH_CATCH( SMESH::throwCorbaException );
1294 return aResGrp._retn();
1297 //=============================================================================
1299 * \brief New group including all mesh elements present in initial groups is created.
1300 * \param theGroups list of groups
1301 * \param theName name of group to be created
1302 * \return pointer to the new group
1304 //=============================================================================
1306 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1307 const char* theName )
1308 throw (SALOME::SALOME_Exception)
1310 SMESH::SMESH_Group_var aResGrp;
1313 _preMeshInfo->FullLoadFromFile();
1316 return SMESH::SMESH_Group::_nil();
1321 SMESH::ElementType aType = SMESH::ALL;
1322 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1324 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1325 if ( CORBA::is_nil( aGrp ) )
1327 if ( aType == SMESH::ALL )
1328 aType = aGrp->GetType();
1329 else if ( aType != aGrp->GetType() )
1330 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1333 if ( aType == SMESH::ALL )
1334 return SMESH::SMESH_Group::_nil();
1339 aResGrp = CreateGroup( aType, theName );
1340 if ( aResGrp->_is_nil() )
1341 return SMESH::SMESH_Group::_nil();
1343 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1344 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1346 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1347 if ( !CORBA::is_nil( aGrp ) )
1349 aResGrp->AddFrom( aGrp );
1350 if ( g > 0 ) pyDump << ", ";
1354 pyDump << " ], '" << theName << "' )";
1356 SMESH_CATCH( SMESH::throwCorbaException );
1358 return aResGrp._retn();
1361 //=============================================================================
1363 * New group is created. All mesh elements that are
1364 * present in both initial groups are added to the new one.
1366 //=============================================================================
1368 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1369 SMESH::SMESH_GroupBase_ptr theGroup2,
1370 const char* theName )
1371 throw (SALOME::SALOME_Exception)
1373 SMESH::SMESH_Group_var aResGrp;
1378 _preMeshInfo->FullLoadFromFile();
1380 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1381 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1383 if ( theGroup1->GetType() != theGroup2->GetType() )
1384 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1388 // Create Intersection
1389 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1390 if ( aResGrp->_is_nil() )
1391 return aResGrp._retn();
1393 SMESHDS_GroupBase* groupDS1 = 0;
1394 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1395 groupDS1 = grp_i->GetGroupDS();
1397 SMESHDS_GroupBase* groupDS2 = 0;
1398 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1399 groupDS2 = grp_i->GetGroupDS();
1401 SMESHDS_Group* resGroupDS = 0;
1402 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1403 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1405 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1407 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1408 while ( elemIt1->more() )
1410 const SMDS_MeshElement* e = elemIt1->next();
1411 if ( groupDS2->Contains( e ))
1412 resGroupDS->SMDSGroup().Add( e );
1415 // Update Python script
1416 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1417 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1419 SMESH_CATCH( SMESH::throwCorbaException );
1421 return aResGrp._retn();
1424 //=============================================================================
1426 \brief Intersect list of groups. New group is created. All mesh elements that
1427 are present in all initial groups simultaneously are added to the new one.
1428 \param theGroups list of groups
1429 \param theName name of group to be created
1430 \return pointer on the group
1432 //=============================================================================
1433 SMESH::SMESH_Group_ptr
1434 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1435 const char* theName )
1436 throw (SALOME::SALOME_Exception)
1438 SMESH::SMESH_Group_var aResGrp;
1443 _preMeshInfo->FullLoadFromFile();
1446 return SMESH::SMESH_Group::_nil();
1448 // check types and get SMESHDS_GroupBase's
1449 SMESH::ElementType aType = SMESH::ALL;
1450 vector< SMESHDS_GroupBase* > groupVec;
1451 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1453 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1454 if ( CORBA::is_nil( aGrp ) )
1456 if ( aType == SMESH::ALL )
1457 aType = aGrp->GetType();
1458 else if ( aType != aGrp->GetType() )
1459 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1462 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1463 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1465 if ( grpDS->IsEmpty() )
1470 groupVec.push_back( grpDS );
1473 if ( aType == SMESH::ALL ) // all groups are nil
1474 return SMESH::SMESH_Group::_nil();
1479 aResGrp = CreateGroup( aType, theName );
1481 SMESHDS_Group* resGroupDS = 0;
1482 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1483 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1484 if ( !resGroupDS || groupVec.empty() )
1485 return aResGrp._retn();
1488 size_t i, nb = groupVec.size();
1489 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1490 while ( elemIt1->more() )
1492 const SMDS_MeshElement* e = elemIt1->next();
1494 for ( i = 1; ( i < nb && inAll ); ++i )
1495 inAll = groupVec[i]->Contains( e );
1498 resGroupDS->SMDSGroup().Add( e );
1501 // Update Python script
1502 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1503 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1505 SMESH_CATCH( SMESH::throwCorbaException );
1507 return aResGrp._retn();
1510 //=============================================================================
1512 * New group is created. All mesh elements that are present in
1513 * a main group but is not present in a tool group are added to the new one
1515 //=============================================================================
1517 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1518 SMESH::SMESH_GroupBase_ptr theGroup2,
1519 const char* theName )
1520 throw (SALOME::SALOME_Exception)
1522 SMESH::SMESH_Group_var aResGrp;
1527 _preMeshInfo->FullLoadFromFile();
1529 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1530 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1532 if ( theGroup1->GetType() != theGroup2->GetType() )
1533 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1537 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1538 if ( aResGrp->_is_nil() )
1539 return aResGrp._retn();
1541 SMESHDS_GroupBase* groupDS1 = 0;
1542 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1543 groupDS1 = grp_i->GetGroupDS();
1545 SMESHDS_GroupBase* groupDS2 = 0;
1546 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1547 groupDS2 = grp_i->GetGroupDS();
1549 SMESHDS_Group* resGroupDS = 0;
1550 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1551 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1553 if ( groupDS1 && groupDS2 && resGroupDS )
1555 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1556 while ( elemIt1->more() )
1558 const SMDS_MeshElement* e = elemIt1->next();
1559 if ( !groupDS2->Contains( e ))
1560 resGroupDS->SMDSGroup().Add( e );
1563 // Update Python script
1564 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1565 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1567 SMESH_CATCH( SMESH::throwCorbaException );
1569 return aResGrp._retn();
1572 //=============================================================================
1574 \brief Cut lists of groups. New group is created. All mesh elements that are
1575 present in main groups but do not present in tool groups are added to the new one
1576 \param theMainGroups list of main groups
1577 \param theToolGroups list of tool groups
1578 \param theName name of group to be created
1579 \return pointer on the group
1581 //=============================================================================
1582 SMESH::SMESH_Group_ptr
1583 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1584 const SMESH::ListOfGroups& theToolGroups,
1585 const char* theName )
1586 throw (SALOME::SALOME_Exception)
1588 SMESH::SMESH_Group_var aResGrp;
1593 _preMeshInfo->FullLoadFromFile();
1596 return SMESH::SMESH_Group::_nil();
1598 // check types and get SMESHDS_GroupBase's
1599 SMESH::ElementType aType = SMESH::ALL;
1600 vector< SMESHDS_GroupBase* > toolGroupVec;
1601 vector< SMDS_ElemIteratorPtr > mainIterVec;
1603 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1605 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1606 if ( CORBA::is_nil( aGrp ) )
1608 if ( aType == SMESH::ALL )
1609 aType = aGrp->GetType();
1610 else if ( aType != aGrp->GetType() )
1611 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1613 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1614 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1615 if ( !grpDS->IsEmpty() )
1616 mainIterVec.push_back( grpDS->GetElements() );
1618 if ( aType == SMESH::ALL ) // all main groups are nil
1619 return SMESH::SMESH_Group::_nil();
1620 if ( mainIterVec.empty() ) // all main groups are empty
1621 return aResGrp._retn();
1623 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1625 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1626 if ( CORBA::is_nil( aGrp ) )
1628 if ( aType != aGrp->GetType() )
1629 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1631 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1632 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1633 toolGroupVec.push_back( grpDS );
1639 aResGrp = CreateGroup( aType, theName );
1641 SMESHDS_Group* resGroupDS = 0;
1642 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1643 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1645 return aResGrp._retn();
1648 size_t i, nb = toolGroupVec.size();
1649 SMDS_ElemIteratorPtr mainElemIt
1650 ( new SMDS_IteratorOnIterators
1651 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1652 while ( mainElemIt->more() )
1654 const SMDS_MeshElement* e = mainElemIt->next();
1656 for ( i = 0; ( i < nb && !isIn ); ++i )
1657 isIn = toolGroupVec[i]->Contains( e );
1660 resGroupDS->SMDSGroup().Add( e );
1663 // Update Python script
1664 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1665 << ".CutListOfGroups( " << theMainGroups << ", "
1666 << theToolGroups << ", '" << theName << "' )";
1668 SMESH_CATCH( SMESH::throwCorbaException );
1670 return aResGrp._retn();
1673 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1675 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1676 bool & toStopChecking )
1678 toStopChecking = ( nbCommon < nbChecked );
1679 return nbCommon == nbNodes;
1681 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1682 bool & toStopChecking )
1684 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1685 return nbCommon == nbCorners;
1687 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1688 bool & toStopChecking )
1690 return nbCommon > 0;
1692 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1693 bool & toStopChecking )
1695 return nbCommon >= (nbNodes+1) / 2;
1699 //=============================================================================
1701 * Create a group of entities basing on nodes of other groups.
1702 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1703 * \param [in] anElemType - a type of elements to include to the new group.
1704 * \param [in] theName - a name of the new group.
1705 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1706 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1707 * new group provided that it is based on nodes of an element of \a aListOfGroups
1708 * \return SMESH_Group - the created group
1710 // IMP 19939, bug 22010, IMP 22635
1711 //=============================================================================
1713 SMESH::SMESH_Group_ptr
1714 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1715 SMESH::ElementType theElemType,
1716 const char* theName,
1717 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1718 CORBA::Boolean theUnderlyingOnly)
1719 throw (SALOME::SALOME_Exception)
1721 SMESH::SMESH_Group_var aResGrp;
1725 _preMeshInfo->FullLoadFromFile();
1727 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1729 if ( !theName || !aMeshDS )
1730 return SMESH::SMESH_Group::_nil();
1732 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1734 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1735 SMESH_Comment nbCoNoStr( "SMESH.");
1736 switch ( theNbCommonNodes ) {
1737 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1738 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1739 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1740 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1741 default: return aResGrp._retn();
1743 int nbChecked, nbCommon, nbNodes, nbCorners;
1749 aResGrp = CreateGroup( theElemType, theName );
1750 if ( aResGrp->_is_nil() )
1751 return SMESH::SMESH_Group::_nil();
1753 SMESHDS_GroupBase* groupBaseDS =
1754 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1755 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1757 vector<bool> isNodeInGroups;
1759 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1761 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1762 if ( CORBA::is_nil( aGrp ) )
1764 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1765 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1768 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1769 if ( !elIt ) continue;
1771 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1773 while ( elIt->more() ) {
1774 const SMDS_MeshElement* el = elIt->next();
1775 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1776 while ( nIt->more() )
1777 resGroupCore.Add( nIt->next() );
1780 // get elements of theElemType based on nodes of every element of group
1781 else if ( theUnderlyingOnly )
1783 while ( elIt->more() )
1785 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1786 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1787 TIDSortedElemSet checkedElems;
1788 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1789 while ( nIt->more() )
1791 const SMDS_MeshNode* n = nIt->next();
1792 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1793 // check nodes of elements of theElemType around el
1794 while ( elOfTypeIt->more() )
1796 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1797 if ( !checkedElems.insert( elOfType ).second ) continue;
1798 nbNodes = elOfType->NbNodes();
1799 nbCorners = elOfType->NbCornerNodes();
1801 bool toStopChecking = false;
1802 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1803 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1804 if ( elNodes.count( nIt2->next() ) &&
1805 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1807 resGroupCore.Add( elOfType );
1814 // get all nodes of elements of groups
1817 while ( elIt->more() )
1819 const SMDS_MeshElement* el = elIt->next(); // an element of group
1820 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1821 while ( nIt->more() )
1823 const SMDS_MeshNode* n = nIt->next();
1824 if ( n->GetID() >= (int) isNodeInGroups.size() )
1825 isNodeInGroups.resize( n->GetID() + 1, false );
1826 isNodeInGroups[ n->GetID() ] = true;
1832 // Get elements of theElemType based on a certain number of nodes of elements of groups
1833 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1835 const SMDS_MeshNode* n;
1836 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1837 const int isNodeInGroupsSize = isNodeInGroups.size();
1838 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1840 if ( !isNodeInGroups[ iN ] ||
1841 !( n = aMeshDS->FindNode( iN )))
1844 // check nodes of elements of theElemType around n
1845 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1846 while ( elOfTypeIt->more() )
1848 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1849 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1854 nbNodes = elOfType->NbNodes();
1855 nbCorners = elOfType->NbCornerNodes();
1857 bool toStopChecking = false;
1858 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1859 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1861 const int nID = nIt->next()->GetID();
1862 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1863 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1865 resGroupCore.Add( elOfType );
1873 // Update Python script
1874 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1875 << ".CreateDimGroup( "
1876 << theGroups << ", " << theElemType << ", '" << theName << "', "
1877 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1879 SMESH_CATCH( SMESH::throwCorbaException );
1881 return aResGrp._retn();
1884 //================================================================================
1886 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1887 * existing 1D elements as group boundaries.
1888 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1889 * adjacent faces is more than \a sharpAngle in degrees.
1890 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1891 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1892 * \return ListOfGroups - the created groups
1894 //================================================================================
1896 SMESH::ListOfGroups*
1897 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1898 CORBA::Boolean theCreateEdges,
1899 CORBA::Boolean theUseExistingEdges )
1900 throw (SALOME::SALOME_Exception)
1902 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1903 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1906 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1912 _preMeshInfo->FullLoadFromFile();
1914 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1916 std::vector< SMESH_MeshAlgos::Edge > edges =
1917 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1919 if ( theCreateEdges )
1921 std::vector<const SMDS_MeshNode *> nodes(2);
1922 for ( size_t i = 0; i < edges.size(); ++i )
1924 nodes[0] = edges[i]._node1;
1925 nodes[1] = edges[i]._node2;
1926 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1928 if ( edges[i]._medium )
1929 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1931 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1935 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1936 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1938 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1940 resultGroups->length( faceGroups.size() );
1941 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1943 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1944 _editor->GenerateGroupName("Group").c_str());
1945 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1947 SMESHDS_GroupBase* groupBaseDS =
1948 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1949 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1951 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1952 for ( size_t i = 0; i < faces.size(); ++i )
1953 groupCore.Add( faces[i] );
1956 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1957 << ".FaceGroupsSeparatedByEdges( "
1958 << TVar( theSharpAngle ) << ", "
1959 << theCreateEdges << ", "
1960 << theUseExistingEdges << " )";
1962 SMESH_CATCH( SMESH::throwCorbaException );
1963 return resultGroups._retn();
1967 //================================================================================
1969 * \brief Remember GEOM group data
1971 //================================================================================
1973 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1974 CORBA::Object_ptr theSmeshObj)
1976 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1979 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1980 if ( groupSO->_is_nil() )
1983 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1984 GEOM::GEOM_IGroupOperations_wrap groupOp =
1985 geomGen->GetIGroupOperations();
1986 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1989 _geomGroupData.push_back( TGeomGroupData() );
1990 TGeomGroupData & groupData = _geomGroupData.back();
1992 CORBA::String_var entry = groupSO->GetID();
1993 groupData._groupEntry = entry.in();
1995 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1996 groupData._indices.insert( ids[i] );
1998 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1999 // shape index in SMESHDS
2000 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2001 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2004 //================================================================================
2006 * Remove GEOM group data relating to removed smesh object
2008 //================================================================================
2010 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2012 list<TGeomGroupData>::iterator
2013 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2014 for ( ; data != dataEnd; ++data ) {
2015 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2016 _geomGroupData.erase( data );
2022 //================================================================================
2024 * \brief Return new group contents if it has been changed and update group data
2026 //================================================================================
2028 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
2030 TopoDS_Shape newShape;
2033 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2034 if ( !groupSO->_is_nil() )
2036 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2037 if ( CORBA::is_nil( groupObj )) return newShape;
2038 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2040 // get indices of group items
2041 set<int> curIndices;
2042 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2043 GEOM::GEOM_IGroupOperations_wrap groupOp =
2044 geomGen->GetIGroupOperations();
2045 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2046 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2047 curIndices.insert( ids[i] );
2049 if ( groupData._indices == curIndices )
2050 return newShape; // group not changed
2053 groupData._indices = curIndices;
2055 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2056 if ( !geomClient ) return newShape;
2057 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2058 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2059 newShape = _gen_i->GeomObjectToShape( geomGroup );
2062 if ( newShape.IsNull() ) {
2063 // geom group becomes empty - return empty compound
2064 TopoDS_Compound compound;
2065 BRep_Builder().MakeCompound(compound);
2066 newShape = compound;
2073 //-----------------------------------------------------------------------------
2075 * \brief Storage of shape and index used in CheckGeomGroupModif()
2077 struct TIndexedShape
2080 TopoDS_Shape _shape;
2081 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2083 //-----------------------------------------------------------------------------
2085 * \brief Data to re-create a group on geometry
2087 struct TGroupOnGeomData
2090 TopoDS_Shape _shape;
2091 SMDSAbs_ElementType _type;
2093 Quantity_Color _color;
2095 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2097 _oldID = group->GetID();
2098 _type = group->GetType();
2099 _name = group->GetStoreName();
2100 _color = group->GetColor();
2104 //-----------------------------------------------------------------------------
2106 * \brief Check if a filter is still valid after geometry removal
2108 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2110 if ( theFilter->_is_nil() )
2112 SMESH::Filter::Criteria_var criteria;
2113 theFilter->GetCriteria( criteria.out() );
2115 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2117 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2119 switch ( criteria[ iCr ].Type )
2121 case SMESH::FT_BelongToGeom:
2122 case SMESH::FT_BelongToPlane:
2123 case SMESH::FT_BelongToCylinder:
2124 case SMESH::FT_BelongToGenSurface:
2125 case SMESH::FT_LyingOnGeom:
2126 entry = thresholdID;
2128 case SMESH::FT_ConnectedElements:
2131 entry = thresholdID;
2137 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2138 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2139 if ( so->_is_nil() )
2141 CORBA::Object_var obj = so->GetObject();
2142 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2143 if ( gen->GeomObjectToShape( geom ).IsNull() )
2146 } // loop on criteria
2152 //=============================================================================
2154 * \brief Update data if geometry changes
2158 //=============================================================================
2160 void SMESH_Mesh_i::CheckGeomModif()
2162 SMESH::SMESH_Mesh_var me = _this();
2163 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2165 //bool removedFromClient = false;
2167 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2169 //removedFromClient = _impl->HasShapeToMesh();
2171 // try to find geometry by study reference
2172 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2173 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2174 if ( !meshSO->_is_nil() &&
2175 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2176 geomRefSO->ReferencedObject( geomSO.inout() ))
2178 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2179 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2182 if ( mainGO->_is_nil() && // geometry removed ==>
2183 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2185 // convert geom dependent groups into standalone ones
2186 CheckGeomGroupModif();
2188 _impl->ShapeToMesh( TopoDS_Shape() );
2190 // remove sub-meshes
2191 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2192 while ( i_sm != _mapSubMeshIor.end() )
2194 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2196 RemoveSubMesh( sm );
2198 // remove all children except groups in the study
2199 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2200 SALOMEDS::SObject_wrap so;
2201 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2202 if ( meshSO->FindSubObject( tag, so.inout() ))
2203 builder->RemoveObjectWithChildren( so );
2205 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2211 if ( !_impl->HasShapeToMesh() ) return;
2214 // Update after group modification
2216 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2217 mainGO->GetTick() == _mainShapeTick )
2219 int nb = NbNodes() + NbElements();
2220 CheckGeomGroupModif();
2221 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2222 _gen_i->UpdateIcons( me );
2226 // Update after shape transformation like Translate
2228 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2229 if ( !geomClient ) return;
2230 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2231 if ( geomGen->_is_nil() ) return;
2233 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2234 geomClient->RemoveShapeFromBuffer( ior.in() );
2236 // Update data taking into account that
2237 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2240 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2241 if ( newShape.IsNull() )
2244 _mainShapeTick = mainGO->GetTick();
2246 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2248 // store data of groups on geometry
2249 std::vector< TGroupOnGeomData > groupsData;
2250 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2251 groupsData.reserve( groups.size() );
2252 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2253 for ( ; g != groups.end(); ++g )
2255 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2257 groupsData.push_back( TGroupOnGeomData( group ));
2260 SMESH::SMESH_GroupOnGeom_var gog;
2261 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2262 if ( i_grp != _mapGroups.end() )
2263 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2265 GEOM::GEOM_Object_var geom;
2266 if ( !gog->_is_nil() )
2267 geom = gog->GetShape();
2268 if ( !geom->_is_nil() )
2270 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2271 geomClient->RemoveShapeFromBuffer( ior.in() );
2272 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2276 // store assigned hypotheses
2277 std::vector< pair< int, THypList > > ids2Hyps;
2278 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2279 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2281 const TopoDS_Shape& s = s2hyps.Key();
2282 const THypList& hyps = s2hyps.ChangeValue();
2283 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2286 // change shape to mesh
2287 int oldNbSubShapes = meshDS->MaxShapeIndex();
2288 _impl->ShapeToMesh( TopoDS_Shape() );
2289 _impl->ShapeToMesh( newShape );
2291 // re-add shapes of geom groups
2292 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2293 for ( ; data != _geomGroupData.end(); ++data )
2295 TopoDS_Shape newShape = newGroupShape( *data );
2296 if ( !newShape.IsNull() )
2298 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2300 TopoDS_Compound compound;
2301 BRep_Builder().MakeCompound( compound );
2302 BRep_Builder().Add( compound, newShape );
2303 newShape = compound;
2305 _impl->GetSubMesh( newShape );
2308 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2309 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2310 SALOME::INTERNAL_ERROR );
2312 // re-assign hypotheses
2313 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2315 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2316 const THypList& hyps = ids2Hyps[i].second;
2317 THypList::const_iterator h = hyps.begin();
2318 for ( ; h != hyps.end(); ++h )
2319 _impl->AddHypothesis( s, (*h)->GetID() );
2322 // restore groups on geometry
2323 for ( size_t i = 0; i < groupsData.size(); ++i )
2325 const TGroupOnGeomData& data = groupsData[i];
2326 if ( data._shape.IsNull() )
2329 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2330 if ( i2g == _mapGroups.end() ) continue;
2332 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2333 if ( !gr_i ) continue;
2335 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2337 _mapGroups.erase( i2g );
2339 g->GetGroupDS()->SetColor( data._color );
2342 // update _mapSubMesh
2343 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2344 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2345 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2349 //=============================================================================
2351 * \brief Update objects depending on changed geom groups
2353 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2354 * issue 0020210: Update of a smesh group after modification of the associated geom group
2356 //=============================================================================
2358 void SMESH_Mesh_i::CheckGeomGroupModif()
2360 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2361 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2362 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2363 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2364 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2366 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2367 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2368 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2370 int nbValid = 0, nbRemoved = 0;
2371 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2372 for ( ; chItr->More(); chItr->Next() )
2374 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2375 if ( !smSO->_is_nil() &&
2376 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2377 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2379 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2380 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2381 if ( !geom->_non_existent() )
2384 continue; // keep the sub-mesh
2387 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2388 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2389 if ( !sm->_is_nil() && !sm->_non_existent() )
2391 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2392 if ( smGeom->_is_nil() )
2394 RemoveSubMesh( sm );
2401 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2402 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2406 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2407 builder->RemoveObjectWithChildren( rootSO );
2411 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2412 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2413 while ( i_gr != _mapGroups.end())
2415 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2417 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2418 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2419 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2420 bool isValidGeom = false;
2421 if ( !onGeom->_is_nil() )
2423 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2425 else if ( !onFilt->_is_nil() )
2427 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2431 isValidGeom = ( !groupSO->_is_nil() &&
2432 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2436 if ( !IsLoaded() || group->IsEmpty() )
2438 RemoveGroup( group );
2440 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2442 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2444 else // is it possible?
2446 builder->RemoveObjectWithChildren( refSO );
2452 if ( !_impl->HasShapeToMesh() ) return;
2454 CORBA::Long nbEntities = NbNodes() + NbElements();
2456 // Check if group contents changed
2458 typedef map< string, TopoDS_Shape > TEntry2Geom;
2459 TEntry2Geom newGroupContents;
2461 list<TGeomGroupData>::iterator
2462 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2463 for ( ; data != dataEnd; ++data )
2465 pair< TEntry2Geom::iterator, bool > it_new =
2466 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2467 bool processedGroup = !it_new.second;
2468 TopoDS_Shape& newShape = it_new.first->second;
2469 if ( !processedGroup )
2470 newShape = newGroupShape( *data );
2471 if ( newShape.IsNull() )
2472 continue; // no changes
2475 _preMeshInfo->ForgetOrLoad();
2477 if ( processedGroup ) { // update group indices
2478 list<TGeomGroupData>::iterator data2 = data;
2479 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2480 data->_indices = data2->_indices;
2483 // Update SMESH objects according to new GEOM group contents
2485 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2486 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2488 int oldID = submesh->GetId();
2489 if ( !_mapSubMeshIor.count( oldID ))
2491 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2493 // update hypotheses
2494 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2495 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2496 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2498 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2499 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2501 // care of submeshes
2502 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2503 int newID = newSubmesh->GetId();
2504 if ( newID != oldID ) {
2505 _mapSubMesh [ newID ] = newSubmesh;
2506 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2507 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2508 _mapSubMesh. erase(oldID);
2509 _mapSubMesh_i. erase(oldID);
2510 _mapSubMeshIor.erase(oldID);
2511 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2516 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2517 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2518 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2520 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2522 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2523 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2524 ds->SetShape( newShape );
2529 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2530 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2532 // Remove groups and submeshes basing on removed sub-shapes
2534 TopTools_MapOfShape newShapeMap;
2535 TopoDS_Iterator shapeIt( newShape );
2536 for ( ; shapeIt.More(); shapeIt.Next() )
2537 newShapeMap.Add( shapeIt.Value() );
2539 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2540 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2542 if ( newShapeMap.Contains( shapeIt.Value() ))
2544 TopTools_IndexedMapOfShape oldShapeMap;
2545 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2546 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2548 const TopoDS_Shape& oldShape = oldShapeMap(i);
2549 int oldInd = meshDS->ShapeToIndex( oldShape );
2551 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2552 if ( i_smIor != _mapSubMeshIor.end() ) {
2553 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2556 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2557 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2559 // check if a group bases on oldInd shape
2560 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2561 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2562 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2563 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2565 RemoveGroup( i_grp->second ); // several groups can base on same shape
2566 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2571 // Reassign hypotheses and update groups after setting the new shape to mesh
2573 // collect anassigned hypotheses
2574 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2575 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2576 TShapeHypList assignedHyps;
2577 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2579 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2580 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2581 if ( !hyps.empty() ) {
2582 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2583 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2584 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2587 // collect shapes supporting groups
2588 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2589 TShapeTypeList groupData;
2590 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2591 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2592 for ( ; grIt != groups.end(); ++grIt )
2594 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2596 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2598 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2600 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2601 _impl->ShapeToMesh( newShape );
2603 // reassign hypotheses
2604 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2605 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2607 TIndexedShape& geom = indS_hyps->first;
2608 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2609 int oldID = geom._index;
2610 int newID = meshDS->ShapeToIndex( geom._shape );
2611 if ( oldID == 1 ) { // main shape
2613 geom._shape = newShape;
2617 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2618 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2619 // care of sub-meshes
2620 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2621 if ( newID != oldID ) {
2622 _mapSubMesh [ newID ] = newSubmesh;
2623 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2624 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2625 _mapSubMesh. erase(oldID);
2626 _mapSubMesh_i. erase(oldID);
2627 _mapSubMeshIor.erase(oldID);
2628 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2632 TShapeTypeList::iterator geomType = groupData.begin();
2633 for ( ; geomType != groupData.end(); ++geomType )
2635 const TIndexedShape& geom = geomType->first;
2636 int oldID = geom._index;
2637 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2640 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2641 CORBA::String_var name = groupSO->GetName();
2643 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2644 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2645 /*id=*/-1, geom._shape ))
2646 group_i->changeLocalId( group->GetID() );
2649 break; // everything has been updated
2652 } // loop on group data
2656 CORBA::Long newNbEntities = NbNodes() + NbElements();
2657 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2658 if ( newNbEntities != nbEntities )
2660 // Add all SObjects with icons to soToUpdateIcons
2661 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2663 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2664 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2665 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2667 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2668 i_gr != _mapGroups.end(); ++i_gr ) // groups
2669 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2672 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2673 for ( ; so != soToUpdateIcons.end(); ++so )
2674 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2677 //=============================================================================
2679 * \brief Create standalone group from a group on geometry or filter
2681 //=============================================================================
2683 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2684 throw (SALOME::SALOME_Exception)
2686 SMESH::SMESH_Group_var aGroup;
2691 _preMeshInfo->FullLoadFromFile();
2693 if ( theGroup->_is_nil() )
2694 return aGroup._retn();
2696 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2698 return aGroup._retn();
2700 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2702 const int anId = aGroupToRem->GetLocalID();
2703 if ( !_impl->ConvertToStandalone( anId ) )
2704 return aGroup._retn();
2705 removeGeomGroupData( theGroup );
2707 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2709 // remove old instance of group from own map
2710 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2711 _mapGroups.erase( anId );
2713 SALOMEDS::StudyBuilder_var builder;
2714 SALOMEDS::SObject_wrap aGroupSO;
2715 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2716 if ( !aStudy->_is_nil() ) {
2717 builder = aStudy->NewBuilder();
2718 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2719 if ( !aGroupSO->_is_nil() )
2721 // remove reference to geometry
2722 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2723 for ( ; chItr->More(); chItr->Next() )
2725 // Remove group's child SObject
2726 SALOMEDS::SObject_wrap so = chItr->Value();
2727 builder->RemoveObject( so );
2729 // Update Python script
2730 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2731 << ".ConvertToStandalone( " << aGroupSO << " )";
2733 // change icon of Group on Filter
2736 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2737 // const int isEmpty = ( elemTypes->length() == 0 );
2740 SALOMEDS::GenericAttribute_wrap anAttr =
2741 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2742 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2743 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2749 // remember new group in own map
2750 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2751 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2753 // register CORBA object for persistence
2754 _gen_i->RegisterObject( aGroup );
2756 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2757 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2758 //aGroup->Register();
2759 aGroupToRem->UnRegister();
2761 SMESH_CATCH( SMESH::throwCorbaException );
2763 return aGroup._retn();
2766 //=============================================================================
2770 //=============================================================================
2772 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2774 if(MYDEBUG) MESSAGE( "createSubMesh" );
2775 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2776 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2779 SMESH_subMesh_i * subMeshServant;
2782 subMeshId = mySubMesh->GetId();
2783 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2785 else // "invalid sub-mesh"
2787 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2788 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2789 if ( _mapSubMesh.empty() )
2792 subMeshId = _mapSubMesh.begin()->first - 1;
2793 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2796 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2798 _mapSubMesh [subMeshId] = mySubMesh;
2799 _mapSubMesh_i [subMeshId] = subMeshServant;
2800 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2802 subMeshServant->Register();
2804 // register CORBA object for persistence
2805 int nextId = _gen_i->RegisterObject( subMesh );
2806 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2807 else { nextId = 0; } // avoid "unused variable" warning
2809 // to track changes of GEOM groups
2810 if ( subMeshId > 0 )
2811 addGeomGroupData( theSubShapeObject, subMesh );
2813 return subMesh._retn();
2816 //=======================================================================
2817 //function : getSubMesh
2819 //=======================================================================
2821 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2823 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2824 if ( it == _mapSubMeshIor.end() )
2825 return SMESH::SMESH_subMesh::_nil();
2827 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2830 //=============================================================================
2834 //=============================================================================
2836 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2837 GEOM::GEOM_Object_ptr theSubShapeObject )
2839 bool isHypChanged = false;
2840 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2841 return isHypChanged;
2843 const int subMeshId = theSubMesh->GetId();
2845 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2848 if (( _mapSubMesh.count( subMeshId )) &&
2849 ( sm = _impl->GetSubMeshContaining( subMeshId )))
2851 TopoDS_Shape S = sm->GetSubShape();
2854 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2855 isHypChanged = !hyps.empty();
2856 if ( isHypChanged && _preMeshInfo )
2857 _preMeshInfo->ForgetOrLoad();
2858 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2859 for ( ; hyp != hyps.end(); ++hyp )
2860 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2867 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2868 isHypChanged = ( aHypList->length() > 0 );
2869 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2870 removeHypothesis( theSubShapeObject, aHypList[i] );
2873 catch( const SALOME::SALOME_Exception& ) {
2874 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2876 removeGeomGroupData( theSubShapeObject );
2880 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2881 if ( id_smi != _mapSubMesh_i.end() )
2882 id_smi->second->UnRegister();
2884 // remove a CORBA object
2885 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2886 if ( id_smptr != _mapSubMeshIor.end() )
2887 SMESH::SMESH_subMesh_var( id_smptr->second );
2889 _mapSubMesh.erase(subMeshId);
2890 _mapSubMesh_i.erase(subMeshId);
2891 _mapSubMeshIor.erase(subMeshId);
2893 return isHypChanged;
2896 //=============================================================================
2900 //=============================================================================
2902 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2903 const char* theName,
2905 const TopoDS_Shape& theShape,
2906 const SMESH_PredicatePtr& thePredicate )
2908 std::string newName;
2909 if ( !theName || !theName[0] )
2911 std::set< std::string > presentNames;
2912 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2913 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2915 CORBA::String_var name = i_gr->second->GetName();
2916 presentNames.insert( name.in() );
2919 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2920 } while ( !presentNames.insert( newName ).second );
2921 theName = newName.c_str();
2923 SMESH::SMESH_GroupBase_var aGroup;
2924 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
2925 theID, theShape, thePredicate ))
2927 int anId = g->GetID();
2928 SMESH_GroupBase_i* aGroupImpl;
2929 if ( !theShape.IsNull() )
2930 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2931 else if ( thePredicate )
2932 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2934 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2936 aGroup = aGroupImpl->_this();
2937 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2938 aGroupImpl->Register();
2940 // register CORBA object for persistence
2941 int nextId = _gen_i->RegisterObject( aGroup );
2942 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2943 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
2945 // to track changes of GEOM groups
2946 if ( !theShape.IsNull() ) {
2947 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2948 addGeomGroupData( geom, aGroup );
2951 return aGroup._retn();
2954 //=============================================================================
2956 * SMESH_Mesh_i::removeGroup
2958 * Should be called by ~SMESH_Group_i()
2960 //=============================================================================
2962 void SMESH_Mesh_i::removeGroup( const int theId )
2964 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2965 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2966 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2967 _mapGroups.erase( theId );
2968 removeGeomGroupData( group );
2969 if ( !_impl->RemoveGroup( theId ))
2971 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2972 RemoveGroup( group );
2974 group->UnRegister();
2978 //=============================================================================
2982 //=============================================================================
2984 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2985 throw(SALOME::SALOME_Exception)
2987 SMESH::log_array_var aLog;
2991 _preMeshInfo->FullLoadFromFile();
2993 list < SMESHDS_Command * >logDS = _impl->GetLog();
2994 aLog = new SMESH::log_array;
2996 int lg = logDS.size();
2999 list < SMESHDS_Command * >::iterator its = logDS.begin();
3000 while(its != logDS.end()){
3001 SMESHDS_Command *com = *its;
3002 int comType = com->GetType();
3004 int lgcom = com->GetNumber();
3006 const list < int >&intList = com->GetIndexes();
3007 int inum = intList.size();
3009 list < int >::const_iterator ii = intList.begin();
3010 const list < double >&coordList = com->GetCoords();
3011 int rnum = coordList.size();
3013 list < double >::const_iterator ir = coordList.begin();
3014 aLog[indexLog].commandType = comType;
3015 aLog[indexLog].number = lgcom;
3016 aLog[indexLog].coords.length(rnum);
3017 aLog[indexLog].indexes.length(inum);
3018 for(int i = 0; i < rnum; i++){
3019 aLog[indexLog].coords[i] = *ir;
3020 //MESSAGE(" "<<i<<" "<<ir.Value());
3023 for(int i = 0; i < inum; i++){
3024 aLog[indexLog].indexes[i] = *ii;
3025 //MESSAGE(" "<<i<<" "<<ii.Value());
3034 SMESH_CATCH( SMESH::throwCorbaException );
3036 return aLog._retn();
3040 //=============================================================================
3044 //=============================================================================
3046 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3050 SMESH_CATCH( SMESH::throwCorbaException );
3053 //=============================================================================
3057 //=============================================================================
3059 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3064 //=============================================================================
3067 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3068 // issue 0020918: groups removal is caused by hyp modification
3069 // issue 0021208: to forget not loaded mesh data at hyp modification
3070 struct TCallUp_i : public SMESH_Mesh::TCallUp
3072 SMESH_Mesh_i* _mesh;
3073 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3074 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3075 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3076 virtual void Load () { _mesh->Load(); }
3080 //================================================================================
3082 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3084 //================================================================================
3086 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3089 _preMeshInfo->ForgetOrLoad();
3091 SMESH::SMESH_Mesh_var mesh = _this();
3092 _gen_i->UpdateIcons( mesh );
3094 // mark a hypothesis as valid after edition
3095 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3096 SALOMEDS::SObject_wrap hypRoot;
3097 if ( !smeshComp->_is_nil() &&
3098 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3100 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3101 for ( ; anIter->More(); anIter->Next() )
3103 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3104 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3105 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3106 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3107 _gen_i->HighLightInvalid( hyp, false );
3112 //=============================================================================
3116 //=============================================================================
3118 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3120 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3123 _impl->SetCallUp( new TCallUp_i(this));
3126 //=============================================================================
3130 //=============================================================================
3132 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3134 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3138 //=============================================================================
3140 * Return mesh editor
3142 //=============================================================================
3144 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3145 throw (SALOME::SALOME_Exception)
3147 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3151 _preMeshInfo->FullLoadFromFile();
3153 // Create MeshEditor
3155 _editor = new SMESH_MeshEditor_i( this, false );
3156 aMeshEdVar = _editor->_this();
3158 // Update Python script
3159 TPythonDump() << _editor << " = "
3160 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3162 SMESH_CATCH( SMESH::throwCorbaException );
3164 return aMeshEdVar._retn();
3167 //=============================================================================
3169 * Return mesh edition previewer
3171 //=============================================================================
3173 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3174 throw (SALOME::SALOME_Exception)
3176 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3180 _preMeshInfo->FullLoadFromFile();
3182 if ( !_previewEditor )
3183 _previewEditor = new SMESH_MeshEditor_i( this, true );
3184 aMeshEdVar = _previewEditor->_this();
3186 SMESH_CATCH( SMESH::throwCorbaException );
3188 return aMeshEdVar._retn();
3191 //================================================================================
3193 * \brief Return true if the mesh has been edited since a last total re-compute
3194 * and those modifications may prevent successful partial re-compute
3196 //================================================================================
3198 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3200 Unexpect aCatch(SALOME_SalomeException);
3201 return _impl->HasModificationsToDiscard();
3204 //================================================================================
3206 * \brief Returns a random unique color
3208 //================================================================================
3210 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3212 const int MAX_ATTEMPTS = 100;
3214 double tolerance = 0.5;
3215 SALOMEDS::Color col;
3219 // generate random color
3220 double red = (double)rand() / RAND_MAX;
3221 double green = (double)rand() / RAND_MAX;
3222 double blue = (double)rand() / RAND_MAX;
3223 // check existence in the list of the existing colors
3224 bool matched = false;
3225 std::list<SALOMEDS::Color>::const_iterator it;
3226 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3227 SALOMEDS::Color color = *it;
3228 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3229 matched = tol < tolerance;
3231 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3232 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3240 //=============================================================================
3242 * Sets auto-color mode. If it is on, groups get unique random colors
3244 //=============================================================================
3246 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3248 Unexpect aCatch(SALOME_SalomeException);
3249 _impl->SetAutoColor(theAutoColor);
3251 TPythonDump pyDump; // not to dump group->SetColor() from below code
3252 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3254 std::list<SALOMEDS::Color> aReservedColors;
3255 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3256 for ( ; it != _mapGroups.end(); it++ ) {
3257 if ( CORBA::is_nil( it->second )) continue;
3258 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3259 it->second->SetColor( aColor );
3260 aReservedColors.push_back( aColor );
3264 //=============================================================================
3266 * Returns true if auto-color mode is on
3268 //=============================================================================
3270 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3272 Unexpect aCatch(SALOME_SalomeException);
3273 return _impl->GetAutoColor();
3276 //=============================================================================
3278 * Checks if there are groups with equal names
3280 //=============================================================================
3282 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3284 return _impl->HasDuplicatedGroupNamesMED();
3287 //================================================================================
3289 * \brief Care of a file before exporting mesh into it
3291 //================================================================================
3293 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3295 SMESH_File aFile( file, false );
3297 if ( aFile.exists() ) {
3298 // existing filesystem node
3299 if ( !aFile.isDirectory() ) {
3300 if ( aFile.openForWriting() ) {
3301 if ( overwrite && ! aFile.remove()) {
3302 msg << "Can't replace " << aFile.getName();
3305 msg << "Can't write into " << aFile.getName();
3308 msg << "Location " << aFile.getName() << " is not a file";
3312 // nonexisting file; check if it can be created
3313 if ( !aFile.openForWriting() ) {
3314 msg << "You cannot create the file "
3316 << ". Check the directory existence and access rights";
3324 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3328 //================================================================================
3330 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3331 * \param file - file name
3332 * \param overwrite - to erase the file or not
3333 * \retval string - mesh name
3335 //================================================================================
3337 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3338 CORBA::Boolean overwrite)
3341 PrepareForWriting(file, overwrite);
3342 string aMeshName = "Mesh";
3343 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3344 if ( !aStudy->_is_nil() ) {
3345 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3346 if ( !aMeshSO->_is_nil() ) {
3347 CORBA::String_var name = aMeshSO->GetName();
3349 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3350 if ( !aStudy->GetProperties()->IsLocked() )
3352 SALOMEDS::GenericAttribute_wrap anAttr;
3353 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3354 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3355 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3356 ASSERT(!aFileName->_is_nil());
3357 aFileName->SetValue(file);
3358 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3359 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3360 ASSERT(!aFileType->_is_nil());
3361 aFileType->SetValue("FICHIERMED");
3365 // Update Python script
3366 // set name of mesh before export
3367 TPythonDump() << _gen_i << ".SetName("
3368 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3370 // check names of groups
3376 //================================================================================
3378 * \brief Export to MED file
3380 //================================================================================
3382 void SMESH_Mesh_i::ExportMED(const char* file,
3383 CORBA::Boolean auto_groups,
3384 CORBA::Long version,
3385 CORBA::Boolean overwrite,
3386 CORBA::Boolean autoDimension)
3387 throw(SALOME::SALOME_Exception)
3389 //MESSAGE("MED minor version: "<< minor);
3392 _preMeshInfo->FullLoadFromFile();
3394 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3395 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3397 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3399 << "auto_groups=" <<auto_groups << ", "
3400 << "minor=" << version << ", "
3401 << "overwrite=" << overwrite << ", "
3402 << "meshPart=None, "
3403 << "autoDimension=" << autoDimension << " )";
3405 SMESH_CATCH( SMESH::throwCorbaException );
3408 //================================================================================
3410 * \brief Export a mesh to a SAUV file
3412 //================================================================================
3414 void SMESH_Mesh_i::ExportSAUV (const char* file,
3415 CORBA::Boolean auto_groups)
3416 throw(SALOME::SALOME_Exception)
3418 Unexpect aCatch(SALOME_SalomeException);
3420 _preMeshInfo->FullLoadFromFile();
3422 string aMeshName = prepareMeshNameAndGroups(file, true);
3423 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3424 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3425 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3429 //================================================================================
3431 * \brief Export a mesh to a DAT file
3433 //================================================================================
3435 void SMESH_Mesh_i::ExportDAT (const char *file)
3436 throw(SALOME::SALOME_Exception)
3438 Unexpect aCatch(SALOME_SalomeException);
3440 _preMeshInfo->FullLoadFromFile();
3442 // Update Python script
3443 // check names of groups
3445 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3448 PrepareForWriting(file);
3449 _impl->ExportDAT(file);
3452 //================================================================================
3454 * \brief Export a mesh to an UNV file
3456 //================================================================================
3458 void SMESH_Mesh_i::ExportUNV (const char *file)
3459 throw(SALOME::SALOME_Exception)
3461 Unexpect aCatch(SALOME_SalomeException);
3463 _preMeshInfo->FullLoadFromFile();
3465 // Update Python script
3466 // check names of groups
3468 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3471 PrepareForWriting(file);
3472 _impl->ExportUNV(file);
3475 //================================================================================
3477 * \brief Export a mesh to an STL file
3479 //================================================================================
3481 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3482 throw(SALOME::SALOME_Exception)
3484 Unexpect aCatch(SALOME_SalomeException);
3486 _preMeshInfo->FullLoadFromFile();
3488 // Update Python script
3489 // check names of groups
3491 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3492 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3494 CORBA::String_var name;
3495 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3496 if ( !so->_is_nil() )
3497 name = so->GetName();
3500 PrepareForWriting( file );
3501 _impl->ExportSTL( file, isascii, name.in() );
3504 //================================================================================
3506 * \brief Export a part of mesh to a med file
3508 //================================================================================
3510 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3512 CORBA::Boolean auto_groups,
3513 CORBA::Long version,
3514 CORBA::Boolean overwrite,
3515 CORBA::Boolean autoDimension,
3516 const GEOM::ListOfFields& fields,
3517 const char* geomAssocFields,
3518 CORBA::Double ZTolerance)
3519 throw (SALOME::SALOME_Exception)
3521 MESSAGE("MED version: "<< version);
3524 _preMeshInfo->FullLoadFromFile();
3527 bool have0dField = false;
3528 if ( fields.length() > 0 )
3530 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3531 if ( shapeToMesh->_is_nil() )
3532 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3534 for ( size_t i = 0; i < fields.length(); ++i )
3536 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3537 THROW_SALOME_CORBA_EXCEPTION
3538 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3539 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3540 if ( fieldShape->_is_nil() )
3541 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3542 if ( !fieldShape->IsSame( shapeToMesh ) )
3543 THROW_SALOME_CORBA_EXCEPTION
3544 ( "Field defined not on shape", SALOME::BAD_PARAM);
3545 if ( fields[i]->GetDimension() == 0 )
3548 if ( geomAssocFields )
3549 for ( int i = 0; geomAssocFields[i]; ++i )
3550 switch ( geomAssocFields[i] ) {
3551 case 'v':case 'e':case 'f':case 's': break;
3552 case 'V':case 'E':case 'F':case 'S': break;
3553 default: THROW_SALOME_CORBA_EXCEPTION
3554 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3558 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3562 string aMeshName = "Mesh";
3563 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3564 if ( CORBA::is_nil( meshPart ) ||
3565 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3567 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3568 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3569 0, autoDimension, /*addODOnVertices=*/have0dField,
3571 meshDS = _impl->GetMeshDS();
3576 _preMeshInfo->FullLoadFromFile();
3578 PrepareForWriting(file, overwrite);
3580 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3581 if ( !SO->_is_nil() ) {
3582 CORBA::String_var name = SO->GetName();
3586 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3587 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3588 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3589 meshDS = tmpDSDeleter._obj = partDS;
3594 if ( _impl->HasShapeToMesh() )
3596 DriverMED_W_Field fieldWriter;
3597 fieldWriter.SetFile( file );
3598 fieldWriter.SetMeshName( aMeshName );
3599 fieldWriter.AddODOnVertices( have0dField );
3601 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3605 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3606 goList->length( fields.length() );
3607 for ( size_t i = 0; i < fields.length(); ++i )
3609 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3612 TPythonDump() << _this() << ".ExportPartToMED( "
3613 << meshPart << ", r'"
3615 << auto_groups << ", "
3617 << overwrite << ", "
3618 << autoDimension << ", "
3620 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3621 << TVar( ZTolerance )
3624 SMESH_CATCH( SMESH::throwCorbaException );
3627 //================================================================================
3629 * Write GEOM fields to MED file
3631 //================================================================================
3633 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3634 SMESHDS_Mesh* meshDS,
3635 const GEOM::ListOfFields& fields,
3636 const char* geomAssocFields)
3638 #define METH "SMESH_Mesh_i::exportMEDFields() "
3640 if (( fields.length() < 1 ) &&
3641 ( !geomAssocFields || !geomAssocFields[0] ))
3644 std::vector< std::vector< double > > dblVals;
3645 std::vector< std::vector< int > > intVals;
3646 std::vector< int > subIdsByDim[ 4 ];
3647 const double noneDblValue = 0.;
3648 const double noneIntValue = 0;
3650 for ( size_t iF = 0; iF < fields.length(); ++iF )
3654 int dim = fields[ iF ]->GetDimension();
3655 SMDSAbs_ElementType elemType;
3656 TopAbs_ShapeEnum shapeType;
3658 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3659 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3660 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3661 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3663 continue; // skip fields on whole shape
3665 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3666 if ( dataType == GEOM::FDT_String )
3668 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3669 if ( stepIDs->length() < 1 )
3671 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3672 if ( comps->length() < 1 )
3674 CORBA::String_var name = fields[ iF ]->GetName();
3676 if ( !fieldWriter.Set( meshDS,
3680 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3683 for ( size_t iC = 0; iC < comps->length(); ++iC )
3684 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3686 dblVals.resize( comps->length() );
3687 intVals.resize( comps->length() );
3689 // find sub-shape IDs
3691 std::vector< int >& subIds = subIdsByDim[ dim ];
3692 if ( subIds.empty() )
3693 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3694 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3695 subIds.push_back( id );
3699 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3703 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3705 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3706 if ( step->_is_nil() )
3709 CORBA::Long stamp = step->GetStamp();
3710 CORBA::Long id = step->GetID();
3711 fieldWriter.SetDtIt( int( stamp ), int( id ));
3713 // fill dblVals or intVals
3714 for ( size_t iC = 0; iC < comps->length(); ++iC )
3715 if ( dataType == GEOM::FDT_Double )
3717 dblVals[ iC ].clear();
3718 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3722 intVals[ iC ].clear();
3723 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3727 case GEOM::FDT_Double:
3729 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3730 if ( dblStep->_is_nil() ) continue;
3731 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3732 if ( vv->length() != subIds.size() * comps->length() )
3733 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3734 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3735 for ( size_t iC = 0; iC < comps->length(); ++iC )
3736 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3741 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3742 if ( intStep->_is_nil() ) continue;
3743 GEOM::ListOfLong_var vv = intStep->GetValues();
3744 if ( vv->length() != subIds.size() * comps->length() )
3745 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3746 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3747 for ( size_t iC = 0; iC < comps->length(); ++iC )
3748 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3751 case GEOM::FDT_Bool:
3753 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3754 if ( boolStep->_is_nil() ) continue;
3755 GEOM::short_array_var vv = boolStep->GetValues();
3756 if ( vv->length() != subIds.size() * comps->length() )
3757 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3758 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3759 for ( size_t iC = 0; iC < comps->length(); ++iC )
3760 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3766 // pass values to fieldWriter
3767 elemIt = fieldWriter.GetOrderedElems();
3768 if ( dataType == GEOM::FDT_Double )
3769 while ( elemIt->more() )
3771 const SMDS_MeshElement* e = elemIt->next();
3772 const int shapeID = e->getshapeId();
3773 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3774 for ( size_t iC = 0; iC < comps->length(); ++iC )
3775 fieldWriter.AddValue( noneDblValue );
3777 for ( size_t iC = 0; iC < comps->length(); ++iC )
3778 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3781 while ( elemIt->more() )
3783 const SMDS_MeshElement* e = elemIt->next();
3784 const int shapeID = e->getshapeId();
3785 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3786 for ( size_t iC = 0; iC < comps->length(); ++iC )
3787 fieldWriter.AddValue( (double) noneIntValue );
3789 for ( size_t iC = 0; iC < comps->length(); ++iC )
3790 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3794 fieldWriter.Perform();
3795 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3796 if ( res && res->IsKO() )
3798 if ( res->myComment.empty() )
3799 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3801 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3807 if ( !geomAssocFields || !geomAssocFields[0] )
3810 // write geomAssocFields
3812 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3813 shapeDim[ TopAbs_COMPOUND ] = 3;
3814 shapeDim[ TopAbs_COMPSOLID ] = 3;
3815 shapeDim[ TopAbs_SOLID ] = 3;
3816 shapeDim[ TopAbs_SHELL ] = 2;
3817 shapeDim[ TopAbs_FACE ] = 2;
3818 shapeDim[ TopAbs_WIRE ] = 1;
3819 shapeDim[ TopAbs_EDGE ] = 1;
3820 shapeDim[ TopAbs_VERTEX ] = 0;
3821 shapeDim[ TopAbs_SHAPE ] = 3;
3823 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3825 std::vector< std::string > compNames;
3826 switch ( geomAssocFields[ iF ]) {
3828 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3829 compNames.push_back( "dim" );
3832 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3835 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3838 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3842 compNames.push_back( "id" );
3843 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3844 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3846 fieldWriter.SetDtIt( -1, -1 );
3848 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3852 if ( compNames.size() == 2 ) // _vertices_
3853 while ( elemIt->more() )
3855 const SMDS_MeshElement* e = elemIt->next();
3856 const int shapeID = e->getshapeId();
3859 fieldWriter.AddValue( (double) -1 );
3860 fieldWriter.AddValue( (double) -1 );
3864 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3865 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3866 fieldWriter.AddValue( (double) shapeID );
3870 while ( elemIt->more() )
3872 const SMDS_MeshElement* e = elemIt->next();
3873 const int shapeID = e->getshapeId();
3875 fieldWriter.AddValue( (double) -1 );
3877 fieldWriter.AddValue( (double) shapeID );
3881 fieldWriter.Perform();
3882 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3883 if ( res && res->IsKO() )
3885 if ( res->myComment.empty() )
3886 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3888 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3891 } // loop on geomAssocFields
3896 //================================================================================
3898 * \brief Export a part of mesh to a DAT file
3900 //================================================================================
3902 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3904 throw (SALOME::SALOME_Exception)
3906 Unexpect aCatch(SALOME_SalomeException);
3908 _preMeshInfo->FullLoadFromFile();
3910 PrepareForWriting(file);
3912 SMESH_MeshPartDS partDS( meshPart );
3913 _impl->ExportDAT(file,&partDS);
3915 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3916 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3918 //================================================================================
3920 * \brief Export a part of mesh to an UNV file
3922 //================================================================================
3924 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3926 throw (SALOME::SALOME_Exception)
3928 Unexpect aCatch(SALOME_SalomeException);
3930 _preMeshInfo->FullLoadFromFile();
3932 PrepareForWriting(file);
3934 SMESH_MeshPartDS partDS( meshPart );
3935 _impl->ExportUNV(file, &partDS);
3937 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3938 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3940 //================================================================================
3942 * \brief Export a part of mesh to an STL file
3944 //================================================================================
3946 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3948 ::CORBA::Boolean isascii)
3949 throw (SALOME::SALOME_Exception)
3951 Unexpect aCatch(SALOME_SalomeException);
3953 _preMeshInfo->FullLoadFromFile();
3955 PrepareForWriting(file);
3957 CORBA::String_var name;
3958 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3959 if ( !so->_is_nil() )
3960 name = so->GetName();
3962 SMESH_MeshPartDS partDS( meshPart );
3963 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3965 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3966 << meshPart<< ", r'" << file << "', " << isascii << ")";
3969 //================================================================================
3971 * \brief Export a part of mesh to an STL file
3973 //================================================================================
3975 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3977 CORBA::Boolean overwrite,
3978 CORBA::Boolean groupElemsByType)
3979 throw (SALOME::SALOME_Exception)
3982 Unexpect aCatch(SALOME_SalomeException);
3984 _preMeshInfo->FullLoadFromFile();
3986 PrepareForWriting(file,overwrite);
3988 std::string meshName("");
3989 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3990 if ( !so->_is_nil() )
3992 CORBA::String_var name = so->GetName();
3993 meshName = name.in();
3997 SMESH_MeshPartDS partDS( meshPart );
3998 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4000 SMESH_CATCH( SMESH::throwCorbaException );
4002 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4003 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4005 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4009 //================================================================================
4011 * \brief Export a part of mesh to a GMF file
4013 //================================================================================
4015 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4017 bool withRequiredGroups)
4018 throw (SALOME::SALOME_Exception)
4020 Unexpect aCatch(SALOME_SalomeException);
4022 _preMeshInfo->FullLoadFromFile();
4024 PrepareForWriting(file,/*overwrite=*/true);
4026 SMESH_MeshPartDS partDS( meshPart );
4027 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4029 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4030 << meshPart<< ", r'"
4032 << withRequiredGroups << ")";
4035 //=============================================================================
4037 * Return computation progress [0.,1]
4039 //=============================================================================
4041 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4045 return _impl->GetComputeProgress();
4047 SMESH_CATCH( SMESH::doNothing );
4051 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4053 Unexpect aCatch(SALOME_SalomeException);
4055 return _preMeshInfo->NbNodes();
4057 return _impl->NbNodes();
4060 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4062 Unexpect aCatch(SALOME_SalomeException);
4064 return _preMeshInfo->NbElements();
4066 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4069 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4071 Unexpect aCatch(SALOME_SalomeException);
4073 return _preMeshInfo->Nb0DElements();
4075 return _impl->Nb0DElements();
4078 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4080 Unexpect aCatch(SALOME_SalomeException);
4082 return _preMeshInfo->NbBalls();
4084 return _impl->NbBalls();
4087 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4089 Unexpect aCatch(SALOME_SalomeException);
4091 return _preMeshInfo->NbEdges();
4093 return _impl->NbEdges();
4096 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4097 throw(SALOME::SALOME_Exception)
4099 Unexpect aCatch(SALOME_SalomeException);
4101 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4103 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4106 //=============================================================================
4108 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4110 Unexpect aCatch(SALOME_SalomeException);
4112 return _preMeshInfo->NbFaces();
4114 return _impl->NbFaces();
4117 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4119 Unexpect aCatch(SALOME_SalomeException);
4121 return _preMeshInfo->NbTriangles();
4123 return _impl->NbTriangles();
4126 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4128 Unexpect aCatch(SALOME_SalomeException);
4130 return _preMeshInfo->NbBiQuadTriangles();
4132 return _impl->NbBiQuadTriangles();
4135 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4137 Unexpect aCatch(SALOME_SalomeException);
4139 return _preMeshInfo->NbQuadrangles();
4141 return _impl->NbQuadrangles();
4144 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4146 Unexpect aCatch(SALOME_SalomeException);
4148 return _preMeshInfo->NbBiQuadQuadrangles();
4150 return _impl->NbBiQuadQuadrangles();
4153 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4155 Unexpect aCatch(SALOME_SalomeException);
4157 return _preMeshInfo->NbPolygons();
4159 return _impl->NbPolygons();
4162 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4164 Unexpect aCatch(SALOME_SalomeException);
4166 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4168 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4171 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4172 throw(SALOME::SALOME_Exception)
4174 Unexpect aCatch(SALOME_SalomeException);
4176 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4178 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4181 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4182 throw(SALOME::SALOME_Exception)
4184 Unexpect aCatch(SALOME_SalomeException);
4186 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4188 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4191 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4192 throw(SALOME::SALOME_Exception)
4194 Unexpect aCatch(SALOME_SalomeException);
4196 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4198 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4201 //=============================================================================
4203 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4205 Unexpect aCatch(SALOME_SalomeException);
4207 return _preMeshInfo->NbVolumes();
4209 return _impl->NbVolumes();
4212 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4214 Unexpect aCatch(SALOME_SalomeException);
4216 return _preMeshInfo->NbTetras();
4218 return _impl->NbTetras();
4221 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4223 Unexpect aCatch(SALOME_SalomeException);
4225 return _preMeshInfo->NbHexas();
4227 return _impl->NbHexas();
4230 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4232 Unexpect aCatch(SALOME_SalomeException);
4234 return _preMeshInfo->NbTriQuadHexas();
4236 return _impl->NbTriQuadraticHexas();
4239 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4241 Unexpect aCatch(SALOME_SalomeException);
4243 return _preMeshInfo->NbPyramids();
4245 return _impl->NbPyramids();
4248 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4250 Unexpect aCatch(SALOME_SalomeException);
4252 return _preMeshInfo->NbPrisms();
4254 return _impl->NbPrisms();
4257 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4259 Unexpect aCatch(SALOME_SalomeException);
4261 return _preMeshInfo->NbHexPrisms();
4263 return _impl->NbHexagonalPrisms();
4266 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4268 Unexpect aCatch(SALOME_SalomeException);
4270 return _preMeshInfo->NbPolyhedrons();
4272 return _impl->NbPolyhedrons();
4275 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4276 throw(SALOME::SALOME_Exception)
4278 Unexpect aCatch(SALOME_SalomeException);
4280 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4282 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4285 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4286 throw(SALOME::SALOME_Exception)
4288 Unexpect aCatch(SALOME_SalomeException);
4290 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4292 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4295 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4296 throw(SALOME::SALOME_Exception)
4298 Unexpect aCatch(SALOME_SalomeException);
4300 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4302 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4305 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4306 throw(SALOME::SALOME_Exception)
4308 Unexpect aCatch(SALOME_SalomeException);
4310 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4312 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4315 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4316 throw(SALOME::SALOME_Exception)
4318 Unexpect aCatch(SALOME_SalomeException);
4320 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4322 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4325 //=============================================================================
4327 * Returns nb of published sub-meshes
4329 //=============================================================================
4331 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4333 Unexpect aCatch(SALOME_SalomeException);
4334 return _mapSubMesh_i.size();
4337 //=============================================================================
4339 * Dumps mesh into a string
4341 //=============================================================================
4343 char* SMESH_Mesh_i::Dump()
4347 return CORBA::string_dup( os.str().c_str() );
4350 //=============================================================================
4352 * Method of SMESH_IDSource interface
4354 //=============================================================================
4356 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4358 return GetElementsId();
4361 //=============================================================================
4363 * Returns ids of all elements
4365 //=============================================================================
4367 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4368 throw (SALOME::SALOME_Exception)
4370 Unexpect aCatch(SALOME_SalomeException);
4372 _preMeshInfo->FullLoadFromFile();
4374 SMESH::long_array_var aResult = new SMESH::long_array();
4375 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4377 if ( aSMESHDS_Mesh == NULL )
4378 return aResult._retn();
4380 long nbElements = NbElements();
4381 aResult->length( nbElements );
4382 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4383 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4384 aResult[i] = anIt->next()->GetID();
4386 return aResult._retn();
4390 //=============================================================================
4392 * Returns ids of all elements of given type
4394 //=============================================================================
4396 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4397 throw (SALOME::SALOME_Exception)
4399 Unexpect aCatch(SALOME_SalomeException);
4401 _preMeshInfo->FullLoadFromFile();
4403 SMESH::long_array_var aResult = new SMESH::long_array();
4404 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4406 if ( aSMESHDS_Mesh == NULL )
4407 return aResult._retn();
4409 long nbElements = NbElements();
4411 // No sense in returning ids of elements along with ids of nodes:
4412 // when theElemType == SMESH::ALL, return node ids only if
4413 // there are no elements
4414 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4415 return GetNodesId();
4417 aResult->length( nbElements );
4421 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4422 while ( i < nbElements && anIt->more() )
4423 aResult[i++] = anIt->next()->GetID();
4425 aResult->length( i );
4427 return aResult._retn();
4430 //=============================================================================
4432 * Returns ids of all nodes
4434 //=============================================================================
4436 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4437 throw (SALOME::SALOME_Exception)
4439 Unexpect aCatch(SALOME_SalomeException);
4441 _preMeshInfo->FullLoadFromFile();
4443 SMESH::long_array_var aResult = new SMESH::long_array();
4444 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4446 if ( aMeshDS == NULL )
4447 return aResult._retn();
4449 long nbNodes = NbNodes();
4450 aResult->length( nbNodes );
4451 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4452 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4453 aResult[i] = anIt->next()->GetID();
4455 return aResult._retn();
4458 //=============================================================================
4462 //=============================================================================
4464 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4465 throw (SALOME::SALOME_Exception)
4467 SMESH::ElementType type = SMESH::ALL;
4471 _preMeshInfo->FullLoadFromFile();
4473 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4475 SMESH_CATCH( SMESH::throwCorbaException );
4480 //=============================================================================
4484 //=============================================================================
4486 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4487 throw (SALOME::SALOME_Exception)
4490 _preMeshInfo->FullLoadFromFile();
4492 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4494 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4496 return ( SMESH::EntityType ) e->GetEntityType();
4499 //=============================================================================
4503 //=============================================================================
4505 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4506 throw (SALOME::SALOME_Exception)
4509 _preMeshInfo->FullLoadFromFile();
4511 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4513 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4515 return ( SMESH::GeometryType ) e->GetGeomType();
4518 //=============================================================================
4520 * Returns ID of elements for given submesh
4522 //=============================================================================
4523 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4524 throw (SALOME::SALOME_Exception)
4526 SMESH::long_array_var aResult = new SMESH::long_array();
4530 _preMeshInfo->FullLoadFromFile();
4532 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4533 if(!SM) return aResult._retn();
4535 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4536 if(!SDSM) return aResult._retn();
4538 aResult->length(SDSM->NbElements());
4540 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4542 while ( eIt->more() ) {
4543 aResult[i++] = eIt->next()->GetID();
4546 SMESH_CATCH( SMESH::throwCorbaException );
4548 return aResult._retn();
4551 //=============================================================================
4553 * Returns ID of nodes for given submesh
4554 * If param all==true - returns all nodes, else -
4555 * returns only nodes on shapes.
4557 //=============================================================================
4559 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4561 throw (SALOME::SALOME_Exception)
4563 SMESH::long_array_var aResult = new SMESH::long_array();
4567 _preMeshInfo->FullLoadFromFile();
4569 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4570 if(!SM) return aResult._retn();
4572 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4573 if(!SDSM) return aResult._retn();
4576 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4577 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4578 while ( nIt->more() ) {
4579 const SMDS_MeshNode* elem = nIt->next();
4580 theElems.insert( elem->GetID() );
4583 else { // all nodes of submesh elements
4584 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4585 while ( eIt->more() ) {
4586 const SMDS_MeshElement* anElem = eIt->next();
4587 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4588 while ( nIt->more() ) {
4589 const SMDS_MeshElement* elem = nIt->next();
4590 theElems.insert( elem->GetID() );
4595 aResult->length(theElems.size());
4596 set<int>::iterator itElem;
4598 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4599 aResult[i++] = *itElem;
4601 SMESH_CATCH( SMESH::throwCorbaException );
4603 return aResult._retn();
4606 //=============================================================================
4608 * Returns type of elements for given submesh
4610 //=============================================================================
4612 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4613 throw (SALOME::SALOME_Exception)
4615 SMESH::ElementType type = SMESH::ALL;
4619 _preMeshInfo->FullLoadFromFile();
4621 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4622 if(!SM) return SMESH::ALL;
4624 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4625 if(!SDSM) return SMESH::ALL;
4627 if(SDSM->NbElements()==0)
4628 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4630 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4631 const SMDS_MeshElement* anElem = eIt->next();
4633 type = ( SMESH::ElementType ) anElem->GetType();
4635 SMESH_CATCH( SMESH::throwCorbaException );
4641 //=============================================================================
4643 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4645 //=============================================================================
4647 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4650 _preMeshInfo->FullLoadFromFile();
4652 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4653 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4658 //=============================================================================
4660 * Get XYZ coordinates of node as list of double
4661 * If there is not node for given ID - returns empty list
4663 //=============================================================================
4665 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4668 _preMeshInfo->FullLoadFromFile();
4670 SMESH::double_array_var aResult = new SMESH::double_array();
4671 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4672 if ( aMeshDS == NULL )
4673 return aResult._retn();
4676 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4678 return aResult._retn();
4682 aResult[0] = aNode->X();
4683 aResult[1] = aNode->Y();
4684 aResult[2] = aNode->Z();
4685 return aResult._retn();
4689 //=============================================================================
4691 * For given node returns list of IDs of inverse elements
4692 * If there is not node for given ID - returns empty list
4694 //=============================================================================
4696 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4697 SMESH::ElementType elemType)
4700 _preMeshInfo->FullLoadFromFile();
4702 SMESH::long_array_var aResult = new SMESH::long_array();
4703 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4704 if ( aMeshDS == NULL )
4705 return aResult._retn();
4708 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4710 return aResult._retn();
4712 // find inverse elements
4713 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4714 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4715 aResult->length( aNode->NbInverseElements( type ));
4716 for( int i = 0; eIt->more(); ++i )
4718 const SMDS_MeshElement* elem = eIt->next();
4719 aResult[ i ] = elem->GetID();
4721 return aResult._retn();
4724 //=============================================================================
4726 * \brief Return position of a node on shape
4728 //=============================================================================
4730 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4733 _preMeshInfo->FullLoadFromFile();
4735 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4736 aNodePosition->shapeID = 0;
4737 aNodePosition->shapeType = GEOM::SHAPE;
4739 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4740 if ( !mesh ) return aNodePosition;
4742 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4744 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4746 aNodePosition->shapeID = aNode->getshapeId();
4747 switch ( pos->GetTypeOfPosition() ) {
4749 aNodePosition->shapeType = GEOM::EDGE;
4750 aNodePosition->params.length(1);
4751 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4753 case SMDS_TOP_FACE: {
4754 SMDS_FacePositionPtr fPos = pos;
4755 aNodePosition->shapeType = GEOM::FACE;
4756 aNodePosition->params.length(2);
4757 aNodePosition->params[0] = fPos->GetUParameter();
4758 aNodePosition->params[1] = fPos->GetVParameter();
4761 case SMDS_TOP_VERTEX:
4762 aNodePosition->shapeType = GEOM::VERTEX;
4764 case SMDS_TOP_3DSPACE:
4765 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4766 aNodePosition->shapeType = GEOM::SOLID;
4767 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4768 aNodePosition->shapeType = GEOM::SHELL;
4774 return aNodePosition;
4777 //=============================================================================
4779 * \brief Return position of an element on shape
4781 //=============================================================================
4783 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4786 _preMeshInfo->FullLoadFromFile();
4788 SMESH::ElementPosition anElementPosition;
4789 anElementPosition.shapeID = 0;
4790 anElementPosition.shapeType = GEOM::SHAPE;
4792 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4793 if ( !mesh ) return anElementPosition;
4795 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4797 anElementPosition.shapeID = anElem->getshapeId();
4798 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4799 if ( !aSp.IsNull() ) {
4800 switch ( aSp.ShapeType() ) {
4802 anElementPosition.shapeType = GEOM::EDGE;
4805 anElementPosition.shapeType = GEOM::FACE;
4808 anElementPosition.shapeType = GEOM::VERTEX;
4811 anElementPosition.shapeType = GEOM::SOLID;
4814 anElementPosition.shapeType = GEOM::SHELL;
4820 return anElementPosition;
4823 //=============================================================================
4825 * If given element is node returns IDs of shape from position
4826 * If there is not node for given ID - returns -1
4828 //=============================================================================
4830 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4833 _preMeshInfo->FullLoadFromFile();
4835 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4836 if ( aMeshDS == NULL )
4840 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4842 return aNode->getshapeId();
4849 //=============================================================================
4851 * For given element returns ID of result shape after
4852 * ::FindShape() from SMESH_MeshEditor
4853 * If there is not element for given ID - returns -1
4855 //=============================================================================
4857 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4860 _preMeshInfo->FullLoadFromFile();
4862 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4863 if ( aMeshDS == NULL )
4866 // try to find element
4867 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4871 ::SMESH_MeshEditor aMeshEditor(_impl);
4872 int index = aMeshEditor.FindShape( elem );
4880 //=============================================================================
4882 * Returns number of nodes for given element
4883 * If there is not element for given ID - returns -1
4885 //=============================================================================
4887 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4890 _preMeshInfo->FullLoadFromFile();
4892 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4893 if ( aMeshDS == NULL ) return -1;
4894 // try to find element
4895 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4896 if(!elem) return -1;
4897 return elem->NbNodes();
4901 //=============================================================================
4903 * Returns ID of node by given index for given element
4904 * If there is not element for given ID - returns -1
4905 * If there is not node for given index - returns -2
4907 //=============================================================================
4909 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4912 _preMeshInfo->FullLoadFromFile();
4914 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4915 if ( aMeshDS == NULL ) return -1;
4916 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4917 if(!elem) return -1;
4918 if( index>=elem->NbNodes() || index<0 ) return -1;
4919 return elem->GetNode(index)->GetID();
4922 //=============================================================================
4924 * Returns IDs of nodes of given element
4926 //=============================================================================
4928 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4931 _preMeshInfo->FullLoadFromFile();
4933 SMESH::long_array_var aResult = new SMESH::long_array();
4934 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4936 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4938 aResult->length( elem->NbNodes() );
4939 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4940 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
4941 aResult[ i ] = n->GetID();
4944 return aResult._retn();
4947 //=============================================================================
4949 * Returns true if given node is medium node
4950 * in given quadratic element
4952 //=============================================================================
4954 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4957 _preMeshInfo->FullLoadFromFile();
4959 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4960 if ( aMeshDS == NULL ) return false;
4962 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4963 if(!aNode) return false;
4964 // try to find element
4965 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4966 if(!elem) return false;
4968 return elem->IsMediumNode(aNode);
4972 //=============================================================================
4974 * Returns true if given node is medium node
4975 * in one of quadratic elements
4977 //=============================================================================
4979 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4980 SMESH::ElementType theElemType)
4983 _preMeshInfo->FullLoadFromFile();
4985 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4986 if ( aMeshDS == NULL ) return false;
4989 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4990 if(!aNode) return false;
4992 SMESH_MesherHelper aHelper( *(_impl) );
4994 SMDSAbs_ElementType aType;
4995 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4996 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4997 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4998 else aType = SMDSAbs_All;
5000 return aHelper.IsMedium(aNode,aType);
5004 //=============================================================================
5006 * Returns number of edges for given element
5008 //=============================================================================
5010 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5013 _preMeshInfo->FullLoadFromFile();
5015 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5016 if ( aMeshDS == NULL ) return -1;
5017 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5018 if(!elem) return -1;
5019 return elem->NbEdges();
5023 //=============================================================================
5025 * Returns number of faces for given element
5027 //=============================================================================
5029 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5032 _preMeshInfo->FullLoadFromFile();
5034 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5035 if ( aMeshDS == NULL ) return -1;
5036 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5037 if(!elem) return -1;
5038 return elem->NbFaces();
5041 //=======================================================================
5042 //function : GetElemFaceNodes
5043 //purpose : Returns nodes of given face (counted from zero) for given element.
5044 //=======================================================================
5046 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5047 CORBA::Short faceIndex)
5050 _preMeshInfo->FullLoadFromFile();
5052 SMESH::long_array_var aResult = new SMESH::long_array();
5053 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5055 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5057 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5058 if ( faceIndex < vtool.NbFaces() )
5060 aResult->length( vtool.NbFaceNodes( faceIndex ));
5061 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5062 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5063 aResult[ i ] = nn[ i ]->GetID();
5067 return aResult._retn();
5070 //=======================================================================
5071 //function : GetElemFaceNodes
5072 //purpose : Returns three components of normal of given mesh face.
5073 //=======================================================================
5075 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5076 CORBA::Boolean normalized)
5079 _preMeshInfo->FullLoadFromFile();
5081 SMESH::double_array_var aResult = new SMESH::double_array();
5083 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5086 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5088 aResult->length( 3 );
5089 aResult[ 0 ] = normal.X();
5090 aResult[ 1 ] = normal.Y();
5091 aResult[ 2 ] = normal.Z();
5094 return aResult._retn();
5097 //=======================================================================
5098 //function : FindElementByNodes
5099 //purpose : Returns an element based on all given nodes.
5100 //=======================================================================
5102 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5105 _preMeshInfo->FullLoadFromFile();
5107 CORBA::Long elemID(0);
5108 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5110 vector< const SMDS_MeshNode * > nn( nodes.length() );
5111 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5112 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5115 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5116 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5117 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5118 _impl->NbVolumes( ORDER_QUADRATIC )))
5119 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5121 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5126 //================================================================================
5128 * \brief Return elements including all given nodes.
5130 //================================================================================
5132 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5133 SMESH::ElementType elemType)
5136 _preMeshInfo->FullLoadFromFile();
5138 SMESH::long_array_var result = new SMESH::long_array();
5140 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5142 vector< const SMDS_MeshNode * > nn( nodes.length() );
5143 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5144 nn[i] = mesh->FindNode( nodes[i] );
5146 std::vector<const SMDS_MeshElement *> elems;
5147 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5148 result->length( elems.size() );
5149 for ( size_t i = 0; i < elems.size(); ++i )
5150 result[i] = elems[i]->GetID();
5152 return result._retn();
5155 //=============================================================================
5157 * Returns true if given element is polygon
5159 //=============================================================================
5161 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5164 _preMeshInfo->FullLoadFromFile();
5166 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5167 if ( aMeshDS == NULL ) return false;
5168 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5169 if(!elem) return false;
5170 return elem->IsPoly();
5174 //=============================================================================
5176 * Returns true if given element is quadratic
5178 //=============================================================================
5180 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5183 _preMeshInfo->FullLoadFromFile();
5185 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5186 if ( aMeshDS == NULL ) return false;
5187 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5188 if(!elem) return false;
5189 return elem->IsQuadratic();
5192 //=============================================================================
5194 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5196 //=============================================================================
5198 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5201 _preMeshInfo->FullLoadFromFile();
5203 if ( const SMDS_BallElement* ball =
5204 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5205 return ball->GetDiameter();
5210 //=============================================================================
5212 * Returns bary center for given element
5214 //=============================================================================
5216 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5219 _preMeshInfo->FullLoadFromFile();
5221 SMESH::double_array_var aResult = new SMESH::double_array();
5222 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5223 if ( aMeshDS == NULL )
5224 return aResult._retn();
5226 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5228 return aResult._retn();
5230 if(elem->GetType()==SMDSAbs_Volume) {
5231 SMDS_VolumeTool aTool;
5232 if(aTool.Set(elem)) {
5234 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5239 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5241 double x=0., y=0., z=0.;
5242 for(; anIt->more(); ) {
5244 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5258 return aResult._retn();
5261 //================================================================================
5263 * \brief Create a group of elements preventing computation of a sub-shape
5265 //================================================================================
5267 SMESH::ListOfGroups*
5268 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5269 const char* theGroupName )
5270 throw ( SALOME::SALOME_Exception )
5272 Unexpect aCatch(SALOME_SalomeException);
5274 if ( !theGroupName || strlen( theGroupName) == 0 )
5275 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5277 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5278 ::SMESH_MeshEditor::ElemFeatures elemType;
5280 // submesh by subshape id
5281 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5282 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5285 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5286 if ( error && error->HasBadElems() )
5288 // sort bad elements by type
5289 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5290 const list<const SMDS_MeshElement*>& badElems =
5291 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5292 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5293 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5294 for ( ; elemIt != elemEnd; ++elemIt )
5296 const SMDS_MeshElement* elem = *elemIt;
5297 if ( !elem ) continue;
5299 if ( elem->GetID() < 1 )
5301 // elem is a temporary element, make a real element
5302 vector< const SMDS_MeshNode* > nodes;
5303 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5304 while ( nIt->more() && elem )
5306 nodes.push_back( nIt->next() );
5307 if ( nodes.back()->GetID() < 1 )
5308 elem = 0; // a temporary element on temporary nodes
5312 ::SMESH_MeshEditor editor( _impl );
5313 elem = editor.AddElement( nodes, elemType.Init( elem ));
5317 elemsByType[ elem->GetType() ].push_back( elem );
5320 // how many groups to create?
5322 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5323 nbTypes += int( !elemsByType[ i ].empty() );
5324 groups->length( nbTypes );
5327 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5329 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5330 if ( elems.empty() ) continue;
5332 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5333 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5335 SMESH::SMESH_Mesh_var mesh = _this();
5336 SALOMEDS::SObject_wrap aSO =
5337 _gen_i->PublishGroup( mesh, groups[ iG ],
5338 GEOM::GEOM_Object::_nil(), theGroupName);
5340 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5341 if ( !grp_i ) continue;
5343 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5344 for ( size_t iE = 0; iE < elems.size(); ++iE )
5345 grpDS->SMDSGroup().Add( elems[ iE ]);
5350 return groups._retn();
5353 //=============================================================================
5355 * Create and publish group servants if any groups were imported or created anyhow
5357 //=============================================================================
5359 void SMESH_Mesh_i::CreateGroupServants()
5361 SMESH::SMESH_Mesh_var aMesh = _this();
5364 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5365 while ( groupIt->more() )
5367 ::SMESH_Group* group = groupIt->next();
5368 int anId = group->GetID();
5370 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5371 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5373 addedIDs.insert( anId );
5375 SMESH_GroupBase_i* aGroupImpl;
5377 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5378 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5380 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5381 shape = groupOnGeom->GetShape();
5384 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5387 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5388 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5389 aGroupImpl->Register();
5391 // register CORBA object for persistence
5392 int nextId = _gen_i->RegisterObject( groupVar );
5393 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5394 else { nextId = 0; } // avoid "unused variable" warning in release mode
5396 // publishing the groups in the study
5397 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5398 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5400 if ( !addedIDs.empty() )
5403 set<int>::iterator id = addedIDs.begin();
5404 for ( ; id != addedIDs.end(); ++id )
5406 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5407 int i = std::distance( _mapGroups.begin(), it );
5408 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5413 //=============================================================================
5415 * \brief Return true if all sub-meshes are computed OK - to update an icon
5417 //=============================================================================
5419 bool SMESH_Mesh_i::IsComputedOK()
5421 return _impl->IsComputedOK();
5424 //=============================================================================
5426 * \brief Return groups cantained in _mapGroups by their IDs
5428 //=============================================================================
5430 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5432 int nbGroups = groupIDs.size();
5433 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5434 aList->length( nbGroups );
5436 list<int>::const_iterator ids = groupIDs.begin();
5437 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5439 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5440 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5441 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5443 aList->length( nbGroups );
5444 return aList._retn();
5447 //=============================================================================
5449 * \brief Return information about imported file
5451 //=============================================================================
5453 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5455 SMESH::MedFileInfo_var res( _medFileInfo );
5456 if ( !res.operator->() ) {
5457 res = new SMESH::MedFileInfo;
5459 res->fileSize = res->major = res->minor = res->release = -1;
5464 //=======================================================================
5465 //function : FileInfoToString
5466 //purpose : Persistence of file info
5467 //=======================================================================
5469 std::string SMESH_Mesh_i::FileInfoToString()
5472 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5474 s = SMESH_Comment( _medFileInfo->fileSize )
5475 << " " << _medFileInfo->major
5476 << " " << _medFileInfo->minor
5477 << " " << _medFileInfo->release
5478 << " " << _medFileInfo->fileName;
5483 //=======================================================================
5484 //function : FileInfoFromString
5485 //purpose : Persistence of file info
5486 //=======================================================================
5488 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5490 std::string size, major, minor, release, fileName;
5491 std::istringstream is(info);
5492 is >> size >> major >> minor >> release;
5493 fileName = info.data() + ( size.size() + 1 +
5496 release.size()+ 1 );
5498 _medFileInfo = new SMESH::MedFileInfo();
5499 _medFileInfo->fileName = fileName.c_str();
5500 _medFileInfo->fileSize = atoi( size.c_str() );
5501 _medFileInfo->major = atoi( major.c_str() );
5502 _medFileInfo->minor = atoi( minor.c_str() );
5503 _medFileInfo->release = atoi( release.c_str() );
5506 //=============================================================================
5508 * \brief Pass names of mesh groups from study to mesh DS
5510 //=============================================================================
5512 void SMESH_Mesh_i::checkGroupNames()
5514 int nbGrp = NbGroups();
5518 SMESH::ListOfGroups* grpList = 0;
5519 // avoid dump of "GetGroups"
5521 // store python dump into a local variable inside local scope
5522 SMESH::TPythonDump pDump; // do not delete this line of code
5523 grpList = GetGroups();
5526 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5527 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5530 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5531 if ( aGrpSO->_is_nil() )
5533 // correct name of the mesh group if necessary
5534 const char* guiName = aGrpSO->GetName();
5535 if ( strcmp(guiName, aGrp->GetName()) )
5536 aGrp->SetName( guiName );
5540 //=============================================================================
5542 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5544 //=============================================================================
5545 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5547 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5551 //=============================================================================
5553 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5555 //=============================================================================
5557 char* SMESH_Mesh_i::GetParameters()
5559 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5562 //=============================================================================
5564 * \brief Returns list of notebook variables used for last Mesh operation
5566 //=============================================================================
5567 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5569 SMESH::string_array_var aResult = new SMESH::string_array();
5570 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5572 CORBA::String_var aParameters = GetParameters();
5573 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5574 if ( aSections->length() > 0 ) {
5575 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5576 aResult->length( aVars.length() );
5577 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5578 aResult[i] = CORBA::string_dup( aVars[i] );
5581 return aResult._retn();
5584 //=======================================================================
5585 //function : GetTypes
5586 //purpose : Returns types of elements it contains
5587 //=======================================================================
5589 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5592 return _preMeshInfo->GetTypes();
5594 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5598 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5599 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5600 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5601 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5602 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5603 if (_impl->NbNodes() &&
5604 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5605 types->length( nbTypes );
5607 return types._retn();
5610 //=======================================================================
5611 //function : GetMesh
5612 //purpose : Returns self
5613 //=======================================================================
5615 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5617 return SMESH::SMESH_Mesh::_duplicate( _this() );
5620 //=======================================================================
5621 //function : IsMeshInfoCorrect
5622 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5623 // * happen if mesh data is not yet fully loaded from the file of study.
5624 //=======================================================================
5626 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5628 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5631 //=============================================================================
5633 * \brief Returns number of mesh elements per each \a EntityType
5635 //=============================================================================
5637 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5640 return _preMeshInfo->GetMeshInfo();
5642 SMESH::long_array_var aRes = new SMESH::long_array();
5643 aRes->length(SMESH::Entity_Last);
5644 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5646 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5648 return aRes._retn();
5649 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5650 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5651 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5652 return aRes._retn();
5655 //=============================================================================
5657 * \brief Returns number of mesh elements per each \a ElementType
5659 //=============================================================================
5661 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5663 SMESH::long_array_var aRes = new SMESH::long_array();
5664 aRes->length(SMESH::NB_ELEMENT_TYPES);
5665 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5668 const SMDS_MeshInfo* meshInfo = 0;
5670 meshInfo = _preMeshInfo;
5671 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5672 meshInfo = & meshDS->GetMeshInfo();
5675 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5676 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5678 return aRes._retn();
5681 //=============================================================================
5683 * Collect statistic of mesh elements given by iterator
5685 //=============================================================================
5687 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5688 SMESH::long_array& theInfo)
5690 if (!theItr) return;
5691 while (theItr->more())
5692 theInfo[ theItr->next()->GetEntityType() ]++;
5694 //=============================================================================
5696 * Returns mesh unstructed grid information.
5698 //=============================================================================
5700 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5702 SALOMEDS::TMPFile_var SeqFile;
5703 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5704 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5706 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5707 aWriter->WriteToOutputStringOn();
5708 aWriter->SetInputData(aGrid);
5709 aWriter->SetFileTypeToBinary();
5711 char* str = aWriter->GetOutputString();
5712 int size = aWriter->GetOutputStringLength();
5714 //Allocate octet buffer of required size
5715 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5716 //Copy ostrstream content to the octet buffer
5717 memcpy(OctetBuf, str, size);
5718 //Create and return TMPFile
5719 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5723 return SeqFile._retn();
5726 //=============================================================================
5727 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5728 * SMESH::ElementType type) */
5730 using namespace SMESH::Controls;
5731 //-----------------------------------------------------------------------------
5732 struct PredicateIterator : public SMDS_ElemIterator
5734 SMDS_ElemIteratorPtr _elemIter;
5735 PredicatePtr _predicate;
5736 const SMDS_MeshElement* _elem;
5737 SMDSAbs_ElementType _type;
5739 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5740 PredicatePtr predicate,
5741 SMDSAbs_ElementType type):
5742 _elemIter(iterator), _predicate(predicate), _type(type)
5750 virtual const SMDS_MeshElement* next()
5752 const SMDS_MeshElement* res = _elem;
5754 while ( _elemIter->more() && !_elem )
5756 if ((_elem = _elemIter->next()) &&
5757 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5758 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5765 //-----------------------------------------------------------------------------
5766 struct IDSourceIterator : public SMDS_ElemIterator
5768 const CORBA::Long* _idPtr;
5769 const CORBA::Long* _idEndPtr;
5770 SMESH::long_array_var _idArray;
5771 const SMDS_Mesh* _mesh;
5772 const SMDSAbs_ElementType _type;
5773 const SMDS_MeshElement* _elem;
5775 IDSourceIterator( const SMDS_Mesh* mesh,
5776 const CORBA::Long* ids,
5778 SMDSAbs_ElementType type):
5779 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5781 if ( _idPtr && nbIds && _mesh )
5784 IDSourceIterator( const SMDS_Mesh* mesh,
5785 SMESH::long_array* idArray,
5786 SMDSAbs_ElementType type):
5787 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5789 if ( idArray && _mesh )
5791 _idPtr = &_idArray[0];
5792 _idEndPtr = _idPtr + _idArray->length();
5800 virtual const SMDS_MeshElement* next()
5802 const SMDS_MeshElement* res = _elem;
5804 while ( _idPtr < _idEndPtr && !_elem )
5806 if ( _type == SMDSAbs_Node )
5808 _elem = _mesh->FindNode( *_idPtr++ );
5810 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5811 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5819 //-----------------------------------------------------------------------------
5821 struct NodeOfElemIterator : public SMDS_ElemIterator
5823 TColStd_MapOfInteger _checkedNodeIDs;
5824 SMDS_ElemIteratorPtr _elemIter;
5825 SMDS_ElemIteratorPtr _nodeIter;
5826 const SMDS_MeshElement* _node;
5828 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5830 if ( _elemIter && _elemIter->more() )
5832 _nodeIter = _elemIter->next()->nodesIterator();
5840 virtual const SMDS_MeshElement* next()
5842 const SMDS_MeshElement* res = _node;
5844 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5846 if ( _nodeIter->more() )
5848 _node = _nodeIter->next();
5849 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5854 _nodeIter = _elemIter->next()->nodesIterator();
5862 //=============================================================================
5864 * Return iterator on elements of given type in given object
5866 //=============================================================================
5868 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5869 SMESH::ElementType theType)
5871 SMDS_ElemIteratorPtr elemIt;
5872 bool typeOK = ( theType == SMESH::ALL );
5873 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5875 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5876 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5877 if ( !mesh_i ) return elemIt;
5878 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5880 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5882 elemIt = meshDS->elementsIterator( elemType );
5885 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5887 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5890 elemIt = sm->GetElements();
5891 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5893 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5894 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5898 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5900 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5901 if ( groupDS && ( elemType == groupDS->GetType() ||
5902 elemType == SMDSAbs_Node ||
5903 elemType == SMDSAbs_All ))
5905 elemIt = groupDS->GetElements();
5906 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5909 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5911 if ( filter_i->GetElementType() == theType ||
5912 filter_i->GetElementType() == SMESH::ALL ||
5913 elemType == SMDSAbs_Node ||
5914 elemType == SMDSAbs_All)
5916 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5917 if ( pred_i && pred_i->GetPredicate() )
5919 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5920 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5921 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
5922 elemIt = SMDS_ElemIteratorPtr
5923 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
5924 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
5930 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5931 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5932 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5934 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
5935 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5938 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5939 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
5943 SMESH::long_array_var ids = theObject->GetIDs();
5944 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
5946 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5949 if ( elemIt && elemIt->more() && !typeOK )
5951 if ( elemType == SMDSAbs_Node )
5953 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5957 elemIt = SMDS_ElemIteratorPtr();
5963 //=============================================================================
5964 namespace // Finding concurrent hypotheses
5965 //=============================================================================
5969 * \brief mapping of mesh dimension into shape type
5971 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5973 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5975 case 0: aType = TopAbs_VERTEX; break;
5976 case 1: aType = TopAbs_EDGE; break;
5977 case 2: aType = TopAbs_FACE; break;
5979 default:aType = TopAbs_SOLID; break;
5984 //-----------------------------------------------------------------------------
5986 * \brief Internal structure used to find concurrent submeshes
5988 * It represents a pair < submesh, concurrent dimension >, where
5989 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5990 * with another submesh. In other words, it is dimension of a hypothesis assigned
5997 int _dim; //!< a dimension the algo can build (concurrent dimension)
5998 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5999 TopTools_MapOfShape _shapeMap;
6000 SMESH_subMesh* _subMesh;
6001 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6003 //-----------------------------------------------------------------------------
6004 // Return the algorithm
6005 const SMESH_Algo* GetAlgo() const
6006 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6008 //-----------------------------------------------------------------------------
6010 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6012 const TopoDS_Shape& theShape)
6014 _subMesh = (SMESH_subMesh*)theSubMesh;
6015 SetShape( theDim, theShape );
6018 //-----------------------------------------------------------------------------
6020 void SetShape(const int theDim,
6021 const TopoDS_Shape& theShape)
6024 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6025 if (_dim >= _ownDim)
6026 _shapeMap.Add( theShape );
6028 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6029 for( ; anExp.More(); anExp.Next() )
6030 _shapeMap.Add( anExp.Current() );
6034 //-----------------------------------------------------------------------------
6035 //! Check sharing of sub-shapes
6036 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6037 const TopTools_MapOfShape& theToFind,
6038 const TopAbs_ShapeEnum theType)
6040 bool isShared = false;
6041 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6042 for (; !isShared && anItr.More(); anItr.Next() )
6044 const TopoDS_Shape aSubSh = anItr.Key();
6045 // check for case when concurrent dimensions are same
6046 isShared = theToFind.Contains( aSubSh );
6047 // check for sub-shape with concurrent dimension
6048 TopExp_Explorer anExp( aSubSh, theType );
6049 for ( ; !isShared && anExp.More(); anExp.Next() )
6050 isShared = theToFind.Contains( anExp.Current() );
6055 //-----------------------------------------------------------------------------
6056 //! check algorithms
6057 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6058 const SMESHDS_Hypothesis* theA2)
6060 if ( !theA1 || !theA2 ||
6061 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6062 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6063 return false; // one of the hypothesis is not algorithm
6064 // check algorithm names (should be equal)
6065 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6069 //-----------------------------------------------------------------------------
6070 //! Check if sub-shape hypotheses are concurrent
6071 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6073 if ( _subMesh == theOther->_subMesh )
6074 return false; // same sub-shape - should not be
6076 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6077 // any of the two submeshes is not on COMPOUND shape )
6078 // -> no concurrency
6079 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6080 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6081 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6082 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6083 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6086 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6087 if ( !checkSubShape )
6090 // check algorithms to be same
6091 const SMESH_Algo* a1 = this->GetAlgo();
6092 const SMESH_Algo* a2 = theOther->GetAlgo();
6093 bool isSame = checkAlgo( a1, a2 );
6097 return false; // pb?
6098 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6101 // check hypothesises for concurrence (skip first as algorithm)
6103 // pointers should be same, because it is referened from mesh hypothesis partition
6104 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6105 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6106 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6107 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6109 // the submeshes are concurrent if their algorithms has different parameters
6110 return nbSame != theOther->_hypotheses.size() - 1;
6113 // Return true if algorithm of this SMESH_DimHyp is used if no
6114 // sub-mesh order is imposed by the user
6115 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6117 // NeedDiscreteBoundary() algo has a higher priority
6118 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6119 theOther->GetAlgo()->NeedDiscreteBoundary() )
6120 return !this->GetAlgo()->NeedDiscreteBoundary();
6122 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6125 }; // end of SMESH_DimHyp
6126 //-----------------------------------------------------------------------------
6128 typedef list<const SMESH_DimHyp*> TDimHypList;
6130 //-----------------------------------------------------------------------------
6132 void addDimHypInstance(const int theDim,
6133 const TopoDS_Shape& theShape,
6134 const SMESH_Algo* theAlgo,
6135 const SMESH_subMesh* theSubMesh,
6136 const list <const SMESHDS_Hypothesis*>& theHypList,
6137 TDimHypList* theDimHypListArr )
6139 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6140 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6141 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6142 dimHyp->_hypotheses.push_front(theAlgo);
6143 listOfdimHyp.push_back( dimHyp );
6146 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6147 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6148 theHypList.begin(), theHypList.end() );
6151 //-----------------------------------------------------------------------------
6152 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6153 TDimHypList& theListOfConcurr)
6155 if ( theListOfConcurr.empty() )
6157 theListOfConcurr.push_back( theDimHyp );
6161 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6162 while ( hypIt != theListOfConcurr.end() &&
6163 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6165 theListOfConcurr.insert( hypIt, theDimHyp );
6169 //-----------------------------------------------------------------------------
6170 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6171 const TDimHypList& theListOfDimHyp,
6172 TDimHypList& theListOfConcurrHyp,
6173 set<int>& theSetOfConcurrId )
6175 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6176 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6178 const SMESH_DimHyp* curDimHyp = *rIt;
6179 if ( curDimHyp == theDimHyp )
6180 break; // meet own dimHyp pointer in same dimension
6182 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6183 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6185 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6190 //-----------------------------------------------------------------------------
6191 void unionLists(TListOfInt& theListOfId,
6192 TListOfListOfInt& theListOfListOfId,
6195 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6196 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6198 continue; //skip already treated lists
6199 // check if other list has any same submesh object
6200 TListOfInt& otherListOfId = *it;
6201 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6202 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6205 // union two lists (from source into target)
6206 TListOfInt::iterator it2 = otherListOfId.begin();
6207 for ( ; it2 != otherListOfId.end(); it2++ ) {
6208 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6209 theListOfId.push_back(*it2);
6211 // clear source list
6212 otherListOfId.clear();
6215 //-----------------------------------------------------------------------------
6217 //! free memory allocated for dimension-hypothesis objects
6218 void removeDimHyps( TDimHypList* theArrOfList )
6220 for (int i = 0; i < 4; i++ ) {
6221 TDimHypList& listOfdimHyp = theArrOfList[i];
6222 TDimHypList::const_iterator it = listOfdimHyp.begin();
6223 for ( ; it != listOfdimHyp.end(); it++ )
6228 //-----------------------------------------------------------------------------
6230 * \brief find common submeshes with given submesh
6231 * \param theSubMeshList list of already collected submesh to check
6232 * \param theSubMesh given submesh to intersect with other
6233 * \param theCommonSubMeshes collected common submeshes
6235 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6236 const SMESH_subMesh* theSubMesh,
6237 set<const SMESH_subMesh*>& theCommon )
6241 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6242 for ( ; it != theSubMeshList.end(); it++ )
6243 theSubMesh->FindIntersection( *it, theCommon );
6244 theSubMeshList.push_back( theSubMesh );
6245 //theCommon.insert( theSubMesh );
6248 //-----------------------------------------------------------------------------
6249 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6251 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6252 for ( ; listsIt != smLists.end(); ++listsIt )
6254 const TListOfInt& smIDs = *listsIt;
6255 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6263 //=============================================================================
6265 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6267 //=============================================================================
6269 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6271 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6272 if ( isSubMeshInList( submeshID, anOrder ))
6275 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6276 return isSubMeshInList( submeshID, allConurrent );
6279 //=============================================================================
6281 * \brief Return submesh objects list in meshing order
6283 //=============================================================================
6285 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6287 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6289 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6291 return aResult._retn();
6293 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6294 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6295 anOrder.splice( anOrder.end(), allConurrent );
6298 TListOfListOfInt::iterator listIt = anOrder.begin();
6299 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6300 unionLists( *listIt, anOrder, listIndx + 1 );
6302 // convert submesh ids into interface instances
6303 // and dump command into python
6304 convertMeshOrder( anOrder, aResult, false );
6306 return aResult._retn();
6309 //=============================================================================
6311 * \brief Finds concurrent sub-meshes
6313 //=============================================================================
6315 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6317 TListOfListOfInt anOrder;
6318 ::SMESH_Mesh& mesh = GetImpl();
6320 // collect submeshes and detect concurrent algorithms and hypothesises
6321 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6323 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6324 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6325 ::SMESH_subMesh* sm = (*i_sm).second;
6327 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6329 // list of assigned hypothesises
6330 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6331 // Find out dimensions where the submesh can be concurrent.
6332 // We define the dimensions by algo of each of hypotheses in hypList
6333 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6334 for( ; hypIt != hypList.end(); hypIt++ ) {
6335 SMESH_Algo* anAlgo = 0;
6336 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6337 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6338 // hyp it-self is algo
6339 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6341 // try to find algorithm with help of sub-shapes
6342 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6343 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6344 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6347 continue; // no algorithm assigned to a current submesh
6349 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6350 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6352 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6353 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6354 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6356 } // end iterations on submesh
6358 // iterate on created dimension-hypotheses and check for concurrents
6359 for ( int i = 0; i < 4; i++ ) {
6360 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6361 // check for concurrents in own and other dimensions (step-by-step)
6362 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6363 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6364 const SMESH_DimHyp* dimHyp = *dhIt;
6365 TDimHypList listOfConcurr;
6366 set<int> setOfConcurrIds;
6367 // looking for concurrents and collect into own list
6368 for ( int j = i; j < 4; j++ )
6369 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6370 // check if any concurrents found
6371 if ( listOfConcurr.size() > 0 ) {
6372 // add own submesh to list of concurrent
6373 addInOrderOfPriority( dimHyp, listOfConcurr );
6374 list<int> listOfConcurrIds;
6375 TDimHypList::iterator hypIt = listOfConcurr.begin();
6376 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6377 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6378 anOrder.push_back( listOfConcurrIds );
6383 removeDimHyps(dimHypListArr);
6385 // now, minimize the number of concurrent groups
6386 // Here we assume that lists of submeshes can have same submesh
6387 // in case of multi-dimension algorithms, as result
6388 // list with common submesh has to be united into one list
6390 TListOfListOfInt::iterator listIt = anOrder.begin();
6391 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6392 unionLists( *listIt, anOrder, listIndx + 1 );
6398 //=============================================================================
6400 * \brief Set submesh object order
6401 * \param theSubMeshArray submesh array order
6403 //=============================================================================
6405 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6408 _preMeshInfo->ForgetOrLoad();
6411 ::SMESH_Mesh& mesh = GetImpl();
6413 TPythonDump aPythonDump; // prevent dump of called methods
6414 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6416 TListOfListOfInt subMeshOrder;
6417 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6419 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6420 TListOfInt subMeshIds;
6422 aPythonDump << ", ";
6423 aPythonDump << "[ ";
6424 // Collect subMeshes which should be clear
6425 // do it list-by-list, because modification of submesh order
6426 // take effect between concurrent submeshes only
6427 set<const SMESH_subMesh*> subMeshToClear;
6428 list<const SMESH_subMesh*> subMeshList;
6429 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6431 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6433 aPythonDump << ", ";
6434 aPythonDump << subMesh;
6435 subMeshIds.push_back( subMesh->GetId() );
6436 // detect common parts of submeshes
6437 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6438 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6440 aPythonDump << " ]";
6441 subMeshOrder.push_back( subMeshIds );
6443 // clear collected sub-meshes
6444 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6445 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6446 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6448 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6449 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6450 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6453 aPythonDump << " ])";
6455 mesh.SetMeshOrder( subMeshOrder );
6458 SMESH::SMESH_Mesh_var me = _this();
6459 _gen_i->UpdateIcons( me );
6464 //=============================================================================
6466 * \brief Convert submesh ids into submesh interfaces
6468 //=============================================================================
6470 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6471 SMESH::submesh_array_array& theResOrder,
6472 const bool theIsDump)
6474 int nbSet = theIdsOrder.size();
6475 TPythonDump aPythonDump; // prevent dump of called methods
6477 aPythonDump << "[ ";
6478 theResOrder.length(nbSet);
6479 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6481 for( ; it != theIdsOrder.end(); it++ ) {
6482 // translate submesh identificators into submesh objects
6483 // takeing into account real number of concurrent lists
6484 const TListOfInt& aSubOrder = (*it);
6485 if (!aSubOrder.size())
6488 aPythonDump << "[ ";
6489 // convert shape indices into interfaces
6490 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6491 aResSubSet->length(aSubOrder.size());
6492 TListOfInt::const_iterator subIt = aSubOrder.begin();
6494 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6495 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6497 SMESH::SMESH_subMesh_var subMesh =
6498 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6501 aPythonDump << ", ";
6502 aPythonDump << subMesh;
6504 aResSubSet[ j++ ] = subMesh;
6507 aPythonDump << " ]";
6509 theResOrder[ listIndx++ ] = aResSubSet;
6511 // correct number of lists
6512 theResOrder.length( listIndx );
6515 // finilise python dump
6516 aPythonDump << " ]";
6517 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6521 namespace // utils used by SMESH_MeshPartDS
6524 * \brief Class used to access to protected data of SMDS_MeshInfo
6526 struct TMeshInfo : public SMDS_MeshInfo
6528 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6531 * \brief Element holing its ID only
6533 struct TElemID : public SMDS_LinearEdge
6535 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6539 //================================================================================
6541 // Implementation of SMESH_MeshPartDS
6543 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6544 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6546 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6547 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6550 _meshDS = mesh_i->GetImpl().GetMeshDS();
6552 SetPersistentId( _meshDS->GetPersistentId() );
6554 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6556 // <meshPart> is the whole mesh
6557 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6559 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6560 myGroupSet = _meshDS->GetGroups();
6565 SMESH::long_array_var anIDs = meshPart->GetIDs();
6566 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6567 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6569 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6570 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6571 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6576 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6577 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6578 if ( _elements[ e->GetType() ].insert( e ).second )
6581 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6582 while ( nIt->more() )
6584 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6585 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6592 ShapeToMesh( _meshDS->ShapeToMesh() );
6594 _meshDS = 0; // to enforce iteration on _elements and _nodes
6597 // -------------------------------------------------------------------------------------
6598 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6599 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6602 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6603 for ( ; partIt != meshPart.end(); ++partIt )
6604 if ( const SMDS_MeshElement * e = *partIt )
6605 if ( _elements[ e->GetType() ].insert( e ).second )
6608 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6609 while ( nIt->more() )
6611 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6612 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6618 // -------------------------------------------------------------------------------------
6619 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6621 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6623 TElemID elem( IDelem );
6624 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6625 if ( !_elements[ iType ].empty() )
6627 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6628 if ( it != _elements[ iType ].end() )
6633 // -------------------------------------------------------------------------------------
6634 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6636 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6638 typedef SMDS_SetIterator
6639 <const SMDS_MeshElement*,
6640 TIDSortedElemSet::const_iterator,
6641 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6642 SMDS_MeshElement::GeomFilter
6645 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6647 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6648 _elements[type].end(),
6649 SMDS_MeshElement::GeomFilter( geomType )));
6651 // -------------------------------------------------------------------------------------
6652 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6654 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6656 typedef SMDS_SetIterator
6657 <const SMDS_MeshElement*,
6658 TIDSortedElemSet::const_iterator,
6659 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6660 SMDS_MeshElement::EntityFilter
6663 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6665 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6666 _elements[type].end(),
6667 SMDS_MeshElement::EntityFilter( entity )));
6669 // -------------------------------------------------------------------------------------
6670 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6672 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6673 if ( type == SMDSAbs_All && !_meshDS )
6675 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6677 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6678 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6680 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6682 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6683 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6685 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6686 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6688 // -------------------------------------------------------------------------------------
6689 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6690 iterType SMESH_MeshPartDS::methName() const \
6692 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6693 return _meshDS ? _meshDS->methName() : iterType \
6694 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6696 // -------------------------------------------------------------------------------------
6697 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6698 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6699 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6700 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6701 #undef _GET_ITER_DEFINE
6703 // END Implementation of SMESH_MeshPartDS
6705 //================================================================================