1 // Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
101 int SMESH_Mesh_i::_idGenerator = 0;
103 //=============================================================================
107 //=============================================================================
109 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
111 : SALOME::GenericObj_i( thePOA )
115 _id = _idGenerator++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
131 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
132 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
133 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
135 aGroup->UnRegister();
136 SMESH::SMESH_GroupBase_var( itGr->second );
141 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
142 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
143 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
145 aSubMesh->UnRegister();
146 SMESH::SMESH_subMesh_var( itSM->second );
148 _mapSubMeshIor.clear();
150 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
151 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
152 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
153 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
154 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
155 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
158 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
162 // clear cached shapes if no more meshes remain; (the cache is blame,
163 // together with publishing, of spent time increasing in issue 22874)
164 if ( _impl->NbMeshes() == 1 )
165 _gen_i->GetShapeReader()->ClearClientBuffer();
167 delete _editor; _editor = NULL;
168 delete _previewEditor; _previewEditor = NULL;
169 delete _impl; _impl = NULL;
170 delete _preMeshInfo; _preMeshInfo = NULL;
173 //=============================================================================
177 * Associates <this> mesh with <theShape> and puts a reference
178 * to <theShape> into the current study;
179 * the previous shape is substituted by the new one.
181 //=============================================================================
183 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
184 throw (SALOME::SALOME_Exception)
186 Unexpect aCatch(SALOME_SalomeException);
188 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
190 catch(SALOME_Exception & S_ex) {
191 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
193 // to track changes of GEOM groups
194 SMESH::SMESH_Mesh_var mesh = _this();
195 addGeomGroupData( theShapeObject, mesh );
196 if ( !CORBA::is_nil( theShapeObject ))
197 _mainShapeTick = theShapeObject->GetTick();
200 //================================================================================
202 * \brief return true if mesh has a shape to build a shape on
204 //================================================================================
206 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
207 throw (SALOME::SALOME_Exception)
209 Unexpect aCatch(SALOME_SalomeException);
212 res = _impl->HasShapeToMesh();
214 catch(SALOME_Exception & S_ex) {
215 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
220 //=======================================================================
221 //function : GetShapeToMesh
223 //=======================================================================
225 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
226 throw (SALOME::SALOME_Exception)
228 Unexpect aCatch(SALOME_SalomeException);
229 GEOM::GEOM_Object_var aShapeObj;
231 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
234 aShapeObj = _gen_i->ShapeToGeomObject( S );
235 if ( aShapeObj->_is_nil() )
237 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
238 // find GEOM_Object by entry (IPAL52735)
239 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
240 for ( ; data != _geomGroupData.end(); ++data )
241 if ( data->_smeshObject->_is_equivalent( _this() ))
243 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
244 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
245 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
251 catch(SALOME_Exception & S_ex) {
252 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
254 return aShapeObj._retn();
257 //================================================================================
259 * \brief Return false if the mesh is not yet fully loaded from the study file
261 //================================================================================
263 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
265 Unexpect aCatch(SALOME_SalomeException);
266 return !_preMeshInfo;
269 //================================================================================
271 * \brief Load full mesh data from the study file
273 //================================================================================
275 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
277 Unexpect aCatch(SALOME_SalomeException);
279 _preMeshInfo->FullLoadFromFile();
282 //================================================================================
284 * \brief Remove all nodes and elements
286 //================================================================================
288 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
290 Unexpect aCatch(SALOME_SalomeException);
292 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
296 //CheckGeomGroupModif(); // issue 20145
298 catch(SALOME_Exception & S_ex) {
299 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
302 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
304 SMESH::SMESH_Mesh_var mesh = _this();
305 _gen_i->UpdateIcons( mesh );
308 //================================================================================
310 * \brief Remove all nodes and elements for indicated shape
312 //================================================================================
314 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
315 throw (SALOME::SALOME_Exception)
317 Unexpect aCatch(SALOME_SalomeException);
319 _preMeshInfo->FullLoadFromFile();
322 _impl->ClearSubMesh( ShapeID );
324 catch(SALOME_Exception & S_ex) {
325 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
327 _impl->GetMeshDS()->Modified();
329 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
332 //=============================================================================
334 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
336 //=============================================================================
338 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
340 SMESH::DriverMED_ReadStatus res;
343 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
344 res = SMESH::DRS_OK; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
346 res = SMESH::DRS_EMPTY; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
348 res = SMESH::DRS_WARN_RENUMBER; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
350 res = SMESH::DRS_WARN_SKIP_ELEM; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
352 res = SMESH::DRS_WARN_DESCENDING; break;
353 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
355 res = SMESH::DRS_FAIL; break;
360 //=============================================================================
362 * Convert ::SMESH_ComputeError to SMESH::ComputeError
364 //=============================================================================
366 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
368 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
369 errVar->subShapeID = -1;
370 errVar->hasBadMesh = false;
372 if ( !errorPtr || errorPtr->IsOK() )
374 errVar->code = SMESH::COMPERR_OK;
378 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
379 errVar->comment = errorPtr->myComment.c_str();
381 return errVar._retn();
384 //=============================================================================
388 * Imports mesh data from MED file
390 //=============================================================================
392 SMESH::DriverMED_ReadStatus
393 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
394 throw ( SALOME::SALOME_Exception )
396 Unexpect aCatch(SALOME_SalomeException);
399 status = _impl->MEDToMesh( theFileName, theMeshName );
401 catch( SALOME_Exception& S_ex ) {
402 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
405 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
408 CreateGroupServants();
410 int major, minor, release;
411 major = minor = release = 0;
412 MED::GetMEDVersion(theFileName, major, minor, release);
413 _medFileInfo = new SMESH::MedFileInfo();
414 _medFileInfo->fileName = theFileName;
415 _medFileInfo->fileSize = 0;
416 _medFileInfo->major = major;
417 _medFileInfo->minor = minor;
418 _medFileInfo->release = release;
419 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
421 return ConvertDriverMEDReadStatus(status);
424 //================================================================================
426 * \brief Imports mesh data from the CGNS file
428 //================================================================================
430 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
431 const int theMeshIndex,
432 std::string& theMeshName )
433 throw ( SALOME::SALOME_Exception )
435 Unexpect aCatch(SALOME_SalomeException);
438 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
440 catch( SALOME_Exception& S_ex ) {
441 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
444 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
447 CreateGroupServants();
449 _medFileInfo = new SMESH::MedFileInfo();
450 _medFileInfo->fileName = theFileName;
451 _medFileInfo->major = 0;
452 _medFileInfo->minor = 0;
453 _medFileInfo->release = 0;
454 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
456 return ConvertDriverMEDReadStatus(status);
459 //================================================================================
461 * \brief Return string representation of a MED file version comprising nbDigits
463 //================================================================================
465 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
467 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
469 return CORBA::string_dup( ver.c_str() );
472 //================================================================================
474 * Return the list of med versions compatibles for write/append,
475 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
477 //================================================================================
478 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
480 SMESH::long_array_var aResult = new SMESH::long_array();
481 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
482 long nbver = mvok.size();
483 aResult->length( nbver );
484 for ( int i = 0; i < nbver; i++ )
485 aResult[i] = mvok[i];
486 return aResult._retn();
489 //=============================================================================
493 * Imports mesh data from MED file
495 //=============================================================================
497 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
498 throw ( SALOME::SALOME_Exception )
502 // Read mesh with name = <theMeshName> into SMESH_Mesh
503 _impl->UNVToMesh( theFileName );
505 CreateGroupServants();
507 _medFileInfo = new SMESH::MedFileInfo();
508 _medFileInfo->fileName = theFileName;
509 _medFileInfo->major = 0;
510 _medFileInfo->minor = 0;
511 _medFileInfo->release = 0;
512 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
514 SMESH_CATCH( SMESH::throwCorbaException );
519 //=============================================================================
523 * Imports mesh data from STL file
525 //=============================================================================
526 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
527 throw ( SALOME::SALOME_Exception )
531 // Read mesh with name = <theMeshName> into SMESH_Mesh
532 std::string name = _impl->STLToMesh( theFileName );
535 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
536 _gen_i->SetName( meshSO, name.c_str() );
538 _medFileInfo = new SMESH::MedFileInfo();
539 _medFileInfo->fileName = theFileName;
540 _medFileInfo->major = 0;
541 _medFileInfo->minor = 0;
542 _medFileInfo->release = 0;
543 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
545 SMESH_CATCH( SMESH::throwCorbaException );
550 //================================================================================
552 * \brief Function used in SMESH_CATCH by ImportGMFFile()
554 //================================================================================
558 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
560 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
564 //================================================================================
566 * \brief Imports data from a GMF file and returns an error description
568 //================================================================================
570 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
571 bool theMakeRequiredGroups )
572 throw (SALOME::SALOME_Exception)
574 SMESH_ComputeErrorPtr error;
577 #define SMESH_CAUGHT error =
580 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
582 _medFileInfo = new SMESH::MedFileInfo();
583 _medFileInfo->fileName = theFileName;
584 _medFileInfo->major = 0;
585 _medFileInfo->minor = 0;
586 _medFileInfo->release = 0;
587 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
589 SMESH_CATCH( exceptionToComputeError );
593 CreateGroupServants();
595 return ConvertComputeError( error );
598 //=============================================================================
602 //=============================================================================
604 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
606 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
607 (SMESH_Hypothesis::Hypothesis_Status theStatus)
610 RETURNCASE( HYP_OK );
611 RETURNCASE( HYP_MISSING );
612 RETURNCASE( HYP_CONCURRENT );
613 RETURNCASE( HYP_BAD_PARAMETER );
614 RETURNCASE( HYP_HIDDEN_ALGO );
615 RETURNCASE( HYP_HIDING_ALGO );
616 RETURNCASE( HYP_UNKNOWN_FATAL );
617 RETURNCASE( HYP_INCOMPATIBLE );
618 RETURNCASE( HYP_NOTCONFORM );
619 RETURNCASE( HYP_ALREADY_EXIST );
620 RETURNCASE( HYP_BAD_DIM );
621 RETURNCASE( HYP_BAD_SUBSHAPE );
622 RETURNCASE( HYP_BAD_GEOMETRY );
623 RETURNCASE( HYP_NEED_SHAPE );
624 RETURNCASE( HYP_INCOMPAT_HYPS );
627 return SMESH::HYP_UNKNOWN_FATAL;
630 //=============================================================================
634 * calls internal addHypothesis() and then adds a reference to <anHyp> under
635 * the SObject actually having a reference to <aSubShape>.
636 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
638 //=============================================================================
640 SMESH::Hypothesis_Status
641 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
642 SMESH::SMESH_Hypothesis_ptr anHyp,
643 CORBA::String_out anErrorText)
644 throw(SALOME::SALOME_Exception)
646 Unexpect aCatch(SALOME_SalomeException);
648 _preMeshInfo->ForgetOrLoad();
651 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
652 anErrorText = error.c_str();
654 SMESH::SMESH_Mesh_var mesh( _this() );
655 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
657 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
658 _gen_i->UpdateIcons( mesh );
660 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
662 // Update Python script
663 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
664 << aSubShape << ", " << anHyp << " )";
666 return ConvertHypothesisStatus(status);
669 //=============================================================================
673 //=============================================================================
675 SMESH_Hypothesis::Hypothesis_Status
676 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
677 SMESH::SMESH_Hypothesis_ptr anHyp,
678 std::string* anErrorText)
680 if(MYDEBUG) MESSAGE("addHypothesis");
682 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
683 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
685 if (CORBA::is_nil( anHyp ))
686 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
688 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
691 TopoDS_Shape myLocSubShape;
692 //use PseudoShape in case if mesh has no shape
694 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
696 myLocSubShape = _impl->GetShapeToMesh();
698 const int hypId = anHyp->GetId();
700 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
701 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
703 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
705 // assure there is a corresponding submesh
706 if ( !_impl->IsMainShape( myLocSubShape )) {
707 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
708 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
709 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
712 else if ( anErrorText )
714 *anErrorText = error;
717 catch(SALOME_Exception & S_ex)
719 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
724 //=============================================================================
728 //=============================================================================
730 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
731 SMESH::SMESH_Hypothesis_ptr anHyp)
732 throw(SALOME::SALOME_Exception)
734 Unexpect aCatch(SALOME_SalomeException);
736 _preMeshInfo->ForgetOrLoad();
738 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
739 SMESH::SMESH_Mesh_var mesh = _this();
741 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
743 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
744 _gen_i->UpdateIcons( mesh );
746 // Update Python script
747 if(_impl->HasShapeToMesh())
748 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
749 << aSubShape << ", " << anHyp << " )";
751 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
754 return ConvertHypothesisStatus(status);
757 //=============================================================================
761 //=============================================================================
763 SMESH_Hypothesis::Hypothesis_Status
764 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
765 SMESH::SMESH_Hypothesis_ptr anHyp)
767 if(MYDEBUG) MESSAGE("removeHypothesis()");
769 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
770 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
772 if (CORBA::is_nil( anHyp ))
773 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
776 _preMeshInfo->ForgetOrLoad();
778 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
781 TopoDS_Shape myLocSubShape;
782 //use PseudoShape in case if mesh has no shape
783 if( _impl->HasShapeToMesh() )
784 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
786 myLocSubShape = _impl->GetShapeToMesh();
788 const int hypId = anHyp->GetId();
789 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
790 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
792 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
796 catch(SALOME_Exception & S_ex)
798 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
803 //=============================================================================
807 //=============================================================================
809 SMESH::ListOfHypothesis *
810 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
811 throw(SALOME::SALOME_Exception)
813 Unexpect aCatch(SALOME_SalomeException);
814 if (MYDEBUG) MESSAGE("GetHypothesisList");
815 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
816 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
818 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
821 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
822 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
823 myLocSubShape = _impl->GetShapeToMesh();
824 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
825 int i = 0, n = aLocalList.size();
828 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
829 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
830 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
832 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
833 if ( id_hypptr != _mapHypo.end() )
834 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
838 catch(SALOME_Exception & S_ex) {
839 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
842 return aList._retn();
845 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
847 Unexpect aCatch(SALOME_SalomeException);
848 if (MYDEBUG) MESSAGE("GetSubMeshes");
850 SMESH::submesh_array_var aList = new SMESH::submesh_array();
853 TPythonDump aPythonDump;
854 if ( !_mapSubMeshIor.empty() )
858 aList->length( _mapSubMeshIor.size() );
860 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
861 for ( ; it != _mapSubMeshIor.end(); it++ ) {
862 if ( CORBA::is_nil( it->second )) continue;
863 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
865 if (i > 1) aPythonDump << ", ";
866 aPythonDump << it->second;
870 catch(SALOME_Exception & S_ex) {
871 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
874 // Update Python script
875 if ( !_mapSubMeshIor.empty() )
876 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
878 return aList._retn();
881 //=============================================================================
885 //=============================================================================
887 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
888 const char* theName )
889 throw(SALOME::SALOME_Exception)
891 Unexpect aCatch(SALOME_SalomeException);
892 if (CORBA::is_nil(aSubShape))
893 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
895 SMESH::SMESH_subMesh_var subMesh;
896 SMESH::SMESH_Mesh_var aMesh = _this();
898 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
900 //Get or Create the SMESH_subMesh object implementation
902 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
904 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
906 TopoDS_Iterator it( myLocSubShape );
908 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
910 subMesh = getSubMesh( subMeshId );
912 // create a new subMesh object servant if there is none for the shape
913 if ( subMesh->_is_nil() )
914 subMesh = createSubMesh( aSubShape );
915 if ( _gen_i->CanPublishInStudy( subMesh ))
917 SALOMEDS::SObject_wrap aSO =
918 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
919 if ( !aSO->_is_nil()) {
920 // Update Python script
921 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
922 << aSubShape << ", '" << theName << "' )";
926 catch(SALOME_Exception & S_ex) {
927 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
929 return subMesh._retn();
932 //=============================================================================
936 //=============================================================================
938 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
939 throw (SALOME::SALOME_Exception)
943 if ( theSubMesh->_is_nil() )
946 GEOM::GEOM_Object_var aSubShape;
947 // Remove submesh's SObject
948 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
949 if ( !anSO->_is_nil() ) {
950 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
951 SALOMEDS::SObject_wrap anObj, aRef;
952 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
953 anObj->ReferencedObject( aRef.inout() ))
955 CORBA::Object_var obj = aRef->GetObject();
956 aSubShape = GEOM::GEOM_Object::_narrow( obj );
958 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
959 // aSubShape = theSubMesh->GetSubShape();
961 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
962 builder->RemoveObjectWithChildren( anSO );
964 // Update Python script
965 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
968 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
970 _preMeshInfo->ForgetOrLoad();
972 SMESH_CATCH( SMESH::throwCorbaException );
975 //=============================================================================
979 //=============================================================================
981 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
982 const char* theName )
983 throw(SALOME::SALOME_Exception)
985 Unexpect aCatch(SALOME_SalomeException);
987 _preMeshInfo->FullLoadFromFile();
989 SMESH::SMESH_Group_var aNewGroup =
990 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
992 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
994 SMESH::SMESH_Mesh_var mesh = _this();
995 SALOMEDS::SObject_wrap aSO =
996 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
997 if ( !aSO->_is_nil())
998 // Update Python script
999 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1000 << theElemType << ", '" << theName << "' )";
1002 return aNewGroup._retn();
1005 //=============================================================================
1009 //=============================================================================
1010 SMESH::SMESH_GroupOnGeom_ptr
1011 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1012 const char* theName,
1013 GEOM::GEOM_Object_ptr theGeomObj)
1014 throw(SALOME::SALOME_Exception)
1016 Unexpect aCatch(SALOME_SalomeException);
1018 _preMeshInfo->FullLoadFromFile();
1020 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1022 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1023 if ( !aShape.IsNull() )
1026 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1028 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1030 SMESH::SMESH_Mesh_var mesh = _this();
1031 SALOMEDS::SObject_wrap aSO =
1032 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1033 if ( !aSO->_is_nil())
1034 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1035 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1039 return aNewGroup._retn();
1042 //================================================================================
1044 * \brief Creates a group whose contents is defined by filter
1045 * \param theElemType - group type
1046 * \param theName - group name
1047 * \param theFilter - the filter
1048 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1050 //================================================================================
1052 SMESH::SMESH_GroupOnFilter_ptr
1053 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1054 const char* theName,
1055 SMESH::Filter_ptr theFilter )
1056 throw (SALOME::SALOME_Exception)
1058 Unexpect aCatch(SALOME_SalomeException);
1060 _preMeshInfo->FullLoadFromFile();
1062 if ( CORBA::is_nil( theFilter ))
1063 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1065 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1067 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1069 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1070 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1073 if ( !aNewGroup->_is_nil() )
1074 aNewGroup->SetFilter( theFilter );
1076 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1078 SMESH::SMESH_Mesh_var mesh = _this();
1079 SALOMEDS::SObject_wrap aSO =
1080 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1082 if ( !aSO->_is_nil())
1083 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1084 << theElemType << ", '" << theName << "', " << theFilter << " )";
1086 return aNewGroup._retn();
1089 //=============================================================================
1093 //=============================================================================
1095 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1096 throw (SALOME::SALOME_Exception)
1098 if ( theGroup->_is_nil() )
1103 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1107 if ( aGroup->GetMeshServant() != this )
1108 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1109 SALOME::BAD_PARAM );
1111 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1112 if ( !aGroupSO->_is_nil() )
1114 // Update Python script
1115 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1117 // Remove group's SObject
1118 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1119 builder->RemoveObjectWithChildren( aGroupSO );
1121 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1123 // Remove the group from SMESH data structures
1124 removeGroup( aGroup->GetLocalID() );
1126 SMESH_CATCH( SMESH::throwCorbaException );
1129 //=============================================================================
1131 * Remove group with its contents
1133 //=============================================================================
1135 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1136 throw (SALOME::SALOME_Exception)
1140 _preMeshInfo->FullLoadFromFile();
1142 if ( theGroup->_is_nil() )
1145 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1146 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1147 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1150 vector<int> nodeIds; // to remove nodes becoming free
1151 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1152 if ( !isNodal && !theGroup->IsEmpty() )
1154 CORBA::Long elemID = theGroup->GetID( 1 );
1155 int nbElemNodes = GetElemNbNodes( elemID );
1156 if ( nbElemNodes > 0 )
1157 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1160 // Retrieve contents
1161 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1162 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1163 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1164 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1165 elems.assign( elemBeg, elemEnd );
1167 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1170 RemoveGroup( theGroup );
1173 for ( size_t i = 0; i < elems.size(); ++i )
1175 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1179 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1180 nodeIds.push_back( nIt->next()->GetID() );
1182 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1186 _impl->GetMeshDS()->RemoveElement( elems[i] );
1190 // Remove free nodes
1191 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1192 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1193 if ( n->NbInverseElements() == 0 )
1194 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1196 // Update Python script (theGroup must be alive for this)
1197 pyDump << SMESH::SMESH_Mesh_var(_this())
1198 << ".RemoveGroupWithContents( " << theGroup << " )";
1200 SMESH_CATCH( SMESH::throwCorbaException );
1203 //================================================================================
1205 * \brief Get the list of groups existing in the mesh
1206 * \retval SMESH::ListOfGroups * - list of groups
1208 //================================================================================
1210 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1212 Unexpect aCatch(SALOME_SalomeException);
1213 if (MYDEBUG) MESSAGE("GetGroups");
1215 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1218 TPythonDump aPythonDump;
1219 if ( !_mapGroups.empty() )
1221 aPythonDump << "[ ";
1223 aList->length( _mapGroups.size() );
1225 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1226 for ( ; it != _mapGroups.end(); it++ ) {
1227 if ( CORBA::is_nil( it->second )) continue;
1228 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1230 if (i > 1) aPythonDump << ", ";
1231 aPythonDump << it->second;
1235 catch(SALOME_Exception & S_ex) {
1236 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1238 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1240 return aList._retn();
1243 //=============================================================================
1245 * Get number of groups existing in the mesh
1247 //=============================================================================
1249 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1251 Unexpect aCatch(SALOME_SalomeException);
1252 return _mapGroups.size();
1255 //=============================================================================
1257 * New group including all mesh elements present in initial groups is created.
1259 //=============================================================================
1261 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1262 SMESH::SMESH_GroupBase_ptr theGroup2,
1263 const char* theName )
1264 throw (SALOME::SALOME_Exception)
1266 SMESH::SMESH_Group_var aResGrp;
1270 _preMeshInfo->FullLoadFromFile();
1272 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1273 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1275 if ( theGroup1->GetType() != theGroup2->GetType() )
1276 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1281 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1282 if ( aResGrp->_is_nil() )
1283 return SMESH::SMESH_Group::_nil();
1285 aResGrp->AddFrom( theGroup1 );
1286 aResGrp->AddFrom( theGroup2 );
1288 // Update Python script
1289 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1290 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1292 SMESH_CATCH( SMESH::throwCorbaException );
1294 return aResGrp._retn();
1297 //=============================================================================
1299 * \brief New group including all mesh elements present in initial groups is created.
1300 * \param theGroups list of groups
1301 * \param theName name of group to be created
1302 * \return pointer to the new group
1304 //=============================================================================
1306 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1307 const char* theName )
1308 throw (SALOME::SALOME_Exception)
1310 SMESH::SMESH_Group_var aResGrp;
1313 _preMeshInfo->FullLoadFromFile();
1316 return SMESH::SMESH_Group::_nil();
1321 SMESH::ElementType aType = SMESH::ALL;
1322 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1324 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1325 if ( CORBA::is_nil( aGrp ) )
1327 if ( aType == SMESH::ALL )
1328 aType = aGrp->GetType();
1329 else if ( aType != aGrp->GetType() )
1330 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1333 if ( aType == SMESH::ALL )
1334 return SMESH::SMESH_Group::_nil();
1339 aResGrp = CreateGroup( aType, theName );
1340 if ( aResGrp->_is_nil() )
1341 return SMESH::SMESH_Group::_nil();
1343 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1344 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1346 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1347 if ( !CORBA::is_nil( aGrp ) )
1349 aResGrp->AddFrom( aGrp );
1350 if ( g > 0 ) pyDump << ", ";
1354 pyDump << " ], '" << theName << "' )";
1356 SMESH_CATCH( SMESH::throwCorbaException );
1358 return aResGrp._retn();
1361 //=============================================================================
1363 * New group is created. All mesh elements that are
1364 * present in both initial groups are added to the new one.
1366 //=============================================================================
1368 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1369 SMESH::SMESH_GroupBase_ptr theGroup2,
1370 const char* theName )
1371 throw (SALOME::SALOME_Exception)
1373 SMESH::SMESH_Group_var aResGrp;
1378 _preMeshInfo->FullLoadFromFile();
1380 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1381 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1383 if ( theGroup1->GetType() != theGroup2->GetType() )
1384 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1388 // Create Intersection
1389 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1390 if ( aResGrp->_is_nil() )
1391 return aResGrp._retn();
1393 SMESHDS_GroupBase* groupDS1 = 0;
1394 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1395 groupDS1 = grp_i->GetGroupDS();
1397 SMESHDS_GroupBase* groupDS2 = 0;
1398 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1399 groupDS2 = grp_i->GetGroupDS();
1401 SMESHDS_Group* resGroupDS = 0;
1402 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1403 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1405 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1407 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1408 while ( elemIt1->more() )
1410 const SMDS_MeshElement* e = elemIt1->next();
1411 if ( groupDS2->Contains( e ))
1412 resGroupDS->SMDSGroup().Add( e );
1415 // Update Python script
1416 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1417 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1419 SMESH_CATCH( SMESH::throwCorbaException );
1421 return aResGrp._retn();
1424 //=============================================================================
1426 \brief Intersect list of groups. New group is created. All mesh elements that
1427 are present in all initial groups simultaneously are added to the new one.
1428 \param theGroups list of groups
1429 \param theName name of group to be created
1430 \return pointer on the group
1432 //=============================================================================
1433 SMESH::SMESH_Group_ptr
1434 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1435 const char* theName )
1436 throw (SALOME::SALOME_Exception)
1438 SMESH::SMESH_Group_var aResGrp;
1443 _preMeshInfo->FullLoadFromFile();
1446 return SMESH::SMESH_Group::_nil();
1448 // check types and get SMESHDS_GroupBase's
1449 SMESH::ElementType aType = SMESH::ALL;
1450 vector< SMESHDS_GroupBase* > groupVec;
1451 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1453 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1454 if ( CORBA::is_nil( aGrp ) )
1456 if ( aType == SMESH::ALL )
1457 aType = aGrp->GetType();
1458 else if ( aType != aGrp->GetType() )
1459 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1462 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1463 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1465 if ( grpDS->IsEmpty() )
1470 groupVec.push_back( grpDS );
1473 if ( aType == SMESH::ALL ) // all groups are nil
1474 return SMESH::SMESH_Group::_nil();
1479 aResGrp = CreateGroup( aType, theName );
1481 SMESHDS_Group* resGroupDS = 0;
1482 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1483 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1484 if ( !resGroupDS || groupVec.empty() )
1485 return aResGrp._retn();
1488 size_t i, nb = groupVec.size();
1489 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1490 while ( elemIt1->more() )
1492 const SMDS_MeshElement* e = elemIt1->next();
1494 for ( i = 1; ( i < nb && inAll ); ++i )
1495 inAll = groupVec[i]->Contains( e );
1498 resGroupDS->SMDSGroup().Add( e );
1501 // Update Python script
1502 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1503 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1505 SMESH_CATCH( SMESH::throwCorbaException );
1507 return aResGrp._retn();
1510 //=============================================================================
1512 * New group is created. All mesh elements that are present in
1513 * a main group but is not present in a tool group are added to the new one
1515 //=============================================================================
1517 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1518 SMESH::SMESH_GroupBase_ptr theGroup2,
1519 const char* theName )
1520 throw (SALOME::SALOME_Exception)
1522 SMESH::SMESH_Group_var aResGrp;
1527 _preMeshInfo->FullLoadFromFile();
1529 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1530 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1532 if ( theGroup1->GetType() != theGroup2->GetType() )
1533 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1537 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1538 if ( aResGrp->_is_nil() )
1539 return aResGrp._retn();
1541 SMESHDS_GroupBase* groupDS1 = 0;
1542 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1543 groupDS1 = grp_i->GetGroupDS();
1545 SMESHDS_GroupBase* groupDS2 = 0;
1546 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1547 groupDS2 = grp_i->GetGroupDS();
1549 SMESHDS_Group* resGroupDS = 0;
1550 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1551 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1553 if ( groupDS1 && groupDS2 && resGroupDS )
1555 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1556 while ( elemIt1->more() )
1558 const SMDS_MeshElement* e = elemIt1->next();
1559 if ( !groupDS2->Contains( e ))
1560 resGroupDS->SMDSGroup().Add( e );
1563 // Update Python script
1564 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1565 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1567 SMESH_CATCH( SMESH::throwCorbaException );
1569 return aResGrp._retn();
1572 //=============================================================================
1574 \brief Cut lists of groups. New group is created. All mesh elements that are
1575 present in main groups but do not present in tool groups are added to the new one
1576 \param theMainGroups list of main groups
1577 \param theToolGroups list of tool groups
1578 \param theName name of group to be created
1579 \return pointer on the group
1581 //=============================================================================
1582 SMESH::SMESH_Group_ptr
1583 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1584 const SMESH::ListOfGroups& theToolGroups,
1585 const char* theName )
1586 throw (SALOME::SALOME_Exception)
1588 SMESH::SMESH_Group_var aResGrp;
1593 _preMeshInfo->FullLoadFromFile();
1596 return SMESH::SMESH_Group::_nil();
1598 // check types and get SMESHDS_GroupBase's
1599 SMESH::ElementType aType = SMESH::ALL;
1600 vector< SMESHDS_GroupBase* > toolGroupVec;
1601 vector< SMDS_ElemIteratorPtr > mainIterVec;
1603 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1605 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1606 if ( CORBA::is_nil( aGrp ) )
1608 if ( aType == SMESH::ALL )
1609 aType = aGrp->GetType();
1610 else if ( aType != aGrp->GetType() )
1611 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1613 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1614 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1615 if ( !grpDS->IsEmpty() )
1616 mainIterVec.push_back( grpDS->GetElements() );
1618 if ( aType == SMESH::ALL ) // all main groups are nil
1619 return SMESH::SMESH_Group::_nil();
1620 if ( mainIterVec.empty() ) // all main groups are empty
1621 return aResGrp._retn();
1623 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1625 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1626 if ( CORBA::is_nil( aGrp ) )
1628 if ( aType != aGrp->GetType() )
1629 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1631 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1632 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1633 toolGroupVec.push_back( grpDS );
1639 aResGrp = CreateGroup( aType, theName );
1641 SMESHDS_Group* resGroupDS = 0;
1642 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1643 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1645 return aResGrp._retn();
1648 size_t i, nb = toolGroupVec.size();
1649 SMDS_ElemIteratorPtr mainElemIt
1650 ( new SMDS_IteratorOnIterators
1651 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1652 while ( mainElemIt->more() )
1654 const SMDS_MeshElement* e = mainElemIt->next();
1656 for ( i = 0; ( i < nb && !isIn ); ++i )
1657 isIn = toolGroupVec[i]->Contains( e );
1660 resGroupDS->SMDSGroup().Add( e );
1663 // Update Python script
1664 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1665 << ".CutListOfGroups( " << theMainGroups << ", "
1666 << theToolGroups << ", '" << theName << "' )";
1668 SMESH_CATCH( SMESH::throwCorbaException );
1670 return aResGrp._retn();
1673 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1675 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1676 bool & toStopChecking )
1678 toStopChecking = ( nbCommon < nbChecked );
1679 return nbCommon == nbNodes;
1681 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1682 bool & toStopChecking )
1684 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1685 return nbCommon == nbCorners;
1687 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1688 bool & toStopChecking )
1690 return nbCommon > 0;
1692 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1693 bool & toStopChecking )
1695 return nbCommon >= (nbNodes+1) / 2;
1699 //=============================================================================
1701 * Create a group of entities basing on nodes of other groups.
1702 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1703 * \param [in] anElemType - a type of elements to include to the new group.
1704 * \param [in] theName - a name of the new group.
1705 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1706 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1707 * new group provided that it is based on nodes of an element of \a aListOfGroups
1708 * \return SMESH_Group - the created group
1710 // IMP 19939, bug 22010, IMP 22635
1711 //=============================================================================
1713 SMESH::SMESH_Group_ptr
1714 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1715 SMESH::ElementType theElemType,
1716 const char* theName,
1717 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1718 CORBA::Boolean theUnderlyingOnly)
1719 throw (SALOME::SALOME_Exception)
1721 SMESH::SMESH_Group_var aResGrp;
1725 _preMeshInfo->FullLoadFromFile();
1727 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1729 if ( !theName || !aMeshDS )
1730 return SMESH::SMESH_Group::_nil();
1732 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1734 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1735 SMESH_Comment nbCoNoStr( "SMESH.");
1736 switch ( theNbCommonNodes ) {
1737 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1738 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1739 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1740 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1741 default: return aResGrp._retn();
1743 int nbChecked, nbCommon, nbNodes, nbCorners;
1749 aResGrp = CreateGroup( theElemType, theName );
1750 if ( aResGrp->_is_nil() )
1751 return SMESH::SMESH_Group::_nil();
1753 SMESHDS_GroupBase* groupBaseDS =
1754 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1755 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1757 vector<bool> isNodeInGroups;
1759 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1761 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1762 if ( CORBA::is_nil( aGrp ) )
1764 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1765 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1768 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1769 if ( !elIt ) continue;
1771 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1773 while ( elIt->more() ) {
1774 const SMDS_MeshElement* el = elIt->next();
1775 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1776 while ( nIt->more() )
1777 resGroupCore.Add( nIt->next() );
1780 // get elements of theElemType based on nodes of every element of group
1781 else if ( theUnderlyingOnly )
1783 while ( elIt->more() )
1785 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1786 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1787 TIDSortedElemSet checkedElems;
1788 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1789 while ( nIt->more() )
1791 const SMDS_MeshNode* n = nIt->next();
1792 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1793 // check nodes of elements of theElemType around el
1794 while ( elOfTypeIt->more() )
1796 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1797 if ( !checkedElems.insert( elOfType ).second ) continue;
1798 nbNodes = elOfType->NbNodes();
1799 nbCorners = elOfType->NbCornerNodes();
1801 bool toStopChecking = false;
1802 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1803 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1804 if ( elNodes.count( nIt2->next() ) &&
1805 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1807 resGroupCore.Add( elOfType );
1814 // get all nodes of elements of groups
1817 while ( elIt->more() )
1819 const SMDS_MeshElement* el = elIt->next(); // an element of group
1820 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1821 while ( nIt->more() )
1823 const SMDS_MeshNode* n = nIt->next();
1824 if ( n->GetID() >= (int) isNodeInGroups.size() )
1825 isNodeInGroups.resize( n->GetID() + 1, false );
1826 isNodeInGroups[ n->GetID() ] = true;
1832 // Get elements of theElemType based on a certain number of nodes of elements of groups
1833 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1835 const SMDS_MeshNode* n;
1836 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1837 const int isNodeInGroupsSize = isNodeInGroups.size();
1838 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1840 if ( !isNodeInGroups[ iN ] ||
1841 !( n = aMeshDS->FindNode( iN )))
1844 // check nodes of elements of theElemType around n
1845 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1846 while ( elOfTypeIt->more() )
1848 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1849 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1854 nbNodes = elOfType->NbNodes();
1855 nbCorners = elOfType->NbCornerNodes();
1857 bool toStopChecking = false;
1858 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1859 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1861 const int nID = nIt->next()->GetID();
1862 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1863 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1865 resGroupCore.Add( elOfType );
1873 // Update Python script
1874 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1875 << ".CreateDimGroup( "
1876 << theGroups << ", " << theElemType << ", '" << theName << "', "
1877 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1879 SMESH_CATCH( SMESH::throwCorbaException );
1881 return aResGrp._retn();
1884 //================================================================================
1886 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1887 * existing 1D elements as group boundaries.
1888 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1889 * adjacent faces is more than \a sharpAngle in degrees.
1890 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1891 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1892 * \return ListOfGroups - the created groups
1894 //================================================================================
1896 SMESH::ListOfGroups*
1897 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1898 CORBA::Boolean theCreateEdges,
1899 CORBA::Boolean theUseExistingEdges )
1900 throw (SALOME::SALOME_Exception)
1902 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1903 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1906 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1912 _preMeshInfo->FullLoadFromFile();
1914 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1916 std::vector< SMESH_MeshAlgos::Edge > edges =
1917 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1919 if ( theCreateEdges )
1921 std::vector<const SMDS_MeshNode *> nodes(2);
1922 for ( size_t i = 0; i < edges.size(); ++i )
1924 nodes[0] = edges[i]._node1;
1925 nodes[1] = edges[i]._node2;
1926 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1928 if ( edges[i]._medium )
1929 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1931 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1935 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1936 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1938 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1940 resultGroups->length( faceGroups.size() );
1941 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1943 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1944 _editor->GenerateGroupName("Group").c_str());
1945 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1947 SMESHDS_GroupBase* groupBaseDS =
1948 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1949 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1951 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1952 for ( size_t i = 0; i < faces.size(); ++i )
1953 groupCore.Add( faces[i] );
1956 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1957 << ".FaceGroupsSeparatedByEdges( "
1958 << TVar( theSharpAngle ) << ", "
1959 << theCreateEdges << ", "
1960 << theUseExistingEdges << " )";
1962 SMESH_CATCH( SMESH::throwCorbaException );
1963 return resultGroups._retn();
1967 //================================================================================
1969 * \brief Remember GEOM group data
1971 //================================================================================
1973 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1974 CORBA::Object_ptr theSmeshObj)
1976 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1979 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1980 if ( groupSO->_is_nil() )
1983 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
1984 GEOM::GEOM_IGroupOperations_wrap groupOp =
1985 geomGen->GetIGroupOperations();
1986 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1989 _geomGroupData.push_back( TGeomGroupData() );
1990 TGeomGroupData & groupData = _geomGroupData.back();
1992 CORBA::String_var entry = groupSO->GetID();
1993 groupData._groupEntry = entry.in();
1995 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1996 groupData._indices.insert( ids[i] );
1998 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1999 // shape index in SMESHDS
2000 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2001 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2004 //================================================================================
2006 * Remove GEOM group data relating to removed smesh object
2008 //================================================================================
2010 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2012 list<TGeomGroupData>::iterator
2013 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2014 for ( ; data != dataEnd; ++data ) {
2015 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2016 _geomGroupData.erase( data );
2022 //================================================================================
2024 * \brief Return new group contents if it has been changed and update group data
2026 //================================================================================
2028 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
2030 TopoDS_Shape newShape;
2033 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2034 if ( !groupSO->_is_nil() )
2036 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2037 if ( CORBA::is_nil( groupObj )) return newShape;
2038 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2040 // get indices of group items
2041 set<int> curIndices;
2042 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2043 GEOM::GEOM_IGroupOperations_wrap groupOp =
2044 geomGen->GetIGroupOperations();
2045 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2046 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2047 curIndices.insert( ids[i] );
2049 if ( groupData._indices == curIndices )
2050 return newShape; // group not changed
2053 groupData._indices = curIndices;
2055 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2056 if ( !geomClient ) return newShape;
2057 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2058 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2059 newShape = _gen_i->GeomObjectToShape( geomGroup );
2062 if ( newShape.IsNull() ) {
2063 // geom group becomes empty - return empty compound
2064 TopoDS_Compound compound;
2065 BRep_Builder().MakeCompound(compound);
2066 newShape = compound;
2073 //-----------------------------------------------------------------------------
2075 * \brief Storage of shape and index used in CheckGeomGroupModif()
2077 struct TIndexedShape
2080 TopoDS_Shape _shape;
2081 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2083 //-----------------------------------------------------------------------------
2085 * \brief Data to re-create a group on geometry
2087 struct TGroupOnGeomData
2090 TopoDS_Shape _shape;
2091 SMDSAbs_ElementType _type;
2093 Quantity_Color _color;
2095 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2097 _oldID = group->GetID();
2098 _type = group->GetType();
2099 _name = group->GetStoreName();
2100 _color = group->GetColor();
2104 //-----------------------------------------------------------------------------
2106 * \brief Check if a filter is still valid after geometry removal
2108 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2110 if ( theFilter->_is_nil() )
2112 SMESH::Filter::Criteria_var criteria;
2113 theFilter->GetCriteria( criteria.out() );
2115 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2117 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2119 switch ( criteria[ iCr ].Type )
2121 case SMESH::FT_BelongToGeom:
2122 case SMESH::FT_BelongToPlane:
2123 case SMESH::FT_BelongToCylinder:
2124 case SMESH::FT_BelongToGenSurface:
2125 case SMESH::FT_LyingOnGeom:
2126 entry = thresholdID;
2128 case SMESH::FT_ConnectedElements:
2131 entry = thresholdID;
2137 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2138 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2139 if ( so->_is_nil() )
2141 CORBA::Object_var obj = so->GetObject();
2142 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2143 if ( gen->GeomObjectToShape( geom ).IsNull() )
2146 } // loop on criteria
2152 //=============================================================================
2154 * \brief Update data if geometry changes
2158 //=============================================================================
2160 void SMESH_Mesh_i::CheckGeomModif()
2162 SMESH::SMESH_Mesh_var me = _this();
2163 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2165 //bool removedFromClient = false;
2167 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2169 //removedFromClient = _impl->HasShapeToMesh();
2171 // try to find geometry by study reference
2172 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2173 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2174 if ( !meshSO->_is_nil() &&
2175 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2176 geomRefSO->ReferencedObject( geomSO.inout() ))
2178 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2179 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2182 if ( mainGO->_is_nil() && // geometry removed ==>
2183 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2185 // convert geom dependent groups into standalone ones
2186 CheckGeomGroupModif();
2188 _impl->ShapeToMesh( TopoDS_Shape() );
2190 // remove sub-meshes
2191 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2192 while ( i_sm != _mapSubMeshIor.end() )
2194 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2196 RemoveSubMesh( sm );
2198 // remove all children except groups in the study
2199 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2200 SALOMEDS::SObject_wrap so;
2201 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2202 if ( meshSO->FindSubObject( tag, so.inout() ))
2203 builder->RemoveObjectWithChildren( so );
2205 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2211 if ( !_impl->HasShapeToMesh() ) return;
2214 // Update after group modification
2216 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2217 mainGO->GetTick() == _mainShapeTick )
2219 int nb = NbNodes() + NbElements();
2220 CheckGeomGroupModif();
2221 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2222 _gen_i->UpdateIcons( me );
2226 // Update after shape transformation like Translate
2228 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2229 if ( !geomClient ) return;
2230 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2231 if ( geomGen->_is_nil() ) return;
2233 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2234 geomClient->RemoveShapeFromBuffer( ior.in() );
2236 // Update data taking into account that
2237 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2240 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2241 if ( newShape.IsNull() )
2244 // for the SHAPER-STUDY: the geometry may be updated, so, add a warning icon
2245 if (_mainShapeTick != mainGO->GetTick()) {
2246 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2247 if ( !meshSO->_is_nil())
2248 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_MESH_WARN");
2251 _mainShapeTick = mainGO->GetTick();
2253 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2255 // store data of groups on geometry
2256 std::vector< TGroupOnGeomData > groupsData;
2257 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2258 groupsData.reserve( groups.size() );
2259 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2260 for ( ; g != groups.end(); ++g )
2262 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2264 groupsData.push_back( TGroupOnGeomData( group ));
2267 SMESH::SMESH_GroupOnGeom_var gog;
2268 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2269 if ( i_grp != _mapGroups.end() )
2270 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2272 GEOM::GEOM_Object_var geom;
2273 if ( !gog->_is_nil() )
2274 geom = gog->GetShape();
2275 if ( !geom->_is_nil() )
2277 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2278 geomClient->RemoveShapeFromBuffer( ior.in() );
2279 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2283 // store assigned hypotheses
2284 std::vector< pair< int, THypList > > ids2Hyps;
2285 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2286 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2288 const TopoDS_Shape& s = s2hyps.Key();
2289 const THypList& hyps = s2hyps.ChangeValue();
2290 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2293 // change shape to mesh
2294 int oldNbSubShapes = meshDS->MaxShapeIndex();
2295 _impl->ShapeToMesh( TopoDS_Shape() );
2296 _impl->ShapeToMesh( newShape );
2298 // re-add shapes of geom groups
2299 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2300 for ( ; data != _geomGroupData.end(); ++data )
2302 TopoDS_Shape newShape = newGroupShape( *data );
2303 if ( !newShape.IsNull() )
2305 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2307 TopoDS_Compound compound;
2308 BRep_Builder().MakeCompound( compound );
2309 BRep_Builder().Add( compound, newShape );
2310 newShape = compound;
2312 _impl->GetSubMesh( newShape );
2315 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2316 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2317 SALOME::INTERNAL_ERROR );
2319 // re-assign hypotheses
2320 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2322 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2323 const THypList& hyps = ids2Hyps[i].second;
2324 THypList::const_iterator h = hyps.begin();
2325 for ( ; h != hyps.end(); ++h )
2326 _impl->AddHypothesis( s, (*h)->GetID() );
2329 // restore groups on geometry
2330 for ( size_t i = 0; i < groupsData.size(); ++i )
2332 const TGroupOnGeomData& data = groupsData[i];
2333 if ( data._shape.IsNull() )
2336 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2337 if ( i2g == _mapGroups.end() ) continue;
2339 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2340 if ( !gr_i ) continue;
2342 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2344 _mapGroups.erase( i2g );
2346 g->GetGroupDS()->SetColor( data._color );
2349 // update _mapSubMesh
2350 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2351 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2352 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2356 //=============================================================================
2358 * \brief Update objects depending on changed geom groups
2360 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2361 * issue 0020210: Update of a smesh group after modification of the associated geom group
2363 //=============================================================================
2365 void SMESH_Mesh_i::CheckGeomGroupModif()
2367 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2368 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2369 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2370 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2371 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2373 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2374 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2375 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2377 int nbValid = 0, nbRemoved = 0;
2378 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2379 for ( ; chItr->More(); chItr->Next() )
2381 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2382 if ( !smSO->_is_nil() &&
2383 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2384 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2386 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2387 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2388 if ( !geom->_non_existent() )
2391 continue; // keep the sub-mesh
2394 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2395 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2396 if ( !sm->_is_nil() && !sm->_non_existent() )
2398 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2399 if ( smGeom->_is_nil() )
2401 RemoveSubMesh( sm );
2408 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2409 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2413 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2414 builder->RemoveObjectWithChildren( rootSO );
2418 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2419 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2420 while ( i_gr != _mapGroups.end())
2422 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2424 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2425 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2426 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2427 bool isValidGeom = false;
2428 if ( !onGeom->_is_nil() )
2430 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2432 else if ( !onFilt->_is_nil() )
2434 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2438 isValidGeom = ( !groupSO->_is_nil() &&
2439 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2443 if ( !IsLoaded() || group->IsEmpty() )
2445 RemoveGroup( group );
2447 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2449 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2451 else // is it possible?
2453 builder->RemoveObjectWithChildren( refSO );
2459 if ( !_impl->HasShapeToMesh() ) return;
2461 CORBA::Long nbEntities = NbNodes() + NbElements();
2463 // Check if group contents changed
2465 typedef map< string, TopoDS_Shape > TEntry2Geom;
2466 TEntry2Geom newGroupContents;
2468 list<TGeomGroupData>::iterator
2469 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2470 for ( ; data != dataEnd; ++data )
2472 pair< TEntry2Geom::iterator, bool > it_new =
2473 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2474 bool processedGroup = !it_new.second;
2475 TopoDS_Shape& newShape = it_new.first->second;
2476 if ( !processedGroup )
2477 newShape = newGroupShape( *data );
2478 if ( newShape.IsNull() )
2479 continue; // no changes
2482 _preMeshInfo->ForgetOrLoad();
2484 if ( processedGroup ) { // update group indices
2485 list<TGeomGroupData>::iterator data2 = data;
2486 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2487 data->_indices = data2->_indices;
2490 // Update SMESH objects according to new GEOM group contents
2492 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2493 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2495 int oldID = submesh->GetId();
2496 if ( !_mapSubMeshIor.count( oldID ))
2498 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2500 // update hypotheses
2501 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2502 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2503 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2505 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2506 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2508 // care of submeshes
2509 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2510 int newID = newSubmesh->GetId();
2511 if ( newID != oldID ) {
2512 _mapSubMesh [ newID ] = newSubmesh;
2513 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2514 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2515 _mapSubMesh. erase(oldID);
2516 _mapSubMesh_i. erase(oldID);
2517 _mapSubMeshIor.erase(oldID);
2518 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2523 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2524 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2525 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2527 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2529 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2530 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2531 ds->SetShape( newShape );
2536 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2537 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2539 // Remove groups and submeshes basing on removed sub-shapes
2541 TopTools_MapOfShape newShapeMap;
2542 TopoDS_Iterator shapeIt( newShape );
2543 for ( ; shapeIt.More(); shapeIt.Next() )
2544 newShapeMap.Add( shapeIt.Value() );
2546 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2547 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2549 if ( newShapeMap.Contains( shapeIt.Value() ))
2551 TopTools_IndexedMapOfShape oldShapeMap;
2552 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2553 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2555 const TopoDS_Shape& oldShape = oldShapeMap(i);
2556 int oldInd = meshDS->ShapeToIndex( oldShape );
2558 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2559 if ( i_smIor != _mapSubMeshIor.end() ) {
2560 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2563 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2564 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2566 // check if a group bases on oldInd shape
2567 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2568 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2569 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2570 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2572 RemoveGroup( i_grp->second ); // several groups can base on same shape
2573 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2578 // Reassign hypotheses and update groups after setting the new shape to mesh
2580 // collect anassigned hypotheses
2581 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2582 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2583 TShapeHypList assignedHyps;
2584 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2586 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2587 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2588 if ( !hyps.empty() ) {
2589 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2590 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2591 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2594 // collect shapes supporting groups
2595 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2596 TShapeTypeList groupData;
2597 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2598 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2599 for ( ; grIt != groups.end(); ++grIt )
2601 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2603 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2605 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2607 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2608 _impl->ShapeToMesh( newShape );
2610 // reassign hypotheses
2611 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2612 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2614 TIndexedShape& geom = indS_hyps->first;
2615 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2616 int oldID = geom._index;
2617 int newID = meshDS->ShapeToIndex( geom._shape );
2618 if ( oldID == 1 ) { // main shape
2620 geom._shape = newShape;
2624 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2625 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2626 // care of sub-meshes
2627 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2628 if ( newID != oldID ) {
2629 _mapSubMesh [ newID ] = newSubmesh;
2630 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2631 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2632 _mapSubMesh. erase(oldID);
2633 _mapSubMesh_i. erase(oldID);
2634 _mapSubMeshIor.erase(oldID);
2635 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2639 TShapeTypeList::iterator geomType = groupData.begin();
2640 for ( ; geomType != groupData.end(); ++geomType )
2642 const TIndexedShape& geom = geomType->first;
2643 int oldID = geom._index;
2644 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2647 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2648 CORBA::String_var name = groupSO->GetName();
2650 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2651 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2652 /*id=*/-1, geom._shape ))
2653 group_i->changeLocalId( group->GetID() );
2656 break; // everything has been updated
2659 } // loop on group data
2663 CORBA::Long newNbEntities = NbNodes() + NbElements();
2664 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2665 if ( newNbEntities != nbEntities )
2667 // Add all SObjects with icons to soToUpdateIcons
2668 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2670 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2671 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2672 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2674 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2675 i_gr != _mapGroups.end(); ++i_gr ) // groups
2676 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2679 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2680 for ( ; so != soToUpdateIcons.end(); ++so )
2681 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2684 //=============================================================================
2686 * \brief Create standalone group from a group on geometry or filter
2688 //=============================================================================
2690 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2691 throw (SALOME::SALOME_Exception)
2693 SMESH::SMESH_Group_var aGroup;
2698 _preMeshInfo->FullLoadFromFile();
2700 if ( theGroup->_is_nil() )
2701 return aGroup._retn();
2703 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2705 return aGroup._retn();
2707 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2709 const int anId = aGroupToRem->GetLocalID();
2710 if ( !_impl->ConvertToStandalone( anId ) )
2711 return aGroup._retn();
2712 removeGeomGroupData( theGroup );
2714 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2716 // remove old instance of group from own map
2717 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2718 _mapGroups.erase( anId );
2720 SALOMEDS::StudyBuilder_var builder;
2721 SALOMEDS::SObject_wrap aGroupSO;
2722 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2723 if ( !aStudy->_is_nil() ) {
2724 builder = aStudy->NewBuilder();
2725 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2726 if ( !aGroupSO->_is_nil() )
2728 // remove reference to geometry
2729 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2730 for ( ; chItr->More(); chItr->Next() )
2732 // Remove group's child SObject
2733 SALOMEDS::SObject_wrap so = chItr->Value();
2734 builder->RemoveObject( so );
2736 // Update Python script
2737 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2738 << ".ConvertToStandalone( " << aGroupSO << " )";
2740 // change icon of Group on Filter
2743 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2744 // const int isEmpty = ( elemTypes->length() == 0 );
2747 SALOMEDS::GenericAttribute_wrap anAttr =
2748 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2749 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2750 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2756 // remember new group in own map
2757 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2758 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2760 // register CORBA object for persistence
2761 _gen_i->RegisterObject( aGroup );
2763 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2764 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2765 //aGroup->Register();
2766 aGroupToRem->UnRegister();
2768 SMESH_CATCH( SMESH::throwCorbaException );
2770 return aGroup._retn();
2773 //=============================================================================
2777 //=============================================================================
2779 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2781 if(MYDEBUG) MESSAGE( "createSubMesh" );
2782 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2783 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2786 SMESH_subMesh_i * subMeshServant;
2789 subMeshId = mySubMesh->GetId();
2790 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2792 else // "invalid sub-mesh"
2794 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2795 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2796 if ( _mapSubMesh.empty() )
2799 subMeshId = _mapSubMesh.begin()->first - 1;
2800 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2803 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2805 _mapSubMesh [subMeshId] = mySubMesh;
2806 _mapSubMesh_i [subMeshId] = subMeshServant;
2807 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2809 subMeshServant->Register();
2811 // register CORBA object for persistence
2812 int nextId = _gen_i->RegisterObject( subMesh );
2813 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2814 else { nextId = 0; } // avoid "unused variable" warning
2816 // to track changes of GEOM groups
2817 if ( subMeshId > 0 )
2818 addGeomGroupData( theSubShapeObject, subMesh );
2820 return subMesh._retn();
2823 //=======================================================================
2824 //function : getSubMesh
2826 //=======================================================================
2828 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2830 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2831 if ( it == _mapSubMeshIor.end() )
2832 return SMESH::SMESH_subMesh::_nil();
2834 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2837 //=============================================================================
2841 //=============================================================================
2843 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2844 GEOM::GEOM_Object_ptr theSubShapeObject )
2846 bool isHypChanged = false;
2847 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2848 return isHypChanged;
2850 const int subMeshId = theSubMesh->GetId();
2852 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2855 if (( _mapSubMesh.count( subMeshId )) &&
2856 ( sm = _impl->GetSubMeshContaining( subMeshId )))
2858 TopoDS_Shape S = sm->GetSubShape();
2861 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2862 isHypChanged = !hyps.empty();
2863 if ( isHypChanged && _preMeshInfo )
2864 _preMeshInfo->ForgetOrLoad();
2865 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2866 for ( ; hyp != hyps.end(); ++hyp )
2867 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2874 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2875 isHypChanged = ( aHypList->length() > 0 );
2876 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2877 removeHypothesis( theSubShapeObject, aHypList[i] );
2880 catch( const SALOME::SALOME_Exception& ) {
2881 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2883 removeGeomGroupData( theSubShapeObject );
2887 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2888 if ( id_smi != _mapSubMesh_i.end() )
2889 id_smi->second->UnRegister();
2891 // remove a CORBA object
2892 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2893 if ( id_smptr != _mapSubMeshIor.end() )
2894 SMESH::SMESH_subMesh_var( id_smptr->second );
2896 _mapSubMesh.erase(subMeshId);
2897 _mapSubMesh_i.erase(subMeshId);
2898 _mapSubMeshIor.erase(subMeshId);
2900 return isHypChanged;
2903 //=============================================================================
2907 //=============================================================================
2909 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2910 const char* theName,
2912 const TopoDS_Shape& theShape,
2913 const SMESH_PredicatePtr& thePredicate )
2915 std::string newName;
2916 if ( !theName || !theName[0] )
2918 std::set< std::string > presentNames;
2919 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2920 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2922 CORBA::String_var name = i_gr->second->GetName();
2923 presentNames.insert( name.in() );
2926 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2927 } while ( !presentNames.insert( newName ).second );
2928 theName = newName.c_str();
2930 SMESH::SMESH_GroupBase_var aGroup;
2931 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
2932 theID, theShape, thePredicate ))
2934 int anId = g->GetID();
2935 SMESH_GroupBase_i* aGroupImpl;
2936 if ( !theShape.IsNull() )
2937 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2938 else if ( thePredicate )
2939 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2941 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2943 aGroup = aGroupImpl->_this();
2944 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2945 aGroupImpl->Register();
2947 // register CORBA object for persistence
2948 int nextId = _gen_i->RegisterObject( aGroup );
2949 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2950 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
2952 // to track changes of GEOM groups
2953 if ( !theShape.IsNull() ) {
2954 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2955 addGeomGroupData( geom, aGroup );
2958 return aGroup._retn();
2961 //=============================================================================
2963 * SMESH_Mesh_i::removeGroup
2965 * Should be called by ~SMESH_Group_i()
2967 //=============================================================================
2969 void SMESH_Mesh_i::removeGroup( const int theId )
2971 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2972 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2973 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2974 _mapGroups.erase( theId );
2975 removeGeomGroupData( group );
2976 if ( !_impl->RemoveGroup( theId ))
2978 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2979 RemoveGroup( group );
2981 group->UnRegister();
2985 //=============================================================================
2989 //=============================================================================
2991 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2992 throw(SALOME::SALOME_Exception)
2994 SMESH::log_array_var aLog;
2998 _preMeshInfo->FullLoadFromFile();
3000 list < SMESHDS_Command * >logDS = _impl->GetLog();
3001 aLog = new SMESH::log_array;
3003 int lg = logDS.size();
3006 list < SMESHDS_Command * >::iterator its = logDS.begin();
3007 while(its != logDS.end()){
3008 SMESHDS_Command *com = *its;
3009 int comType = com->GetType();
3011 int lgcom = com->GetNumber();
3013 const list < int >&intList = com->GetIndexes();
3014 int inum = intList.size();
3016 list < int >::const_iterator ii = intList.begin();
3017 const list < double >&coordList = com->GetCoords();
3018 int rnum = coordList.size();
3020 list < double >::const_iterator ir = coordList.begin();
3021 aLog[indexLog].commandType = comType;
3022 aLog[indexLog].number = lgcom;
3023 aLog[indexLog].coords.length(rnum);
3024 aLog[indexLog].indexes.length(inum);
3025 for(int i = 0; i < rnum; i++){
3026 aLog[indexLog].coords[i] = *ir;
3027 //MESSAGE(" "<<i<<" "<<ir.Value());
3030 for(int i = 0; i < inum; i++){
3031 aLog[indexLog].indexes[i] = *ii;
3032 //MESSAGE(" "<<i<<" "<<ii.Value());
3041 SMESH_CATCH( SMESH::throwCorbaException );
3043 return aLog._retn();
3047 //=============================================================================
3051 //=============================================================================
3053 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3057 SMESH_CATCH( SMESH::throwCorbaException );
3060 //=============================================================================
3064 //=============================================================================
3066 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3071 //=============================================================================
3074 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3075 // issue 0020918: groups removal is caused by hyp modification
3076 // issue 0021208: to forget not loaded mesh data at hyp modification
3077 struct TCallUp_i : public SMESH_Mesh::TCallUp
3079 SMESH_Mesh_i* _mesh;
3080 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3081 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3082 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3083 virtual void Load () { _mesh->Load(); }
3087 //================================================================================
3089 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3091 //================================================================================
3093 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3096 _preMeshInfo->ForgetOrLoad();
3098 SMESH::SMESH_Mesh_var mesh = _this();
3099 _gen_i->UpdateIcons( mesh );
3101 // mark a hypothesis as valid after edition
3102 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3103 SALOMEDS::SObject_wrap hypRoot;
3104 if ( !smeshComp->_is_nil() &&
3105 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3107 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3108 for ( ; anIter->More(); anIter->Next() )
3110 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3111 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3112 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3113 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3114 _gen_i->HighLightInvalid( hyp, false );
3119 //=============================================================================
3123 //=============================================================================
3125 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3127 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3130 _impl->SetCallUp( new TCallUp_i(this));
3133 //=============================================================================
3137 //=============================================================================
3139 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3141 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3145 //=============================================================================
3147 * Return mesh editor
3149 //=============================================================================
3151 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3152 throw (SALOME::SALOME_Exception)
3154 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3158 _preMeshInfo->FullLoadFromFile();
3160 // Create MeshEditor
3162 _editor = new SMESH_MeshEditor_i( this, false );
3163 aMeshEdVar = _editor->_this();
3165 // Update Python script
3166 TPythonDump() << _editor << " = "
3167 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3169 SMESH_CATCH( SMESH::throwCorbaException );
3171 return aMeshEdVar._retn();
3174 //=============================================================================
3176 * Return mesh edition previewer
3178 //=============================================================================
3180 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3181 throw (SALOME::SALOME_Exception)
3183 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3187 _preMeshInfo->FullLoadFromFile();
3189 if ( !_previewEditor )
3190 _previewEditor = new SMESH_MeshEditor_i( this, true );
3191 aMeshEdVar = _previewEditor->_this();
3193 SMESH_CATCH( SMESH::throwCorbaException );
3195 return aMeshEdVar._retn();
3198 //================================================================================
3200 * \brief Return true if the mesh has been edited since a last total re-compute
3201 * and those modifications may prevent successful partial re-compute
3203 //================================================================================
3205 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3207 Unexpect aCatch(SALOME_SalomeException);
3208 return _impl->HasModificationsToDiscard();
3211 //================================================================================
3213 * \brief Returns a random unique color
3215 //================================================================================
3217 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3219 const int MAX_ATTEMPTS = 100;
3221 double tolerance = 0.5;
3222 SALOMEDS::Color col;
3226 // generate random color
3227 double red = (double)rand() / RAND_MAX;
3228 double green = (double)rand() / RAND_MAX;
3229 double blue = (double)rand() / RAND_MAX;
3230 // check existence in the list of the existing colors
3231 bool matched = false;
3232 std::list<SALOMEDS::Color>::const_iterator it;
3233 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3234 SALOMEDS::Color color = *it;
3235 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3236 matched = tol < tolerance;
3238 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3239 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3247 //=============================================================================
3249 * Sets auto-color mode. If it is on, groups get unique random colors
3251 //=============================================================================
3253 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3255 Unexpect aCatch(SALOME_SalomeException);
3256 _impl->SetAutoColor(theAutoColor);
3258 TPythonDump pyDump; // not to dump group->SetColor() from below code
3259 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3261 std::list<SALOMEDS::Color> aReservedColors;
3262 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3263 for ( ; it != _mapGroups.end(); it++ ) {
3264 if ( CORBA::is_nil( it->second )) continue;
3265 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3266 it->second->SetColor( aColor );
3267 aReservedColors.push_back( aColor );
3271 //=============================================================================
3273 * Returns true if auto-color mode is on
3275 //=============================================================================
3277 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3279 Unexpect aCatch(SALOME_SalomeException);
3280 return _impl->GetAutoColor();
3283 //=============================================================================
3285 * Checks if there are groups with equal names
3287 //=============================================================================
3289 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3291 return _impl->HasDuplicatedGroupNamesMED();
3294 //================================================================================
3296 * \brief Care of a file before exporting mesh into it
3298 //================================================================================
3300 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3302 SMESH_File aFile( file, false );
3304 if ( aFile.exists() ) {
3305 // existing filesystem node
3306 if ( !aFile.isDirectory() ) {
3307 if ( aFile.openForWriting() ) {
3308 if ( overwrite && ! aFile.remove()) {
3309 msg << "Can't replace " << aFile.getName();
3312 msg << "Can't write into " << aFile.getName();
3315 msg << "Location " << aFile.getName() << " is not a file";
3319 // nonexisting file; check if it can be created
3320 if ( !aFile.openForWriting() ) {
3321 msg << "You cannot create the file "
3323 << ". Check the directory existence and access rights";
3331 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3335 //================================================================================
3337 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3338 * \param file - file name
3339 * \param overwrite - to erase the file or not
3340 * \retval string - mesh name
3342 //================================================================================
3344 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3345 CORBA::Boolean overwrite)
3348 PrepareForWriting(file, overwrite);
3349 string aMeshName = "Mesh";
3350 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3351 if ( !aStudy->_is_nil() ) {
3352 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3353 if ( !aMeshSO->_is_nil() ) {
3354 CORBA::String_var name = aMeshSO->GetName();
3356 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3357 if ( !aStudy->GetProperties()->IsLocked() )
3359 SALOMEDS::GenericAttribute_wrap anAttr;
3360 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3361 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3362 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3363 ASSERT(!aFileName->_is_nil());
3364 aFileName->SetValue(file);
3365 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3366 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3367 ASSERT(!aFileType->_is_nil());
3368 aFileType->SetValue("FICHIERMED");
3372 // Update Python script
3373 // set name of mesh before export
3374 TPythonDump() << _gen_i << ".SetName("
3375 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3377 // check names of groups
3383 //================================================================================
3385 * \brief Export to MED file
3387 //================================================================================
3389 void SMESH_Mesh_i::ExportMED(const char* file,
3390 CORBA::Boolean auto_groups,
3391 CORBA::Long version,
3392 CORBA::Boolean overwrite,
3393 CORBA::Boolean autoDimension)
3394 throw(SALOME::SALOME_Exception)
3396 //MESSAGE("MED minor version: "<< minor);
3399 _preMeshInfo->FullLoadFromFile();
3401 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3402 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3404 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3406 << "auto_groups=" <<auto_groups << ", "
3407 << "minor=" << version << ", "
3408 << "overwrite=" << overwrite << ", "
3409 << "meshPart=None, "
3410 << "autoDimension=" << autoDimension << " )";
3412 SMESH_CATCH( SMESH::throwCorbaException );
3415 //================================================================================
3417 * \brief Export a mesh to a SAUV file
3419 //================================================================================
3421 void SMESH_Mesh_i::ExportSAUV (const char* file,
3422 CORBA::Boolean auto_groups)
3423 throw(SALOME::SALOME_Exception)
3425 Unexpect aCatch(SALOME_SalomeException);
3427 _preMeshInfo->FullLoadFromFile();
3429 string aMeshName = prepareMeshNameAndGroups(file, true);
3430 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3431 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3432 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3436 //================================================================================
3438 * \brief Export a mesh to a DAT file
3440 //================================================================================
3442 void SMESH_Mesh_i::ExportDAT (const char *file)
3443 throw(SALOME::SALOME_Exception)
3445 Unexpect aCatch(SALOME_SalomeException);
3447 _preMeshInfo->FullLoadFromFile();
3449 // Update Python script
3450 // check names of groups
3452 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3455 PrepareForWriting(file);
3456 _impl->ExportDAT(file);
3459 //================================================================================
3461 * \brief Export a mesh to an UNV file
3463 //================================================================================
3465 void SMESH_Mesh_i::ExportUNV (const char *file)
3466 throw(SALOME::SALOME_Exception)
3468 Unexpect aCatch(SALOME_SalomeException);
3470 _preMeshInfo->FullLoadFromFile();
3472 // Update Python script
3473 // check names of groups
3475 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3478 PrepareForWriting(file);
3479 _impl->ExportUNV(file);
3482 //================================================================================
3484 * \brief Export a mesh to an STL file
3486 //================================================================================
3488 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3489 throw(SALOME::SALOME_Exception)
3491 Unexpect aCatch(SALOME_SalomeException);
3493 _preMeshInfo->FullLoadFromFile();
3495 // Update Python script
3496 // check names of groups
3498 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3499 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3501 CORBA::String_var name;
3502 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3503 if ( !so->_is_nil() )
3504 name = so->GetName();
3507 PrepareForWriting( file );
3508 _impl->ExportSTL( file, isascii, name.in() );
3511 //================================================================================
3513 * \brief Export a part of mesh to a med file
3515 //================================================================================
3517 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3519 CORBA::Boolean auto_groups,
3520 CORBA::Long version,
3521 CORBA::Boolean overwrite,
3522 CORBA::Boolean autoDimension,
3523 const GEOM::ListOfFields& fields,
3524 const char* geomAssocFields,
3525 CORBA::Double ZTolerance)
3526 throw (SALOME::SALOME_Exception)
3528 MESSAGE("MED version: "<< version);
3531 _preMeshInfo->FullLoadFromFile();
3534 bool have0dField = false;
3535 if ( fields.length() > 0 )
3537 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3538 if ( shapeToMesh->_is_nil() )
3539 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3541 for ( size_t i = 0; i < fields.length(); ++i )
3543 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3544 THROW_SALOME_CORBA_EXCEPTION
3545 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3546 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3547 if ( fieldShape->_is_nil() )
3548 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3549 if ( !fieldShape->IsSame( shapeToMesh ) )
3550 THROW_SALOME_CORBA_EXCEPTION
3551 ( "Field defined not on shape", SALOME::BAD_PARAM);
3552 if ( fields[i]->GetDimension() == 0 )
3555 if ( geomAssocFields )
3556 for ( int i = 0; geomAssocFields[i]; ++i )
3557 switch ( geomAssocFields[i] ) {
3558 case 'v':case 'e':case 'f':case 's': break;
3559 case 'V':case 'E':case 'F':case 'S': break;
3560 default: THROW_SALOME_CORBA_EXCEPTION
3561 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3565 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3569 string aMeshName = "Mesh";
3570 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3571 if ( CORBA::is_nil( meshPart ) ||
3572 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3574 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3575 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3576 0, autoDimension, /*addODOnVertices=*/have0dField,
3578 meshDS = _impl->GetMeshDS();
3583 _preMeshInfo->FullLoadFromFile();
3585 PrepareForWriting(file, overwrite);
3587 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3588 if ( !SO->_is_nil() ) {
3589 CORBA::String_var name = SO->GetName();
3593 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3594 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3595 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3596 meshDS = tmpDSDeleter._obj = partDS;
3601 if ( _impl->HasShapeToMesh() )
3603 DriverMED_W_Field fieldWriter;
3604 fieldWriter.SetFile( file );
3605 fieldWriter.SetMeshName( aMeshName );
3606 fieldWriter.AddODOnVertices( have0dField );
3608 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3612 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3613 goList->length( fields.length() );
3614 for ( size_t i = 0; i < fields.length(); ++i )
3616 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3619 TPythonDump() << _this() << ".ExportPartToMED( "
3620 << meshPart << ", r'"
3622 << auto_groups << ", "
3624 << overwrite << ", "
3625 << autoDimension << ", "
3627 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3628 << TVar( ZTolerance )
3631 SMESH_CATCH( SMESH::throwCorbaException );
3634 //================================================================================
3636 * Write GEOM fields to MED file
3638 //================================================================================
3640 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3641 SMESHDS_Mesh* meshDS,
3642 const GEOM::ListOfFields& fields,
3643 const char* geomAssocFields)
3645 #define METH "SMESH_Mesh_i::exportMEDFields() "
3647 if (( fields.length() < 1 ) &&
3648 ( !geomAssocFields || !geomAssocFields[0] ))
3651 std::vector< std::vector< double > > dblVals;
3652 std::vector< std::vector< int > > intVals;
3653 std::vector< int > subIdsByDim[ 4 ];
3654 const double noneDblValue = 0.;
3655 const double noneIntValue = 0;
3657 for ( size_t iF = 0; iF < fields.length(); ++iF )
3661 int dim = fields[ iF ]->GetDimension();
3662 SMDSAbs_ElementType elemType;
3663 TopAbs_ShapeEnum shapeType;
3665 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3666 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3667 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3668 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3670 continue; // skip fields on whole shape
3672 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3673 if ( dataType == GEOM::FDT_String )
3675 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3676 if ( stepIDs->length() < 1 )
3678 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3679 if ( comps->length() < 1 )
3681 CORBA::String_var name = fields[ iF ]->GetName();
3683 if ( !fieldWriter.Set( meshDS,
3687 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3690 for ( size_t iC = 0; iC < comps->length(); ++iC )
3691 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3693 dblVals.resize( comps->length() );
3694 intVals.resize( comps->length() );
3696 // find sub-shape IDs
3698 std::vector< int >& subIds = subIdsByDim[ dim ];
3699 if ( subIds.empty() )
3700 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3701 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3702 subIds.push_back( id );
3706 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3710 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3712 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3713 if ( step->_is_nil() )
3716 CORBA::Long stamp = step->GetStamp();
3717 CORBA::Long id = step->GetID();
3718 fieldWriter.SetDtIt( int( stamp ), int( id ));
3720 // fill dblVals or intVals
3721 for ( size_t iC = 0; iC < comps->length(); ++iC )
3722 if ( dataType == GEOM::FDT_Double )
3724 dblVals[ iC ].clear();
3725 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3729 intVals[ iC ].clear();
3730 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3734 case GEOM::FDT_Double:
3736 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3737 if ( dblStep->_is_nil() ) continue;
3738 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3739 if ( vv->length() != subIds.size() * comps->length() )
3740 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3741 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3742 for ( size_t iC = 0; iC < comps->length(); ++iC )
3743 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3748 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3749 if ( intStep->_is_nil() ) continue;
3750 GEOM::ListOfLong_var vv = intStep->GetValues();
3751 if ( vv->length() != subIds.size() * comps->length() )
3752 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3753 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3754 for ( size_t iC = 0; iC < comps->length(); ++iC )
3755 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3758 case GEOM::FDT_Bool:
3760 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3761 if ( boolStep->_is_nil() ) continue;
3762 GEOM::short_array_var vv = boolStep->GetValues();
3763 if ( vv->length() != subIds.size() * comps->length() )
3764 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3765 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3766 for ( size_t iC = 0; iC < comps->length(); ++iC )
3767 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3773 // pass values to fieldWriter
3774 elemIt = fieldWriter.GetOrderedElems();
3775 if ( dataType == GEOM::FDT_Double )
3776 while ( elemIt->more() )
3778 const SMDS_MeshElement* e = elemIt->next();
3779 const int shapeID = e->getshapeId();
3780 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3781 for ( size_t iC = 0; iC < comps->length(); ++iC )
3782 fieldWriter.AddValue( noneDblValue );
3784 for ( size_t iC = 0; iC < comps->length(); ++iC )
3785 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3788 while ( elemIt->more() )
3790 const SMDS_MeshElement* e = elemIt->next();
3791 const int shapeID = e->getshapeId();
3792 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3793 for ( size_t iC = 0; iC < comps->length(); ++iC )
3794 fieldWriter.AddValue( (double) noneIntValue );
3796 for ( size_t iC = 0; iC < comps->length(); ++iC )
3797 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3801 fieldWriter.Perform();
3802 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3803 if ( res && res->IsKO() )
3805 if ( res->myComment.empty() )
3806 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3808 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3814 if ( !geomAssocFields || !geomAssocFields[0] )
3817 // write geomAssocFields
3819 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3820 shapeDim[ TopAbs_COMPOUND ] = 3;
3821 shapeDim[ TopAbs_COMPSOLID ] = 3;
3822 shapeDim[ TopAbs_SOLID ] = 3;
3823 shapeDim[ TopAbs_SHELL ] = 2;
3824 shapeDim[ TopAbs_FACE ] = 2;
3825 shapeDim[ TopAbs_WIRE ] = 1;
3826 shapeDim[ TopAbs_EDGE ] = 1;
3827 shapeDim[ TopAbs_VERTEX ] = 0;
3828 shapeDim[ TopAbs_SHAPE ] = 3;
3830 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3832 std::vector< std::string > compNames;
3833 switch ( geomAssocFields[ iF ]) {
3835 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3836 compNames.push_back( "dim" );
3839 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3842 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3845 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3849 compNames.push_back( "id" );
3850 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3851 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3853 fieldWriter.SetDtIt( -1, -1 );
3855 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3859 if ( compNames.size() == 2 ) // _vertices_
3860 while ( elemIt->more() )
3862 const SMDS_MeshElement* e = elemIt->next();
3863 const int shapeID = e->getshapeId();
3866 fieldWriter.AddValue( (double) -1 );
3867 fieldWriter.AddValue( (double) -1 );
3871 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3872 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3873 fieldWriter.AddValue( (double) shapeID );
3877 while ( elemIt->more() )
3879 const SMDS_MeshElement* e = elemIt->next();
3880 const int shapeID = e->getshapeId();
3882 fieldWriter.AddValue( (double) -1 );
3884 fieldWriter.AddValue( (double) shapeID );
3888 fieldWriter.Perform();
3889 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3890 if ( res && res->IsKO() )
3892 if ( res->myComment.empty() )
3893 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3895 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3898 } // loop on geomAssocFields
3903 //================================================================================
3905 * \brief Export a part of mesh to a DAT file
3907 //================================================================================
3909 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3911 throw (SALOME::SALOME_Exception)
3913 Unexpect aCatch(SALOME_SalomeException);
3915 _preMeshInfo->FullLoadFromFile();
3917 PrepareForWriting(file);
3919 SMESH_MeshPartDS partDS( meshPart );
3920 _impl->ExportDAT(file,&partDS);
3922 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3923 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3925 //================================================================================
3927 * \brief Export a part of mesh to an UNV file
3929 //================================================================================
3931 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3933 throw (SALOME::SALOME_Exception)
3935 Unexpect aCatch(SALOME_SalomeException);
3937 _preMeshInfo->FullLoadFromFile();
3939 PrepareForWriting(file);
3941 SMESH_MeshPartDS partDS( meshPart );
3942 _impl->ExportUNV(file, &partDS);
3944 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3945 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3947 //================================================================================
3949 * \brief Export a part of mesh to an STL file
3951 //================================================================================
3953 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3955 ::CORBA::Boolean isascii)
3956 throw (SALOME::SALOME_Exception)
3958 Unexpect aCatch(SALOME_SalomeException);
3960 _preMeshInfo->FullLoadFromFile();
3962 PrepareForWriting(file);
3964 CORBA::String_var name;
3965 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3966 if ( !so->_is_nil() )
3967 name = so->GetName();
3969 SMESH_MeshPartDS partDS( meshPart );
3970 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3972 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3973 << meshPart<< ", r'" << file << "', " << isascii << ")";
3976 //================================================================================
3978 * \brief Export a part of mesh to an STL file
3980 //================================================================================
3982 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3984 CORBA::Boolean overwrite,
3985 CORBA::Boolean groupElemsByType)
3986 throw (SALOME::SALOME_Exception)
3989 Unexpect aCatch(SALOME_SalomeException);
3991 _preMeshInfo->FullLoadFromFile();
3993 PrepareForWriting(file,overwrite);
3995 std::string meshName("");
3996 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3997 if ( !so->_is_nil() )
3999 CORBA::String_var name = so->GetName();
4000 meshName = name.in();
4004 SMESH_MeshPartDS partDS( meshPart );
4005 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4007 SMESH_CATCH( SMESH::throwCorbaException );
4009 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4010 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4012 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4016 //================================================================================
4018 * \brief Export a part of mesh to a GMF file
4020 //================================================================================
4022 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4024 bool withRequiredGroups)
4025 throw (SALOME::SALOME_Exception)
4027 Unexpect aCatch(SALOME_SalomeException);
4029 _preMeshInfo->FullLoadFromFile();
4031 PrepareForWriting(file,/*overwrite=*/true);
4033 SMESH_MeshPartDS partDS( meshPart );
4034 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4036 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4037 << meshPart<< ", r'"
4039 << withRequiredGroups << ")";
4042 //=============================================================================
4044 * Return computation progress [0.,1]
4046 //=============================================================================
4048 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4052 return _impl->GetComputeProgress();
4054 SMESH_CATCH( SMESH::doNothing );
4058 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4060 Unexpect aCatch(SALOME_SalomeException);
4062 return _preMeshInfo->NbNodes();
4064 return _impl->NbNodes();
4067 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4069 Unexpect aCatch(SALOME_SalomeException);
4071 return _preMeshInfo->NbElements();
4073 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4076 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4078 Unexpect aCatch(SALOME_SalomeException);
4080 return _preMeshInfo->Nb0DElements();
4082 return _impl->Nb0DElements();
4085 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4087 Unexpect aCatch(SALOME_SalomeException);
4089 return _preMeshInfo->NbBalls();
4091 return _impl->NbBalls();
4094 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4096 Unexpect aCatch(SALOME_SalomeException);
4098 return _preMeshInfo->NbEdges();
4100 return _impl->NbEdges();
4103 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4104 throw(SALOME::SALOME_Exception)
4106 Unexpect aCatch(SALOME_SalomeException);
4108 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4110 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4113 //=============================================================================
4115 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4117 Unexpect aCatch(SALOME_SalomeException);
4119 return _preMeshInfo->NbFaces();
4121 return _impl->NbFaces();
4124 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4126 Unexpect aCatch(SALOME_SalomeException);
4128 return _preMeshInfo->NbTriangles();
4130 return _impl->NbTriangles();
4133 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4135 Unexpect aCatch(SALOME_SalomeException);
4137 return _preMeshInfo->NbBiQuadTriangles();
4139 return _impl->NbBiQuadTriangles();
4142 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4144 Unexpect aCatch(SALOME_SalomeException);
4146 return _preMeshInfo->NbQuadrangles();
4148 return _impl->NbQuadrangles();
4151 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4153 Unexpect aCatch(SALOME_SalomeException);
4155 return _preMeshInfo->NbBiQuadQuadrangles();
4157 return _impl->NbBiQuadQuadrangles();
4160 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4162 Unexpect aCatch(SALOME_SalomeException);
4164 return _preMeshInfo->NbPolygons();
4166 return _impl->NbPolygons();
4169 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4171 Unexpect aCatch(SALOME_SalomeException);
4173 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4175 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4178 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4179 throw(SALOME::SALOME_Exception)
4181 Unexpect aCatch(SALOME_SalomeException);
4183 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4185 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4188 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4189 throw(SALOME::SALOME_Exception)
4191 Unexpect aCatch(SALOME_SalomeException);
4193 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4195 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4198 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4199 throw(SALOME::SALOME_Exception)
4201 Unexpect aCatch(SALOME_SalomeException);
4203 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4205 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4208 //=============================================================================
4210 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4212 Unexpect aCatch(SALOME_SalomeException);
4214 return _preMeshInfo->NbVolumes();
4216 return _impl->NbVolumes();
4219 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4221 Unexpect aCatch(SALOME_SalomeException);
4223 return _preMeshInfo->NbTetras();
4225 return _impl->NbTetras();
4228 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4230 Unexpect aCatch(SALOME_SalomeException);
4232 return _preMeshInfo->NbHexas();
4234 return _impl->NbHexas();
4237 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4239 Unexpect aCatch(SALOME_SalomeException);
4241 return _preMeshInfo->NbTriQuadHexas();
4243 return _impl->NbTriQuadraticHexas();
4246 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4248 Unexpect aCatch(SALOME_SalomeException);
4250 return _preMeshInfo->NbPyramids();
4252 return _impl->NbPyramids();
4255 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4257 Unexpect aCatch(SALOME_SalomeException);
4259 return _preMeshInfo->NbPrisms();
4261 return _impl->NbPrisms();
4264 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4266 Unexpect aCatch(SALOME_SalomeException);
4268 return _preMeshInfo->NbHexPrisms();
4270 return _impl->NbHexagonalPrisms();
4273 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4275 Unexpect aCatch(SALOME_SalomeException);
4277 return _preMeshInfo->NbPolyhedrons();
4279 return _impl->NbPolyhedrons();
4282 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4283 throw(SALOME::SALOME_Exception)
4285 Unexpect aCatch(SALOME_SalomeException);
4287 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4289 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4292 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4293 throw(SALOME::SALOME_Exception)
4295 Unexpect aCatch(SALOME_SalomeException);
4297 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4299 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4302 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4303 throw(SALOME::SALOME_Exception)
4305 Unexpect aCatch(SALOME_SalomeException);
4307 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4309 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4312 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4313 throw(SALOME::SALOME_Exception)
4315 Unexpect aCatch(SALOME_SalomeException);
4317 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4319 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4322 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4323 throw(SALOME::SALOME_Exception)
4325 Unexpect aCatch(SALOME_SalomeException);
4327 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4329 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4332 //=============================================================================
4334 * Returns nb of published sub-meshes
4336 //=============================================================================
4338 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4340 Unexpect aCatch(SALOME_SalomeException);
4341 return _mapSubMesh_i.size();
4344 //=============================================================================
4346 * Dumps mesh into a string
4348 //=============================================================================
4350 char* SMESH_Mesh_i::Dump()
4354 return CORBA::string_dup( os.str().c_str() );
4357 //=============================================================================
4359 * Method of SMESH_IDSource interface
4361 //=============================================================================
4363 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4365 return GetElementsId();
4368 //=============================================================================
4370 * Returns ids of all elements
4372 //=============================================================================
4374 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4375 throw (SALOME::SALOME_Exception)
4377 Unexpect aCatch(SALOME_SalomeException);
4379 _preMeshInfo->FullLoadFromFile();
4381 SMESH::long_array_var aResult = new SMESH::long_array();
4382 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4384 if ( aSMESHDS_Mesh == NULL )
4385 return aResult._retn();
4387 long nbElements = NbElements();
4388 aResult->length( nbElements );
4389 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4390 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4391 aResult[i] = anIt->next()->GetID();
4393 return aResult._retn();
4397 //=============================================================================
4399 * Returns ids of all elements of given type
4401 //=============================================================================
4403 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4404 throw (SALOME::SALOME_Exception)
4406 Unexpect aCatch(SALOME_SalomeException);
4408 _preMeshInfo->FullLoadFromFile();
4410 SMESH::long_array_var aResult = new SMESH::long_array();
4411 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4413 if ( aSMESHDS_Mesh == NULL )
4414 return aResult._retn();
4416 long nbElements = NbElements();
4418 // No sense in returning ids of elements along with ids of nodes:
4419 // when theElemType == SMESH::ALL, return node ids only if
4420 // there are no elements
4421 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4422 return GetNodesId();
4424 aResult->length( nbElements );
4428 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4429 while ( i < nbElements && anIt->more() )
4430 aResult[i++] = anIt->next()->GetID();
4432 aResult->length( i );
4434 return aResult._retn();
4437 //=============================================================================
4439 * Returns ids of all nodes
4441 //=============================================================================
4443 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4444 throw (SALOME::SALOME_Exception)
4446 Unexpect aCatch(SALOME_SalomeException);
4448 _preMeshInfo->FullLoadFromFile();
4450 SMESH::long_array_var aResult = new SMESH::long_array();
4451 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4453 if ( aMeshDS == NULL )
4454 return aResult._retn();
4456 long nbNodes = NbNodes();
4457 aResult->length( nbNodes );
4458 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4459 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4460 aResult[i] = anIt->next()->GetID();
4462 return aResult._retn();
4465 //=============================================================================
4469 //=============================================================================
4471 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4472 throw (SALOME::SALOME_Exception)
4474 SMESH::ElementType type = SMESH::ALL;
4478 _preMeshInfo->FullLoadFromFile();
4480 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4482 SMESH_CATCH( SMESH::throwCorbaException );
4487 //=============================================================================
4491 //=============================================================================
4493 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4494 throw (SALOME::SALOME_Exception)
4497 _preMeshInfo->FullLoadFromFile();
4499 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4501 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4503 return ( SMESH::EntityType ) e->GetEntityType();
4506 //=============================================================================
4510 //=============================================================================
4512 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4513 throw (SALOME::SALOME_Exception)
4516 _preMeshInfo->FullLoadFromFile();
4518 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4520 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4522 return ( SMESH::GeometryType ) e->GetGeomType();
4525 //=============================================================================
4527 * Returns ID of elements for given submesh
4529 //=============================================================================
4530 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4531 throw (SALOME::SALOME_Exception)
4533 SMESH::long_array_var aResult = new SMESH::long_array();
4537 _preMeshInfo->FullLoadFromFile();
4539 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4540 if(!SM) return aResult._retn();
4542 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4543 if(!SDSM) return aResult._retn();
4545 aResult->length(SDSM->NbElements());
4547 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4549 while ( eIt->more() ) {
4550 aResult[i++] = eIt->next()->GetID();
4553 SMESH_CATCH( SMESH::throwCorbaException );
4555 return aResult._retn();
4558 //=============================================================================
4560 * Returns ID of nodes for given submesh
4561 * If param all==true - returns all nodes, else -
4562 * returns only nodes on shapes.
4564 //=============================================================================
4566 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4568 throw (SALOME::SALOME_Exception)
4570 SMESH::long_array_var aResult = new SMESH::long_array();
4574 _preMeshInfo->FullLoadFromFile();
4576 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4577 if(!SM) return aResult._retn();
4579 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4580 if(!SDSM) return aResult._retn();
4583 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4584 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4585 while ( nIt->more() ) {
4586 const SMDS_MeshNode* elem = nIt->next();
4587 theElems.insert( elem->GetID() );
4590 else { // all nodes of submesh elements
4591 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4592 while ( eIt->more() ) {
4593 const SMDS_MeshElement* anElem = eIt->next();
4594 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4595 while ( nIt->more() ) {
4596 const SMDS_MeshElement* elem = nIt->next();
4597 theElems.insert( elem->GetID() );
4602 aResult->length(theElems.size());
4603 set<int>::iterator itElem;
4605 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4606 aResult[i++] = *itElem;
4608 SMESH_CATCH( SMESH::throwCorbaException );
4610 return aResult._retn();
4613 //=============================================================================
4615 * Returns type of elements for given submesh
4617 //=============================================================================
4619 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4620 throw (SALOME::SALOME_Exception)
4622 SMESH::ElementType type = SMESH::ALL;
4626 _preMeshInfo->FullLoadFromFile();
4628 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4629 if(!SM) return SMESH::ALL;
4631 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4632 if(!SDSM) return SMESH::ALL;
4634 if(SDSM->NbElements()==0)
4635 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4637 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4638 const SMDS_MeshElement* anElem = eIt->next();
4640 type = ( SMESH::ElementType ) anElem->GetType();
4642 SMESH_CATCH( SMESH::throwCorbaException );
4648 //=============================================================================
4650 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4652 //=============================================================================
4654 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4657 _preMeshInfo->FullLoadFromFile();
4659 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4660 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4665 //=============================================================================
4667 * Get XYZ coordinates of node as list of double
4668 * If there is not node for given ID - returns empty list
4670 //=============================================================================
4672 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4675 _preMeshInfo->FullLoadFromFile();
4677 SMESH::double_array_var aResult = new SMESH::double_array();
4678 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4679 if ( aMeshDS == NULL )
4680 return aResult._retn();
4683 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4685 return aResult._retn();
4689 aResult[0] = aNode->X();
4690 aResult[1] = aNode->Y();
4691 aResult[2] = aNode->Z();
4692 return aResult._retn();
4696 //=============================================================================
4698 * For given node returns list of IDs of inverse elements
4699 * If there is not node for given ID - returns empty list
4701 //=============================================================================
4703 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4704 SMESH::ElementType elemType)
4707 _preMeshInfo->FullLoadFromFile();
4709 SMESH::long_array_var aResult = new SMESH::long_array();
4710 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4711 if ( aMeshDS == NULL )
4712 return aResult._retn();
4715 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4717 return aResult._retn();
4719 // find inverse elements
4720 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4721 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4722 aResult->length( aNode->NbInverseElements( type ));
4723 for( int i = 0; eIt->more(); ++i )
4725 const SMDS_MeshElement* elem = eIt->next();
4726 aResult[ i ] = elem->GetID();
4728 return aResult._retn();
4731 //=============================================================================
4733 * \brief Return position of a node on shape
4735 //=============================================================================
4737 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4740 _preMeshInfo->FullLoadFromFile();
4742 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4743 aNodePosition->shapeID = 0;
4744 aNodePosition->shapeType = GEOM::SHAPE;
4746 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4747 if ( !mesh ) return aNodePosition;
4749 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4751 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4753 aNodePosition->shapeID = aNode->getshapeId();
4754 switch ( pos->GetTypeOfPosition() ) {
4756 aNodePosition->shapeType = GEOM::EDGE;
4757 aNodePosition->params.length(1);
4758 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4760 case SMDS_TOP_FACE: {
4761 SMDS_FacePositionPtr fPos = pos;
4762 aNodePosition->shapeType = GEOM::FACE;
4763 aNodePosition->params.length(2);
4764 aNodePosition->params[0] = fPos->GetUParameter();
4765 aNodePosition->params[1] = fPos->GetVParameter();
4768 case SMDS_TOP_VERTEX:
4769 aNodePosition->shapeType = GEOM::VERTEX;
4771 case SMDS_TOP_3DSPACE:
4772 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4773 aNodePosition->shapeType = GEOM::SOLID;
4774 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4775 aNodePosition->shapeType = GEOM::SHELL;
4781 return aNodePosition;
4784 //=============================================================================
4786 * \brief Return position of an element on shape
4788 //=============================================================================
4790 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4793 _preMeshInfo->FullLoadFromFile();
4795 SMESH::ElementPosition anElementPosition;
4796 anElementPosition.shapeID = 0;
4797 anElementPosition.shapeType = GEOM::SHAPE;
4799 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4800 if ( !mesh ) return anElementPosition;
4802 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4804 anElementPosition.shapeID = anElem->getshapeId();
4805 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4806 if ( !aSp.IsNull() ) {
4807 switch ( aSp.ShapeType() ) {
4809 anElementPosition.shapeType = GEOM::EDGE;
4812 anElementPosition.shapeType = GEOM::FACE;
4815 anElementPosition.shapeType = GEOM::VERTEX;
4818 anElementPosition.shapeType = GEOM::SOLID;
4821 anElementPosition.shapeType = GEOM::SHELL;
4827 return anElementPosition;
4830 //=============================================================================
4832 * If given element is node returns IDs of shape from position
4833 * If there is not node for given ID - returns -1
4835 //=============================================================================
4837 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4840 _preMeshInfo->FullLoadFromFile();
4842 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4843 if ( aMeshDS == NULL )
4847 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4849 return aNode->getshapeId();
4856 //=============================================================================
4858 * For given element returns ID of result shape after
4859 * ::FindShape() from SMESH_MeshEditor
4860 * If there is not element for given ID - returns -1
4862 //=============================================================================
4864 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4867 _preMeshInfo->FullLoadFromFile();
4869 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4870 if ( aMeshDS == NULL )
4873 // try to find element
4874 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4878 ::SMESH_MeshEditor aMeshEditor(_impl);
4879 int index = aMeshEditor.FindShape( elem );
4887 //=============================================================================
4889 * Returns number of nodes for given element
4890 * If there is not element for given ID - returns -1
4892 //=============================================================================
4894 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4897 _preMeshInfo->FullLoadFromFile();
4899 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4900 if ( aMeshDS == NULL ) return -1;
4901 // try to find element
4902 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4903 if(!elem) return -1;
4904 return elem->NbNodes();
4908 //=============================================================================
4910 * Returns ID of node by given index for given element
4911 * If there is not element for given ID - returns -1
4912 * If there is not node for given index - returns -2
4914 //=============================================================================
4916 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4919 _preMeshInfo->FullLoadFromFile();
4921 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4922 if ( aMeshDS == NULL ) return -1;
4923 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4924 if(!elem) return -1;
4925 if( index>=elem->NbNodes() || index<0 ) return -1;
4926 return elem->GetNode(index)->GetID();
4929 //=============================================================================
4931 * Returns IDs of nodes of given element
4933 //=============================================================================
4935 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4938 _preMeshInfo->FullLoadFromFile();
4940 SMESH::long_array_var aResult = new SMESH::long_array();
4941 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4943 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4945 aResult->length( elem->NbNodes() );
4946 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4947 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
4948 aResult[ i ] = n->GetID();
4951 return aResult._retn();
4954 //=============================================================================
4956 * Returns true if given node is medium node
4957 * in given quadratic element
4959 //=============================================================================
4961 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4964 _preMeshInfo->FullLoadFromFile();
4966 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4967 if ( aMeshDS == NULL ) return false;
4969 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4970 if(!aNode) return false;
4971 // try to find element
4972 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4973 if(!elem) return false;
4975 return elem->IsMediumNode(aNode);
4979 //=============================================================================
4981 * Returns true if given node is medium node
4982 * in one of quadratic elements
4984 //=============================================================================
4986 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4987 SMESH::ElementType theElemType)
4990 _preMeshInfo->FullLoadFromFile();
4992 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4993 if ( aMeshDS == NULL ) return false;
4996 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4997 if(!aNode) return false;
4999 SMESH_MesherHelper aHelper( *(_impl) );
5001 SMDSAbs_ElementType aType;
5002 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5003 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5004 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5005 else aType = SMDSAbs_All;
5007 return aHelper.IsMedium(aNode,aType);
5011 //=============================================================================
5013 * Returns number of edges for given element
5015 //=============================================================================
5017 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5020 _preMeshInfo->FullLoadFromFile();
5022 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5023 if ( aMeshDS == NULL ) return -1;
5024 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5025 if(!elem) return -1;
5026 return elem->NbEdges();
5030 //=============================================================================
5032 * Returns number of faces for given element
5034 //=============================================================================
5036 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5039 _preMeshInfo->FullLoadFromFile();
5041 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5042 if ( aMeshDS == NULL ) return -1;
5043 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5044 if(!elem) return -1;
5045 return elem->NbFaces();
5048 //=======================================================================
5049 //function : GetElemFaceNodes
5050 //purpose : Returns nodes of given face (counted from zero) for given element.
5051 //=======================================================================
5053 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5054 CORBA::Short faceIndex)
5057 _preMeshInfo->FullLoadFromFile();
5059 SMESH::long_array_var aResult = new SMESH::long_array();
5060 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5062 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5064 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5065 if ( faceIndex < vtool.NbFaces() )
5067 aResult->length( vtool.NbFaceNodes( faceIndex ));
5068 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5069 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5070 aResult[ i ] = nn[ i ]->GetID();
5074 return aResult._retn();
5077 //=======================================================================
5078 //function : GetFaceNormal
5079 //purpose : Returns three components of normal of given mesh face.
5080 //=======================================================================
5082 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5083 CORBA::Boolean normalized)
5086 _preMeshInfo->FullLoadFromFile();
5088 SMESH::double_array_var aResult = new SMESH::double_array();
5090 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5093 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5095 aResult->length( 3 );
5096 aResult[ 0 ] = normal.X();
5097 aResult[ 1 ] = normal.Y();
5098 aResult[ 2 ] = normal.Z();
5101 return aResult._retn();
5104 //=======================================================================
5105 //function : FindElementByNodes
5106 //purpose : Returns an element based on all given nodes.
5107 //=======================================================================
5109 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5112 _preMeshInfo->FullLoadFromFile();
5114 CORBA::Long elemID(0);
5115 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5117 vector< const SMDS_MeshNode * > nn( nodes.length() );
5118 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5119 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5122 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5123 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5124 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5125 _impl->NbVolumes( ORDER_QUADRATIC )))
5126 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5128 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5133 //================================================================================
5135 * \brief Return elements including all given nodes.
5137 //================================================================================
5139 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5140 SMESH::ElementType elemType)
5143 _preMeshInfo->FullLoadFromFile();
5145 SMESH::long_array_var result = new SMESH::long_array();
5147 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5149 vector< const SMDS_MeshNode * > nn( nodes.length() );
5150 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5151 nn[i] = mesh->FindNode( nodes[i] );
5153 std::vector<const SMDS_MeshElement *> elems;
5154 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5155 result->length( elems.size() );
5156 for ( size_t i = 0; i < elems.size(); ++i )
5157 result[i] = elems[i]->GetID();
5159 return result._retn();
5162 //=============================================================================
5164 * Returns true if given element is polygon
5166 //=============================================================================
5168 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5171 _preMeshInfo->FullLoadFromFile();
5173 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5174 if ( aMeshDS == NULL ) return false;
5175 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5176 if(!elem) return false;
5177 return elem->IsPoly();
5181 //=============================================================================
5183 * Returns true if given element is quadratic
5185 //=============================================================================
5187 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5190 _preMeshInfo->FullLoadFromFile();
5192 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5193 if ( aMeshDS == NULL ) return false;
5194 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5195 if(!elem) return false;
5196 return elem->IsQuadratic();
5199 //=============================================================================
5201 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5203 //=============================================================================
5205 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5208 _preMeshInfo->FullLoadFromFile();
5210 if ( const SMDS_BallElement* ball =
5211 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5212 return ball->GetDiameter();
5217 //=============================================================================
5219 * Returns bary center for given element
5221 //=============================================================================
5223 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5226 _preMeshInfo->FullLoadFromFile();
5228 SMESH::double_array_var aResult = new SMESH::double_array();
5229 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5230 if ( aMeshDS == NULL )
5231 return aResult._retn();
5233 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5235 return aResult._retn();
5237 if(elem->GetType()==SMDSAbs_Volume) {
5238 SMDS_VolumeTool aTool;
5239 if(aTool.Set(elem)) {
5241 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5246 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5248 double x=0., y=0., z=0.;
5249 for(; anIt->more(); ) {
5251 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5265 return aResult._retn();
5268 //================================================================================
5270 * \brief Create a group of elements preventing computation of a sub-shape
5272 //================================================================================
5274 SMESH::ListOfGroups*
5275 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5276 const char* theGroupName )
5277 throw ( SALOME::SALOME_Exception )
5279 Unexpect aCatch(SALOME_SalomeException);
5281 if ( !theGroupName || strlen( theGroupName) == 0 )
5282 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5284 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5285 ::SMESH_MeshEditor::ElemFeatures elemType;
5287 // submesh by subshape id
5288 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5289 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5292 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5293 if ( error && error->HasBadElems() )
5295 // sort bad elements by type
5296 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5297 const list<const SMDS_MeshElement*>& badElems =
5298 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5299 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5300 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5301 for ( ; elemIt != elemEnd; ++elemIt )
5303 const SMDS_MeshElement* elem = *elemIt;
5304 if ( !elem ) continue;
5306 if ( elem->GetID() < 1 )
5308 // elem is a temporary element, make a real element
5309 vector< const SMDS_MeshNode* > nodes;
5310 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5311 while ( nIt->more() && elem )
5313 nodes.push_back( nIt->next() );
5314 if ( nodes.back()->GetID() < 1 )
5315 elem = 0; // a temporary element on temporary nodes
5319 ::SMESH_MeshEditor editor( _impl );
5320 elem = editor.AddElement( nodes, elemType.Init( elem ));
5324 elemsByType[ elem->GetType() ].push_back( elem );
5327 // how many groups to create?
5329 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5330 nbTypes += int( !elemsByType[ i ].empty() );
5331 groups->length( nbTypes );
5334 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5336 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5337 if ( elems.empty() ) continue;
5339 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5340 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5342 SMESH::SMESH_Mesh_var mesh = _this();
5343 SALOMEDS::SObject_wrap aSO =
5344 _gen_i->PublishGroup( mesh, groups[ iG ],
5345 GEOM::GEOM_Object::_nil(), theGroupName);
5347 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5348 if ( !grp_i ) continue;
5350 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5351 for ( size_t iE = 0; iE < elems.size(); ++iE )
5352 grpDS->SMDSGroup().Add( elems[ iE ]);
5357 return groups._retn();
5360 //=============================================================================
5362 * Create and publish group servants if any groups were imported or created anyhow
5364 //=============================================================================
5366 void SMESH_Mesh_i::CreateGroupServants()
5368 SMESH::SMESH_Mesh_var aMesh = _this();
5371 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5372 while ( groupIt->more() )
5374 ::SMESH_Group* group = groupIt->next();
5375 int anId = group->GetID();
5377 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5378 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5380 addedIDs.insert( anId );
5382 SMESH_GroupBase_i* aGroupImpl;
5384 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5385 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5387 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5388 shape = groupOnGeom->GetShape();
5391 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5394 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5395 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5396 aGroupImpl->Register();
5398 // register CORBA object for persistence
5399 int nextId = _gen_i->RegisterObject( groupVar );
5400 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5401 else { nextId = 0; } // avoid "unused variable" warning in release mode
5403 // publishing the groups in the study
5404 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5405 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5407 if ( !addedIDs.empty() )
5410 set<int>::iterator id = addedIDs.begin();
5411 for ( ; id != addedIDs.end(); ++id )
5413 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5414 int i = std::distance( _mapGroups.begin(), it );
5415 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5420 //=============================================================================
5422 * \brief Return true if all sub-meshes are computed OK - to update an icon
5424 //=============================================================================
5426 bool SMESH_Mesh_i::IsComputedOK()
5428 return _impl->IsComputedOK();
5431 //=============================================================================
5433 * \brief Return groups cantained in _mapGroups by their IDs
5435 //=============================================================================
5437 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5439 int nbGroups = groupIDs.size();
5440 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5441 aList->length( nbGroups );
5443 list<int>::const_iterator ids = groupIDs.begin();
5444 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5446 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5447 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5448 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5450 aList->length( nbGroups );
5451 return aList._retn();
5454 //=============================================================================
5456 * \brief Return information about imported file
5458 //=============================================================================
5460 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5462 SMESH::MedFileInfo_var res( _medFileInfo );
5463 if ( !res.operator->() ) {
5464 res = new SMESH::MedFileInfo;
5466 res->fileSize = res->major = res->minor = res->release = -1;
5471 //=======================================================================
5472 //function : FileInfoToString
5473 //purpose : Persistence of file info
5474 //=======================================================================
5476 std::string SMESH_Mesh_i::FileInfoToString()
5479 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5481 s = SMESH_Comment( _medFileInfo->fileSize )
5482 << " " << _medFileInfo->major
5483 << " " << _medFileInfo->minor
5484 << " " << _medFileInfo->release
5485 << " " << _medFileInfo->fileName;
5490 //=======================================================================
5491 //function : FileInfoFromString
5492 //purpose : Persistence of file info
5493 //=======================================================================
5495 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5497 std::string size, major, minor, release, fileName;
5498 std::istringstream is(info);
5499 is >> size >> major >> minor >> release;
5500 fileName = info.data() + ( size.size() + 1 +
5503 release.size()+ 1 );
5505 _medFileInfo = new SMESH::MedFileInfo();
5506 _medFileInfo->fileName = fileName.c_str();
5507 _medFileInfo->fileSize = atoi( size.c_str() );
5508 _medFileInfo->major = atoi( major.c_str() );
5509 _medFileInfo->minor = atoi( minor.c_str() );
5510 _medFileInfo->release = atoi( release.c_str() );
5513 //=============================================================================
5515 * \brief Pass names of mesh groups from study to mesh DS
5517 //=============================================================================
5519 void SMESH_Mesh_i::checkGroupNames()
5521 int nbGrp = NbGroups();
5525 SMESH::ListOfGroups* grpList = 0;
5526 // avoid dump of "GetGroups"
5528 // store python dump into a local variable inside local scope
5529 SMESH::TPythonDump pDump; // do not delete this line of code
5530 grpList = GetGroups();
5533 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5534 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5537 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5538 if ( aGrpSO->_is_nil() )
5540 // correct name of the mesh group if necessary
5541 const char* guiName = aGrpSO->GetName();
5542 if ( strcmp(guiName, aGrp->GetName()) )
5543 aGrp->SetName( guiName );
5547 //=============================================================================
5549 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5551 //=============================================================================
5552 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5554 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5558 //=============================================================================
5560 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5562 //=============================================================================
5564 char* SMESH_Mesh_i::GetParameters()
5566 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5569 //=============================================================================
5571 * \brief Returns list of notebook variables used for last Mesh operation
5573 //=============================================================================
5574 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5576 SMESH::string_array_var aResult = new SMESH::string_array();
5577 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5579 CORBA::String_var aParameters = GetParameters();
5580 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5581 if ( aSections->length() > 0 ) {
5582 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5583 aResult->length( aVars.length() );
5584 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5585 aResult[i] = CORBA::string_dup( aVars[i] );
5588 return aResult._retn();
5591 //=======================================================================
5592 //function : GetTypes
5593 //purpose : Returns types of elements it contains
5594 //=======================================================================
5596 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5599 return _preMeshInfo->GetTypes();
5601 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5605 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5606 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5607 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5608 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5609 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5610 if (_impl->NbNodes() &&
5611 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5612 types->length( nbTypes );
5614 return types._retn();
5617 //=======================================================================
5618 //function : GetMesh
5619 //purpose : Returns self
5620 //=======================================================================
5622 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5624 return SMESH::SMESH_Mesh::_duplicate( _this() );
5627 //=======================================================================
5628 //function : IsMeshInfoCorrect
5629 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5630 // * happen if mesh data is not yet fully loaded from the file of study.
5631 //=======================================================================
5633 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5635 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5638 //=============================================================================
5640 * \brief Returns number of mesh elements per each \a EntityType
5642 //=============================================================================
5644 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5647 return _preMeshInfo->GetMeshInfo();
5649 SMESH::long_array_var aRes = new SMESH::long_array();
5650 aRes->length(SMESH::Entity_Last);
5651 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5653 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5655 return aRes._retn();
5656 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5657 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5658 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5659 return aRes._retn();
5662 //=============================================================================
5664 * \brief Returns number of mesh elements per each \a ElementType
5666 //=============================================================================
5668 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5670 SMESH::long_array_var aRes = new SMESH::long_array();
5671 aRes->length(SMESH::NB_ELEMENT_TYPES);
5672 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5675 const SMDS_MeshInfo* meshInfo = 0;
5677 meshInfo = _preMeshInfo;
5678 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5679 meshInfo = & meshDS->GetMeshInfo();
5682 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5683 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5685 return aRes._retn();
5688 //=============================================================================
5690 * Collect statistic of mesh elements given by iterator
5692 //=============================================================================
5694 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5695 SMESH::long_array& theInfo)
5697 if (!theItr) return;
5698 while (theItr->more())
5699 theInfo[ theItr->next()->GetEntityType() ]++;
5701 //=============================================================================
5703 * Returns mesh unstructed grid information.
5705 //=============================================================================
5707 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5709 SALOMEDS::TMPFile_var SeqFile;
5710 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5711 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5713 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5714 aWriter->WriteToOutputStringOn();
5715 aWriter->SetInputData(aGrid);
5716 aWriter->SetFileTypeToBinary();
5718 char* str = aWriter->GetOutputString();
5719 int size = aWriter->GetOutputStringLength();
5721 //Allocate octet buffer of required size
5722 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5723 //Copy ostrstream content to the octet buffer
5724 memcpy(OctetBuf, str, size);
5725 //Create and return TMPFile
5726 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5730 return SeqFile._retn();
5733 //=============================================================================
5734 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5735 * SMESH::ElementType type) */
5737 using namespace SMESH::Controls;
5738 //-----------------------------------------------------------------------------
5739 struct PredicateIterator : public SMDS_ElemIterator
5741 SMDS_ElemIteratorPtr _elemIter;
5742 PredicatePtr _predicate;
5743 const SMDS_MeshElement* _elem;
5744 SMDSAbs_ElementType _type;
5746 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5747 PredicatePtr predicate,
5748 SMDSAbs_ElementType type):
5749 _elemIter(iterator), _predicate(predicate), _type(type)
5757 virtual const SMDS_MeshElement* next()
5759 const SMDS_MeshElement* res = _elem;
5761 while ( _elemIter->more() && !_elem )
5763 if ((_elem = _elemIter->next()) &&
5764 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5765 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5772 //-----------------------------------------------------------------------------
5773 struct IDSourceIterator : public SMDS_ElemIterator
5775 const CORBA::Long* _idPtr;
5776 const CORBA::Long* _idEndPtr;
5777 SMESH::long_array_var _idArray;
5778 const SMDS_Mesh* _mesh;
5779 const SMDSAbs_ElementType _type;
5780 const SMDS_MeshElement* _elem;
5782 IDSourceIterator( const SMDS_Mesh* mesh,
5783 const CORBA::Long* ids,
5785 SMDSAbs_ElementType type):
5786 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5788 if ( _idPtr && nbIds && _mesh )
5791 IDSourceIterator( const SMDS_Mesh* mesh,
5792 SMESH::long_array* idArray,
5793 SMDSAbs_ElementType type):
5794 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5796 if ( idArray && _mesh )
5798 _idPtr = &_idArray[0];
5799 _idEndPtr = _idPtr + _idArray->length();
5807 virtual const SMDS_MeshElement* next()
5809 const SMDS_MeshElement* res = _elem;
5811 while ( _idPtr < _idEndPtr && !_elem )
5813 if ( _type == SMDSAbs_Node )
5815 _elem = _mesh->FindNode( *_idPtr++ );
5817 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5818 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5826 //-----------------------------------------------------------------------------
5828 struct NodeOfElemIterator : public SMDS_ElemIterator
5830 TColStd_MapOfInteger _checkedNodeIDs;
5831 SMDS_ElemIteratorPtr _elemIter;
5832 SMDS_ElemIteratorPtr _nodeIter;
5833 const SMDS_MeshElement* _node;
5835 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5837 if ( _elemIter && _elemIter->more() )
5839 _nodeIter = _elemIter->next()->nodesIterator();
5847 virtual const SMDS_MeshElement* next()
5849 const SMDS_MeshElement* res = _node;
5851 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5853 if ( _nodeIter->more() )
5855 _node = _nodeIter->next();
5856 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5861 _nodeIter = _elemIter->next()->nodesIterator();
5869 //=============================================================================
5871 * Return iterator on elements of given type in given object
5873 //=============================================================================
5875 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5876 SMESH::ElementType theType)
5878 SMDS_ElemIteratorPtr elemIt;
5879 bool typeOK = ( theType == SMESH::ALL );
5880 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5882 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5883 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5884 if ( !mesh_i ) return elemIt;
5885 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5887 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5889 elemIt = meshDS->elementsIterator( elemType );
5892 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5894 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5897 elemIt = sm->GetElements();
5898 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5900 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5901 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5905 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5907 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5908 if ( groupDS && ( elemType == groupDS->GetType() ||
5909 elemType == SMDSAbs_Node ||
5910 elemType == SMDSAbs_All ))
5912 elemIt = groupDS->GetElements();
5913 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5916 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5918 if ( filter_i->GetElementType() == theType ||
5919 filter_i->GetElementType() == SMESH::ALL ||
5920 elemType == SMDSAbs_Node ||
5921 elemType == SMDSAbs_All)
5923 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5924 if ( pred_i && pred_i->GetPredicate() )
5926 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5927 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5928 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
5929 elemIt = SMDS_ElemIteratorPtr
5930 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
5931 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
5937 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5938 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5939 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5941 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
5942 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5945 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5946 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
5950 SMESH::long_array_var ids = theObject->GetIDs();
5951 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
5953 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5956 if ( elemIt && elemIt->more() && !typeOK )
5958 if ( elemType == SMDSAbs_Node )
5960 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5964 elemIt = SMDS_ElemIteratorPtr();
5970 //=============================================================================
5971 namespace // Finding concurrent hypotheses
5972 //=============================================================================
5976 * \brief mapping of mesh dimension into shape type
5978 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5980 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5982 case 0: aType = TopAbs_VERTEX; break;
5983 case 1: aType = TopAbs_EDGE; break;
5984 case 2: aType = TopAbs_FACE; break;
5986 default:aType = TopAbs_SOLID; break;
5991 //-----------------------------------------------------------------------------
5993 * \brief Internal structure used to find concurrent submeshes
5995 * It represents a pair < submesh, concurrent dimension >, where
5996 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5997 * with another submesh. In other words, it is dimension of a hypothesis assigned
6004 int _dim; //!< a dimension the algo can build (concurrent dimension)
6005 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6006 TopTools_MapOfShape _shapeMap;
6007 SMESH_subMesh* _subMesh;
6008 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6010 //-----------------------------------------------------------------------------
6011 // Return the algorithm
6012 const SMESH_Algo* GetAlgo() const
6013 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6015 //-----------------------------------------------------------------------------
6017 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6019 const TopoDS_Shape& theShape)
6021 _subMesh = (SMESH_subMesh*)theSubMesh;
6022 SetShape( theDim, theShape );
6025 //-----------------------------------------------------------------------------
6027 void SetShape(const int theDim,
6028 const TopoDS_Shape& theShape)
6031 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6032 if (_dim >= _ownDim)
6033 _shapeMap.Add( theShape );
6035 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6036 for( ; anExp.More(); anExp.Next() )
6037 _shapeMap.Add( anExp.Current() );
6041 //-----------------------------------------------------------------------------
6042 //! Check sharing of sub-shapes
6043 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6044 const TopTools_MapOfShape& theToFind,
6045 const TopAbs_ShapeEnum theType)
6047 bool isShared = false;
6048 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6049 for (; !isShared && anItr.More(); anItr.Next() )
6051 const TopoDS_Shape aSubSh = anItr.Key();
6052 // check for case when concurrent dimensions are same
6053 isShared = theToFind.Contains( aSubSh );
6054 // check for sub-shape with concurrent dimension
6055 TopExp_Explorer anExp( aSubSh, theType );
6056 for ( ; !isShared && anExp.More(); anExp.Next() )
6057 isShared = theToFind.Contains( anExp.Current() );
6062 //-----------------------------------------------------------------------------
6063 //! check algorithms
6064 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6065 const SMESHDS_Hypothesis* theA2)
6067 if ( !theA1 || !theA2 ||
6068 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6069 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6070 return false; // one of the hypothesis is not algorithm
6071 // check algorithm names (should be equal)
6072 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6076 //-----------------------------------------------------------------------------
6077 //! Check if sub-shape hypotheses are concurrent
6078 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6080 if ( _subMesh == theOther->_subMesh )
6081 return false; // same sub-shape - should not be
6083 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6084 // any of the two submeshes is not on COMPOUND shape )
6085 // -> no concurrency
6086 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6087 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6088 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6089 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6090 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6093 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6094 if ( !checkSubShape )
6097 // check algorithms to be same
6098 const SMESH_Algo* a1 = this->GetAlgo();
6099 const SMESH_Algo* a2 = theOther->GetAlgo();
6100 bool isSame = checkAlgo( a1, a2 );
6104 return false; // pb?
6105 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6108 // check hypothesises for concurrence (skip first as algorithm)
6110 // pointers should be same, because it is referened from mesh hypothesis partition
6111 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6112 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6113 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6114 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6116 // the submeshes are concurrent if their algorithms has different parameters
6117 return nbSame != theOther->_hypotheses.size() - 1;
6120 // Return true if algorithm of this SMESH_DimHyp is used if no
6121 // sub-mesh order is imposed by the user
6122 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6124 // NeedDiscreteBoundary() algo has a higher priority
6125 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6126 theOther->GetAlgo()->NeedDiscreteBoundary() )
6127 return !this->GetAlgo()->NeedDiscreteBoundary();
6129 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6132 }; // end of SMESH_DimHyp
6133 //-----------------------------------------------------------------------------
6135 typedef list<const SMESH_DimHyp*> TDimHypList;
6137 //-----------------------------------------------------------------------------
6139 void addDimHypInstance(const int theDim,
6140 const TopoDS_Shape& theShape,
6141 const SMESH_Algo* theAlgo,
6142 const SMESH_subMesh* theSubMesh,
6143 const list <const SMESHDS_Hypothesis*>& theHypList,
6144 TDimHypList* theDimHypListArr )
6146 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6147 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6148 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6149 dimHyp->_hypotheses.push_front(theAlgo);
6150 listOfdimHyp.push_back( dimHyp );
6153 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6154 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6155 theHypList.begin(), theHypList.end() );
6158 //-----------------------------------------------------------------------------
6159 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6160 TDimHypList& theListOfConcurr)
6162 if ( theListOfConcurr.empty() )
6164 theListOfConcurr.push_back( theDimHyp );
6168 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6169 while ( hypIt != theListOfConcurr.end() &&
6170 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6172 theListOfConcurr.insert( hypIt, theDimHyp );
6176 //-----------------------------------------------------------------------------
6177 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6178 const TDimHypList& theListOfDimHyp,
6179 TDimHypList& theListOfConcurrHyp,
6180 set<int>& theSetOfConcurrId )
6182 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6183 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6185 const SMESH_DimHyp* curDimHyp = *rIt;
6186 if ( curDimHyp == theDimHyp )
6187 break; // meet own dimHyp pointer in same dimension
6189 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6190 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6192 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6197 //-----------------------------------------------------------------------------
6198 void unionLists(TListOfInt& theListOfId,
6199 TListOfListOfInt& theListOfListOfId,
6202 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6203 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6205 continue; //skip already treated lists
6206 // check if other list has any same submesh object
6207 TListOfInt& otherListOfId = *it;
6208 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6209 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6212 // union two lists (from source into target)
6213 TListOfInt::iterator it2 = otherListOfId.begin();
6214 for ( ; it2 != otherListOfId.end(); it2++ ) {
6215 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6216 theListOfId.push_back(*it2);
6218 // clear source list
6219 otherListOfId.clear();
6222 //-----------------------------------------------------------------------------
6224 //! free memory allocated for dimension-hypothesis objects
6225 void removeDimHyps( TDimHypList* theArrOfList )
6227 for (int i = 0; i < 4; i++ ) {
6228 TDimHypList& listOfdimHyp = theArrOfList[i];
6229 TDimHypList::const_iterator it = listOfdimHyp.begin();
6230 for ( ; it != listOfdimHyp.end(); it++ )
6235 //-----------------------------------------------------------------------------
6237 * \brief find common submeshes with given submesh
6238 * \param theSubMeshList list of already collected submesh to check
6239 * \param theSubMesh given submesh to intersect with other
6240 * \param theCommonSubMeshes collected common submeshes
6242 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6243 const SMESH_subMesh* theSubMesh,
6244 set<const SMESH_subMesh*>& theCommon )
6248 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6249 for ( ; it != theSubMeshList.end(); it++ )
6250 theSubMesh->FindIntersection( *it, theCommon );
6251 theSubMeshList.push_back( theSubMesh );
6252 //theCommon.insert( theSubMesh );
6255 //-----------------------------------------------------------------------------
6256 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6258 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6259 for ( ; listsIt != smLists.end(); ++listsIt )
6261 const TListOfInt& smIDs = *listsIt;
6262 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6270 //=============================================================================
6272 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6274 //=============================================================================
6276 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6278 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6279 if ( isSubMeshInList( submeshID, anOrder ))
6282 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6283 return isSubMeshInList( submeshID, allConurrent );
6286 //=============================================================================
6288 * \brief Return submesh objects list in meshing order
6290 //=============================================================================
6292 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6294 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6296 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6298 return aResult._retn();
6300 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6301 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6302 anOrder.splice( anOrder.end(), allConurrent );
6305 TListOfListOfInt::iterator listIt = anOrder.begin();
6306 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6307 unionLists( *listIt, anOrder, listIndx + 1 );
6309 // convert submesh ids into interface instances
6310 // and dump command into python
6311 convertMeshOrder( anOrder, aResult, false );
6313 return aResult._retn();
6316 //=============================================================================
6318 * \brief Finds concurrent sub-meshes
6320 //=============================================================================
6322 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6324 TListOfListOfInt anOrder;
6325 ::SMESH_Mesh& mesh = GetImpl();
6327 // collect submeshes and detect concurrent algorithms and hypothesises
6328 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6330 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6331 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6332 ::SMESH_subMesh* sm = (*i_sm).second;
6334 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6336 // list of assigned hypothesises
6337 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6338 // Find out dimensions where the submesh can be concurrent.
6339 // We define the dimensions by algo of each of hypotheses in hypList
6340 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6341 for( ; hypIt != hypList.end(); hypIt++ ) {
6342 SMESH_Algo* anAlgo = 0;
6343 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6344 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6345 // hyp it-self is algo
6346 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6348 // try to find algorithm with help of sub-shapes
6349 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6350 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6351 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6354 continue; // no algorithm assigned to a current submesh
6356 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6357 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6359 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6360 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6361 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6363 } // end iterations on submesh
6365 // iterate on created dimension-hypotheses and check for concurrents
6366 for ( int i = 0; i < 4; i++ ) {
6367 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6368 // check for concurrents in own and other dimensions (step-by-step)
6369 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6370 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6371 const SMESH_DimHyp* dimHyp = *dhIt;
6372 TDimHypList listOfConcurr;
6373 set<int> setOfConcurrIds;
6374 // looking for concurrents and collect into own list
6375 for ( int j = i; j < 4; j++ )
6376 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6377 // check if any concurrents found
6378 if ( listOfConcurr.size() > 0 ) {
6379 // add own submesh to list of concurrent
6380 addInOrderOfPriority( dimHyp, listOfConcurr );
6381 list<int> listOfConcurrIds;
6382 TDimHypList::iterator hypIt = listOfConcurr.begin();
6383 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6384 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6385 anOrder.push_back( listOfConcurrIds );
6390 removeDimHyps(dimHypListArr);
6392 // now, minimize the number of concurrent groups
6393 // Here we assume that lists of submeshes can have same submesh
6394 // in case of multi-dimension algorithms, as result
6395 // list with common submesh has to be united into one list
6397 TListOfListOfInt::iterator listIt = anOrder.begin();
6398 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6399 unionLists( *listIt, anOrder, listIndx + 1 );
6405 //=============================================================================
6407 * \brief Set submesh object order
6408 * \param theSubMeshArray submesh array order
6410 //=============================================================================
6412 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6415 _preMeshInfo->ForgetOrLoad();
6418 ::SMESH_Mesh& mesh = GetImpl();
6420 TPythonDump aPythonDump; // prevent dump of called methods
6421 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6423 TListOfListOfInt subMeshOrder;
6424 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6426 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6427 TListOfInt subMeshIds;
6429 aPythonDump << ", ";
6430 aPythonDump << "[ ";
6431 // Collect subMeshes which should be clear
6432 // do it list-by-list, because modification of submesh order
6433 // take effect between concurrent submeshes only
6434 set<const SMESH_subMesh*> subMeshToClear;
6435 list<const SMESH_subMesh*> subMeshList;
6436 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6438 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6440 aPythonDump << ", ";
6441 aPythonDump << subMesh;
6442 subMeshIds.push_back( subMesh->GetId() );
6443 // detect common parts of submeshes
6444 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6445 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6447 aPythonDump << " ]";
6448 subMeshOrder.push_back( subMeshIds );
6450 // clear collected sub-meshes
6451 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6452 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6453 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6455 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6456 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6457 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6460 aPythonDump << " ])";
6462 mesh.SetMeshOrder( subMeshOrder );
6465 SMESH::SMESH_Mesh_var me = _this();
6466 _gen_i->UpdateIcons( me );
6471 //=============================================================================
6473 * \brief Convert submesh ids into submesh interfaces
6475 //=============================================================================
6477 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6478 SMESH::submesh_array_array& theResOrder,
6479 const bool theIsDump)
6481 int nbSet = theIdsOrder.size();
6482 TPythonDump aPythonDump; // prevent dump of called methods
6484 aPythonDump << "[ ";
6485 theResOrder.length(nbSet);
6486 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6488 for( ; it != theIdsOrder.end(); it++ ) {
6489 // translate submesh identificators into submesh objects
6490 // takeing into account real number of concurrent lists
6491 const TListOfInt& aSubOrder = (*it);
6492 if (!aSubOrder.size())
6495 aPythonDump << "[ ";
6496 // convert shape indices into interfaces
6497 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6498 aResSubSet->length(aSubOrder.size());
6499 TListOfInt::const_iterator subIt = aSubOrder.begin();
6501 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6502 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6504 SMESH::SMESH_subMesh_var subMesh =
6505 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6508 aPythonDump << ", ";
6509 aPythonDump << subMesh;
6511 aResSubSet[ j++ ] = subMesh;
6514 aPythonDump << " ]";
6516 theResOrder[ listIndx++ ] = aResSubSet;
6518 // correct number of lists
6519 theResOrder.length( listIndx );
6522 // finilise python dump
6523 aPythonDump << " ]";
6524 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6528 namespace // utils used by SMESH_MeshPartDS
6531 * \brief Class used to access to protected data of SMDS_MeshInfo
6533 struct TMeshInfo : public SMDS_MeshInfo
6535 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6538 * \brief Element holing its ID only
6540 struct TElemID : public SMDS_LinearEdge
6542 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6546 //================================================================================
6548 // Implementation of SMESH_MeshPartDS
6550 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6551 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6553 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6554 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6557 _meshDS = mesh_i->GetImpl().GetMeshDS();
6559 SetPersistentId( _meshDS->GetPersistentId() );
6561 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6563 // <meshPart> is the whole mesh
6564 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6566 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6567 myGroupSet = _meshDS->GetGroups();
6572 SMESH::long_array_var anIDs = meshPart->GetIDs();
6573 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6574 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6576 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6577 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6578 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6583 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6584 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6585 if ( _elements[ e->GetType() ].insert( e ).second )
6588 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6589 while ( nIt->more() )
6591 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6592 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6599 ShapeToMesh( _meshDS->ShapeToMesh() );
6601 _meshDS = 0; // to enforce iteration on _elements and _nodes
6604 // -------------------------------------------------------------------------------------
6605 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6606 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6609 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6610 for ( ; partIt != meshPart.end(); ++partIt )
6611 if ( const SMDS_MeshElement * e = *partIt )
6612 if ( _elements[ e->GetType() ].insert( e ).second )
6615 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6616 while ( nIt->more() )
6618 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6619 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6625 // -------------------------------------------------------------------------------------
6626 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6628 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6630 TElemID elem( IDelem );
6631 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6632 if ( !_elements[ iType ].empty() )
6634 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6635 if ( it != _elements[ iType ].end() )
6640 // -------------------------------------------------------------------------------------
6641 bool SMESH_MeshPartDS::HasNumerationHoles()
6643 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6645 return ( MinNodeID() != 1 ||
6646 MaxNodeID() != NbNodes() ||
6647 MinElementID() != 1 ||
6648 MaxElementID() != NbElements() );
6650 // -------------------------------------------------------------------------------------
6651 int SMESH_MeshPartDS::MaxNodeID() const
6653 if ( _meshDS ) return _meshDS->MaxNodeID();
6654 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6656 // -------------------------------------------------------------------------------------
6657 int SMESH_MeshPartDS::MinNodeID() const
6659 if ( _meshDS ) return _meshDS->MinNodeID();
6660 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6662 // -------------------------------------------------------------------------------------
6663 int SMESH_MeshPartDS::MaxElementID() const
6665 if ( _meshDS ) return _meshDS->MaxElementID();
6667 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6668 if ( !_elements[ iType ].empty() )
6669 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6672 // -------------------------------------------------------------------------------------
6673 int SMESH_MeshPartDS::MinElementID() const
6675 if ( _meshDS ) return _meshDS->MinElementID();
6677 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6678 if ( !_elements[ iType ].empty() )
6679 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6682 // -------------------------------------------------------------------------------------
6683 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6685 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6687 typedef SMDS_SetIterator
6688 <const SMDS_MeshElement*,
6689 TIDSortedElemSet::const_iterator,
6690 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6691 SMDS_MeshElement::GeomFilter
6694 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6696 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6697 _elements[type].end(),
6698 SMDS_MeshElement::GeomFilter( geomType )));
6700 // -------------------------------------------------------------------------------------
6701 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6703 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6705 typedef SMDS_SetIterator
6706 <const SMDS_MeshElement*,
6707 TIDSortedElemSet::const_iterator,
6708 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6709 SMDS_MeshElement::EntityFilter
6712 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6714 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6715 _elements[type].end(),
6716 SMDS_MeshElement::EntityFilter( entity )));
6718 // -------------------------------------------------------------------------------------
6719 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6721 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6722 if ( type == SMDSAbs_All && !_meshDS )
6724 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6726 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6727 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6729 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6731 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6732 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6734 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6735 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6737 // -------------------------------------------------------------------------------------
6738 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6739 iterType SMESH_MeshPartDS::methName() const \
6741 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6742 return _meshDS ? _meshDS->methName() : iterType \
6743 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6745 // -------------------------------------------------------------------------------------
6746 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6747 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6748 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6749 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6750 #undef _GET_ITER_DEFINE
6752 // END Implementation of SMESH_MeshPartDS
6754 //================================================================================