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 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1108 if ( !aGroupSO->_is_nil() )
1110 // Update Python script
1111 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1113 // Remove group's SObject
1114 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1115 builder->RemoveObjectWithChildren( aGroupSO );
1117 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1119 // Remove the group from SMESH data structures
1120 removeGroup( aGroup->GetLocalID() );
1122 SMESH_CATCH( SMESH::throwCorbaException );
1125 //=============================================================================
1127 * Remove group with its contents
1129 //=============================================================================
1131 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1132 throw (SALOME::SALOME_Exception)
1136 _preMeshInfo->FullLoadFromFile();
1138 if ( theGroup->_is_nil() )
1141 vector<int> nodeIds; // to remove nodes becoming free
1142 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1143 if ( !isNodal && !theGroup->IsEmpty() )
1145 CORBA::Long elemID = theGroup->GetID( 1 );
1146 int nbElemNodes = GetElemNbNodes( elemID );
1147 if ( nbElemNodes > 0 )
1148 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1151 // Retrieve contents
1152 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1153 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1154 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1155 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1156 elems.assign( elemBeg, elemEnd );
1158 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1161 RemoveGroup( theGroup );
1164 for ( size_t i = 0; i < elems.size(); ++i )
1166 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1170 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1171 nodeIds.push_back( nIt->next()->GetID() );
1173 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1177 _impl->GetMeshDS()->RemoveElement( elems[i] );
1181 // Remove free nodes
1182 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1183 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1184 if ( n->NbInverseElements() == 0 )
1185 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1187 // Update Python script (theGroup must be alive for this)
1188 pyDump << SMESH::SMESH_Mesh_var(_this())
1189 << ".RemoveGroupWithContents( " << theGroup << " )";
1191 SMESH_CATCH( SMESH::throwCorbaException );
1194 //================================================================================
1196 * \brief Get the list of groups existing in the mesh
1197 * \retval SMESH::ListOfGroups * - list of groups
1199 //================================================================================
1201 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1203 Unexpect aCatch(SALOME_SalomeException);
1204 if (MYDEBUG) MESSAGE("GetGroups");
1206 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1209 TPythonDump aPythonDump;
1210 if ( !_mapGroups.empty() )
1212 aPythonDump << "[ ";
1214 aList->length( _mapGroups.size() );
1216 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1217 for ( ; it != _mapGroups.end(); it++ ) {
1218 if ( CORBA::is_nil( it->second )) continue;
1219 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1221 if (i > 1) aPythonDump << ", ";
1222 aPythonDump << it->second;
1226 catch(SALOME_Exception & S_ex) {
1227 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1229 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1231 return aList._retn();
1234 //=============================================================================
1236 * Get number of groups existing in the mesh
1238 //=============================================================================
1240 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1242 Unexpect aCatch(SALOME_SalomeException);
1243 return _mapGroups.size();
1246 //=============================================================================
1248 * New group including all mesh elements present in initial groups is created.
1250 //=============================================================================
1252 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1253 SMESH::SMESH_GroupBase_ptr theGroup2,
1254 const char* theName )
1255 throw (SALOME::SALOME_Exception)
1257 SMESH::SMESH_Group_var aResGrp;
1261 _preMeshInfo->FullLoadFromFile();
1263 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1264 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1266 if ( theGroup1->GetType() != theGroup2->GetType() )
1267 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1272 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1273 if ( aResGrp->_is_nil() )
1274 return SMESH::SMESH_Group::_nil();
1276 aResGrp->AddFrom( theGroup1 );
1277 aResGrp->AddFrom( theGroup2 );
1279 // Update Python script
1280 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1281 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1283 SMESH_CATCH( SMESH::throwCorbaException );
1285 return aResGrp._retn();
1288 //=============================================================================
1290 * \brief New group including all mesh elements present in initial groups is created.
1291 * \param theGroups list of groups
1292 * \param theName name of group to be created
1293 * \return pointer to the new group
1295 //=============================================================================
1297 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1298 const char* theName )
1299 throw (SALOME::SALOME_Exception)
1301 SMESH::SMESH_Group_var aResGrp;
1304 _preMeshInfo->FullLoadFromFile();
1307 return SMESH::SMESH_Group::_nil();
1312 SMESH::ElementType aType = SMESH::ALL;
1313 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1315 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1316 if ( CORBA::is_nil( aGrp ) )
1318 if ( aType == SMESH::ALL )
1319 aType = aGrp->GetType();
1320 else if ( aType != aGrp->GetType() )
1321 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1324 if ( aType == SMESH::ALL )
1325 return SMESH::SMESH_Group::_nil();
1330 aResGrp = CreateGroup( aType, theName );
1331 if ( aResGrp->_is_nil() )
1332 return SMESH::SMESH_Group::_nil();
1334 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1335 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1337 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1338 if ( !CORBA::is_nil( aGrp ) )
1340 aResGrp->AddFrom( aGrp );
1341 if ( g > 0 ) pyDump << ", ";
1345 pyDump << " ], '" << theName << "' )";
1347 SMESH_CATCH( SMESH::throwCorbaException );
1349 return aResGrp._retn();
1352 //=============================================================================
1354 * New group is created. All mesh elements that are
1355 * present in both initial groups are added to the new one.
1357 //=============================================================================
1359 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1360 SMESH::SMESH_GroupBase_ptr theGroup2,
1361 const char* theName )
1362 throw (SALOME::SALOME_Exception)
1364 SMESH::SMESH_Group_var aResGrp;
1369 _preMeshInfo->FullLoadFromFile();
1371 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1372 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1374 if ( theGroup1->GetType() != theGroup2->GetType() )
1375 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1379 // Create Intersection
1380 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1381 if ( aResGrp->_is_nil() )
1382 return aResGrp._retn();
1384 SMESHDS_GroupBase* groupDS1 = 0;
1385 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1386 groupDS1 = grp_i->GetGroupDS();
1388 SMESHDS_GroupBase* groupDS2 = 0;
1389 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1390 groupDS2 = grp_i->GetGroupDS();
1392 SMESHDS_Group* resGroupDS = 0;
1393 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1394 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1396 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1398 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1399 while ( elemIt1->more() )
1401 const SMDS_MeshElement* e = elemIt1->next();
1402 if ( groupDS2->Contains( e ))
1403 resGroupDS->SMDSGroup().Add( e );
1406 // Update Python script
1407 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1408 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1410 SMESH_CATCH( SMESH::throwCorbaException );
1412 return aResGrp._retn();
1415 //=============================================================================
1417 \brief Intersect list of groups. New group is created. All mesh elements that
1418 are present in all initial groups simultaneously are added to the new one.
1419 \param theGroups list of groups
1420 \param theName name of group to be created
1421 \return pointer on the group
1423 //=============================================================================
1424 SMESH::SMESH_Group_ptr
1425 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1426 const char* theName )
1427 throw (SALOME::SALOME_Exception)
1429 SMESH::SMESH_Group_var aResGrp;
1434 _preMeshInfo->FullLoadFromFile();
1437 return SMESH::SMESH_Group::_nil();
1439 // check types and get SMESHDS_GroupBase's
1440 SMESH::ElementType aType = SMESH::ALL;
1441 vector< SMESHDS_GroupBase* > groupVec;
1442 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1444 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1445 if ( CORBA::is_nil( aGrp ) )
1447 if ( aType == SMESH::ALL )
1448 aType = aGrp->GetType();
1449 else if ( aType != aGrp->GetType() )
1450 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1453 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1454 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1456 if ( grpDS->IsEmpty() )
1461 groupVec.push_back( grpDS );
1464 if ( aType == SMESH::ALL ) // all groups are nil
1465 return SMESH::SMESH_Group::_nil();
1470 aResGrp = CreateGroup( aType, theName );
1472 SMESHDS_Group* resGroupDS = 0;
1473 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1474 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1475 if ( !resGroupDS || groupVec.empty() )
1476 return aResGrp._retn();
1479 size_t i, nb = groupVec.size();
1480 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1481 while ( elemIt1->more() )
1483 const SMDS_MeshElement* e = elemIt1->next();
1485 for ( i = 1; ( i < nb && inAll ); ++i )
1486 inAll = groupVec[i]->Contains( e );
1489 resGroupDS->SMDSGroup().Add( e );
1492 // Update Python script
1493 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1494 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1496 SMESH_CATCH( SMESH::throwCorbaException );
1498 return aResGrp._retn();
1501 //=============================================================================
1503 * New group is created. All mesh elements that are present in
1504 * a main group but is not present in a tool group are added to the new one
1506 //=============================================================================
1508 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1509 SMESH::SMESH_GroupBase_ptr theGroup2,
1510 const char* theName )
1511 throw (SALOME::SALOME_Exception)
1513 SMESH::SMESH_Group_var aResGrp;
1518 _preMeshInfo->FullLoadFromFile();
1520 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1521 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1523 if ( theGroup1->GetType() != theGroup2->GetType() )
1524 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1528 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1529 if ( aResGrp->_is_nil() )
1530 return aResGrp._retn();
1532 SMESHDS_GroupBase* groupDS1 = 0;
1533 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1534 groupDS1 = grp_i->GetGroupDS();
1536 SMESHDS_GroupBase* groupDS2 = 0;
1537 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1538 groupDS2 = grp_i->GetGroupDS();
1540 SMESHDS_Group* resGroupDS = 0;
1541 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1542 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1544 if ( groupDS1 && groupDS2 && resGroupDS )
1546 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1547 while ( elemIt1->more() )
1549 const SMDS_MeshElement* e = elemIt1->next();
1550 if ( !groupDS2->Contains( e ))
1551 resGroupDS->SMDSGroup().Add( e );
1554 // Update Python script
1555 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1556 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1558 SMESH_CATCH( SMESH::throwCorbaException );
1560 return aResGrp._retn();
1563 //=============================================================================
1565 \brief Cut lists of groups. New group is created. All mesh elements that are
1566 present in main groups but do not present in tool groups are added to the new one
1567 \param theMainGroups list of main groups
1568 \param theToolGroups list of tool groups
1569 \param theName name of group to be created
1570 \return pointer on the group
1572 //=============================================================================
1573 SMESH::SMESH_Group_ptr
1574 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1575 const SMESH::ListOfGroups& theToolGroups,
1576 const char* theName )
1577 throw (SALOME::SALOME_Exception)
1579 SMESH::SMESH_Group_var aResGrp;
1584 _preMeshInfo->FullLoadFromFile();
1587 return SMESH::SMESH_Group::_nil();
1589 // check types and get SMESHDS_GroupBase's
1590 SMESH::ElementType aType = SMESH::ALL;
1591 vector< SMESHDS_GroupBase* > toolGroupVec;
1592 vector< SMDS_ElemIteratorPtr > mainIterVec;
1594 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1596 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1597 if ( CORBA::is_nil( aGrp ) )
1599 if ( aType == SMESH::ALL )
1600 aType = aGrp->GetType();
1601 else if ( aType != aGrp->GetType() )
1602 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1604 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1605 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1606 if ( !grpDS->IsEmpty() )
1607 mainIterVec.push_back( grpDS->GetElements() );
1609 if ( aType == SMESH::ALL ) // all main groups are nil
1610 return SMESH::SMESH_Group::_nil();
1611 if ( mainIterVec.empty() ) // all main groups are empty
1612 return aResGrp._retn();
1614 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1616 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1617 if ( CORBA::is_nil( aGrp ) )
1619 if ( aType != aGrp->GetType() )
1620 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1622 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1623 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1624 toolGroupVec.push_back( grpDS );
1630 aResGrp = CreateGroup( aType, theName );
1632 SMESHDS_Group* resGroupDS = 0;
1633 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1634 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1636 return aResGrp._retn();
1639 size_t i, nb = toolGroupVec.size();
1640 SMDS_ElemIteratorPtr mainElemIt
1641 ( new SMDS_IteratorOnIterators
1642 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1643 while ( mainElemIt->more() )
1645 const SMDS_MeshElement* e = mainElemIt->next();
1647 for ( i = 0; ( i < nb && !isIn ); ++i )
1648 isIn = toolGroupVec[i]->Contains( e );
1651 resGroupDS->SMDSGroup().Add( e );
1654 // Update Python script
1655 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1656 << ".CutListOfGroups( " << theMainGroups << ", "
1657 << theToolGroups << ", '" << theName << "' )";
1659 SMESH_CATCH( SMESH::throwCorbaException );
1661 return aResGrp._retn();
1664 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1666 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1667 bool & toStopChecking )
1669 toStopChecking = ( nbCommon < nbChecked );
1670 return nbCommon == nbNodes;
1672 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1673 bool & toStopChecking )
1675 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1676 return nbCommon == nbCorners;
1678 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1679 bool & toStopChecking )
1681 return nbCommon > 0;
1683 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1684 bool & toStopChecking )
1686 return nbCommon >= (nbNodes+1) / 2;
1690 //=============================================================================
1692 * Create a group of entities basing on nodes of other groups.
1693 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1694 * \param [in] anElemType - a type of elements to include to the new group.
1695 * \param [in] theName - a name of the new group.
1696 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1697 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1698 * new group provided that it is based on nodes of an element of \a aListOfGroups
1699 * \return SMESH_Group - the created group
1701 // IMP 19939, bug 22010, IMP 22635
1702 //=============================================================================
1704 SMESH::SMESH_Group_ptr
1705 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1706 SMESH::ElementType theElemType,
1707 const char* theName,
1708 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1709 CORBA::Boolean theUnderlyingOnly)
1710 throw (SALOME::SALOME_Exception)
1712 SMESH::SMESH_Group_var aResGrp;
1716 _preMeshInfo->FullLoadFromFile();
1718 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1720 if ( !theName || !aMeshDS )
1721 return SMESH::SMESH_Group::_nil();
1723 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1725 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1726 SMESH_Comment nbCoNoStr( "SMESH.");
1727 switch ( theNbCommonNodes ) {
1728 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1729 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1730 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1731 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1732 default: return aResGrp._retn();
1734 int nbChecked, nbCommon, nbNodes, nbCorners;
1740 aResGrp = CreateGroup( theElemType, theName );
1741 if ( aResGrp->_is_nil() )
1742 return SMESH::SMESH_Group::_nil();
1744 SMESHDS_GroupBase* groupBaseDS =
1745 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1746 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1748 vector<bool> isNodeInGroups;
1750 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1752 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1753 if ( CORBA::is_nil( aGrp ) )
1755 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1756 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1759 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1760 if ( !elIt ) continue;
1762 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1764 while ( elIt->more() ) {
1765 const SMDS_MeshElement* el = elIt->next();
1766 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1767 while ( nIt->more() )
1768 resGroupCore.Add( nIt->next() );
1771 // get elements of theElemType based on nodes of every element of group
1772 else if ( theUnderlyingOnly )
1774 while ( elIt->more() )
1776 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1777 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1778 TIDSortedElemSet checkedElems;
1779 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1780 while ( nIt->more() )
1782 const SMDS_MeshNode* n = nIt->next();
1783 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1784 // check nodes of elements of theElemType around el
1785 while ( elOfTypeIt->more() )
1787 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1788 if ( !checkedElems.insert( elOfType ).second ) continue;
1789 nbNodes = elOfType->NbNodes();
1790 nbCorners = elOfType->NbCornerNodes();
1792 bool toStopChecking = false;
1793 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1794 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1795 if ( elNodes.count( nIt2->next() ) &&
1796 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1798 resGroupCore.Add( elOfType );
1805 // get all nodes of elements of groups
1808 while ( elIt->more() )
1810 const SMDS_MeshElement* el = elIt->next(); // an element of group
1811 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1812 while ( nIt->more() )
1814 const SMDS_MeshNode* n = nIt->next();
1815 if ( n->GetID() >= (int) isNodeInGroups.size() )
1816 isNodeInGroups.resize( n->GetID() + 1, false );
1817 isNodeInGroups[ n->GetID() ] = true;
1823 // Get elements of theElemType based on a certain number of nodes of elements of groups
1824 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1826 const SMDS_MeshNode* n;
1827 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1828 const int isNodeInGroupsSize = isNodeInGroups.size();
1829 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1831 if ( !isNodeInGroups[ iN ] ||
1832 !( n = aMeshDS->FindNode( iN )))
1835 // check nodes of elements of theElemType around n
1836 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1837 while ( elOfTypeIt->more() )
1839 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1840 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1845 nbNodes = elOfType->NbNodes();
1846 nbCorners = elOfType->NbCornerNodes();
1848 bool toStopChecking = false;
1849 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1850 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1852 const int nID = nIt->next()->GetID();
1853 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1854 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1856 resGroupCore.Add( elOfType );
1864 // Update Python script
1865 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1866 << ".CreateDimGroup( "
1867 << theGroups << ", " << theElemType << ", '" << theName << "', "
1868 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1870 SMESH_CATCH( SMESH::throwCorbaException );
1872 return aResGrp._retn();
1875 //================================================================================
1877 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1878 * existing 1D elements as group boundaries.
1879 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1880 * adjacent faces is more than \a sharpAngle in degrees.
1881 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1882 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1883 * \return ListOfGroups - the created groups
1885 //================================================================================
1887 SMESH::ListOfGroups*
1888 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1889 CORBA::Boolean theCreateEdges,
1890 CORBA::Boolean theUseExistingEdges )
1891 throw (SALOME::SALOME_Exception)
1893 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1894 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1897 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1903 _preMeshInfo->FullLoadFromFile();
1905 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1907 std::vector< SMESH_MeshAlgos::Edge > edges =
1908 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1910 if ( theCreateEdges )
1912 std::vector<const SMDS_MeshNode *> nodes(2);
1913 for ( size_t i = 0; i < edges.size(); ++i )
1915 nodes[0] = edges[i]._node1;
1916 nodes[1] = edges[i]._node2;
1917 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1919 if ( edges[i]._medium )
1920 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1922 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1926 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1927 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1929 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1931 resultGroups->length( faceGroups.size() );
1932 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1934 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1935 _editor->GenerateGroupName("Group").c_str());
1936 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1938 SMESHDS_GroupBase* groupBaseDS =
1939 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1940 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1942 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1943 for ( size_t i = 0; i < faces.size(); ++i )
1944 groupCore.Add( faces[i] );
1947 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1948 << ".FaceGroupsSeparatedByEdges( "
1949 << TVar( theSharpAngle ) << ", "
1950 << theCreateEdges << ", "
1951 << theUseExistingEdges << " )";
1953 SMESH_CATCH( SMESH::throwCorbaException );
1954 return resultGroups._retn();
1958 //================================================================================
1960 * \brief Remember GEOM group data
1962 //================================================================================
1964 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1965 CORBA::Object_ptr theSmeshObj)
1967 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1970 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1971 if ( groupSO->_is_nil() )
1974 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1975 GEOM::GEOM_IGroupOperations_wrap groupOp =
1976 geomGen->GetIGroupOperations();
1977 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1980 _geomGroupData.push_back( TGeomGroupData() );
1981 TGeomGroupData & groupData = _geomGroupData.back();
1983 CORBA::String_var entry = groupSO->GetID();
1984 groupData._groupEntry = entry.in();
1986 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1987 groupData._indices.insert( ids[i] );
1989 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1990 // shape index in SMESHDS
1991 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1992 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1995 //================================================================================
1997 * Remove GEOM group data relating to removed smesh object
1999 //================================================================================
2001 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2003 list<TGeomGroupData>::iterator
2004 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2005 for ( ; data != dataEnd; ++data ) {
2006 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2007 _geomGroupData.erase( data );
2013 //================================================================================
2015 * \brief Return new group contents if it has been changed and update group data
2017 //================================================================================
2019 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
2021 TopoDS_Shape newShape;
2024 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2025 if ( !groupSO->_is_nil() )
2027 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2028 if ( CORBA::is_nil( groupObj )) return newShape;
2029 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2031 // get indices of group items
2032 set<int> curIndices;
2033 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2034 GEOM::GEOM_IGroupOperations_wrap groupOp =
2035 geomGen->GetIGroupOperations();
2036 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2037 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2038 curIndices.insert( ids[i] );
2040 if ( groupData._indices == curIndices )
2041 return newShape; // group not changed
2044 groupData._indices = curIndices;
2046 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2047 if ( !geomClient ) return newShape;
2048 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2049 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2050 newShape = _gen_i->GeomObjectToShape( geomGroup );
2053 if ( newShape.IsNull() ) {
2054 // geom group becomes empty - return empty compound
2055 TopoDS_Compound compound;
2056 BRep_Builder().MakeCompound(compound);
2057 newShape = compound;
2064 //-----------------------------------------------------------------------------
2066 * \brief Storage of shape and index used in CheckGeomGroupModif()
2068 struct TIndexedShape
2071 TopoDS_Shape _shape;
2072 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2074 //-----------------------------------------------------------------------------
2076 * \brief Data to re-create a group on geometry
2078 struct TGroupOnGeomData
2081 TopoDS_Shape _shape;
2082 SMDSAbs_ElementType _type;
2084 Quantity_Color _color;
2086 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2088 _oldID = group->GetID();
2089 _type = group->GetType();
2090 _name = group->GetStoreName();
2091 _color = group->GetColor();
2095 //-----------------------------------------------------------------------------
2097 * \brief Check if a filter is still valid after geometry removal
2099 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2101 if ( theFilter->_is_nil() )
2103 SMESH::Filter::Criteria_var criteria;
2104 theFilter->GetCriteria( criteria.out() );
2106 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2108 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2110 switch ( criteria[ iCr ].Type )
2112 case SMESH::FT_BelongToGeom:
2113 case SMESH::FT_BelongToPlane:
2114 case SMESH::FT_BelongToCylinder:
2115 case SMESH::FT_BelongToGenSurface:
2116 case SMESH::FT_LyingOnGeom:
2117 entry = thresholdID;
2119 case SMESH::FT_ConnectedElements:
2122 entry = thresholdID;
2128 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2129 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2130 if ( so->_is_nil() )
2132 CORBA::Object_var obj = so->GetObject();
2133 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2134 if ( gen->GeomObjectToShape( geom ).IsNull() )
2137 } // loop on criteria
2143 //=============================================================================
2145 * \brief Update data if geometry changes
2149 //=============================================================================
2151 void SMESH_Mesh_i::CheckGeomModif()
2153 SMESH::SMESH_Mesh_var me = _this();
2154 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2156 //bool removedFromClient = false;
2158 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2160 //removedFromClient = _impl->HasShapeToMesh();
2162 // try to find geometry by study reference
2163 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2164 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2165 if ( !meshSO->_is_nil() &&
2166 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2167 geomRefSO->ReferencedObject( geomSO.inout() ))
2169 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2170 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2173 if ( mainGO->_is_nil() && // geometry removed ==>
2174 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2176 // convert geom dependent groups into standalone ones
2177 CheckGeomGroupModif();
2179 _impl->ShapeToMesh( TopoDS_Shape() );
2181 // remove sub-meshes
2182 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2183 while ( i_sm != _mapSubMeshIor.end() )
2185 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2187 RemoveSubMesh( sm );
2189 // remove all children except groups in the study
2190 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2191 SALOMEDS::SObject_wrap so;
2192 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2193 if ( meshSO->FindSubObject( tag, so.inout() ))
2194 builder->RemoveObjectWithChildren( so );
2196 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2202 if ( !_impl->HasShapeToMesh() ) return;
2205 // Update after group modification
2207 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2208 mainGO->GetTick() == _mainShapeTick )
2210 int nb = NbNodes() + NbElements();
2211 CheckGeomGroupModif();
2212 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2213 _gen_i->UpdateIcons( me );
2217 // Update after shape transformation like Translate
2219 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2220 if ( !geomClient ) return;
2221 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2222 if ( geomGen->_is_nil() ) return;
2224 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2225 geomClient->RemoveShapeFromBuffer( ior.in() );
2227 // Update data taking into account that
2228 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2231 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2232 if ( newShape.IsNull() )
2235 _mainShapeTick = mainGO->GetTick();
2237 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2239 // store data of groups on geometry
2240 std::vector< TGroupOnGeomData > groupsData;
2241 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2242 groupsData.reserve( groups.size() );
2243 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2244 for ( ; g != groups.end(); ++g )
2246 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2248 groupsData.push_back( TGroupOnGeomData( group ));
2251 SMESH::SMESH_GroupOnGeom_var gog;
2252 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2253 if ( i_grp != _mapGroups.end() )
2254 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2256 GEOM::GEOM_Object_var geom;
2257 if ( !gog->_is_nil() )
2258 geom = gog->GetShape();
2259 if ( !geom->_is_nil() )
2261 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2262 geomClient->RemoveShapeFromBuffer( ior.in() );
2263 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2267 // store assigned hypotheses
2268 std::vector< pair< int, THypList > > ids2Hyps;
2269 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2270 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2272 const TopoDS_Shape& s = s2hyps.Key();
2273 const THypList& hyps = s2hyps.ChangeValue();
2274 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2277 // change shape to mesh
2278 int oldNbSubShapes = meshDS->MaxShapeIndex();
2279 _impl->ShapeToMesh( TopoDS_Shape() );
2280 _impl->ShapeToMesh( newShape );
2282 // re-add shapes of geom groups
2283 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2284 for ( ; data != _geomGroupData.end(); ++data )
2286 TopoDS_Shape newShape = newGroupShape( *data );
2287 if ( !newShape.IsNull() )
2289 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2291 TopoDS_Compound compound;
2292 BRep_Builder().MakeCompound( compound );
2293 BRep_Builder().Add( compound, newShape );
2294 newShape = compound;
2296 _impl->GetSubMesh( newShape );
2299 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2300 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2301 SALOME::INTERNAL_ERROR );
2303 // re-assign hypotheses
2304 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2306 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2307 const THypList& hyps = ids2Hyps[i].second;
2308 THypList::const_iterator h = hyps.begin();
2309 for ( ; h != hyps.end(); ++h )
2310 _impl->AddHypothesis( s, (*h)->GetID() );
2313 // restore groups on geometry
2314 for ( size_t i = 0; i < groupsData.size(); ++i )
2316 const TGroupOnGeomData& data = groupsData[i];
2317 if ( data._shape.IsNull() )
2320 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2321 if ( i2g == _mapGroups.end() ) continue;
2323 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2324 if ( !gr_i ) continue;
2326 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2328 _mapGroups.erase( i2g );
2330 g->GetGroupDS()->SetColor( data._color );
2333 // update _mapSubMesh
2334 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2335 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2336 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2340 //=============================================================================
2342 * \brief Update objects depending on changed geom groups
2344 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2345 * issue 0020210: Update of a smesh group after modification of the associated geom group
2347 //=============================================================================
2349 void SMESH_Mesh_i::CheckGeomGroupModif()
2351 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2352 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2353 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2354 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2355 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2357 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2358 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2359 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2361 int nbValid = 0, nbRemoved = 0;
2362 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2363 for ( ; chItr->More(); chItr->Next() )
2365 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2366 if ( !smSO->_is_nil() &&
2367 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2368 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2370 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2371 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2372 if ( !geom->_non_existent() )
2375 continue; // keep the sub-mesh
2378 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2379 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2380 if ( !sm->_is_nil() && !sm->_non_existent() )
2382 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2383 if ( smGeom->_is_nil() )
2385 RemoveSubMesh( sm );
2392 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2393 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2397 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2398 builder->RemoveObjectWithChildren( rootSO );
2402 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2403 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2404 while ( i_gr != _mapGroups.end())
2406 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2408 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2409 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2410 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2411 bool isValidGeom = false;
2412 if ( !onGeom->_is_nil() )
2414 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2416 else if ( !onFilt->_is_nil() )
2418 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2422 isValidGeom = ( !groupSO->_is_nil() &&
2423 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2427 if ( !IsLoaded() || group->IsEmpty() )
2429 RemoveGroup( group );
2431 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2433 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2435 else // is it possible?
2437 builder->RemoveObjectWithChildren( refSO );
2443 if ( !_impl->HasShapeToMesh() ) return;
2445 CORBA::Long nbEntities = NbNodes() + NbElements();
2447 // Check if group contents changed
2449 typedef map< string, TopoDS_Shape > TEntry2Geom;
2450 TEntry2Geom newGroupContents;
2452 list<TGeomGroupData>::iterator
2453 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2454 for ( ; data != dataEnd; ++data )
2456 pair< TEntry2Geom::iterator, bool > it_new =
2457 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2458 bool processedGroup = !it_new.second;
2459 TopoDS_Shape& newShape = it_new.first->second;
2460 if ( !processedGroup )
2461 newShape = newGroupShape( *data );
2462 if ( newShape.IsNull() )
2463 continue; // no changes
2466 _preMeshInfo->ForgetOrLoad();
2468 if ( processedGroup ) { // update group indices
2469 list<TGeomGroupData>::iterator data2 = data;
2470 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2471 data->_indices = data2->_indices;
2474 // Update SMESH objects according to new GEOM group contents
2476 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2477 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2479 int oldID = submesh->GetId();
2480 if ( !_mapSubMeshIor.count( oldID ))
2482 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2484 // update hypotheses
2485 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2486 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2487 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2489 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2490 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2492 // care of submeshes
2493 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2494 int newID = newSubmesh->GetId();
2495 if ( newID != oldID ) {
2496 _mapSubMesh [ newID ] = newSubmesh;
2497 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2498 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2499 _mapSubMesh. erase(oldID);
2500 _mapSubMesh_i. erase(oldID);
2501 _mapSubMeshIor.erase(oldID);
2502 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2507 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2508 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2509 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2511 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2513 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2514 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2515 ds->SetShape( newShape );
2520 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2521 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2523 // Remove groups and submeshes basing on removed sub-shapes
2525 TopTools_MapOfShape newShapeMap;
2526 TopoDS_Iterator shapeIt( newShape );
2527 for ( ; shapeIt.More(); shapeIt.Next() )
2528 newShapeMap.Add( shapeIt.Value() );
2530 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2531 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2533 if ( newShapeMap.Contains( shapeIt.Value() ))
2535 TopTools_IndexedMapOfShape oldShapeMap;
2536 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2537 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2539 const TopoDS_Shape& oldShape = oldShapeMap(i);
2540 int oldInd = meshDS->ShapeToIndex( oldShape );
2542 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2543 if ( i_smIor != _mapSubMeshIor.end() ) {
2544 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2547 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2548 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2550 // check if a group bases on oldInd shape
2551 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2552 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2553 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2554 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2556 RemoveGroup( i_grp->second ); // several groups can base on same shape
2557 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2562 // Reassign hypotheses and update groups after setting the new shape to mesh
2564 // collect anassigned hypotheses
2565 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2566 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2567 TShapeHypList assignedHyps;
2568 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2570 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2571 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2572 if ( !hyps.empty() ) {
2573 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2574 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2575 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2578 // collect shapes supporting groups
2579 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2580 TShapeTypeList groupData;
2581 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2582 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2583 for ( ; grIt != groups.end(); ++grIt )
2585 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2587 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2589 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2591 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2592 _impl->ShapeToMesh( newShape );
2594 // reassign hypotheses
2595 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2596 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2598 TIndexedShape& geom = indS_hyps->first;
2599 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2600 int oldID = geom._index;
2601 int newID = meshDS->ShapeToIndex( geom._shape );
2602 if ( oldID == 1 ) { // main shape
2604 geom._shape = newShape;
2608 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2609 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2610 // care of sub-meshes
2611 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2612 if ( newID != oldID ) {
2613 _mapSubMesh [ newID ] = newSubmesh;
2614 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2615 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2616 _mapSubMesh. erase(oldID);
2617 _mapSubMesh_i. erase(oldID);
2618 _mapSubMeshIor.erase(oldID);
2619 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2623 TShapeTypeList::iterator geomType = groupData.begin();
2624 for ( ; geomType != groupData.end(); ++geomType )
2626 const TIndexedShape& geom = geomType->first;
2627 int oldID = geom._index;
2628 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2631 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2632 CORBA::String_var name = groupSO->GetName();
2634 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2635 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2636 /*id=*/-1, geom._shape ))
2637 group_i->changeLocalId( group->GetID() );
2640 break; // everything has been updated
2643 } // loop on group data
2647 CORBA::Long newNbEntities = NbNodes() + NbElements();
2648 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2649 if ( newNbEntities != nbEntities )
2651 // Add all SObjects with icons to soToUpdateIcons
2652 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2654 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2655 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2656 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2658 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2659 i_gr != _mapGroups.end(); ++i_gr ) // groups
2660 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2663 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2664 for ( ; so != soToUpdateIcons.end(); ++so )
2665 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2668 //=============================================================================
2670 * \brief Create standalone group from a group on geometry or filter
2672 //=============================================================================
2674 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2675 throw (SALOME::SALOME_Exception)
2677 SMESH::SMESH_Group_var aGroup;
2682 _preMeshInfo->FullLoadFromFile();
2684 if ( theGroup->_is_nil() )
2685 return aGroup._retn();
2687 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2689 return aGroup._retn();
2691 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2693 const int anId = aGroupToRem->GetLocalID();
2694 if ( !_impl->ConvertToStandalone( anId ) )
2695 return aGroup._retn();
2696 removeGeomGroupData( theGroup );
2698 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2700 // remove old instance of group from own map
2701 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2702 _mapGroups.erase( anId );
2704 SALOMEDS::StudyBuilder_var builder;
2705 SALOMEDS::SObject_wrap aGroupSO;
2706 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2707 if ( !aStudy->_is_nil() ) {
2708 builder = aStudy->NewBuilder();
2709 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2710 if ( !aGroupSO->_is_nil() )
2712 // remove reference to geometry
2713 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2714 for ( ; chItr->More(); chItr->Next() )
2716 // Remove group's child SObject
2717 SALOMEDS::SObject_wrap so = chItr->Value();
2718 builder->RemoveObject( so );
2720 // Update Python script
2721 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2722 << ".ConvertToStandalone( " << aGroupSO << " )";
2724 // change icon of Group on Filter
2727 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2728 // const int isEmpty = ( elemTypes->length() == 0 );
2731 SALOMEDS::GenericAttribute_wrap anAttr =
2732 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2733 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2734 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2740 // remember new group in own map
2741 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2742 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2744 // register CORBA object for persistence
2745 _gen_i->RegisterObject( aGroup );
2747 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2748 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2749 //aGroup->Register();
2750 aGroupToRem->UnRegister();
2752 SMESH_CATCH( SMESH::throwCorbaException );
2754 return aGroup._retn();
2757 //=============================================================================
2761 //=============================================================================
2763 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2765 if(MYDEBUG) MESSAGE( "createSubMesh" );
2766 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2767 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2770 SMESH_subMesh_i * subMeshServant;
2773 subMeshId = mySubMesh->GetId();
2774 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2776 else // "invalid sub-mesh"
2778 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2779 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2780 if ( _mapSubMesh.empty() )
2783 subMeshId = _mapSubMesh.begin()->first - 1;
2784 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2787 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2789 _mapSubMesh [subMeshId] = mySubMesh;
2790 _mapSubMesh_i [subMeshId] = subMeshServant;
2791 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2793 subMeshServant->Register();
2795 // register CORBA object for persistence
2796 int nextId = _gen_i->RegisterObject( subMesh );
2797 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2798 else { nextId = 0; } // avoid "unused variable" warning
2800 // to track changes of GEOM groups
2801 if ( subMeshId > 0 )
2802 addGeomGroupData( theSubShapeObject, subMesh );
2804 return subMesh._retn();
2807 //=======================================================================
2808 //function : getSubMesh
2810 //=======================================================================
2812 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2814 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2815 if ( it == _mapSubMeshIor.end() )
2816 return SMESH::SMESH_subMesh::_nil();
2818 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2821 //=============================================================================
2825 //=============================================================================
2827 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2828 GEOM::GEOM_Object_ptr theSubShapeObject )
2830 bool isHypChanged = false;
2831 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2832 return isHypChanged;
2834 const int subMeshId = theSubMesh->GetId();
2836 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2839 if (( _mapSubMesh.count( subMeshId )) &&
2840 ( sm = _impl->GetSubMeshContaining( subMeshId )))
2842 TopoDS_Shape S = sm->GetSubShape();
2845 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2846 isHypChanged = !hyps.empty();
2847 if ( isHypChanged && _preMeshInfo )
2848 _preMeshInfo->ForgetOrLoad();
2849 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2850 for ( ; hyp != hyps.end(); ++hyp )
2851 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2858 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2859 isHypChanged = ( aHypList->length() > 0 );
2860 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2861 removeHypothesis( theSubShapeObject, aHypList[i] );
2864 catch( const SALOME::SALOME_Exception& ) {
2865 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2867 removeGeomGroupData( theSubShapeObject );
2871 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2872 if ( id_smi != _mapSubMesh_i.end() )
2873 id_smi->second->UnRegister();
2875 // remove a CORBA object
2876 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2877 if ( id_smptr != _mapSubMeshIor.end() )
2878 SMESH::SMESH_subMesh_var( id_smptr->second );
2880 _mapSubMesh.erase(subMeshId);
2881 _mapSubMesh_i.erase(subMeshId);
2882 _mapSubMeshIor.erase(subMeshId);
2884 return isHypChanged;
2887 //=============================================================================
2891 //=============================================================================
2893 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2894 const char* theName,
2896 const TopoDS_Shape& theShape,
2897 const SMESH_PredicatePtr& thePredicate )
2899 std::string newName;
2900 if ( !theName || !theName[0] )
2902 std::set< std::string > presentNames;
2903 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2904 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2906 CORBA::String_var name = i_gr->second->GetName();
2907 presentNames.insert( name.in() );
2910 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2911 } while ( !presentNames.insert( newName ).second );
2912 theName = newName.c_str();
2914 SMESH::SMESH_GroupBase_var aGroup;
2915 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
2916 theID, theShape, thePredicate ))
2918 int anId = g->GetID();
2919 SMESH_GroupBase_i* aGroupImpl;
2920 if ( !theShape.IsNull() )
2921 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2922 else if ( thePredicate )
2923 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2925 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2927 aGroup = aGroupImpl->_this();
2928 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2929 aGroupImpl->Register();
2931 // register CORBA object for persistence
2932 int nextId = _gen_i->RegisterObject( aGroup );
2933 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2934 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
2936 // to track changes of GEOM groups
2937 if ( !theShape.IsNull() ) {
2938 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2939 addGeomGroupData( geom, aGroup );
2942 return aGroup._retn();
2945 //=============================================================================
2947 * SMESH_Mesh_i::removeGroup
2949 * Should be called by ~SMESH_Group_i()
2951 //=============================================================================
2953 void SMESH_Mesh_i::removeGroup( const int theId )
2955 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2956 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2957 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2958 _mapGroups.erase( theId );
2959 removeGeomGroupData( group );
2960 if ( !_impl->RemoveGroup( theId ))
2962 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2963 RemoveGroup( group );
2965 group->UnRegister();
2969 //=============================================================================
2973 //=============================================================================
2975 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2976 throw(SALOME::SALOME_Exception)
2978 SMESH::log_array_var aLog;
2982 _preMeshInfo->FullLoadFromFile();
2984 list < SMESHDS_Command * >logDS = _impl->GetLog();
2985 aLog = new SMESH::log_array;
2987 int lg = logDS.size();
2990 list < SMESHDS_Command * >::iterator its = logDS.begin();
2991 while(its != logDS.end()){
2992 SMESHDS_Command *com = *its;
2993 int comType = com->GetType();
2995 int lgcom = com->GetNumber();
2997 const list < int >&intList = com->GetIndexes();
2998 int inum = intList.size();
3000 list < int >::const_iterator ii = intList.begin();
3001 const list < double >&coordList = com->GetCoords();
3002 int rnum = coordList.size();
3004 list < double >::const_iterator ir = coordList.begin();
3005 aLog[indexLog].commandType = comType;
3006 aLog[indexLog].number = lgcom;
3007 aLog[indexLog].coords.length(rnum);
3008 aLog[indexLog].indexes.length(inum);
3009 for(int i = 0; i < rnum; i++){
3010 aLog[indexLog].coords[i] = *ir;
3011 //MESSAGE(" "<<i<<" "<<ir.Value());
3014 for(int i = 0; i < inum; i++){
3015 aLog[indexLog].indexes[i] = *ii;
3016 //MESSAGE(" "<<i<<" "<<ii.Value());
3025 SMESH_CATCH( SMESH::throwCorbaException );
3027 return aLog._retn();
3031 //=============================================================================
3035 //=============================================================================
3037 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3041 SMESH_CATCH( SMESH::throwCorbaException );
3044 //=============================================================================
3048 //=============================================================================
3050 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3055 //=============================================================================
3058 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3059 // issue 0020918: groups removal is caused by hyp modification
3060 // issue 0021208: to forget not loaded mesh data at hyp modification
3061 struct TCallUp_i : public SMESH_Mesh::TCallUp
3063 SMESH_Mesh_i* _mesh;
3064 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3065 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3066 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3067 virtual void Load () { _mesh->Load(); }
3071 //================================================================================
3073 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3075 //================================================================================
3077 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3080 _preMeshInfo->ForgetOrLoad();
3082 SMESH::SMESH_Mesh_var mesh = _this();
3083 _gen_i->UpdateIcons( mesh );
3085 // mark a hypothesis as valid after edition
3086 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3087 SALOMEDS::SObject_wrap hypRoot;
3088 if ( !smeshComp->_is_nil() &&
3089 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3091 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3092 for ( ; anIter->More(); anIter->Next() )
3094 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3095 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3096 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3097 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3098 _gen_i->HighLightInvalid( hyp, false );
3103 //=============================================================================
3107 //=============================================================================
3109 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3111 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3114 _impl->SetCallUp( new TCallUp_i(this));
3117 //=============================================================================
3121 //=============================================================================
3123 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3125 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3129 //=============================================================================
3131 * Return mesh editor
3133 //=============================================================================
3135 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3136 throw (SALOME::SALOME_Exception)
3138 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3142 _preMeshInfo->FullLoadFromFile();
3144 // Create MeshEditor
3146 _editor = new SMESH_MeshEditor_i( this, false );
3147 aMeshEdVar = _editor->_this();
3149 // Update Python script
3150 TPythonDump() << _editor << " = "
3151 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3153 SMESH_CATCH( SMESH::throwCorbaException );
3155 return aMeshEdVar._retn();
3158 //=============================================================================
3160 * Return mesh edition previewer
3162 //=============================================================================
3164 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3165 throw (SALOME::SALOME_Exception)
3167 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3171 _preMeshInfo->FullLoadFromFile();
3173 if ( !_previewEditor )
3174 _previewEditor = new SMESH_MeshEditor_i( this, true );
3175 aMeshEdVar = _previewEditor->_this();
3177 SMESH_CATCH( SMESH::throwCorbaException );
3179 return aMeshEdVar._retn();
3182 //================================================================================
3184 * \brief Return true if the mesh has been edited since a last total re-compute
3185 * and those modifications may prevent successful partial re-compute
3187 //================================================================================
3189 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3191 Unexpect aCatch(SALOME_SalomeException);
3192 return _impl->HasModificationsToDiscard();
3195 //================================================================================
3197 * \brief Returns a random unique color
3199 //================================================================================
3201 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3203 const int MAX_ATTEMPTS = 100;
3205 double tolerance = 0.5;
3206 SALOMEDS::Color col;
3210 // generate random color
3211 double red = (double)rand() / RAND_MAX;
3212 double green = (double)rand() / RAND_MAX;
3213 double blue = (double)rand() / RAND_MAX;
3214 // check existence in the list of the existing colors
3215 bool matched = false;
3216 std::list<SALOMEDS::Color>::const_iterator it;
3217 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3218 SALOMEDS::Color color = *it;
3219 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3220 matched = tol < tolerance;
3222 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3223 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3231 //=============================================================================
3233 * Sets auto-color mode. If it is on, groups get unique random colors
3235 //=============================================================================
3237 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3239 Unexpect aCatch(SALOME_SalomeException);
3240 _impl->SetAutoColor(theAutoColor);
3242 TPythonDump pyDump; // not to dump group->SetColor() from below code
3243 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3245 std::list<SALOMEDS::Color> aReservedColors;
3246 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3247 for ( ; it != _mapGroups.end(); it++ ) {
3248 if ( CORBA::is_nil( it->second )) continue;
3249 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3250 it->second->SetColor( aColor );
3251 aReservedColors.push_back( aColor );
3255 //=============================================================================
3257 * Returns true if auto-color mode is on
3259 //=============================================================================
3261 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3263 Unexpect aCatch(SALOME_SalomeException);
3264 return _impl->GetAutoColor();
3267 //=============================================================================
3269 * Checks if there are groups with equal names
3271 //=============================================================================
3273 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3275 return _impl->HasDuplicatedGroupNamesMED();
3278 //================================================================================
3280 * \brief Care of a file before exporting mesh into it
3282 //================================================================================
3284 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3286 SMESH_File aFile( file );
3288 if (aFile.exists()) {
3289 // existing filesystem node
3290 if ( !aFile.isDirectory() ) {
3291 if ( aFile.openForWriting() ) {
3292 if ( overwrite && ! aFile.remove()) {
3293 msg << "Can't replace " << aFile.getName();
3296 msg << "Can't write into " << aFile.getName();
3299 msg << "Location " << aFile.getName() << " is not a file";
3303 // nonexisting file; check if it can be created
3304 if ( !aFile.openForWriting() ) {
3305 msg << "You cannot create the file "
3307 << ". Check the directory existence and access rights";
3315 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3319 //================================================================================
3321 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3322 * \param file - file name
3323 * \param overwrite - to erase the file or not
3324 * \retval string - mesh name
3326 //================================================================================
3328 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3329 CORBA::Boolean overwrite)
3332 PrepareForWriting(file, overwrite);
3333 string aMeshName = "Mesh";
3334 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3335 if ( !aStudy->_is_nil() ) {
3336 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3337 if ( !aMeshSO->_is_nil() ) {
3338 CORBA::String_var name = aMeshSO->GetName();
3340 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3341 if ( !aStudy->GetProperties()->IsLocked() )
3343 SALOMEDS::GenericAttribute_wrap anAttr;
3344 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3345 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3346 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3347 ASSERT(!aFileName->_is_nil());
3348 aFileName->SetValue(file);
3349 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3350 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3351 ASSERT(!aFileType->_is_nil());
3352 aFileType->SetValue("FICHIERMED");
3356 // Update Python script
3357 // set name of mesh before export
3358 TPythonDump() << _gen_i << ".SetName("
3359 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3361 // check names of groups
3367 //================================================================================
3369 * \brief Export to MED file
3371 //================================================================================
3373 void SMESH_Mesh_i::ExportMED(const char* file,
3374 CORBA::Boolean auto_groups,
3375 CORBA::Long version,
3376 CORBA::Boolean overwrite,
3377 CORBA::Boolean autoDimension)
3378 throw(SALOME::SALOME_Exception)
3380 //MESSAGE("MED minor version: "<< minor);
3383 _preMeshInfo->FullLoadFromFile();
3385 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3386 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3388 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3390 << "auto_groups=" <<auto_groups << ", "
3391 << "minor=" << version << ", "
3392 << "overwrite=" << overwrite << ", "
3393 << "meshPart=None, "
3394 << "autoDimension=" << autoDimension << " )";
3396 SMESH_CATCH( SMESH::throwCorbaException );
3399 //================================================================================
3401 * \brief Export a mesh to a SAUV file
3403 //================================================================================
3405 void SMESH_Mesh_i::ExportSAUV (const char* file,
3406 CORBA::Boolean auto_groups)
3407 throw(SALOME::SALOME_Exception)
3409 Unexpect aCatch(SALOME_SalomeException);
3411 _preMeshInfo->FullLoadFromFile();
3413 string aMeshName = prepareMeshNameAndGroups(file, true);
3414 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3415 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3416 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3420 //================================================================================
3422 * \brief Export a mesh to a DAT file
3424 //================================================================================
3426 void SMESH_Mesh_i::ExportDAT (const char *file)
3427 throw(SALOME::SALOME_Exception)
3429 Unexpect aCatch(SALOME_SalomeException);
3431 _preMeshInfo->FullLoadFromFile();
3433 // Update Python script
3434 // check names of groups
3436 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3439 PrepareForWriting(file);
3440 _impl->ExportDAT(file);
3443 //================================================================================
3445 * \brief Export a mesh to an UNV file
3447 //================================================================================
3449 void SMESH_Mesh_i::ExportUNV (const char *file)
3450 throw(SALOME::SALOME_Exception)
3452 Unexpect aCatch(SALOME_SalomeException);
3454 _preMeshInfo->FullLoadFromFile();
3456 // Update Python script
3457 // check names of groups
3459 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3462 PrepareForWriting(file);
3463 _impl->ExportUNV(file);
3466 //================================================================================
3468 * \brief Export a mesh to an STL file
3470 //================================================================================
3472 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3473 throw(SALOME::SALOME_Exception)
3475 Unexpect aCatch(SALOME_SalomeException);
3477 _preMeshInfo->FullLoadFromFile();
3479 // Update Python script
3480 // check names of groups
3482 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3483 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3485 CORBA::String_var name;
3486 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3487 if ( !so->_is_nil() )
3488 name = so->GetName();
3491 PrepareForWriting( file );
3492 _impl->ExportSTL( file, isascii, name.in() );
3495 //================================================================================
3497 * \brief Export a part of mesh to a med file
3499 //================================================================================
3501 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3503 CORBA::Boolean auto_groups,
3504 CORBA::Long version,
3505 CORBA::Boolean overwrite,
3506 CORBA::Boolean autoDimension,
3507 const GEOM::ListOfFields& fields,
3508 const char* geomAssocFields,
3509 CORBA::Double ZTolerance)
3510 throw (SALOME::SALOME_Exception)
3512 MESSAGE("MED version: "<< version);
3515 _preMeshInfo->FullLoadFromFile();
3518 bool have0dField = false;
3519 if ( fields.length() > 0 )
3521 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3522 if ( shapeToMesh->_is_nil() )
3523 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3525 for ( size_t i = 0; i < fields.length(); ++i )
3527 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3528 THROW_SALOME_CORBA_EXCEPTION
3529 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3530 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3531 if ( fieldShape->_is_nil() )
3532 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3533 if ( !fieldShape->IsSame( shapeToMesh ) )
3534 THROW_SALOME_CORBA_EXCEPTION
3535 ( "Field defined not on shape", SALOME::BAD_PARAM);
3536 if ( fields[i]->GetDimension() == 0 )
3539 if ( geomAssocFields )
3540 for ( int i = 0; geomAssocFields[i]; ++i )
3541 switch ( geomAssocFields[i] ) {
3542 case 'v':case 'e':case 'f':case 's': break;
3543 case 'V':case 'E':case 'F':case 'S': break;
3544 default: THROW_SALOME_CORBA_EXCEPTION
3545 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3549 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3553 string aMeshName = "Mesh";
3554 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3555 if ( CORBA::is_nil( meshPart ) ||
3556 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3558 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3559 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3560 0, autoDimension, /*addODOnVertices=*/have0dField,
3562 meshDS = _impl->GetMeshDS();
3567 _preMeshInfo->FullLoadFromFile();
3569 PrepareForWriting(file, overwrite);
3571 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3572 if ( !SO->_is_nil() ) {
3573 CORBA::String_var name = SO->GetName();
3577 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3578 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3579 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3580 meshDS = tmpDSDeleter._obj = partDS;
3585 if ( _impl->HasShapeToMesh() )
3587 DriverMED_W_Field fieldWriter;
3588 fieldWriter.SetFile( file );
3589 fieldWriter.SetMeshName( aMeshName );
3590 fieldWriter.AddODOnVertices( have0dField );
3592 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3596 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3597 goList->length( fields.length() );
3598 for ( size_t i = 0; i < fields.length(); ++i )
3600 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3603 TPythonDump() << _this() << ".ExportPartToMED( "
3604 << meshPart << ", r'"
3606 << auto_groups << ", "
3608 << overwrite << ", "
3609 << autoDimension << ", "
3611 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3612 << TVar( ZTolerance )
3615 SMESH_CATCH( SMESH::throwCorbaException );
3618 //================================================================================
3620 * Write GEOM fields to MED file
3622 //================================================================================
3624 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3625 SMESHDS_Mesh* meshDS,
3626 const GEOM::ListOfFields& fields,
3627 const char* geomAssocFields)
3629 #define METH "SMESH_Mesh_i::exportMEDFields() "
3631 if (( fields.length() < 1 ) &&
3632 ( !geomAssocFields || !geomAssocFields[0] ))
3635 std::vector< std::vector< double > > dblVals;
3636 std::vector< std::vector< int > > intVals;
3637 std::vector< int > subIdsByDim[ 4 ];
3638 const double noneDblValue = 0.;
3639 const double noneIntValue = 0;
3641 for ( size_t iF = 0; iF < fields.length(); ++iF )
3645 int dim = fields[ iF ]->GetDimension();
3646 SMDSAbs_ElementType elemType;
3647 TopAbs_ShapeEnum shapeType;
3649 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3650 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3651 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3652 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3654 continue; // skip fields on whole shape
3656 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3657 if ( dataType == GEOM::FDT_String )
3659 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3660 if ( stepIDs->length() < 1 )
3662 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3663 if ( comps->length() < 1 )
3665 CORBA::String_var name = fields[ iF ]->GetName();
3667 if ( !fieldWriter.Set( meshDS,
3671 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3674 for ( size_t iC = 0; iC < comps->length(); ++iC )
3675 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3677 dblVals.resize( comps->length() );
3678 intVals.resize( comps->length() );
3680 // find sub-shape IDs
3682 std::vector< int >& subIds = subIdsByDim[ dim ];
3683 if ( subIds.empty() )
3684 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3685 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3686 subIds.push_back( id );
3690 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3694 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3696 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3697 if ( step->_is_nil() )
3700 CORBA::Long stamp = step->GetStamp();
3701 CORBA::Long id = step->GetID();
3702 fieldWriter.SetDtIt( int( stamp ), int( id ));
3704 // fill dblVals or intVals
3705 for ( size_t iC = 0; iC < comps->length(); ++iC )
3706 if ( dataType == GEOM::FDT_Double )
3708 dblVals[ iC ].clear();
3709 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3713 intVals[ iC ].clear();
3714 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3718 case GEOM::FDT_Double:
3720 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3721 if ( dblStep->_is_nil() ) continue;
3722 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3723 if ( vv->length() != subIds.size() * comps->length() )
3724 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3725 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3726 for ( size_t iC = 0; iC < comps->length(); ++iC )
3727 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3732 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3733 if ( intStep->_is_nil() ) continue;
3734 GEOM::ListOfLong_var vv = intStep->GetValues();
3735 if ( vv->length() != subIds.size() * comps->length() )
3736 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3737 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3738 for ( size_t iC = 0; iC < comps->length(); ++iC )
3739 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3742 case GEOM::FDT_Bool:
3744 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3745 if ( boolStep->_is_nil() ) continue;
3746 GEOM::short_array_var vv = boolStep->GetValues();
3747 if ( vv->length() != subIds.size() * comps->length() )
3748 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3749 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3750 for ( size_t iC = 0; iC < comps->length(); ++iC )
3751 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3757 // pass values to fieldWriter
3758 elemIt = fieldWriter.GetOrderedElems();
3759 if ( dataType == GEOM::FDT_Double )
3760 while ( elemIt->more() )
3762 const SMDS_MeshElement* e = elemIt->next();
3763 const int shapeID = e->getshapeId();
3764 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3765 for ( size_t iC = 0; iC < comps->length(); ++iC )
3766 fieldWriter.AddValue( noneDblValue );
3768 for ( size_t iC = 0; iC < comps->length(); ++iC )
3769 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3772 while ( elemIt->more() )
3774 const SMDS_MeshElement* e = elemIt->next();
3775 const int shapeID = e->getshapeId();
3776 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3777 for ( size_t iC = 0; iC < comps->length(); ++iC )
3778 fieldWriter.AddValue( (double) noneIntValue );
3780 for ( size_t iC = 0; iC < comps->length(); ++iC )
3781 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3785 fieldWriter.Perform();
3786 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3787 if ( res && res->IsKO() )
3789 if ( res->myComment.empty() )
3790 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3792 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3798 if ( !geomAssocFields || !geomAssocFields[0] )
3801 // write geomAssocFields
3803 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3804 shapeDim[ TopAbs_COMPOUND ] = 3;
3805 shapeDim[ TopAbs_COMPSOLID ] = 3;
3806 shapeDim[ TopAbs_SOLID ] = 3;
3807 shapeDim[ TopAbs_SHELL ] = 2;
3808 shapeDim[ TopAbs_FACE ] = 2;
3809 shapeDim[ TopAbs_WIRE ] = 1;
3810 shapeDim[ TopAbs_EDGE ] = 1;
3811 shapeDim[ TopAbs_VERTEX ] = 0;
3812 shapeDim[ TopAbs_SHAPE ] = 3;
3814 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3816 std::vector< std::string > compNames;
3817 switch ( geomAssocFields[ iF ]) {
3819 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3820 compNames.push_back( "dim" );
3823 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3826 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3829 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3833 compNames.push_back( "id" );
3834 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3835 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3837 fieldWriter.SetDtIt( -1, -1 );
3839 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3843 if ( compNames.size() == 2 ) // _vertices_
3844 while ( elemIt->more() )
3846 const SMDS_MeshElement* e = elemIt->next();
3847 const int shapeID = e->getshapeId();
3850 fieldWriter.AddValue( (double) -1 );
3851 fieldWriter.AddValue( (double) -1 );
3855 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3856 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3857 fieldWriter.AddValue( (double) shapeID );
3861 while ( elemIt->more() )
3863 const SMDS_MeshElement* e = elemIt->next();
3864 const int shapeID = e->getshapeId();
3866 fieldWriter.AddValue( (double) -1 );
3868 fieldWriter.AddValue( (double) shapeID );
3872 fieldWriter.Perform();
3873 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3874 if ( res && res->IsKO() )
3876 if ( res->myComment.empty() )
3877 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3879 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3882 } // loop on geomAssocFields
3887 //================================================================================
3889 * \brief Export a part of mesh to a DAT file
3891 //================================================================================
3893 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3895 throw (SALOME::SALOME_Exception)
3897 Unexpect aCatch(SALOME_SalomeException);
3899 _preMeshInfo->FullLoadFromFile();
3901 PrepareForWriting(file);
3903 SMESH_MeshPartDS partDS( meshPart );
3904 _impl->ExportDAT(file,&partDS);
3906 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3907 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3909 //================================================================================
3911 * \brief Export a part of mesh to an UNV file
3913 //================================================================================
3915 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3917 throw (SALOME::SALOME_Exception)
3919 Unexpect aCatch(SALOME_SalomeException);
3921 _preMeshInfo->FullLoadFromFile();
3923 PrepareForWriting(file);
3925 SMESH_MeshPartDS partDS( meshPart );
3926 _impl->ExportUNV(file, &partDS);
3928 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3929 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3931 //================================================================================
3933 * \brief Export a part of mesh to an STL file
3935 //================================================================================
3937 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3939 ::CORBA::Boolean isascii)
3940 throw (SALOME::SALOME_Exception)
3942 Unexpect aCatch(SALOME_SalomeException);
3944 _preMeshInfo->FullLoadFromFile();
3946 PrepareForWriting(file);
3948 CORBA::String_var name;
3949 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3950 if ( !so->_is_nil() )
3951 name = so->GetName();
3953 SMESH_MeshPartDS partDS( meshPart );
3954 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3956 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3957 << meshPart<< ", r'" << file << "', " << isascii << ")";
3960 //================================================================================
3962 * \brief Export a part of mesh to an STL file
3964 //================================================================================
3966 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3968 CORBA::Boolean overwrite,
3969 CORBA::Boolean groupElemsByType)
3970 throw (SALOME::SALOME_Exception)
3973 Unexpect aCatch(SALOME_SalomeException);
3975 _preMeshInfo->FullLoadFromFile();
3977 PrepareForWriting(file,overwrite);
3979 std::string meshName("");
3980 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3981 if ( !so->_is_nil() )
3983 CORBA::String_var name = so->GetName();
3984 meshName = name.in();
3988 SMESH_MeshPartDS partDS( meshPart );
3989 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3991 SMESH_CATCH( SMESH::throwCorbaException );
3993 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3994 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3996 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4000 //================================================================================
4002 * \brief Export a part of mesh to a GMF file
4004 //================================================================================
4006 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4008 bool withRequiredGroups)
4009 throw (SALOME::SALOME_Exception)
4011 Unexpect aCatch(SALOME_SalomeException);
4013 _preMeshInfo->FullLoadFromFile();
4015 PrepareForWriting(file,/*overwrite=*/true);
4017 SMESH_MeshPartDS partDS( meshPart );
4018 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4020 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4021 << meshPart<< ", r'"
4023 << withRequiredGroups << ")";
4026 //=============================================================================
4028 * Return computation progress [0.,1]
4030 //=============================================================================
4032 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4036 return _impl->GetComputeProgress();
4038 SMESH_CATCH( SMESH::doNothing );
4042 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4044 Unexpect aCatch(SALOME_SalomeException);
4046 return _preMeshInfo->NbNodes();
4048 return _impl->NbNodes();
4051 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4053 Unexpect aCatch(SALOME_SalomeException);
4055 return _preMeshInfo->NbElements();
4057 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4060 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4062 Unexpect aCatch(SALOME_SalomeException);
4064 return _preMeshInfo->Nb0DElements();
4066 return _impl->Nb0DElements();
4069 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4071 Unexpect aCatch(SALOME_SalomeException);
4073 return _preMeshInfo->NbBalls();
4075 return _impl->NbBalls();
4078 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4080 Unexpect aCatch(SALOME_SalomeException);
4082 return _preMeshInfo->NbEdges();
4084 return _impl->NbEdges();
4087 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4088 throw(SALOME::SALOME_Exception)
4090 Unexpect aCatch(SALOME_SalomeException);
4092 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4094 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4097 //=============================================================================
4099 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4101 Unexpect aCatch(SALOME_SalomeException);
4103 return _preMeshInfo->NbFaces();
4105 return _impl->NbFaces();
4108 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4110 Unexpect aCatch(SALOME_SalomeException);
4112 return _preMeshInfo->NbTriangles();
4114 return _impl->NbTriangles();
4117 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4119 Unexpect aCatch(SALOME_SalomeException);
4121 return _preMeshInfo->NbBiQuadTriangles();
4123 return _impl->NbBiQuadTriangles();
4126 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4128 Unexpect aCatch(SALOME_SalomeException);
4130 return _preMeshInfo->NbQuadrangles();
4132 return _impl->NbQuadrangles();
4135 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4137 Unexpect aCatch(SALOME_SalomeException);
4139 return _preMeshInfo->NbBiQuadQuadrangles();
4141 return _impl->NbBiQuadQuadrangles();
4144 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4146 Unexpect aCatch(SALOME_SalomeException);
4148 return _preMeshInfo->NbPolygons();
4150 return _impl->NbPolygons();
4153 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4155 Unexpect aCatch(SALOME_SalomeException);
4157 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4159 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4162 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4163 throw(SALOME::SALOME_Exception)
4165 Unexpect aCatch(SALOME_SalomeException);
4167 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4169 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4172 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4173 throw(SALOME::SALOME_Exception)
4175 Unexpect aCatch(SALOME_SalomeException);
4177 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4179 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4182 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4183 throw(SALOME::SALOME_Exception)
4185 Unexpect aCatch(SALOME_SalomeException);
4187 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4189 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4192 //=============================================================================
4194 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4196 Unexpect aCatch(SALOME_SalomeException);
4198 return _preMeshInfo->NbVolumes();
4200 return _impl->NbVolumes();
4203 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4205 Unexpect aCatch(SALOME_SalomeException);
4207 return _preMeshInfo->NbTetras();
4209 return _impl->NbTetras();
4212 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4214 Unexpect aCatch(SALOME_SalomeException);
4216 return _preMeshInfo->NbHexas();
4218 return _impl->NbHexas();
4221 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4223 Unexpect aCatch(SALOME_SalomeException);
4225 return _preMeshInfo->NbTriQuadHexas();
4227 return _impl->NbTriQuadraticHexas();
4230 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4232 Unexpect aCatch(SALOME_SalomeException);
4234 return _preMeshInfo->NbPyramids();
4236 return _impl->NbPyramids();
4239 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4241 Unexpect aCatch(SALOME_SalomeException);
4243 return _preMeshInfo->NbPrisms();
4245 return _impl->NbPrisms();
4248 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4250 Unexpect aCatch(SALOME_SalomeException);
4252 return _preMeshInfo->NbHexPrisms();
4254 return _impl->NbHexagonalPrisms();
4257 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4259 Unexpect aCatch(SALOME_SalomeException);
4261 return _preMeshInfo->NbPolyhedrons();
4263 return _impl->NbPolyhedrons();
4266 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4267 throw(SALOME::SALOME_Exception)
4269 Unexpect aCatch(SALOME_SalomeException);
4271 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4273 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4276 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4277 throw(SALOME::SALOME_Exception)
4279 Unexpect aCatch(SALOME_SalomeException);
4281 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4283 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4286 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4287 throw(SALOME::SALOME_Exception)
4289 Unexpect aCatch(SALOME_SalomeException);
4291 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4293 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4296 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4297 throw(SALOME::SALOME_Exception)
4299 Unexpect aCatch(SALOME_SalomeException);
4301 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4303 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4306 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4307 throw(SALOME::SALOME_Exception)
4309 Unexpect aCatch(SALOME_SalomeException);
4311 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4313 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4316 //=============================================================================
4318 * Returns nb of published sub-meshes
4320 //=============================================================================
4322 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4324 Unexpect aCatch(SALOME_SalomeException);
4325 return _mapSubMesh_i.size();
4328 //=============================================================================
4330 * Dumps mesh into a string
4332 //=============================================================================
4334 char* SMESH_Mesh_i::Dump()
4338 return CORBA::string_dup( os.str().c_str() );
4341 //=============================================================================
4343 * Method of SMESH_IDSource interface
4345 //=============================================================================
4347 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4349 return GetElementsId();
4352 //=============================================================================
4354 * Returns ids of all elements
4356 //=============================================================================
4358 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4359 throw (SALOME::SALOME_Exception)
4361 Unexpect aCatch(SALOME_SalomeException);
4363 _preMeshInfo->FullLoadFromFile();
4365 SMESH::long_array_var aResult = new SMESH::long_array();
4366 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4368 if ( aSMESHDS_Mesh == NULL )
4369 return aResult._retn();
4371 long nbElements = NbElements();
4372 aResult->length( nbElements );
4373 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4374 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4375 aResult[i] = anIt->next()->GetID();
4377 return aResult._retn();
4381 //=============================================================================
4383 * Returns ids of all elements of given type
4385 //=============================================================================
4387 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4388 throw (SALOME::SALOME_Exception)
4390 Unexpect aCatch(SALOME_SalomeException);
4392 _preMeshInfo->FullLoadFromFile();
4394 SMESH::long_array_var aResult = new SMESH::long_array();
4395 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4397 if ( aSMESHDS_Mesh == NULL )
4398 return aResult._retn();
4400 long nbElements = NbElements();
4402 // No sense in returning ids of elements along with ids of nodes:
4403 // when theElemType == SMESH::ALL, return node ids only if
4404 // there are no elements
4405 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4406 return GetNodesId();
4408 aResult->length( nbElements );
4412 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4413 while ( i < nbElements && anIt->more() )
4414 aResult[i++] = anIt->next()->GetID();
4416 aResult->length( i );
4418 return aResult._retn();
4421 //=============================================================================
4423 * Returns ids of all nodes
4425 //=============================================================================
4427 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4428 throw (SALOME::SALOME_Exception)
4430 Unexpect aCatch(SALOME_SalomeException);
4432 _preMeshInfo->FullLoadFromFile();
4434 SMESH::long_array_var aResult = new SMESH::long_array();
4435 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4437 if ( aMeshDS == NULL )
4438 return aResult._retn();
4440 long nbNodes = NbNodes();
4441 aResult->length( nbNodes );
4442 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4443 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4444 aResult[i] = anIt->next()->GetID();
4446 return aResult._retn();
4449 //=============================================================================
4453 //=============================================================================
4455 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4456 throw (SALOME::SALOME_Exception)
4458 SMESH::ElementType type = SMESH::ALL;
4462 _preMeshInfo->FullLoadFromFile();
4464 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4466 SMESH_CATCH( SMESH::throwCorbaException );
4471 //=============================================================================
4475 //=============================================================================
4477 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4478 throw (SALOME::SALOME_Exception)
4481 _preMeshInfo->FullLoadFromFile();
4483 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4485 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4487 return ( SMESH::EntityType ) e->GetEntityType();
4490 //=============================================================================
4494 //=============================================================================
4496 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4497 throw (SALOME::SALOME_Exception)
4500 _preMeshInfo->FullLoadFromFile();
4502 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4504 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4506 return ( SMESH::GeometryType ) e->GetGeomType();
4509 //=============================================================================
4511 * Returns ID of elements for given submesh
4513 //=============================================================================
4514 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4515 throw (SALOME::SALOME_Exception)
4517 SMESH::long_array_var aResult = new SMESH::long_array();
4521 _preMeshInfo->FullLoadFromFile();
4523 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4524 if(!SM) return aResult._retn();
4526 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4527 if(!SDSM) return aResult._retn();
4529 aResult->length(SDSM->NbElements());
4531 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4533 while ( eIt->more() ) {
4534 aResult[i++] = eIt->next()->GetID();
4537 SMESH_CATCH( SMESH::throwCorbaException );
4539 return aResult._retn();
4542 //=============================================================================
4544 * Returns ID of nodes for given submesh
4545 * If param all==true - returns all nodes, else -
4546 * returns only nodes on shapes.
4548 //=============================================================================
4550 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4552 throw (SALOME::SALOME_Exception)
4554 SMESH::long_array_var aResult = new SMESH::long_array();
4558 _preMeshInfo->FullLoadFromFile();
4560 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4561 if(!SM) return aResult._retn();
4563 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4564 if(!SDSM) return aResult._retn();
4567 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4568 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4569 while ( nIt->more() ) {
4570 const SMDS_MeshNode* elem = nIt->next();
4571 theElems.insert( elem->GetID() );
4574 else { // all nodes of submesh elements
4575 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4576 while ( eIt->more() ) {
4577 const SMDS_MeshElement* anElem = eIt->next();
4578 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4579 while ( nIt->more() ) {
4580 const SMDS_MeshElement* elem = nIt->next();
4581 theElems.insert( elem->GetID() );
4586 aResult->length(theElems.size());
4587 set<int>::iterator itElem;
4589 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4590 aResult[i++] = *itElem;
4592 SMESH_CATCH( SMESH::throwCorbaException );
4594 return aResult._retn();
4597 //=============================================================================
4599 * Returns type of elements for given submesh
4601 //=============================================================================
4603 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4604 throw (SALOME::SALOME_Exception)
4606 SMESH::ElementType type = SMESH::ALL;
4610 _preMeshInfo->FullLoadFromFile();
4612 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4613 if(!SM) return SMESH::ALL;
4615 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4616 if(!SDSM) return SMESH::ALL;
4618 if(SDSM->NbElements()==0)
4619 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4621 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4622 const SMDS_MeshElement* anElem = eIt->next();
4624 type = ( SMESH::ElementType ) anElem->GetType();
4626 SMESH_CATCH( SMESH::throwCorbaException );
4632 //=============================================================================
4634 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4636 //=============================================================================
4638 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4641 _preMeshInfo->FullLoadFromFile();
4643 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4644 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4649 //=============================================================================
4651 * Get XYZ coordinates of node as list of double
4652 * If there is not node for given ID - returns empty list
4654 //=============================================================================
4656 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4659 _preMeshInfo->FullLoadFromFile();
4661 SMESH::double_array_var aResult = new SMESH::double_array();
4662 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4663 if ( aMeshDS == NULL )
4664 return aResult._retn();
4667 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4669 return aResult._retn();
4673 aResult[0] = aNode->X();
4674 aResult[1] = aNode->Y();
4675 aResult[2] = aNode->Z();
4676 return aResult._retn();
4680 //=============================================================================
4682 * For given node returns list of IDs of inverse elements
4683 * If there is not node for given ID - returns empty list
4685 //=============================================================================
4687 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4688 SMESH::ElementType elemType)
4691 _preMeshInfo->FullLoadFromFile();
4693 SMESH::long_array_var aResult = new SMESH::long_array();
4694 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4695 if ( aMeshDS == NULL )
4696 return aResult._retn();
4699 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4701 return aResult._retn();
4703 // find inverse elements
4704 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4705 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4706 aResult->length( aNode->NbInverseElements( type ));
4707 for( int i = 0; eIt->more(); ++i )
4709 const SMDS_MeshElement* elem = eIt->next();
4710 aResult[ i ] = elem->GetID();
4712 return aResult._retn();
4715 //=============================================================================
4717 * \brief Return position of a node on shape
4719 //=============================================================================
4721 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4724 _preMeshInfo->FullLoadFromFile();
4726 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4727 aNodePosition->shapeID = 0;
4728 aNodePosition->shapeType = GEOM::SHAPE;
4730 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4731 if ( !mesh ) return aNodePosition;
4733 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4735 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4737 aNodePosition->shapeID = aNode->getshapeId();
4738 switch ( pos->GetTypeOfPosition() ) {
4740 aNodePosition->shapeType = GEOM::EDGE;
4741 aNodePosition->params.length(1);
4742 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4744 case SMDS_TOP_FACE: {
4745 SMDS_FacePositionPtr fPos = pos;
4746 aNodePosition->shapeType = GEOM::FACE;
4747 aNodePosition->params.length(2);
4748 aNodePosition->params[0] = fPos->GetUParameter();
4749 aNodePosition->params[1] = fPos->GetVParameter();
4752 case SMDS_TOP_VERTEX:
4753 aNodePosition->shapeType = GEOM::VERTEX;
4755 case SMDS_TOP_3DSPACE:
4756 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4757 aNodePosition->shapeType = GEOM::SOLID;
4758 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4759 aNodePosition->shapeType = GEOM::SHELL;
4765 return aNodePosition;
4768 //=============================================================================
4770 * \brief Return position of an element on shape
4772 //=============================================================================
4774 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4777 _preMeshInfo->FullLoadFromFile();
4779 SMESH::ElementPosition anElementPosition;
4780 anElementPosition.shapeID = 0;
4781 anElementPosition.shapeType = GEOM::SHAPE;
4783 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4784 if ( !mesh ) return anElementPosition;
4786 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4788 anElementPosition.shapeID = anElem->getshapeId();
4789 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4790 if ( !aSp.IsNull() ) {
4791 switch ( aSp.ShapeType() ) {
4793 anElementPosition.shapeType = GEOM::EDGE;
4796 anElementPosition.shapeType = GEOM::FACE;
4799 anElementPosition.shapeType = GEOM::VERTEX;
4802 anElementPosition.shapeType = GEOM::SOLID;
4805 anElementPosition.shapeType = GEOM::SHELL;
4811 return anElementPosition;
4814 //=============================================================================
4816 * If given element is node returns IDs of shape from position
4817 * If there is not node for given ID - returns -1
4819 //=============================================================================
4821 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4824 _preMeshInfo->FullLoadFromFile();
4826 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4827 if ( aMeshDS == NULL )
4831 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4833 return aNode->getshapeId();
4840 //=============================================================================
4842 * For given element returns ID of result shape after
4843 * ::FindShape() from SMESH_MeshEditor
4844 * If there is not element for given ID - returns -1
4846 //=============================================================================
4848 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4851 _preMeshInfo->FullLoadFromFile();
4853 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4854 if ( aMeshDS == NULL )
4857 // try to find element
4858 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4862 ::SMESH_MeshEditor aMeshEditor(_impl);
4863 int index = aMeshEditor.FindShape( elem );
4871 //=============================================================================
4873 * Returns number of nodes for given element
4874 * If there is not element for given ID - returns -1
4876 //=============================================================================
4878 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4881 _preMeshInfo->FullLoadFromFile();
4883 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4884 if ( aMeshDS == NULL ) return -1;
4885 // try to find element
4886 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4887 if(!elem) return -1;
4888 return elem->NbNodes();
4892 //=============================================================================
4894 * Returns ID of node by given index for given element
4895 * If there is not element for given ID - returns -1
4896 * If there is not node for given index - returns -2
4898 //=============================================================================
4900 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4903 _preMeshInfo->FullLoadFromFile();
4905 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4906 if ( aMeshDS == NULL ) return -1;
4907 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4908 if(!elem) return -1;
4909 if( index>=elem->NbNodes() || index<0 ) return -1;
4910 return elem->GetNode(index)->GetID();
4913 //=============================================================================
4915 * Returns IDs of nodes of given element
4917 //=============================================================================
4919 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4922 _preMeshInfo->FullLoadFromFile();
4924 SMESH::long_array_var aResult = new SMESH::long_array();
4925 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4927 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4929 aResult->length( elem->NbNodes() );
4930 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4931 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
4932 aResult[ i ] = n->GetID();
4935 return aResult._retn();
4938 //=============================================================================
4940 * Returns true if given node is medium node
4941 * in given quadratic element
4943 //=============================================================================
4945 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4948 _preMeshInfo->FullLoadFromFile();
4950 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4951 if ( aMeshDS == NULL ) return false;
4953 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4954 if(!aNode) return false;
4955 // try to find element
4956 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4957 if(!elem) return false;
4959 return elem->IsMediumNode(aNode);
4963 //=============================================================================
4965 * Returns true if given node is medium node
4966 * in one of quadratic elements
4968 //=============================================================================
4970 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4971 SMESH::ElementType theElemType)
4974 _preMeshInfo->FullLoadFromFile();
4976 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4977 if ( aMeshDS == NULL ) return false;
4980 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4981 if(!aNode) return false;
4983 SMESH_MesherHelper aHelper( *(_impl) );
4985 SMDSAbs_ElementType aType;
4986 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4987 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4988 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4989 else aType = SMDSAbs_All;
4991 return aHelper.IsMedium(aNode,aType);
4995 //=============================================================================
4997 * Returns number of edges for given element
4999 //=============================================================================
5001 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5004 _preMeshInfo->FullLoadFromFile();
5006 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5007 if ( aMeshDS == NULL ) return -1;
5008 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5009 if(!elem) return -1;
5010 return elem->NbEdges();
5014 //=============================================================================
5016 * Returns number of faces for given element
5018 //=============================================================================
5020 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5023 _preMeshInfo->FullLoadFromFile();
5025 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5026 if ( aMeshDS == NULL ) return -1;
5027 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5028 if(!elem) return -1;
5029 return elem->NbFaces();
5032 //=======================================================================
5033 //function : GetElemFaceNodes
5034 //purpose : Returns nodes of given face (counted from zero) for given element.
5035 //=======================================================================
5037 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5038 CORBA::Short faceIndex)
5041 _preMeshInfo->FullLoadFromFile();
5043 SMESH::long_array_var aResult = new SMESH::long_array();
5044 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5046 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5048 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5049 if ( faceIndex < vtool.NbFaces() )
5051 aResult->length( vtool.NbFaceNodes( faceIndex ));
5052 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5053 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5054 aResult[ i ] = nn[ i ]->GetID();
5058 return aResult._retn();
5061 //=======================================================================
5062 //function : GetElemFaceNodes
5063 //purpose : Returns three components of normal of given mesh face.
5064 //=======================================================================
5066 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5067 CORBA::Boolean normalized)
5070 _preMeshInfo->FullLoadFromFile();
5072 SMESH::double_array_var aResult = new SMESH::double_array();
5074 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5077 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5079 aResult->length( 3 );
5080 aResult[ 0 ] = normal.X();
5081 aResult[ 1 ] = normal.Y();
5082 aResult[ 2 ] = normal.Z();
5085 return aResult._retn();
5088 //=======================================================================
5089 //function : FindElementByNodes
5090 //purpose : Returns an element based on all given nodes.
5091 //=======================================================================
5093 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5096 _preMeshInfo->FullLoadFromFile();
5098 CORBA::Long elemID(0);
5099 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5101 vector< const SMDS_MeshNode * > nn( nodes.length() );
5102 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5103 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5106 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5107 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5108 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5109 _impl->NbVolumes( ORDER_QUADRATIC )))
5110 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5112 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5117 //================================================================================
5119 * \brief Return elements including all given nodes.
5121 //================================================================================
5123 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5124 SMESH::ElementType elemType)
5127 _preMeshInfo->FullLoadFromFile();
5129 SMESH::long_array_var result = new SMESH::long_array();
5131 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5133 vector< const SMDS_MeshNode * > nn( nodes.length() );
5134 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5135 nn[i] = mesh->FindNode( nodes[i] );
5137 std::vector<const SMDS_MeshElement *> elems;
5138 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5139 result->length( elems.size() );
5140 for ( size_t i = 0; i < elems.size(); ++i )
5141 result[i] = elems[i]->GetID();
5143 return result._retn();
5146 //=============================================================================
5148 * Returns true if given element is polygon
5150 //=============================================================================
5152 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5155 _preMeshInfo->FullLoadFromFile();
5157 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5158 if ( aMeshDS == NULL ) return false;
5159 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5160 if(!elem) return false;
5161 return elem->IsPoly();
5165 //=============================================================================
5167 * Returns true if given element is quadratic
5169 //=============================================================================
5171 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5174 _preMeshInfo->FullLoadFromFile();
5176 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5177 if ( aMeshDS == NULL ) return false;
5178 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5179 if(!elem) return false;
5180 return elem->IsQuadratic();
5183 //=============================================================================
5185 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5187 //=============================================================================
5189 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5192 _preMeshInfo->FullLoadFromFile();
5194 if ( const SMDS_BallElement* ball =
5195 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5196 return ball->GetDiameter();
5201 //=============================================================================
5203 * Returns bary center for given element
5205 //=============================================================================
5207 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5210 _preMeshInfo->FullLoadFromFile();
5212 SMESH::double_array_var aResult = new SMESH::double_array();
5213 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5214 if ( aMeshDS == NULL )
5215 return aResult._retn();
5217 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5219 return aResult._retn();
5221 if(elem->GetType()==SMDSAbs_Volume) {
5222 SMDS_VolumeTool aTool;
5223 if(aTool.Set(elem)) {
5225 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5230 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5232 double x=0., y=0., z=0.;
5233 for(; anIt->more(); ) {
5235 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5249 return aResult._retn();
5252 //================================================================================
5254 * \brief Create a group of elements preventing computation of a sub-shape
5256 //================================================================================
5258 SMESH::ListOfGroups*
5259 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5260 const char* theGroupName )
5261 throw ( SALOME::SALOME_Exception )
5263 Unexpect aCatch(SALOME_SalomeException);
5265 if ( !theGroupName || strlen( theGroupName) == 0 )
5266 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5268 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5269 ::SMESH_MeshEditor::ElemFeatures elemType;
5271 // submesh by subshape id
5272 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5273 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5276 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5277 if ( error && error->HasBadElems() )
5279 // sort bad elements by type
5280 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5281 const list<const SMDS_MeshElement*>& badElems =
5282 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5283 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5284 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5285 for ( ; elemIt != elemEnd; ++elemIt )
5287 const SMDS_MeshElement* elem = *elemIt;
5288 if ( !elem ) continue;
5290 if ( elem->GetID() < 1 )
5292 // elem is a temporary element, make a real element
5293 vector< const SMDS_MeshNode* > nodes;
5294 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5295 while ( nIt->more() && elem )
5297 nodes.push_back( nIt->next() );
5298 if ( nodes.back()->GetID() < 1 )
5299 elem = 0; // a temporary element on temporary nodes
5303 ::SMESH_MeshEditor editor( _impl );
5304 elem = editor.AddElement( nodes, elemType.Init( elem ));
5308 elemsByType[ elem->GetType() ].push_back( elem );
5311 // how many groups to create?
5313 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5314 nbTypes += int( !elemsByType[ i ].empty() );
5315 groups->length( nbTypes );
5318 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5320 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5321 if ( elems.empty() ) continue;
5323 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5324 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5326 SMESH::SMESH_Mesh_var mesh = _this();
5327 SALOMEDS::SObject_wrap aSO =
5328 _gen_i->PublishGroup( mesh, groups[ iG ],
5329 GEOM::GEOM_Object::_nil(), theGroupName);
5331 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5332 if ( !grp_i ) continue;
5334 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5335 for ( size_t iE = 0; iE < elems.size(); ++iE )
5336 grpDS->SMDSGroup().Add( elems[ iE ]);
5341 return groups._retn();
5344 //=============================================================================
5346 * Create and publish group servants if any groups were imported or created anyhow
5348 //=============================================================================
5350 void SMESH_Mesh_i::CreateGroupServants()
5352 SMESH::SMESH_Mesh_var aMesh = _this();
5355 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5356 while ( groupIt->more() )
5358 ::SMESH_Group* group = groupIt->next();
5359 int anId = group->GetID();
5361 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5362 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5364 addedIDs.insert( anId );
5366 SMESH_GroupBase_i* aGroupImpl;
5368 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5369 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5371 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5372 shape = groupOnGeom->GetShape();
5375 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5378 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5379 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5380 aGroupImpl->Register();
5382 // register CORBA object for persistence
5383 int nextId = _gen_i->RegisterObject( groupVar );
5384 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5385 else { nextId = 0; } // avoid "unused variable" warning in release mode
5387 // publishing the groups in the study
5388 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5389 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5391 if ( !addedIDs.empty() )
5394 set<int>::iterator id = addedIDs.begin();
5395 for ( ; id != addedIDs.end(); ++id )
5397 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5398 int i = std::distance( _mapGroups.begin(), it );
5399 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5404 //=============================================================================
5406 * \brief Return true if all sub-meshes are computed OK - to update an icon
5408 //=============================================================================
5410 bool SMESH_Mesh_i::IsComputedOK()
5412 return _impl->IsComputedOK();
5415 //=============================================================================
5417 * \brief Return groups cantained in _mapGroups by their IDs
5419 //=============================================================================
5421 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5423 int nbGroups = groupIDs.size();
5424 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5425 aList->length( nbGroups );
5427 list<int>::const_iterator ids = groupIDs.begin();
5428 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5430 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5431 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5432 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5434 aList->length( nbGroups );
5435 return aList._retn();
5438 //=============================================================================
5440 * \brief Return information about imported file
5442 //=============================================================================
5444 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5446 SMESH::MedFileInfo_var res( _medFileInfo );
5447 if ( !res.operator->() ) {
5448 res = new SMESH::MedFileInfo;
5450 res->fileSize = res->major = res->minor = res->release = -1;
5455 //=======================================================================
5456 //function : FileInfoToString
5457 //purpose : Persistence of file info
5458 //=======================================================================
5460 std::string SMESH_Mesh_i::FileInfoToString()
5463 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5465 s = SMESH_Comment( _medFileInfo->fileSize )
5466 << " " << _medFileInfo->major
5467 << " " << _medFileInfo->minor
5468 << " " << _medFileInfo->release
5469 << " " << _medFileInfo->fileName;
5474 //=======================================================================
5475 //function : FileInfoFromString
5476 //purpose : Persistence of file info
5477 //=======================================================================
5479 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5481 std::string size, major, minor, release, fileName;
5482 std::istringstream is(info);
5483 is >> size >> major >> minor >> release;
5484 fileName = info.data() + ( size.size() + 1 +
5487 release.size()+ 1 );
5489 _medFileInfo = new SMESH::MedFileInfo();
5490 _medFileInfo->fileName = fileName.c_str();
5491 _medFileInfo->fileSize = atoi( size.c_str() );
5492 _medFileInfo->major = atoi( major.c_str() );
5493 _medFileInfo->minor = atoi( minor.c_str() );
5494 _medFileInfo->release = atoi( release.c_str() );
5497 //=============================================================================
5499 * \brief Pass names of mesh groups from study to mesh DS
5501 //=============================================================================
5503 void SMESH_Mesh_i::checkGroupNames()
5505 int nbGrp = NbGroups();
5509 SMESH::ListOfGroups* grpList = 0;
5510 // avoid dump of "GetGroups"
5512 // store python dump into a local variable inside local scope
5513 SMESH::TPythonDump pDump; // do not delete this line of code
5514 grpList = GetGroups();
5517 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5518 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5521 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5522 if ( aGrpSO->_is_nil() )
5524 // correct name of the mesh group if necessary
5525 const char* guiName = aGrpSO->GetName();
5526 if ( strcmp(guiName, aGrp->GetName()) )
5527 aGrp->SetName( guiName );
5531 //=============================================================================
5533 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5535 //=============================================================================
5536 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5538 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5542 //=============================================================================
5544 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5546 //=============================================================================
5548 char* SMESH_Mesh_i::GetParameters()
5550 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5553 //=============================================================================
5555 * \brief Returns list of notebook variables used for last Mesh operation
5557 //=============================================================================
5558 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5560 SMESH::string_array_var aResult = new SMESH::string_array();
5561 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5563 CORBA::String_var aParameters = GetParameters();
5564 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5565 if ( aSections->length() > 0 ) {
5566 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5567 aResult->length( aVars.length() );
5568 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5569 aResult[i] = CORBA::string_dup( aVars[i] );
5572 return aResult._retn();
5575 //=======================================================================
5576 //function : GetTypes
5577 //purpose : Returns types of elements it contains
5578 //=======================================================================
5580 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5583 return _preMeshInfo->GetTypes();
5585 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5589 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5590 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5591 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5592 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5593 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5594 if (_impl->NbNodes() &&
5595 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5596 types->length( nbTypes );
5598 return types._retn();
5601 //=======================================================================
5602 //function : GetMesh
5603 //purpose : Returns self
5604 //=======================================================================
5606 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5608 return SMESH::SMESH_Mesh::_duplicate( _this() );
5611 //=======================================================================
5612 //function : IsMeshInfoCorrect
5613 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5614 // * happen if mesh data is not yet fully loaded from the file of study.
5615 //=======================================================================
5617 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5619 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5622 //=============================================================================
5624 * \brief Returns number of mesh elements per each \a EntityType
5626 //=============================================================================
5628 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5631 return _preMeshInfo->GetMeshInfo();
5633 SMESH::long_array_var aRes = new SMESH::long_array();
5634 aRes->length(SMESH::Entity_Last);
5635 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5637 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5639 return aRes._retn();
5640 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5641 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5642 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5643 return aRes._retn();
5646 //=============================================================================
5648 * \brief Returns number of mesh elements per each \a ElementType
5650 //=============================================================================
5652 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5654 SMESH::long_array_var aRes = new SMESH::long_array();
5655 aRes->length(SMESH::NB_ELEMENT_TYPES);
5656 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5659 const SMDS_MeshInfo* meshInfo = 0;
5661 meshInfo = _preMeshInfo;
5662 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5663 meshInfo = & meshDS->GetMeshInfo();
5666 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5667 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5669 return aRes._retn();
5672 //=============================================================================
5674 * Collect statistic of mesh elements given by iterator
5676 //=============================================================================
5678 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5679 SMESH::long_array& theInfo)
5681 if (!theItr) return;
5682 while (theItr->more())
5683 theInfo[ theItr->next()->GetEntityType() ]++;
5685 //=============================================================================
5687 * Returns mesh unstructed grid information.
5689 //=============================================================================
5691 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5693 SALOMEDS::TMPFile_var SeqFile;
5694 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5695 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5697 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5698 aWriter->WriteToOutputStringOn();
5699 aWriter->SetInputData(aGrid);
5700 aWriter->SetFileTypeToBinary();
5702 char* str = aWriter->GetOutputString();
5703 int size = aWriter->GetOutputStringLength();
5705 //Allocate octet buffer of required size
5706 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5707 //Copy ostrstream content to the octet buffer
5708 memcpy(OctetBuf, str, size);
5709 //Create and return TMPFile
5710 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5714 return SeqFile._retn();
5717 //=============================================================================
5718 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5719 * SMESH::ElementType type) */
5721 using namespace SMESH::Controls;
5722 //-----------------------------------------------------------------------------
5723 struct PredicateIterator : public SMDS_ElemIterator
5725 SMDS_ElemIteratorPtr _elemIter;
5726 PredicatePtr _predicate;
5727 const SMDS_MeshElement* _elem;
5728 SMDSAbs_ElementType _type;
5730 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5731 PredicatePtr predicate,
5732 SMDSAbs_ElementType type):
5733 _elemIter(iterator), _predicate(predicate), _type(type)
5741 virtual const SMDS_MeshElement* next()
5743 const SMDS_MeshElement* res = _elem;
5745 while ( _elemIter->more() && !_elem )
5747 if ((_elem = _elemIter->next()) &&
5748 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5749 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5756 //-----------------------------------------------------------------------------
5757 struct IDSourceIterator : public SMDS_ElemIterator
5759 const CORBA::Long* _idPtr;
5760 const CORBA::Long* _idEndPtr;
5761 SMESH::long_array_var _idArray;
5762 const SMDS_Mesh* _mesh;
5763 const SMDSAbs_ElementType _type;
5764 const SMDS_MeshElement* _elem;
5766 IDSourceIterator( const SMDS_Mesh* mesh,
5767 const CORBA::Long* ids,
5769 SMDSAbs_ElementType type):
5770 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5772 if ( _idPtr && nbIds && _mesh )
5775 IDSourceIterator( const SMDS_Mesh* mesh,
5776 SMESH::long_array* idArray,
5777 SMDSAbs_ElementType type):
5778 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5780 if ( idArray && _mesh )
5782 _idPtr = &_idArray[0];
5783 _idEndPtr = _idPtr + _idArray->length();
5791 virtual const SMDS_MeshElement* next()
5793 const SMDS_MeshElement* res = _elem;
5795 while ( _idPtr < _idEndPtr && !_elem )
5797 if ( _type == SMDSAbs_Node )
5799 _elem = _mesh->FindNode( *_idPtr++ );
5801 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5802 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5810 //-----------------------------------------------------------------------------
5812 struct NodeOfElemIterator : public SMDS_ElemIterator
5814 TColStd_MapOfInteger _checkedNodeIDs;
5815 SMDS_ElemIteratorPtr _elemIter;
5816 SMDS_ElemIteratorPtr _nodeIter;
5817 const SMDS_MeshElement* _node;
5819 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5821 if ( _elemIter && _elemIter->more() )
5823 _nodeIter = _elemIter->next()->nodesIterator();
5831 virtual const SMDS_MeshElement* next()
5833 const SMDS_MeshElement* res = _node;
5835 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5837 if ( _nodeIter->more() )
5839 _node = _nodeIter->next();
5840 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5845 _nodeIter = _elemIter->next()->nodesIterator();
5853 //=============================================================================
5855 * Return iterator on elements of given type in given object
5857 //=============================================================================
5859 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5860 SMESH::ElementType theType)
5862 SMDS_ElemIteratorPtr elemIt;
5863 bool typeOK = ( theType == SMESH::ALL );
5864 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5866 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5867 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5868 if ( !mesh_i ) return elemIt;
5869 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5871 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5873 elemIt = meshDS->elementsIterator( elemType );
5876 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5878 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5881 elemIt = sm->GetElements();
5882 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5884 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5885 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5889 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5891 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5892 if ( groupDS && ( elemType == groupDS->GetType() ||
5893 elemType == SMDSAbs_Node ||
5894 elemType == SMDSAbs_All ))
5896 elemIt = groupDS->GetElements();
5897 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5900 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5902 if ( filter_i->GetElementType() == theType ||
5903 filter_i->GetElementType() == SMESH::ALL ||
5904 elemType == SMDSAbs_Node ||
5905 elemType == SMDSAbs_All)
5907 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5908 if ( pred_i && pred_i->GetPredicate() )
5910 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5911 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5912 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
5913 elemIt = SMDS_ElemIteratorPtr
5914 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
5915 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
5921 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5922 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5923 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5925 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
5926 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5929 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5930 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
5934 SMESH::long_array_var ids = theObject->GetIDs();
5935 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
5937 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5940 if ( elemIt && elemIt->more() && !typeOK )
5942 if ( elemType == SMDSAbs_Node )
5944 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5948 elemIt = SMDS_ElemIteratorPtr();
5954 //=============================================================================
5955 namespace // Finding concurrent hypotheses
5956 //=============================================================================
5960 * \brief mapping of mesh dimension into shape type
5962 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5964 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5966 case 0: aType = TopAbs_VERTEX; break;
5967 case 1: aType = TopAbs_EDGE; break;
5968 case 2: aType = TopAbs_FACE; break;
5970 default:aType = TopAbs_SOLID; break;
5975 //-----------------------------------------------------------------------------
5977 * \brief Internal structure used to find concurrent submeshes
5979 * It represents a pair < submesh, concurrent dimension >, where
5980 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5981 * with another submesh. In other words, it is dimension of a hypothesis assigned
5988 int _dim; //!< a dimension the algo can build (concurrent dimension)
5989 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5990 TopTools_MapOfShape _shapeMap;
5991 SMESH_subMesh* _subMesh;
5992 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5994 //-----------------------------------------------------------------------------
5995 // Return the algorithm
5996 const SMESH_Algo* GetAlgo() const
5997 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5999 //-----------------------------------------------------------------------------
6001 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6003 const TopoDS_Shape& theShape)
6005 _subMesh = (SMESH_subMesh*)theSubMesh;
6006 SetShape( theDim, theShape );
6009 //-----------------------------------------------------------------------------
6011 void SetShape(const int theDim,
6012 const TopoDS_Shape& theShape)
6015 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6016 if (_dim >= _ownDim)
6017 _shapeMap.Add( theShape );
6019 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6020 for( ; anExp.More(); anExp.Next() )
6021 _shapeMap.Add( anExp.Current() );
6025 //-----------------------------------------------------------------------------
6026 //! Check sharing of sub-shapes
6027 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6028 const TopTools_MapOfShape& theToFind,
6029 const TopAbs_ShapeEnum theType)
6031 bool isShared = false;
6032 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6033 for (; !isShared && anItr.More(); anItr.Next() )
6035 const TopoDS_Shape aSubSh = anItr.Key();
6036 // check for case when concurrent dimensions are same
6037 isShared = theToFind.Contains( aSubSh );
6038 // check for sub-shape with concurrent dimension
6039 TopExp_Explorer anExp( aSubSh, theType );
6040 for ( ; !isShared && anExp.More(); anExp.Next() )
6041 isShared = theToFind.Contains( anExp.Current() );
6046 //-----------------------------------------------------------------------------
6047 //! check algorithms
6048 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6049 const SMESHDS_Hypothesis* theA2)
6051 if ( !theA1 || !theA2 ||
6052 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6053 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6054 return false; // one of the hypothesis is not algorithm
6055 // check algorithm names (should be equal)
6056 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6060 //-----------------------------------------------------------------------------
6061 //! Check if sub-shape hypotheses are concurrent
6062 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6064 if ( _subMesh == theOther->_subMesh )
6065 return false; // same sub-shape - should not be
6067 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6068 // any of the two submeshes is not on COMPOUND shape )
6069 // -> no concurrency
6070 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6071 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6072 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6073 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6074 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6077 // bool checkSubShape = ( _dim >= theOther->_dim )
6078 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
6079 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
6080 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6081 if ( !checkSubShape )
6084 // check algorithms to be same
6085 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
6086 return true; // different algorithms -> concurrency !
6088 // check hypothesises for concurrence (skip first as algorithm)
6090 // pointers should be same, because it is referened from mesh hypothesis partition
6091 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6092 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6093 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6094 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6096 // the submeshes are concurrent if their algorithms has different parameters
6097 return nbSame != (int)theOther->_hypotheses.size() - 1;
6100 // Return true if algorithm of this SMESH_DimHyp is used if no
6101 // sub-mesh order is imposed by the user
6102 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6104 // NeedDiscreteBoundary() algo has a higher priority
6105 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6106 theOther->GetAlgo()->NeedDiscreteBoundary() )
6107 return !this->GetAlgo()->NeedDiscreteBoundary();
6109 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6112 }; // end of SMESH_DimHyp
6113 //-----------------------------------------------------------------------------
6115 typedef list<const SMESH_DimHyp*> TDimHypList;
6117 //-----------------------------------------------------------------------------
6119 void addDimHypInstance(const int theDim,
6120 const TopoDS_Shape& theShape,
6121 const SMESH_Algo* theAlgo,
6122 const SMESH_subMesh* theSubMesh,
6123 const list <const SMESHDS_Hypothesis*>& theHypList,
6124 TDimHypList* theDimHypListArr )
6126 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6127 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6128 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6129 dimHyp->_hypotheses.push_front(theAlgo);
6130 listOfdimHyp.push_back( dimHyp );
6133 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6134 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6135 theHypList.begin(), theHypList.end() );
6138 //-----------------------------------------------------------------------------
6139 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6140 TDimHypList& theListOfConcurr)
6142 if ( theListOfConcurr.empty() )
6144 theListOfConcurr.push_back( theDimHyp );
6148 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6149 while ( hypIt != theListOfConcurr.end() &&
6150 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6152 theListOfConcurr.insert( hypIt, theDimHyp );
6156 //-----------------------------------------------------------------------------
6157 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6158 const TDimHypList& theListOfDimHyp,
6159 TDimHypList& theListOfConcurrHyp,
6160 set<int>& theSetOfConcurrId )
6162 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6163 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6165 const SMESH_DimHyp* curDimHyp = *rIt;
6166 if ( curDimHyp == theDimHyp )
6167 break; // meet own dimHyp pointer in same dimension
6169 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6170 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6172 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6177 //-----------------------------------------------------------------------------
6178 void unionLists(TListOfInt& theListOfId,
6179 TListOfListOfInt& theListOfListOfId,
6182 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6183 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6185 continue; //skip already treated lists
6186 // check if other list has any same submesh object
6187 TListOfInt& otherListOfId = *it;
6188 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6189 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6192 // union two lists (from source into target)
6193 TListOfInt::iterator it2 = otherListOfId.begin();
6194 for ( ; it2 != otherListOfId.end(); it2++ ) {
6195 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6196 theListOfId.push_back(*it2);
6198 // clear source list
6199 otherListOfId.clear();
6202 //-----------------------------------------------------------------------------
6204 //! free memory allocated for dimension-hypothesis objects
6205 void removeDimHyps( TDimHypList* theArrOfList )
6207 for (int i = 0; i < 4; i++ ) {
6208 TDimHypList& listOfdimHyp = theArrOfList[i];
6209 TDimHypList::const_iterator it = listOfdimHyp.begin();
6210 for ( ; it != listOfdimHyp.end(); it++ )
6215 //-----------------------------------------------------------------------------
6217 * \brief find common submeshes with given submesh
6218 * \param theSubMeshList list of already collected submesh to check
6219 * \param theSubMesh given submesh to intersect with other
6220 * \param theCommonSubMeshes collected common submeshes
6222 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6223 const SMESH_subMesh* theSubMesh,
6224 set<const SMESH_subMesh*>& theCommon )
6228 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6229 for ( ; it != theSubMeshList.end(); it++ )
6230 theSubMesh->FindIntersection( *it, theCommon );
6231 theSubMeshList.push_back( theSubMesh );
6232 //theCommon.insert( theSubMesh );
6235 //-----------------------------------------------------------------------------
6236 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6238 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6239 for ( ; listsIt != smLists.end(); ++listsIt )
6241 const TListOfInt& smIDs = *listsIt;
6242 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6250 //=============================================================================
6252 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6254 //=============================================================================
6256 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6258 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6259 if ( isSubMeshInList( submeshID, anOrder ))
6262 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6263 return isSubMeshInList( submeshID, allConurrent );
6266 //=============================================================================
6268 * \brief Return submesh objects list in meshing order
6270 //=============================================================================
6272 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6274 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6276 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6278 return aResult._retn();
6280 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6281 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6282 anOrder.splice( anOrder.end(), allConurrent );
6285 TListOfListOfInt::iterator listIt = anOrder.begin();
6286 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6287 unionLists( *listIt, anOrder, listIndx + 1 );
6289 // convert submesh ids into interface instances
6290 // and dump command into python
6291 convertMeshOrder( anOrder, aResult, false );
6293 return aResult._retn();
6296 //=============================================================================
6298 * \brief Finds concurrent sub-meshes
6300 //=============================================================================
6302 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6304 TListOfListOfInt anOrder;
6305 ::SMESH_Mesh& mesh = GetImpl();
6307 // collect submeshes and detect concurrent algorithms and hypothesises
6308 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6310 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6311 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6312 ::SMESH_subMesh* sm = (*i_sm).second;
6314 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6316 // list of assigned hypothesises
6317 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6318 // Find out dimensions where the submesh can be concurrent.
6319 // We define the dimensions by algo of each of hypotheses in hypList
6320 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6321 for( ; hypIt != hypList.end(); hypIt++ ) {
6322 SMESH_Algo* anAlgo = 0;
6323 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6324 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6325 // hyp it-self is algo
6326 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6328 // try to find algorithm with help of sub-shapes
6329 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6330 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6331 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6334 continue; // no algorithm assigned to a current submesh
6336 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6337 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6339 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6340 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6341 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6343 } // end iterations on submesh
6345 // iterate on created dimension-hypotheses and check for concurrents
6346 for ( int i = 0; i < 4; i++ ) {
6347 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6348 // check for concurrents in own and other dimensions (step-by-step)
6349 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6350 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6351 const SMESH_DimHyp* dimHyp = *dhIt;
6352 TDimHypList listOfConcurr;
6353 set<int> setOfConcurrIds;
6354 // looking for concurrents and collect into own list
6355 for ( int j = i; j < 4; j++ )
6356 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6357 // check if any concurrents found
6358 if ( listOfConcurr.size() > 0 ) {
6359 // add own submesh to list of concurrent
6360 addInOrderOfPriority( dimHyp, listOfConcurr );
6361 list<int> listOfConcurrIds;
6362 TDimHypList::iterator hypIt = listOfConcurr.begin();
6363 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6364 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6365 anOrder.push_back( listOfConcurrIds );
6370 removeDimHyps(dimHypListArr);
6372 // now, minimize the number of concurrent groups
6373 // Here we assume that lists of submeshes can have same submesh
6374 // in case of multi-dimension algorithms, as result
6375 // list with common submesh has to be united into one list
6377 TListOfListOfInt::iterator listIt = anOrder.begin();
6378 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6379 unionLists( *listIt, anOrder, listIndx + 1 );
6385 //=============================================================================
6387 * \brief Set submesh object order
6388 * \param theSubMeshArray submesh array order
6390 //=============================================================================
6392 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6395 _preMeshInfo->ForgetOrLoad();
6398 ::SMESH_Mesh& mesh = GetImpl();
6400 TPythonDump aPythonDump; // prevent dump of called methods
6401 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6403 TListOfListOfInt subMeshOrder;
6404 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6406 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6407 TListOfInt subMeshIds;
6409 aPythonDump << ", ";
6410 aPythonDump << "[ ";
6411 // Collect subMeshes which should be clear
6412 // do it list-by-list, because modification of submesh order
6413 // take effect between concurrent submeshes only
6414 set<const SMESH_subMesh*> subMeshToClear;
6415 list<const SMESH_subMesh*> subMeshList;
6416 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6418 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6420 aPythonDump << ", ";
6421 aPythonDump << subMesh;
6422 subMeshIds.push_back( subMesh->GetId() );
6423 // detect common parts of submeshes
6424 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6425 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6427 aPythonDump << " ]";
6428 subMeshOrder.push_back( subMeshIds );
6430 // clear collected sub-meshes
6431 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6432 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6433 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6435 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6436 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6437 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6440 aPythonDump << " ])";
6442 mesh.SetMeshOrder( subMeshOrder );
6445 SMESH::SMESH_Mesh_var me = _this();
6446 _gen_i->UpdateIcons( me );
6451 //=============================================================================
6453 * \brief Convert submesh ids into submesh interfaces
6455 //=============================================================================
6457 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6458 SMESH::submesh_array_array& theResOrder,
6459 const bool theIsDump)
6461 int nbSet = theIdsOrder.size();
6462 TPythonDump aPythonDump; // prevent dump of called methods
6464 aPythonDump << "[ ";
6465 theResOrder.length(nbSet);
6466 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6468 for( ; it != theIdsOrder.end(); it++ ) {
6469 // translate submesh identificators into submesh objects
6470 // takeing into account real number of concurrent lists
6471 const TListOfInt& aSubOrder = (*it);
6472 if (!aSubOrder.size())
6475 aPythonDump << "[ ";
6476 // convert shape indices into interfaces
6477 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6478 aResSubSet->length(aSubOrder.size());
6479 TListOfInt::const_iterator subIt = aSubOrder.begin();
6481 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6482 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6484 SMESH::SMESH_subMesh_var subMesh =
6485 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6488 aPythonDump << ", ";
6489 aPythonDump << subMesh;
6491 aResSubSet[ j++ ] = subMesh;
6494 aPythonDump << " ]";
6496 theResOrder[ listIndx++ ] = aResSubSet;
6498 // correct number of lists
6499 theResOrder.length( listIndx );
6502 // finilise python dump
6503 aPythonDump << " ]";
6504 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6508 namespace // utils used by SMESH_MeshPartDS
6511 * \brief Class used to access to protected data of SMDS_MeshInfo
6513 struct TMeshInfo : public SMDS_MeshInfo
6515 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6518 * \brief Element holing its ID only
6520 struct TElemID : public SMDS_LinearEdge
6522 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6526 //================================================================================
6528 // Implementation of SMESH_MeshPartDS
6530 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6531 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6533 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6534 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6537 _meshDS = mesh_i->GetImpl().GetMeshDS();
6539 SetPersistentId( _meshDS->GetPersistentId() );
6541 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6543 // <meshPart> is the whole mesh
6544 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6546 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6547 myGroupSet = _meshDS->GetGroups();
6552 SMESH::long_array_var anIDs = meshPart->GetIDs();
6553 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6554 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6556 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6557 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6558 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6563 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6564 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6565 if ( _elements[ e->GetType() ].insert( e ).second )
6568 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6569 while ( nIt->more() )
6571 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6572 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6579 ShapeToMesh( _meshDS->ShapeToMesh() );
6581 _meshDS = 0; // to enforce iteration on _elements and _nodes
6584 // -------------------------------------------------------------------------------------
6585 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6586 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6589 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6590 for ( ; partIt != meshPart.end(); ++partIt )
6591 if ( const SMDS_MeshElement * e = *partIt )
6592 if ( _elements[ e->GetType() ].insert( e ).second )
6595 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6596 while ( nIt->more() )
6598 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6599 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6605 // -------------------------------------------------------------------------------------
6606 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6608 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6610 TElemID elem( IDelem );
6611 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6612 if ( !_elements[ iType ].empty() )
6614 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6615 if ( it != _elements[ iType ].end() )
6620 // -------------------------------------------------------------------------------------
6621 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6623 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6625 typedef SMDS_SetIterator
6626 <const SMDS_MeshElement*,
6627 TIDSortedElemSet::const_iterator,
6628 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6629 SMDS_MeshElement::GeomFilter
6632 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6634 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6635 _elements[type].end(),
6636 SMDS_MeshElement::GeomFilter( geomType )));
6638 // -------------------------------------------------------------------------------------
6639 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6641 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6643 typedef SMDS_SetIterator
6644 <const SMDS_MeshElement*,
6645 TIDSortedElemSet::const_iterator,
6646 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6647 SMDS_MeshElement::EntityFilter
6650 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6652 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6653 _elements[type].end(),
6654 SMDS_MeshElement::EntityFilter( entity )));
6656 // -------------------------------------------------------------------------------------
6657 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6659 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6660 if ( type == SMDSAbs_All && !_meshDS )
6662 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6664 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6665 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6667 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6669 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6670 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6672 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6673 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6675 // -------------------------------------------------------------------------------------
6676 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6677 iterType SMESH_MeshPartDS::methName() const \
6679 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6680 return _meshDS ? _meshDS->methName() : iterType \
6681 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6683 // -------------------------------------------------------------------------------------
6684 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6685 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6686 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6687 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6688 #undef _GET_ITER_DEFINE
6690 // END Implementation of SMESH_MeshPartDS
6692 //================================================================================