1 // Copyright (C) 2007-2016 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_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 #include <vtkUnstructuredGridWriter.h>
84 // to pass CORBA exception through SMESH_TRY
85 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
87 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
90 static int MYDEBUG = 0;
92 static int MYDEBUG = 0;
96 using SMESH::TPythonDump;
98 int SMESH_Mesh_i::_idGenerator = 0;
100 //=============================================================================
104 //=============================================================================
106 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
108 : SALOME::GenericObj_i( thePOA )
112 _id = _idGenerator++;
114 _previewEditor = NULL;
119 //=============================================================================
123 //=============================================================================
125 SMESH_Mesh_i::~SMESH_Mesh_i()
128 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
129 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
130 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
132 aGroup->UnRegister();
133 SMESH::SMESH_GroupBase_var( itGr->second );
138 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
139 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
140 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
142 aSubMesh->UnRegister();
143 SMESH::SMESH_subMesh_var( itSM->second );
145 _mapSubMeshIor.clear();
147 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
148 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
149 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
150 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
151 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
152 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
155 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
159 // clear cashed shapes if no more meshes remain; (the cash is blame,
160 // together with publishing, of spent time increasing in issue 22874)
161 if ( _impl->NbMeshes() == 1 )
162 _gen_i->GetShapeReader()->ClearClientBuffer();
164 delete _editor; _editor = NULL;
165 delete _previewEditor; _previewEditor = NULL;
166 delete _impl; _impl = NULL;
167 delete _preMeshInfo; _preMeshInfo = NULL;
170 //=============================================================================
174 * Associates <this> mesh with <theShape> and puts a reference
175 * to <theShape> into the current study;
176 * the previous shape is substituted by the new one.
178 //=============================================================================
180 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
181 throw (SALOME::SALOME_Exception)
183 Unexpect aCatch(SALOME_SalomeException);
185 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
187 catch(SALOME_Exception & S_ex) {
188 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
190 // to track changes of GEOM groups
191 SMESH::SMESH_Mesh_var mesh = _this();
192 addGeomGroupData( theShapeObject, mesh );
193 if ( !CORBA::is_nil( theShapeObject ))
194 _mainShapeTick = theShapeObject->GetTick();
197 //================================================================================
199 * \brief return true if mesh has a shape to build a shape on
201 //================================================================================
203 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
204 throw (SALOME::SALOME_Exception)
206 Unexpect aCatch(SALOME_SalomeException);
209 res = _impl->HasShapeToMesh();
211 catch(SALOME_Exception & S_ex) {
212 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
217 //=======================================================================
218 //function : GetShapeToMesh
220 //=======================================================================
222 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
223 throw (SALOME::SALOME_Exception)
225 Unexpect aCatch(SALOME_SalomeException);
226 GEOM::GEOM_Object_var aShapeObj;
228 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
231 aShapeObj = _gen_i->ShapeToGeomObject( S );
232 if ( aShapeObj->_is_nil() )
234 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
235 // find GEOM_Object by entry (IPAL52735)
236 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
237 for ( ; data != _geomGroupData.end(); ++data )
238 if ( data->_smeshObject->_is_equivalent( _this() ))
240 SALOMEDS::SObject_wrap so = SMESH_Gen_i::getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
241 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
242 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
248 catch(SALOME_Exception & S_ex) {
249 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
251 return aShapeObj._retn();
254 //================================================================================
256 * \brief Return false if the mesh is not yet fully loaded from the study file
258 //================================================================================
260 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
262 Unexpect aCatch(SALOME_SalomeException);
263 return !_preMeshInfo;
266 //================================================================================
268 * \brief Load full mesh data from the study file
270 //================================================================================
272 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
274 Unexpect aCatch(SALOME_SalomeException);
276 _preMeshInfo->FullLoadFromFile();
279 //================================================================================
281 * \brief Remove all nodes and elements
283 //================================================================================
285 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
287 Unexpect aCatch(SALOME_SalomeException);
289 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
293 //CheckGeomGroupModif(); // issue 20145
295 catch(SALOME_Exception & S_ex) {
296 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
299 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
302 //================================================================================
304 * \brief Remove all nodes and elements for indicated shape
306 //================================================================================
308 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
309 throw (SALOME::SALOME_Exception)
311 Unexpect aCatch(SALOME_SalomeException);
313 _preMeshInfo->FullLoadFromFile();
316 _impl->ClearSubMesh( ShapeID );
318 catch(SALOME_Exception & S_ex) {
319 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
321 _impl->GetMeshDS()->Modified();
323 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
326 //=============================================================================
328 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
330 //=============================================================================
332 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
334 SMESH::DriverMED_ReadStatus res;
337 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
338 res = SMESH::DRS_OK; break;
339 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
340 res = SMESH::DRS_EMPTY; break;
341 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
342 res = SMESH::DRS_WARN_RENUMBER; break;
343 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
344 res = SMESH::DRS_WARN_SKIP_ELEM; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
346 res = SMESH::DRS_WARN_DESCENDING; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
349 res = SMESH::DRS_FAIL; break;
354 //=============================================================================
356 * Convert ::SMESH_ComputeError to SMESH::ComputeError
358 //=============================================================================
360 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
362 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
363 errVar->subShapeID = -1;
364 errVar->hasBadMesh = false;
366 if ( !errorPtr || errorPtr->IsOK() )
368 errVar->code = SMESH::COMPERR_OK;
372 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
373 errVar->comment = errorPtr->myComment.c_str();
375 return errVar._retn();
378 //=============================================================================
382 * Imports mesh data from MED file
384 //=============================================================================
386 SMESH::DriverMED_ReadStatus
387 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
388 throw ( SALOME::SALOME_Exception )
390 Unexpect aCatch(SALOME_SalomeException);
393 status = _impl->MEDToMesh( theFileName, theMeshName );
395 catch( SALOME_Exception& S_ex ) {
396 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
399 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
402 CreateGroupServants();
404 int major, minor, release;
405 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
406 major = minor = release = -1;
407 _medFileInfo = new SMESH::MedFileInfo();
408 _medFileInfo->fileName = theFileName;
409 _medFileInfo->fileSize = 0;
410 _medFileInfo->major = major;
411 _medFileInfo->minor = minor;
412 _medFileInfo->release = release;
413 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
415 return ConvertDriverMEDReadStatus(status);
418 //================================================================================
420 * \brief Imports mesh data from the CGNS file
422 //================================================================================
424 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
425 const int theMeshIndex,
426 std::string& theMeshName )
427 throw ( SALOME::SALOME_Exception )
429 Unexpect aCatch(SALOME_SalomeException);
432 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
434 catch( SALOME_Exception& S_ex ) {
435 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
438 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
441 CreateGroupServants();
443 return ConvertDriverMEDReadStatus(status);
446 //================================================================================
448 * \brief Return string representation of a MED file version comprising nbDigits
450 //================================================================================
452 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
454 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
456 return CORBA::string_dup( ver.c_str() );
459 //=============================================================================
463 * Imports mesh data from MED file
465 //=============================================================================
467 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
468 throw ( SALOME::SALOME_Exception )
472 // Read mesh with name = <theMeshName> into SMESH_Mesh
473 _impl->UNVToMesh( theFileName );
475 CreateGroupServants();
477 SMESH_CATCH( SMESH::throwCorbaException );
482 //=============================================================================
486 * Imports mesh data from STL file
488 //=============================================================================
489 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
490 throw ( SALOME::SALOME_Exception )
494 // Read mesh with name = <theMeshName> into SMESH_Mesh
495 std::string name = _impl->STLToMesh( theFileName );
498 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
499 _gen_i->SetName( meshSO, name.c_str() );
502 SMESH_CATCH( SMESH::throwCorbaException );
507 //================================================================================
509 * \brief Function used in SMESH_CATCH by ImportGMFFile()
511 //================================================================================
515 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
517 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
521 //================================================================================
523 * \brief Imports data from a GMF file and returns an error description
525 //================================================================================
527 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
528 bool theMakeRequiredGroups )
529 throw (SALOME::SALOME_Exception)
531 SMESH_ComputeErrorPtr error;
534 #define SMESH_CAUGHT error =
537 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
539 SMESH_CATCH( exceptionToComputeError );
543 CreateGroupServants();
545 return ConvertComputeError( error );
548 //=============================================================================
552 //=============================================================================
554 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
556 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
557 (SMESH_Hypothesis::Hypothesis_Status theStatus)
560 RETURNCASE( HYP_OK );
561 RETURNCASE( HYP_MISSING );
562 RETURNCASE( HYP_CONCURENT );
563 RETURNCASE( HYP_BAD_PARAMETER );
564 RETURNCASE( HYP_HIDDEN_ALGO );
565 RETURNCASE( HYP_HIDING_ALGO );
566 RETURNCASE( HYP_UNKNOWN_FATAL );
567 RETURNCASE( HYP_INCOMPATIBLE );
568 RETURNCASE( HYP_NOTCONFORM );
569 RETURNCASE( HYP_ALREADY_EXIST );
570 RETURNCASE( HYP_BAD_DIM );
571 RETURNCASE( HYP_BAD_SUBSHAPE );
572 RETURNCASE( HYP_BAD_GEOMETRY );
573 RETURNCASE( HYP_NEED_SHAPE );
574 RETURNCASE( HYP_INCOMPAT_HYPS );
577 return SMESH::HYP_UNKNOWN_FATAL;
580 //=============================================================================
584 * calls internal addHypothesis() and then adds a reference to <anHyp> under
585 * the SObject actually having a reference to <aSubShape>.
586 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
588 //=============================================================================
590 SMESH::Hypothesis_Status
591 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
592 SMESH::SMESH_Hypothesis_ptr anHyp,
593 CORBA::String_out anErrorText)
594 throw(SALOME::SALOME_Exception)
596 Unexpect aCatch(SALOME_SalomeException);
598 _preMeshInfo->ForgetOrLoad();
601 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
602 anErrorText = error.c_str();
604 SMESH::SMESH_Mesh_var mesh( _this() );
605 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
607 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
609 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
611 // Update Python script
612 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
613 << aSubShape << ", " << anHyp << " )";
615 return ConvertHypothesisStatus(status);
618 //=============================================================================
622 //=============================================================================
624 SMESH_Hypothesis::Hypothesis_Status
625 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
626 SMESH::SMESH_Hypothesis_ptr anHyp,
627 std::string* anErrorText)
629 if(MYDEBUG) MESSAGE("addHypothesis");
631 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
632 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
634 if (CORBA::is_nil( anHyp ))
635 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
637 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
640 TopoDS_Shape myLocSubShape;
641 //use PseudoShape in case if mesh has no shape
643 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
645 myLocSubShape = _impl->GetShapeToMesh();
647 const int hypId = anHyp->GetId();
649 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
650 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
652 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
654 // assure there is a corresponding submesh
655 if ( !_impl->IsMainShape( myLocSubShape )) {
656 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
657 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
658 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
661 else if ( anErrorText )
663 *anErrorText = error;
666 catch(SALOME_Exception & S_ex)
668 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
673 //=============================================================================
677 //=============================================================================
679 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
680 SMESH::SMESH_Hypothesis_ptr anHyp)
681 throw(SALOME::SALOME_Exception)
683 Unexpect aCatch(SALOME_SalomeException);
685 _preMeshInfo->ForgetOrLoad();
687 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
688 SMESH::SMESH_Mesh_var mesh = _this();
690 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
692 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
694 // Update Python script
695 if(_impl->HasShapeToMesh())
696 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
697 << aSubShape << ", " << anHyp << " )";
699 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
702 return ConvertHypothesisStatus(status);
705 //=============================================================================
709 //=============================================================================
711 SMESH_Hypothesis::Hypothesis_Status
712 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
713 SMESH::SMESH_Hypothesis_ptr anHyp)
715 if(MYDEBUG) MESSAGE("removeHypothesis()");
717 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
718 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
720 if (CORBA::is_nil( anHyp ))
721 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
723 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
726 TopoDS_Shape myLocSubShape;
727 //use PseudoShape in case if mesh has no shape
728 if( _impl->HasShapeToMesh() )
729 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
731 myLocSubShape = _impl->GetShapeToMesh();
733 const int hypId = anHyp->GetId();
734 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
735 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
737 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
741 catch(SALOME_Exception & S_ex)
743 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
748 //=============================================================================
752 //=============================================================================
754 SMESH::ListOfHypothesis *
755 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
756 throw(SALOME::SALOME_Exception)
758 Unexpect aCatch(SALOME_SalomeException);
759 if (MYDEBUG) MESSAGE("GetHypothesisList");
760 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
761 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
763 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
766 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
767 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
768 myLocSubShape = _impl->GetShapeToMesh();
769 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
770 int i = 0, n = aLocalList.size();
773 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
774 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
775 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
777 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
778 if ( id_hypptr != _mapHypo.end() )
779 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
783 catch(SALOME_Exception & S_ex) {
784 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
787 return aList._retn();
790 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
792 Unexpect aCatch(SALOME_SalomeException);
793 if (MYDEBUG) MESSAGE("GetSubMeshes");
795 SMESH::submesh_array_var aList = new SMESH::submesh_array();
798 TPythonDump aPythonDump;
799 if ( !_mapSubMeshIor.empty() )
803 aList->length( _mapSubMeshIor.size() );
805 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
806 for ( ; it != _mapSubMeshIor.end(); it++ ) {
807 if ( CORBA::is_nil( it->second )) continue;
808 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
810 if (i > 1) aPythonDump << ", ";
811 aPythonDump << it->second;
815 catch(SALOME_Exception & S_ex) {
816 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
819 // Update Python script
820 if ( !_mapSubMeshIor.empty() )
821 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
823 return aList._retn();
826 //=============================================================================
830 //=============================================================================
832 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
833 const char* theName )
834 throw(SALOME::SALOME_Exception)
836 Unexpect aCatch(SALOME_SalomeException);
837 if (CORBA::is_nil(aSubShape))
838 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
840 SMESH::SMESH_subMesh_var subMesh;
841 SMESH::SMESH_Mesh_var aMesh = _this();
843 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
845 //Get or Create the SMESH_subMesh object implementation
847 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
849 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
851 TopoDS_Iterator it( myLocSubShape );
853 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
855 subMesh = getSubMesh( subMeshId );
857 // create a new subMesh object servant if there is none for the shape
858 if ( subMesh->_is_nil() )
859 subMesh = createSubMesh( aSubShape );
860 if ( _gen_i->CanPublishInStudy( subMesh ))
862 SALOMEDS::SObject_wrap aSO =
863 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
864 if ( !aSO->_is_nil()) {
865 // Update Python script
866 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
867 << aSubShape << ", '" << theName << "' )";
871 catch(SALOME_Exception & S_ex) {
872 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
874 return subMesh._retn();
877 //=============================================================================
881 //=============================================================================
883 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
884 throw (SALOME::SALOME_Exception)
888 if ( theSubMesh->_is_nil() )
891 GEOM::GEOM_Object_var aSubShape;
892 // Remove submesh's SObject
893 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
894 if ( !anSO->_is_nil() ) {
895 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
896 SALOMEDS::SObject_wrap anObj, aRef;
897 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
898 anObj->ReferencedObject( aRef.inout() ))
900 CORBA::Object_var obj = aRef->GetObject();
901 aSubShape = GEOM::GEOM_Object::_narrow( obj );
903 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
904 // aSubShape = theSubMesh->GetSubShape();
906 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
907 builder->RemoveObjectWithChildren( anSO );
909 // Update Python script
910 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
913 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
915 _preMeshInfo->ForgetOrLoad();
917 SMESH_CATCH( SMESH::throwCorbaException );
920 //=============================================================================
924 //=============================================================================
926 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
927 const char* theName )
928 throw(SALOME::SALOME_Exception)
930 Unexpect aCatch(SALOME_SalomeException);
932 _preMeshInfo->FullLoadFromFile();
934 SMESH::SMESH_Group_var aNewGroup =
935 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
937 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
939 SMESH::SMESH_Mesh_var mesh = _this();
940 SALOMEDS::SObject_wrap aSO =
941 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
942 if ( !aSO->_is_nil())
943 // Update Python script
944 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
945 << theElemType << ", '" << theName << "' )";
947 return aNewGroup._retn();
950 //=============================================================================
954 //=============================================================================
955 SMESH::SMESH_GroupOnGeom_ptr
956 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
958 GEOM::GEOM_Object_ptr theGeomObj)
959 throw(SALOME::SALOME_Exception)
961 Unexpect aCatch(SALOME_SalomeException);
963 _preMeshInfo->FullLoadFromFile();
965 SMESH::SMESH_GroupOnGeom_var aNewGroup;
967 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
968 if ( !aShape.IsNull() )
971 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
973 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
975 SMESH::SMESH_Mesh_var mesh = _this();
976 SALOMEDS::SObject_wrap aSO =
977 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
978 if ( !aSO->_is_nil())
979 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
980 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
984 return aNewGroup._retn();
987 //================================================================================
989 * \brief Creates a group whose contents is defined by filter
990 * \param theElemType - group type
991 * \param theName - group name
992 * \param theFilter - the filter
993 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
995 //================================================================================
997 SMESH::SMESH_GroupOnFilter_ptr
998 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1000 SMESH::Filter_ptr theFilter )
1001 throw (SALOME::SALOME_Exception)
1003 Unexpect aCatch(SALOME_SalomeException);
1005 _preMeshInfo->FullLoadFromFile();
1007 if ( CORBA::is_nil( theFilter ))
1008 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1010 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1012 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1014 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1015 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1018 if ( !aNewGroup->_is_nil() )
1019 aNewGroup->SetFilter( theFilter );
1021 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1023 SMESH::SMESH_Mesh_var mesh = _this();
1024 SALOMEDS::SObject_wrap aSO =
1025 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1027 if ( !aSO->_is_nil())
1028 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1029 << theElemType << ", '" << theName << "', " << theFilter << " )";
1031 return aNewGroup._retn();
1034 //=============================================================================
1038 //=============================================================================
1040 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1041 throw (SALOME::SALOME_Exception)
1043 if ( theGroup->_is_nil() )
1048 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1052 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1053 if ( !aGroupSO->_is_nil() )
1055 // Update Python script
1056 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1058 // Remove group's SObject
1059 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1060 builder->RemoveObjectWithChildren( aGroupSO );
1062 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1064 // Remove the group from SMESH data structures
1065 removeGroup( aGroup->GetLocalID() );
1067 SMESH_CATCH( SMESH::throwCorbaException );
1070 //=============================================================================
1072 * Remove group with its contents
1074 //=============================================================================
1076 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1077 throw (SALOME::SALOME_Exception)
1081 _preMeshInfo->FullLoadFromFile();
1083 if ( theGroup->_is_nil() )
1086 vector<int> nodeIds; // to remove nodes becoming free
1087 if ( !theGroup->IsEmpty() )
1089 CORBA::Long elemID = theGroup->GetID( 1 );
1090 int nbElemNodes = GetElemNbNodes( elemID );
1091 if ( nbElemNodes > 0 )
1092 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1096 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1097 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1098 while ( elemIt->more() )
1100 const SMDS_MeshElement* e = elemIt->next();
1102 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1103 while ( nIt->more() )
1104 nodeIds.push_back( nIt->next()->GetID() );
1106 _impl->GetMeshDS()->RemoveElement( e );
1109 // Remove free nodes
1110 if ( theGroup->GetType() != SMESH::NODE )
1111 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1112 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1113 if ( n->NbInverseElements() == 0 )
1114 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1116 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1118 // Update Python script (theGroup must be alive for this)
1119 pyDump << SMESH::SMESH_Mesh_var(_this())
1120 << ".RemoveGroupWithContents( " << theGroup << " )";
1123 RemoveGroup( theGroup );
1125 SMESH_CATCH( SMESH::throwCorbaException );
1128 //================================================================================
1130 * \brief Get the list of groups existing in the mesh
1131 * \retval SMESH::ListOfGroups * - list of groups
1133 //================================================================================
1135 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1137 Unexpect aCatch(SALOME_SalomeException);
1138 if (MYDEBUG) MESSAGE("GetGroups");
1140 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1143 TPythonDump aPythonDump;
1144 if ( !_mapGroups.empty() )
1146 aPythonDump << "[ ";
1148 aList->length( _mapGroups.size() );
1150 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1151 for ( ; it != _mapGroups.end(); it++ ) {
1152 if ( CORBA::is_nil( it->second )) continue;
1153 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1155 if (i > 1) aPythonDump << ", ";
1156 aPythonDump << it->second;
1160 catch(SALOME_Exception & S_ex) {
1161 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1163 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1165 return aList._retn();
1168 //=============================================================================
1170 * Get number of groups existing in the mesh
1172 //=============================================================================
1174 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1176 Unexpect aCatch(SALOME_SalomeException);
1177 return _mapGroups.size();
1180 //=============================================================================
1182 * New group including all mesh elements present in initial groups is created.
1184 //=============================================================================
1186 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1187 SMESH::SMESH_GroupBase_ptr theGroup2,
1188 const char* theName )
1189 throw (SALOME::SALOME_Exception)
1191 SMESH::SMESH_Group_var aResGrp;
1195 _preMeshInfo->FullLoadFromFile();
1197 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1198 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1200 if ( theGroup1->GetType() != theGroup2->GetType() )
1201 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1206 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1207 if ( aResGrp->_is_nil() )
1208 return SMESH::SMESH_Group::_nil();
1210 aResGrp->AddFrom( theGroup1 );
1211 aResGrp->AddFrom( theGroup2 );
1213 // Update Python script
1214 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1215 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1217 SMESH_CATCH( SMESH::throwCorbaException );
1219 return aResGrp._retn();
1222 //=============================================================================
1224 * \brief New group including all mesh elements present in initial groups is created.
1225 * \param theGroups list of groups
1226 * \param theName name of group to be created
1227 * \return pointer to the new group
1229 //=============================================================================
1231 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1232 const char* theName )
1233 throw (SALOME::SALOME_Exception)
1235 SMESH::SMESH_Group_var aResGrp;
1238 _preMeshInfo->FullLoadFromFile();
1241 return SMESH::SMESH_Group::_nil();
1246 SMESH::ElementType aType = SMESH::ALL;
1247 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1249 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1250 if ( CORBA::is_nil( aGrp ) )
1252 if ( aType == SMESH::ALL )
1253 aType = aGrp->GetType();
1254 else if ( aType != aGrp->GetType() )
1255 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1258 if ( aType == SMESH::ALL )
1259 return SMESH::SMESH_Group::_nil();
1264 aResGrp = CreateGroup( aType, theName );
1265 if ( aResGrp->_is_nil() )
1266 return SMESH::SMESH_Group::_nil();
1268 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1269 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1271 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1272 if ( !CORBA::is_nil( aGrp ) )
1274 aResGrp->AddFrom( aGrp );
1275 if ( g > 0 ) pyDump << ", ";
1279 pyDump << " ], '" << theName << "' )";
1281 SMESH_CATCH( SMESH::throwCorbaException );
1283 return aResGrp._retn();
1286 //=============================================================================
1288 * New group is created. All mesh elements that are
1289 * present in both initial groups are added to the new one.
1291 //=============================================================================
1293 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1294 SMESH::SMESH_GroupBase_ptr theGroup2,
1295 const char* theName )
1296 throw (SALOME::SALOME_Exception)
1298 SMESH::SMESH_Group_var aResGrp;
1303 _preMeshInfo->FullLoadFromFile();
1305 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1306 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1308 if ( theGroup1->GetType() != theGroup2->GetType() )
1309 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1313 // Create Intersection
1314 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1315 if ( aResGrp->_is_nil() )
1316 return aResGrp._retn();
1318 SMESHDS_GroupBase* groupDS1 = 0;
1319 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1320 groupDS1 = grp_i->GetGroupDS();
1322 SMESHDS_GroupBase* groupDS2 = 0;
1323 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1324 groupDS2 = grp_i->GetGroupDS();
1326 SMESHDS_Group* resGroupDS = 0;
1327 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1328 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1330 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1332 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1333 while ( elemIt1->more() )
1335 const SMDS_MeshElement* e = elemIt1->next();
1336 if ( groupDS2->Contains( e ))
1337 resGroupDS->SMDSGroup().Add( e );
1340 // Update Python script
1341 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1342 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1344 SMESH_CATCH( SMESH::throwCorbaException );
1346 return aResGrp._retn();
1349 //=============================================================================
1351 \brief Intersect list of groups. New group is created. All mesh elements that
1352 are present in all initial groups simultaneously are added to the new one.
1353 \param theGroups list of groups
1354 \param theName name of group to be created
1355 \return pointer on the group
1357 //=============================================================================
1358 SMESH::SMESH_Group_ptr
1359 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1360 const char* theName )
1361 throw (SALOME::SALOME_Exception)
1363 SMESH::SMESH_Group_var aResGrp;
1368 _preMeshInfo->FullLoadFromFile();
1371 return SMESH::SMESH_Group::_nil();
1373 // check types and get SMESHDS_GroupBase's
1374 SMESH::ElementType aType = SMESH::ALL;
1375 vector< SMESHDS_GroupBase* > groupVec;
1376 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1378 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1379 if ( CORBA::is_nil( aGrp ) )
1381 if ( aType == SMESH::ALL )
1382 aType = aGrp->GetType();
1383 else if ( aType != aGrp->GetType() )
1384 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1387 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1388 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1390 if ( grpDS->IsEmpty() )
1395 groupVec.push_back( grpDS );
1398 if ( aType == SMESH::ALL ) // all groups are nil
1399 return SMESH::SMESH_Group::_nil();
1404 aResGrp = CreateGroup( aType, theName );
1406 SMESHDS_Group* resGroupDS = 0;
1407 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1408 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1409 if ( !resGroupDS || groupVec.empty() )
1410 return aResGrp._retn();
1413 size_t i, nb = groupVec.size();
1414 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1415 while ( elemIt1->more() )
1417 const SMDS_MeshElement* e = elemIt1->next();
1419 for ( i = 1; ( i < nb && inAll ); ++i )
1420 inAll = groupVec[i]->Contains( e );
1423 resGroupDS->SMDSGroup().Add( e );
1426 // Update Python script
1427 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1428 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1430 SMESH_CATCH( SMESH::throwCorbaException );
1432 return aResGrp._retn();
1435 //=============================================================================
1437 * New group is created. All mesh elements that are present in
1438 * a main group but is not present in a tool group are added to the new one
1440 //=============================================================================
1442 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1443 SMESH::SMESH_GroupBase_ptr theGroup2,
1444 const char* theName )
1445 throw (SALOME::SALOME_Exception)
1447 SMESH::SMESH_Group_var aResGrp;
1452 _preMeshInfo->FullLoadFromFile();
1454 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1455 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1457 if ( theGroup1->GetType() != theGroup2->GetType() )
1458 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1462 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1463 if ( aResGrp->_is_nil() )
1464 return aResGrp._retn();
1466 SMESHDS_GroupBase* groupDS1 = 0;
1467 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1468 groupDS1 = grp_i->GetGroupDS();
1470 SMESHDS_GroupBase* groupDS2 = 0;
1471 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1472 groupDS2 = grp_i->GetGroupDS();
1474 SMESHDS_Group* resGroupDS = 0;
1475 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1476 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1478 if ( groupDS1 && groupDS2 && resGroupDS )
1480 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1481 while ( elemIt1->more() )
1483 const SMDS_MeshElement* e = elemIt1->next();
1484 if ( !groupDS2->Contains( e ))
1485 resGroupDS->SMDSGroup().Add( e );
1488 // Update Python script
1489 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1490 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1492 SMESH_CATCH( SMESH::throwCorbaException );
1494 return aResGrp._retn();
1497 //=============================================================================
1499 \brief Cut lists of groups. New group is created. All mesh elements that are
1500 present in main groups but do not present in tool groups are added to the new one
1501 \param theMainGroups list of main groups
1502 \param theToolGroups list of tool groups
1503 \param theName name of group to be created
1504 \return pointer on the group
1506 //=============================================================================
1507 SMESH::SMESH_Group_ptr
1508 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1509 const SMESH::ListOfGroups& theToolGroups,
1510 const char* theName )
1511 throw (SALOME::SALOME_Exception)
1513 SMESH::SMESH_Group_var aResGrp;
1518 _preMeshInfo->FullLoadFromFile();
1521 return SMESH::SMESH_Group::_nil();
1523 // check types and get SMESHDS_GroupBase's
1524 SMESH::ElementType aType = SMESH::ALL;
1525 vector< SMESHDS_GroupBase* > toolGroupVec;
1526 vector< SMDS_ElemIteratorPtr > mainIterVec;
1528 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1530 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1531 if ( CORBA::is_nil( aGrp ) )
1533 if ( aType == SMESH::ALL )
1534 aType = aGrp->GetType();
1535 else if ( aType != aGrp->GetType() )
1536 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1538 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1539 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1540 if ( !grpDS->IsEmpty() )
1541 mainIterVec.push_back( grpDS->GetElements() );
1543 if ( aType == SMESH::ALL ) // all main groups are nil
1544 return SMESH::SMESH_Group::_nil();
1545 if ( mainIterVec.empty() ) // all main groups are empty
1546 return aResGrp._retn();
1548 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1550 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1551 if ( CORBA::is_nil( aGrp ) )
1553 if ( aType != aGrp->GetType() )
1554 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1556 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1557 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1558 toolGroupVec.push_back( grpDS );
1564 aResGrp = CreateGroup( aType, theName );
1566 SMESHDS_Group* resGroupDS = 0;
1567 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1568 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1570 return aResGrp._retn();
1573 size_t i, nb = toolGroupVec.size();
1574 SMDS_ElemIteratorPtr mainElemIt
1575 ( new SMDS_IteratorOnIterators
1576 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1577 while ( mainElemIt->more() )
1579 const SMDS_MeshElement* e = mainElemIt->next();
1581 for ( i = 0; ( i < nb && !isIn ); ++i )
1582 isIn = toolGroupVec[i]->Contains( e );
1585 resGroupDS->SMDSGroup().Add( e );
1588 // Update Python script
1589 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1590 << ".CutListOfGroups( " << theMainGroups << ", "
1591 << theToolGroups << ", '" << theName << "' )";
1593 SMESH_CATCH( SMESH::throwCorbaException );
1595 return aResGrp._retn();
1598 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1600 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1601 bool & toStopChecking )
1603 toStopChecking = ( nbCommon < nbChecked );
1604 return nbCommon == nbNodes;
1606 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1607 bool & toStopChecking )
1609 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1610 return nbCommon == nbCorners;
1612 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1613 bool & toStopChecking )
1615 return nbCommon > 0;
1617 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1618 bool & toStopChecking )
1620 return nbCommon >= (nbNodes+1) / 2;
1624 //=============================================================================
1626 * Create a group of entities basing on nodes of other groups.
1627 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1628 * \param [in] anElemType - a type of elements to include to the new group.
1629 * \param [in] theName - a name of the new group.
1630 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1631 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1632 * new group provided that it is based on nodes of an element of \a aListOfGroups
1633 * \return SMESH_Group - the created group
1635 // IMP 19939, bug 22010, IMP 22635
1636 //=============================================================================
1638 SMESH::SMESH_Group_ptr
1639 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1640 SMESH::ElementType theElemType,
1641 const char* theName,
1642 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1643 CORBA::Boolean theUnderlyingOnly)
1644 throw (SALOME::SALOME_Exception)
1646 SMESH::SMESH_Group_var aResGrp;
1650 _preMeshInfo->FullLoadFromFile();
1652 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1654 if ( !theName || !aMeshDS )
1655 return SMESH::SMESH_Group::_nil();
1657 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1659 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1660 SMESH_Comment nbCoNoStr( "SMESH.");
1661 switch ( theNbCommonNodes ) {
1662 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1663 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1664 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1665 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1666 default: return aResGrp._retn();
1668 int nbChecked, nbCommon, nbNodes, nbCorners;
1674 aResGrp = CreateGroup( theElemType, theName );
1675 if ( aResGrp->_is_nil() )
1676 return SMESH::SMESH_Group::_nil();
1678 SMESHDS_GroupBase* groupBaseDS =
1679 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1680 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1682 vector<bool> isNodeInGroups;
1684 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1686 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1687 if ( CORBA::is_nil( aGrp ) )
1689 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1690 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1693 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1694 if ( !elIt ) continue;
1696 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1698 while ( elIt->more() ) {
1699 const SMDS_MeshElement* el = elIt->next();
1700 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1701 while ( nIt->more() )
1702 resGroupCore.Add( nIt->next() );
1705 // get elements of theElemType based on nodes of every element of group
1706 else if ( theUnderlyingOnly )
1708 while ( elIt->more() )
1710 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1711 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1712 TIDSortedElemSet checkedElems;
1713 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1714 while ( nIt->more() )
1716 const SMDS_MeshNode* n = nIt->next();
1717 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1718 // check nodes of elements of theElemType around el
1719 while ( elOfTypeIt->more() )
1721 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1722 if ( !checkedElems.insert( elOfType ).second ) continue;
1723 nbNodes = elOfType->NbNodes();
1724 nbCorners = elOfType->NbCornerNodes();
1726 bool toStopChecking = false;
1727 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1728 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1729 if ( elNodes.count( nIt2->next() ) &&
1730 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1732 resGroupCore.Add( elOfType );
1739 // get all nodes of elements of groups
1742 while ( elIt->more() )
1744 const SMDS_MeshElement* el = elIt->next(); // an element of group
1745 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1746 while ( nIt->more() )
1748 const SMDS_MeshNode* n = nIt->next();
1749 if ( n->GetID() >= (int) isNodeInGroups.size() )
1750 isNodeInGroups.resize( n->GetID() + 1, false );
1751 isNodeInGroups[ n->GetID() ] = true;
1757 // Get elements of theElemType based on a certain number of nodes of elements of groups
1758 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1760 const SMDS_MeshNode* n;
1761 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1762 const int isNodeInGroupsSize = isNodeInGroups.size();
1763 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1765 if ( !isNodeInGroups[ iN ] ||
1766 !( n = aMeshDS->FindNode( iN )))
1769 // check nodes of elements of theElemType around n
1770 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1771 while ( elOfTypeIt->more() )
1773 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1774 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1779 nbNodes = elOfType->NbNodes();
1780 nbCorners = elOfType->NbCornerNodes();
1782 bool toStopChecking = false;
1783 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1784 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1786 const int nID = nIt->next()->GetID();
1787 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1788 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1790 resGroupCore.Add( elOfType );
1798 // Update Python script
1799 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1800 << ".CreateDimGroup( "
1801 << theGroups << ", " << theElemType << ", '" << theName << "', "
1802 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1804 SMESH_CATCH( SMESH::throwCorbaException );
1806 return aResGrp._retn();
1809 //================================================================================
1811 * \brief Remember GEOM group data
1813 //================================================================================
1815 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1816 CORBA::Object_ptr theSmeshObj)
1818 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1821 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1822 if ( groupSO->_is_nil() )
1825 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1826 GEOM::GEOM_IGroupOperations_wrap groupOp =
1827 geomGen->GetIGroupOperations();
1828 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1831 _geomGroupData.push_back( TGeomGroupData() );
1832 TGeomGroupData & groupData = _geomGroupData.back();
1834 CORBA::String_var entry = groupSO->GetID();
1835 groupData._groupEntry = entry.in();
1837 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1838 groupData._indices.insert( ids[i] );
1840 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1841 // shape index in SMESHDS
1842 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1843 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1846 //================================================================================
1848 * Remove GEOM group data relating to removed smesh object
1850 //================================================================================
1852 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1854 list<TGeomGroupData>::iterator
1855 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1856 for ( ; data != dataEnd; ++data ) {
1857 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1858 _geomGroupData.erase( data );
1864 //================================================================================
1866 * \brief Return new group contents if it has been changed and update group data
1868 //================================================================================
1870 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1872 TopoDS_Shape newShape;
1875 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
1876 if ( !groupSO->_is_nil() )
1878 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1879 if ( CORBA::is_nil( groupObj )) return newShape;
1880 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1882 // get indices of group items
1883 set<int> curIndices;
1884 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1885 GEOM::GEOM_IGroupOperations_wrap groupOp =
1886 geomGen->GetIGroupOperations();
1887 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1888 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1889 curIndices.insert( ids[i] );
1891 if ( groupData._indices == curIndices )
1892 return newShape; // group not changed
1895 groupData._indices = curIndices;
1897 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1898 if ( !geomClient ) return newShape;
1899 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1900 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1901 newShape = _gen_i->GeomObjectToShape( geomGroup );
1904 if ( newShape.IsNull() ) {
1905 // geom group becomes empty - return empty compound
1906 TopoDS_Compound compound;
1907 BRep_Builder().MakeCompound(compound);
1908 newShape = compound;
1915 //-----------------------------------------------------------------------------
1917 * \brief Storage of shape and index used in CheckGeomGroupModif()
1919 struct TIndexedShape
1922 TopoDS_Shape _shape;
1923 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1925 //-----------------------------------------------------------------------------
1927 * \brief Data to re-create a group on geometry
1929 struct TGroupOnGeomData
1933 SMDSAbs_ElementType _type;
1935 Quantity_Color _color;
1939 //=============================================================================
1941 * \brief Update data if geometry changes
1945 //=============================================================================
1947 void SMESH_Mesh_i::CheckGeomModif()
1949 if ( !_impl->HasShapeToMesh() ) return;
1951 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1952 //if ( mainGO->_is_nil() ) return;
1954 // Update after group modification
1956 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1957 called by other mesh (IPAL52735) */
1958 mainGO->GetType() == GEOM_GROUP ||
1959 mainGO->GetTick() == _mainShapeTick )
1961 CheckGeomGroupModif();
1965 // Update after shape transformation like Translate
1967 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1968 if ( !geomClient ) return;
1969 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1970 if ( geomGen->_is_nil() ) return;
1972 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1973 geomClient->RemoveShapeFromBuffer( ior.in() );
1975 // Update data taking into account that
1976 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1979 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1980 if ( newShape.IsNull() )
1983 _mainShapeTick = mainGO->GetTick();
1985 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1987 // store data of groups on geometry
1988 vector< TGroupOnGeomData > groupsData;
1989 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1990 groupsData.reserve( groups.size() );
1991 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1992 for ( ; g != groups.end(); ++g )
1993 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1995 TGroupOnGeomData data;
1996 data._oldID = group->GetID();
1997 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1998 data._type = group->GetType();
1999 data._name = group->GetStoreName();
2000 data._color = group->GetColor();
2001 groupsData.push_back( data );
2003 // store assigned hypotheses
2004 vector< pair< int, THypList > > ids2Hyps;
2005 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2006 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2008 const TopoDS_Shape& s = s2hyps.Key();
2009 const THypList& hyps = s2hyps.ChangeValue();
2010 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2013 // change shape to mesh
2014 int oldNbSubShapes = meshDS->MaxShapeIndex();
2015 _impl->ShapeToMesh( TopoDS_Shape() );
2016 _impl->ShapeToMesh( newShape );
2018 // re-add shapes of geom groups
2019 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2020 for ( ; data != _geomGroupData.end(); ++data )
2022 TopoDS_Shape newShape = newGroupShape( *data );
2023 if ( !newShape.IsNull() )
2025 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2027 TopoDS_Compound compound;
2028 BRep_Builder().MakeCompound( compound );
2029 BRep_Builder().Add( compound, newShape );
2030 newShape = compound;
2032 _impl->GetSubMesh( newShape );
2035 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2036 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2037 SALOME::INTERNAL_ERROR );
2039 // re-assign hypotheses
2040 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2042 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2043 const THypList& hyps = ids2Hyps[i].second;
2044 THypList::const_iterator h = hyps.begin();
2045 for ( ; h != hyps.end(); ++h )
2046 _impl->AddHypothesis( s, (*h)->GetID() );
2050 for ( size_t i = 0; i < groupsData.size(); ++i )
2052 const TGroupOnGeomData& data = groupsData[i];
2054 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2055 if ( i2g == _mapGroups.end() ) continue;
2057 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2058 if ( !gr_i ) continue;
2061 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2062 meshDS->IndexToShape( data._shapeID ));
2065 _mapGroups.erase( i2g );
2069 g->GetGroupDS()->SetColor( data._color );
2070 gr_i->changeLocalId( id );
2071 _mapGroups[ id ] = i2g->second;
2072 if ( data._oldID != id )
2073 _mapGroups.erase( i2g );
2077 // update _mapSubMesh
2078 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2079 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2080 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2084 //=============================================================================
2086 * \brief Update objects depending on changed geom groups
2088 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2089 * issue 0020210: Update of a smesh group after modification of the associated geom group
2091 //=============================================================================
2093 void SMESH_Mesh_i::CheckGeomGroupModif()
2095 if ( !_impl->HasShapeToMesh() ) return;
2097 CORBA::Long nbEntities = NbNodes() + NbElements();
2099 // Check if group contents changed
2101 typedef map< string, TopoDS_Shape > TEntry2Geom;
2102 TEntry2Geom newGroupContents;
2104 list<TGeomGroupData>::iterator
2105 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2106 for ( ; data != dataEnd; ++data )
2108 pair< TEntry2Geom::iterator, bool > it_new =
2109 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2110 bool processedGroup = !it_new.second;
2111 TopoDS_Shape& newShape = it_new.first->second;
2112 if ( !processedGroup )
2113 newShape = newGroupShape( *data );
2114 if ( newShape.IsNull() )
2115 continue; // no changes
2118 _preMeshInfo->ForgetOrLoad();
2120 if ( processedGroup ) { // update group indices
2121 list<TGeomGroupData>::iterator data2 = data;
2122 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2123 data->_indices = data2->_indices;
2126 // Update SMESH objects according to new GEOM group contents
2128 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2129 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2131 int oldID = submesh->GetId();
2132 if ( !_mapSubMeshIor.count( oldID ))
2134 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2136 // update hypotheses
2137 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2138 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2139 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2141 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2142 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2144 // care of submeshes
2145 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2146 int newID = newSubmesh->GetId();
2147 if ( newID != oldID ) {
2148 _mapSubMesh [ newID ] = newSubmesh;
2149 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2150 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2151 _mapSubMesh. erase(oldID);
2152 _mapSubMesh_i. erase(oldID);
2153 _mapSubMeshIor.erase(oldID);
2154 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2159 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2160 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2161 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2163 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2165 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2166 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2167 ds->SetShape( newShape );
2172 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2173 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2175 // Remove groups and submeshes basing on removed sub-shapes
2177 TopTools_MapOfShape newShapeMap;
2178 TopoDS_Iterator shapeIt( newShape );
2179 for ( ; shapeIt.More(); shapeIt.Next() )
2180 newShapeMap.Add( shapeIt.Value() );
2182 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2183 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2185 if ( newShapeMap.Contains( shapeIt.Value() ))
2187 TopTools_IndexedMapOfShape oldShapeMap;
2188 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2189 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2191 const TopoDS_Shape& oldShape = oldShapeMap(i);
2192 int oldInd = meshDS->ShapeToIndex( oldShape );
2194 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2195 if ( i_smIor != _mapSubMeshIor.end() ) {
2196 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2199 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2200 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2202 // check if a group bases on oldInd shape
2203 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2204 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2205 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2206 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2208 RemoveGroup( i_grp->second ); // several groups can base on same shape
2209 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2214 // Reassign hypotheses and update groups after setting the new shape to mesh
2216 // collect anassigned hypotheses
2217 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2218 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2219 TShapeHypList assignedHyps;
2220 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2222 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2223 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2224 if ( !hyps.empty() ) {
2225 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2226 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2227 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2230 // collect shapes supporting groups
2231 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2232 TShapeTypeList groupData;
2233 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2234 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2235 for ( ; grIt != groups.end(); ++grIt )
2237 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2239 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2241 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2243 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2244 _impl->ShapeToMesh( newShape );
2246 // reassign hypotheses
2247 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2248 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2250 TIndexedShape& geom = indS_hyps->first;
2251 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2252 int oldID = geom._index;
2253 int newID = meshDS->ShapeToIndex( geom._shape );
2254 if ( oldID == 1 ) { // main shape
2256 geom._shape = newShape;
2260 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2261 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2262 // care of sub-meshes
2263 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2264 if ( newID != oldID ) {
2265 _mapSubMesh [ newID ] = newSubmesh;
2266 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2267 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2268 _mapSubMesh. erase(oldID);
2269 _mapSubMesh_i. erase(oldID);
2270 _mapSubMeshIor.erase(oldID);
2271 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2275 TShapeTypeList::iterator geomType = groupData.begin();
2276 for ( ; geomType != groupData.end(); ++geomType )
2278 const TIndexedShape& geom = geomType->first;
2279 int oldID = geom._index;
2280 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2283 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2284 CORBA::String_var name = groupSO->GetName();
2286 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2288 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2289 group_i->changeLocalId( newID );
2292 break; // everything has been updated
2295 } // loop on group data
2299 CORBA::Long newNbEntities = NbNodes() + NbElements();
2300 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2301 if ( newNbEntities != nbEntities )
2303 // Add all SObjects with icons to soToUpdateIcons
2304 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2306 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2307 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2308 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2310 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2311 i_gr != _mapGroups.end(); ++i_gr ) // groups
2312 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2315 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2316 for ( ; so != soToUpdateIcons.end(); ++so )
2317 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2320 //=============================================================================
2322 * \brief Create standalone group from a group on geometry or filter
2324 //=============================================================================
2326 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2327 throw (SALOME::SALOME_Exception)
2329 SMESH::SMESH_Group_var aGroup;
2334 _preMeshInfo->FullLoadFromFile();
2336 if ( theGroup->_is_nil() )
2337 return aGroup._retn();
2339 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2341 return aGroup._retn();
2343 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2345 const int anId = aGroupToRem->GetLocalID();
2346 if ( !_impl->ConvertToStandalone( anId ) )
2347 return aGroup._retn();
2348 removeGeomGroupData( theGroup );
2350 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2352 // remove old instance of group from own map
2353 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2354 _mapGroups.erase( anId );
2356 SALOMEDS::StudyBuilder_var builder;
2357 SALOMEDS::SObject_wrap aGroupSO;
2358 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2359 if ( !aStudy->_is_nil() ) {
2360 builder = aStudy->NewBuilder();
2361 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2362 if ( !aGroupSO->_is_nil() )
2364 // remove reference to geometry
2365 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2366 for ( ; chItr->More(); chItr->Next() )
2367 // Remove group's child SObject
2368 builder->RemoveObject( chItr->Value() );
2370 // Update Python script
2371 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2372 << ".ConvertToStandalone( " << aGroupSO << " )";
2374 // change icon of Group on Filter
2377 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2378 const int isEmpty = ( elemTypes->length() == 0 );
2381 SALOMEDS::GenericAttribute_wrap anAttr =
2382 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2383 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2384 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2390 // remember new group in own map
2391 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2392 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2394 // register CORBA object for persistence
2395 _gen_i->RegisterObject( aGroup );
2397 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2398 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2399 //aGroup->Register();
2400 aGroupToRem->UnRegister();
2402 SMESH_CATCH( SMESH::throwCorbaException );
2404 return aGroup._retn();
2407 //=============================================================================
2411 //=============================================================================
2413 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2415 if(MYDEBUG) MESSAGE( "createSubMesh" );
2416 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2417 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2418 const int subMeshId = mySubMesh->GetId();
2420 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2421 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2423 _mapSubMesh [subMeshId] = mySubMesh;
2424 _mapSubMesh_i [subMeshId] = subMeshServant;
2425 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2427 subMeshServant->Register();
2429 // register CORBA object for persistence
2430 int nextId = _gen_i->RegisterObject( subMesh );
2431 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2432 else { nextId = 0; } // avoid "unused variable" warning
2434 // to track changes of GEOM groups
2435 addGeomGroupData( theSubShapeObject, subMesh );
2437 return subMesh._retn();
2440 //=======================================================================
2441 //function : getSubMesh
2443 //=======================================================================
2445 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2447 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2448 if ( it == _mapSubMeshIor.end() )
2449 return SMESH::SMESH_subMesh::_nil();
2451 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2454 //=============================================================================
2458 //=============================================================================
2460 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2461 GEOM::GEOM_Object_ptr theSubShapeObject )
2463 bool isHypChanged = false;
2464 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2465 return isHypChanged;
2467 const int subMeshId = theSubMesh->GetId();
2469 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2471 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2473 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2476 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2477 isHypChanged = !hyps.empty();
2478 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2479 for ( ; hyp != hyps.end(); ++hyp )
2480 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2487 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2488 isHypChanged = ( aHypList->length() > 0 );
2489 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2490 removeHypothesis( theSubShapeObject, aHypList[i] );
2493 catch( const SALOME::SALOME_Exception& ) {
2494 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2496 removeGeomGroupData( theSubShapeObject );
2500 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2501 if ( id_smi != _mapSubMesh_i.end() )
2502 id_smi->second->UnRegister();
2504 // remove a CORBA object
2505 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2506 if ( id_smptr != _mapSubMeshIor.end() )
2507 SMESH::SMESH_subMesh_var( id_smptr->second );
2509 _mapSubMesh.erase(subMeshId);
2510 _mapSubMesh_i.erase(subMeshId);
2511 _mapSubMeshIor.erase(subMeshId);
2513 return isHypChanged;
2516 //=============================================================================
2520 //=============================================================================
2522 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2523 const char* theName,
2524 const TopoDS_Shape& theShape,
2525 const SMESH_PredicatePtr& thePredicate )
2527 std::string newName;
2528 if ( !theName || strlen( theName ) == 0 )
2530 std::set< std::string > presentNames;
2531 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2532 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2534 CORBA::String_var name = i_gr->second->GetName();
2535 presentNames.insert( name.in() );
2538 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2539 } while ( !presentNames.insert( newName ).second );
2540 theName = newName.c_str();
2543 SMESH::SMESH_GroupBase_var aGroup;
2544 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2546 SMESH_GroupBase_i* aGroupImpl;
2547 if ( !theShape.IsNull() )
2548 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2549 else if ( thePredicate )
2550 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2552 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2554 aGroup = aGroupImpl->_this();
2555 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2556 aGroupImpl->Register();
2558 // register CORBA object for persistence
2559 int nextId = _gen_i->RegisterObject( aGroup );
2560 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2561 else { nextId = 0; } // avoid "unused variable" warning in release mode
2563 // to track changes of GEOM groups
2564 if ( !theShape.IsNull() ) {
2565 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2566 addGeomGroupData( geom, aGroup );
2569 return aGroup._retn();
2572 //=============================================================================
2574 * SMESH_Mesh_i::removeGroup
2576 * Should be called by ~SMESH_Group_i()
2578 //=============================================================================
2580 void SMESH_Mesh_i::removeGroup( const int theId )
2582 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2583 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2584 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2585 _mapGroups.erase( theId );
2586 removeGeomGroupData( group );
2587 if ( !_impl->RemoveGroup( theId ))
2589 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2590 RemoveGroup( group );
2592 group->UnRegister();
2596 //=============================================================================
2600 //=============================================================================
2602 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2603 throw(SALOME::SALOME_Exception)
2605 SMESH::log_array_var aLog;
2609 _preMeshInfo->FullLoadFromFile();
2611 list < SMESHDS_Command * >logDS = _impl->GetLog();
2612 aLog = new SMESH::log_array;
2614 int lg = logDS.size();
2617 list < SMESHDS_Command * >::iterator its = logDS.begin();
2618 while(its != logDS.end()){
2619 SMESHDS_Command *com = *its;
2620 int comType = com->GetType();
2622 int lgcom = com->GetNumber();
2624 const list < int >&intList = com->GetIndexes();
2625 int inum = intList.size();
2627 list < int >::const_iterator ii = intList.begin();
2628 const list < double >&coordList = com->GetCoords();
2629 int rnum = coordList.size();
2631 list < double >::const_iterator ir = coordList.begin();
2632 aLog[indexLog].commandType = comType;
2633 aLog[indexLog].number = lgcom;
2634 aLog[indexLog].coords.length(rnum);
2635 aLog[indexLog].indexes.length(inum);
2636 for(int i = 0; i < rnum; i++){
2637 aLog[indexLog].coords[i] = *ir;
2638 //MESSAGE(" "<<i<<" "<<ir.Value());
2641 for(int i = 0; i < inum; i++){
2642 aLog[indexLog].indexes[i] = *ii;
2643 //MESSAGE(" "<<i<<" "<<ii.Value());
2652 SMESH_CATCH( SMESH::throwCorbaException );
2654 return aLog._retn();
2658 //=============================================================================
2662 //=============================================================================
2664 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2668 SMESH_CATCH( SMESH::throwCorbaException );
2671 //=============================================================================
2675 //=============================================================================
2677 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2682 //=============================================================================
2685 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2686 // issue 0020918: groups removal is caused by hyp modification
2687 // issue 0021208: to forget not loaded mesh data at hyp modification
2688 struct TCallUp_i : public SMESH_Mesh::TCallUp
2690 SMESH_Mesh_i* _mesh;
2691 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2692 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2693 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2694 virtual void Load () { _mesh->Load(); }
2698 //================================================================================
2700 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2702 //================================================================================
2704 void SMESH_Mesh_i::onHypothesisModified()
2707 _preMeshInfo->ForgetOrLoad();
2710 //=============================================================================
2714 //=============================================================================
2716 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2718 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2721 _impl->SetCallUp( new TCallUp_i(this));
2724 //=============================================================================
2728 //=============================================================================
2730 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2732 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2736 //=============================================================================
2738 * Return mesh editor
2740 //=============================================================================
2742 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2743 throw (SALOME::SALOME_Exception)
2745 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2749 _preMeshInfo->FullLoadFromFile();
2751 // Create MeshEditor
2753 _editor = new SMESH_MeshEditor_i( this, false );
2754 aMeshEdVar = _editor->_this();
2756 // Update Python script
2757 TPythonDump() << _editor << " = "
2758 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2760 SMESH_CATCH( SMESH::throwCorbaException );
2762 return aMeshEdVar._retn();
2765 //=============================================================================
2767 * Return mesh edition previewer
2769 //=============================================================================
2771 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2772 throw (SALOME::SALOME_Exception)
2774 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2778 _preMeshInfo->FullLoadFromFile();
2780 if ( !_previewEditor )
2781 _previewEditor = new SMESH_MeshEditor_i( this, true );
2782 aMeshEdVar = _previewEditor->_this();
2784 SMESH_CATCH( SMESH::throwCorbaException );
2786 return aMeshEdVar._retn();
2789 //================================================================================
2791 * \brief Return true if the mesh has been edited since a last total re-compute
2792 * and those modifications may prevent successful partial re-compute
2794 //================================================================================
2796 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2798 Unexpect aCatch(SALOME_SalomeException);
2799 return _impl->HasModificationsToDiscard();
2802 //================================================================================
2804 * \brief Returns a random unique color
2806 //================================================================================
2808 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2810 const int MAX_ATTEMPTS = 100;
2812 double tolerance = 0.5;
2813 SALOMEDS::Color col;
2817 // generate random color
2818 double red = (double)rand() / RAND_MAX;
2819 double green = (double)rand() / RAND_MAX;
2820 double blue = (double)rand() / RAND_MAX;
2821 // check existence in the list of the existing colors
2822 bool matched = false;
2823 std::list<SALOMEDS::Color>::const_iterator it;
2824 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2825 SALOMEDS::Color color = *it;
2826 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2827 matched = tol < tolerance;
2829 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2830 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2838 //=============================================================================
2840 * Sets auto-color mode. If it is on, groups get unique random colors
2842 //=============================================================================
2844 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2846 Unexpect aCatch(SALOME_SalomeException);
2847 _impl->SetAutoColor(theAutoColor);
2849 TPythonDump pyDump; // not to dump group->SetColor() from below code
2850 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2852 std::list<SALOMEDS::Color> aReservedColors;
2853 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2854 for ( ; it != _mapGroups.end(); it++ ) {
2855 if ( CORBA::is_nil( it->second )) continue;
2856 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2857 it->second->SetColor( aColor );
2858 aReservedColors.push_back( aColor );
2862 //=============================================================================
2864 * Returns true if auto-color mode is on
2866 //=============================================================================
2868 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2870 Unexpect aCatch(SALOME_SalomeException);
2871 return _impl->GetAutoColor();
2874 //=============================================================================
2876 * Checks if there are groups with equal names
2878 //=============================================================================
2880 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2882 return _impl->HasDuplicatedGroupNamesMED();
2885 //================================================================================
2887 * \brief Care of a file before exporting mesh into it
2889 //================================================================================
2891 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2893 SMESH_File aFile( file );
2895 if (aFile.exists()) {
2896 // existing filesystem node
2897 if ( !aFile.isDirectory() ) {
2898 if ( aFile.openForWriting() ) {
2899 if ( overwrite && ! aFile.remove()) {
2900 msg << "Can't replace " << aFile.getName();
2903 msg << "Can't write into " << aFile.getName();
2906 msg << "Location " << aFile.getName() << " is not a file";
2910 // nonexisting file; check if it can be created
2911 if ( !aFile.openForWriting() ) {
2912 msg << "You cannot create the file "
2914 << ". Check the directory existence and access rights";
2922 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2926 //================================================================================
2928 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2929 * \param file - file name
2930 * \param overwrite - to erase the file or not
2931 * \retval string - mesh name
2933 //================================================================================
2935 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2936 CORBA::Boolean overwrite)
2939 PrepareForWriting(file, overwrite);
2940 string aMeshName = "Mesh";
2941 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2942 if ( !aStudy->_is_nil() ) {
2943 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
2944 if ( !aMeshSO->_is_nil() ) {
2945 CORBA::String_var name = aMeshSO->GetName();
2947 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2948 if ( !aStudy->GetProperties()->IsLocked() )
2950 SALOMEDS::GenericAttribute_wrap anAttr;
2951 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2952 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2953 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2954 ASSERT(!aFileName->_is_nil());
2955 aFileName->SetValue(file);
2956 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2957 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2958 ASSERT(!aFileType->_is_nil());
2959 aFileType->SetValue("FICHIERMED");
2963 // Update Python script
2964 // set name of mesh before export
2965 TPythonDump() << _gen_i << ".SetName("
2966 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2968 // check names of groups
2974 //================================================================================
2976 * \brief Export to med file
2978 //================================================================================
2980 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2981 CORBA::Boolean auto_groups,
2982 SMESH::MED_VERSION theVersion,
2983 CORBA::Boolean overwrite,
2984 CORBA::Boolean autoDimension)
2985 throw(SALOME::SALOME_Exception)
2989 _preMeshInfo->FullLoadFromFile();
2991 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2992 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2994 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2995 << file << "', " << auto_groups << ", "
2996 << theVersion << ", " << overwrite << ", "
2997 << autoDimension << " )";
2999 SMESH_CATCH( SMESH::throwCorbaException );
3002 //================================================================================
3004 * \brief Export a mesh to a med file
3006 //================================================================================
3008 void SMESH_Mesh_i::ExportToMED (const char* file,
3009 CORBA::Boolean auto_groups,
3010 SMESH::MED_VERSION theVersion)
3011 throw(SALOME::SALOME_Exception)
3013 ExportToMEDX(file,auto_groups,theVersion,true);
3016 //================================================================================
3018 * \brief Export a mesh to a med file
3020 //================================================================================
3022 void SMESH_Mesh_i::ExportMED (const char* file,
3023 CORBA::Boolean auto_groups)
3024 throw(SALOME::SALOME_Exception)
3026 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3029 //================================================================================
3031 * \brief Export a mesh to a SAUV file
3033 //================================================================================
3035 void SMESH_Mesh_i::ExportSAUV (const char* file,
3036 CORBA::Boolean auto_groups)
3037 throw(SALOME::SALOME_Exception)
3039 Unexpect aCatch(SALOME_SalomeException);
3041 _preMeshInfo->FullLoadFromFile();
3043 string aMeshName = prepareMeshNameAndGroups(file, true);
3044 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3045 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3046 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3050 //================================================================================
3052 * \brief Export a mesh to a DAT file
3054 //================================================================================
3056 void SMESH_Mesh_i::ExportDAT (const char *file)
3057 throw(SALOME::SALOME_Exception)
3059 Unexpect aCatch(SALOME_SalomeException);
3061 _preMeshInfo->FullLoadFromFile();
3063 // Update Python script
3064 // check names of groups
3066 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3069 PrepareForWriting(file);
3070 _impl->ExportDAT(file);
3073 //================================================================================
3075 * \brief Export a mesh to an UNV file
3077 //================================================================================
3079 void SMESH_Mesh_i::ExportUNV (const char *file)
3080 throw(SALOME::SALOME_Exception)
3082 Unexpect aCatch(SALOME_SalomeException);
3084 _preMeshInfo->FullLoadFromFile();
3086 // Update Python script
3087 // check names of groups
3089 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3092 PrepareForWriting(file);
3093 _impl->ExportUNV(file);
3096 //================================================================================
3098 * \brief Export a mesh to an STL file
3100 //================================================================================
3102 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3103 throw(SALOME::SALOME_Exception)
3105 Unexpect aCatch(SALOME_SalomeException);
3107 _preMeshInfo->FullLoadFromFile();
3109 // Update Python script
3110 // check names of groups
3112 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3113 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3115 CORBA::String_var name;
3116 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3117 if ( !so->_is_nil() )
3118 name = so->GetName();
3121 PrepareForWriting( file );
3122 _impl->ExportSTL( file, isascii, name.in() );
3125 //================================================================================
3127 * \brief Export a part of mesh to a med file
3129 //================================================================================
3131 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3133 CORBA::Boolean auto_groups,
3134 SMESH::MED_VERSION version,
3135 CORBA::Boolean overwrite,
3136 CORBA::Boolean autoDimension,
3137 const GEOM::ListOfFields& fields,
3138 const char* geomAssocFields)
3139 throw (SALOME::SALOME_Exception)
3143 _preMeshInfo->FullLoadFromFile();
3146 bool have0dField = false;
3147 if ( fields.length() > 0 )
3149 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3150 if ( shapeToMesh->_is_nil() )
3151 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3153 for ( size_t i = 0; i < fields.length(); ++i )
3155 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3156 THROW_SALOME_CORBA_EXCEPTION
3157 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3158 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3159 if ( fieldShape->_is_nil() )
3160 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3161 if ( !fieldShape->IsSame( shapeToMesh ) )
3162 THROW_SALOME_CORBA_EXCEPTION
3163 ( "Field defined not on shape", SALOME::BAD_PARAM);
3164 if ( fields[i]->GetDimension() == 0 )
3167 if ( geomAssocFields )
3168 for ( int i = 0; geomAssocFields[i]; ++i )
3169 switch ( geomAssocFields[i] ) {
3170 case 'v':case 'e':case 'f':case 's': break;
3171 case 'V':case 'E':case 'F':case 'S': break;
3172 default: THROW_SALOME_CORBA_EXCEPTION
3173 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3177 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3181 string aMeshName = "Mesh";
3182 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3183 if ( CORBA::is_nil( meshPart ) ||
3184 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3186 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3187 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3188 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3189 meshDS = _impl->GetMeshDS();
3194 _preMeshInfo->FullLoadFromFile();
3196 PrepareForWriting(file, overwrite);
3198 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3199 if ( !SO->_is_nil() ) {
3200 CORBA::String_var name = SO->GetName();
3204 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3205 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3206 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3207 meshDS = tmpDSDeleter._obj = partDS;
3212 if ( _impl->HasShapeToMesh() )
3214 DriverMED_W_Field fieldWriter;
3215 fieldWriter.SetFile( file );
3216 fieldWriter.SetMeshName( aMeshName );
3217 fieldWriter.AddODOnVertices( have0dField );
3219 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3223 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3224 goList->length( fields.length() );
3225 for ( size_t i = 0; i < fields.length(); ++i )
3227 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3230 TPythonDump() << _this() << ".ExportPartToMED( "
3231 << meshPart << ", r'" << file << "', "
3232 << auto_groups << ", " << version << ", " << overwrite << ", "
3233 << autoDimension << ", " << goList
3234 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3236 SMESH_CATCH( SMESH::throwCorbaException );
3239 //================================================================================
3241 * Write GEOM fields to MED file
3243 //================================================================================
3245 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3246 SMESHDS_Mesh* meshDS,
3247 const GEOM::ListOfFields& fields,
3248 const char* geomAssocFields)
3250 #define METH "SMESH_Mesh_i::exportMEDFields() "
3252 if (( fields.length() < 1 ) &&
3253 ( !geomAssocFields || !geomAssocFields[0] ))
3256 std::vector< std::vector< double > > dblVals;
3257 std::vector< std::vector< int > > intVals;
3258 std::vector< int > subIdsByDim[ 4 ];
3259 const double noneDblValue = 0.;
3260 const double noneIntValue = 0;
3262 for ( size_t iF = 0; iF < fields.length(); ++iF )
3266 int dim = fields[ iF ]->GetDimension();
3267 SMDSAbs_ElementType elemType;
3268 TopAbs_ShapeEnum shapeType;
3270 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3271 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3272 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3273 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3275 continue; // skip fields on whole shape
3277 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3278 if ( dataType == GEOM::FDT_String )
3280 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3281 if ( stepIDs->length() < 1 )
3283 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3284 if ( comps->length() < 1 )
3286 CORBA::String_var name = fields[ iF ]->GetName();
3288 if ( !fieldWriter.Set( meshDS,
3292 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3295 for ( size_t iC = 0; iC < comps->length(); ++iC )
3296 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3298 dblVals.resize( comps->length() );
3299 intVals.resize( comps->length() );
3301 // find sub-shape IDs
3303 std::vector< int >& subIds = subIdsByDim[ dim ];
3304 if ( subIds.empty() )
3305 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3306 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3307 subIds.push_back( id );
3311 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3315 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3317 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3318 if ( step->_is_nil() )
3321 CORBA::Long stamp = step->GetStamp();
3322 CORBA::Long id = step->GetID();
3323 fieldWriter.SetDtIt( int( stamp ), int( id ));
3325 // fill dblVals or intVals
3326 for ( size_t iC = 0; iC < comps->length(); ++iC )
3327 if ( dataType == GEOM::FDT_Double )
3329 dblVals[ iC ].clear();
3330 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3334 intVals[ iC ].clear();
3335 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3339 case GEOM::FDT_Double:
3341 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3342 if ( dblStep->_is_nil() ) continue;
3343 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3344 if ( vv->length() != subIds.size() * comps->length() )
3345 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3346 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3347 for ( size_t iC = 0; iC < comps->length(); ++iC )
3348 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3353 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3354 if ( intStep->_is_nil() ) continue;
3355 GEOM::ListOfLong_var vv = intStep->GetValues();
3356 if ( vv->length() != subIds.size() * comps->length() )
3357 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3358 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3359 for ( size_t iC = 0; iC < comps->length(); ++iC )
3360 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3363 case GEOM::FDT_Bool:
3365 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3366 if ( boolStep->_is_nil() ) continue;
3367 GEOM::short_array_var vv = boolStep->GetValues();
3368 if ( vv->length() != subIds.size() * comps->length() )
3369 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3370 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3371 for ( size_t iC = 0; iC < comps->length(); ++iC )
3372 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3378 // pass values to fieldWriter
3379 elemIt = fieldWriter.GetOrderedElems();
3380 if ( dataType == GEOM::FDT_Double )
3381 while ( elemIt->more() )
3383 const SMDS_MeshElement* e = elemIt->next();
3384 const int shapeID = e->getshapeId();
3385 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3386 for ( size_t iC = 0; iC < comps->length(); ++iC )
3387 fieldWriter.AddValue( noneDblValue );
3389 for ( size_t iC = 0; iC < comps->length(); ++iC )
3390 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3393 while ( elemIt->more() )
3395 const SMDS_MeshElement* e = elemIt->next();
3396 const int shapeID = e->getshapeId();
3397 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3398 for ( size_t iC = 0; iC < comps->length(); ++iC )
3399 fieldWriter.AddValue( (double) noneIntValue );
3401 for ( size_t iC = 0; iC < comps->length(); ++iC )
3402 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3406 fieldWriter.Perform();
3407 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3408 if ( res && res->IsKO() )
3410 if ( res->myComment.empty() )
3411 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3413 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3419 if ( !geomAssocFields || !geomAssocFields[0] )
3422 // write geomAssocFields
3424 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3425 shapeDim[ TopAbs_COMPOUND ] = 3;
3426 shapeDim[ TopAbs_COMPSOLID ] = 3;
3427 shapeDim[ TopAbs_SOLID ] = 3;
3428 shapeDim[ TopAbs_SHELL ] = 2;
3429 shapeDim[ TopAbs_FACE ] = 2;
3430 shapeDim[ TopAbs_WIRE ] = 1;
3431 shapeDim[ TopAbs_EDGE ] = 1;
3432 shapeDim[ TopAbs_VERTEX ] = 0;
3433 shapeDim[ TopAbs_SHAPE ] = 3;
3435 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3437 std::vector< std::string > compNames;
3438 switch ( geomAssocFields[ iF ]) {
3440 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3441 compNames.push_back( "dim" );
3444 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3447 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3450 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3454 compNames.push_back( "id" );
3455 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3456 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3458 fieldWriter.SetDtIt( -1, -1 );
3460 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3464 if ( compNames.size() == 2 ) // _vertices_
3465 while ( elemIt->more() )
3467 const SMDS_MeshElement* e = elemIt->next();
3468 const int shapeID = e->getshapeId();
3471 fieldWriter.AddValue( (double) -1 );
3472 fieldWriter.AddValue( (double) -1 );
3476 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3477 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3478 fieldWriter.AddValue( (double) shapeID );
3482 while ( elemIt->more() )
3484 const SMDS_MeshElement* e = elemIt->next();
3485 const int shapeID = e->getshapeId();
3487 fieldWriter.AddValue( (double) -1 );
3489 fieldWriter.AddValue( (double) shapeID );
3493 fieldWriter.Perform();
3494 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3495 if ( res && res->IsKO() )
3497 if ( res->myComment.empty() )
3498 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3500 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3503 } // loop on geomAssocFields
3508 //================================================================================
3510 * \brief Export a part of mesh to a DAT file
3512 //================================================================================
3514 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3516 throw (SALOME::SALOME_Exception)
3518 Unexpect aCatch(SALOME_SalomeException);
3520 _preMeshInfo->FullLoadFromFile();
3522 PrepareForWriting(file);
3524 SMESH_MeshPartDS partDS( meshPart );
3525 _impl->ExportDAT(file,&partDS);
3527 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3528 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3530 //================================================================================
3532 * \brief Export a part of mesh to an UNV file
3534 //================================================================================
3536 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3538 throw (SALOME::SALOME_Exception)
3540 Unexpect aCatch(SALOME_SalomeException);
3542 _preMeshInfo->FullLoadFromFile();
3544 PrepareForWriting(file);
3546 SMESH_MeshPartDS partDS( meshPart );
3547 _impl->ExportUNV(file, &partDS);
3549 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3550 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3552 //================================================================================
3554 * \brief Export a part of mesh to an STL file
3556 //================================================================================
3558 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3560 ::CORBA::Boolean isascii)
3561 throw (SALOME::SALOME_Exception)
3563 Unexpect aCatch(SALOME_SalomeException);
3565 _preMeshInfo->FullLoadFromFile();
3567 PrepareForWriting(file);
3569 CORBA::String_var name;
3570 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3571 if ( !so->_is_nil() )
3572 name = so->GetName();
3574 SMESH_MeshPartDS partDS( meshPart );
3575 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3577 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3578 << meshPart<< ", r'" << file << "', " << isascii << ")";
3581 //================================================================================
3583 * \brief Export a part of mesh to an STL file
3585 //================================================================================
3587 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3589 CORBA::Boolean overwrite)
3590 throw (SALOME::SALOME_Exception)
3593 Unexpect aCatch(SALOME_SalomeException);
3595 _preMeshInfo->FullLoadFromFile();
3597 PrepareForWriting(file,overwrite);
3599 std::string meshName("");
3600 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3601 if ( !so->_is_nil() )
3603 CORBA::String_var name = so->GetName();
3604 meshName = name.in();
3606 SMESH_MeshPartDS partDS( meshPart );
3607 _impl->ExportCGNS(file, &partDS, meshName.c_str() );
3609 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3610 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3612 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3616 //================================================================================
3618 * \brief Export a part of mesh to a GMF file
3620 //================================================================================
3622 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3624 bool withRequiredGroups)
3625 throw (SALOME::SALOME_Exception)
3627 Unexpect aCatch(SALOME_SalomeException);
3629 _preMeshInfo->FullLoadFromFile();
3631 PrepareForWriting(file,/*overwrite=*/true);
3633 SMESH_MeshPartDS partDS( meshPart );
3634 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3636 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3637 << meshPart<< ", r'"
3639 << withRequiredGroups << ")";
3642 //=============================================================================
3644 * Return computation progress [0.,1]
3646 //=============================================================================
3648 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3652 return _impl->GetComputeProgress();
3654 SMESH_CATCH( SMESH::doNothing );
3658 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3660 Unexpect aCatch(SALOME_SalomeException);
3662 return _preMeshInfo->NbNodes();
3664 return _impl->NbNodes();
3667 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3669 Unexpect aCatch(SALOME_SalomeException);
3671 return _preMeshInfo->NbElements();
3673 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3676 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3678 Unexpect aCatch(SALOME_SalomeException);
3680 return _preMeshInfo->Nb0DElements();
3682 return _impl->Nb0DElements();
3685 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3687 Unexpect aCatch(SALOME_SalomeException);
3689 return _preMeshInfo->NbBalls();
3691 return _impl->NbBalls();
3694 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3696 Unexpect aCatch(SALOME_SalomeException);
3698 return _preMeshInfo->NbEdges();
3700 return _impl->NbEdges();
3703 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3704 throw(SALOME::SALOME_Exception)
3706 Unexpect aCatch(SALOME_SalomeException);
3708 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3710 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3713 //=============================================================================
3715 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3717 Unexpect aCatch(SALOME_SalomeException);
3719 return _preMeshInfo->NbFaces();
3721 return _impl->NbFaces();
3724 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3726 Unexpect aCatch(SALOME_SalomeException);
3728 return _preMeshInfo->NbTriangles();
3730 return _impl->NbTriangles();
3733 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3735 Unexpect aCatch(SALOME_SalomeException);
3737 return _preMeshInfo->NbBiQuadTriangles();
3739 return _impl->NbBiQuadTriangles();
3742 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3744 Unexpect aCatch(SALOME_SalomeException);
3746 return _preMeshInfo->NbQuadrangles();
3748 return _impl->NbQuadrangles();
3751 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3753 Unexpect aCatch(SALOME_SalomeException);
3755 return _preMeshInfo->NbBiQuadQuadrangles();
3757 return _impl->NbBiQuadQuadrangles();
3760 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3762 Unexpect aCatch(SALOME_SalomeException);
3764 return _preMeshInfo->NbPolygons();
3766 return _impl->NbPolygons();
3769 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3771 Unexpect aCatch(SALOME_SalomeException);
3773 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3775 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3778 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3779 throw(SALOME::SALOME_Exception)
3781 Unexpect aCatch(SALOME_SalomeException);
3783 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3785 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3788 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3789 throw(SALOME::SALOME_Exception)
3791 Unexpect aCatch(SALOME_SalomeException);
3793 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3795 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3798 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3799 throw(SALOME::SALOME_Exception)
3801 Unexpect aCatch(SALOME_SalomeException);
3803 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3805 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3808 //=============================================================================
3810 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3812 Unexpect aCatch(SALOME_SalomeException);
3814 return _preMeshInfo->NbVolumes();
3816 return _impl->NbVolumes();
3819 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3821 Unexpect aCatch(SALOME_SalomeException);
3823 return _preMeshInfo->NbTetras();
3825 return _impl->NbTetras();
3828 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3830 Unexpect aCatch(SALOME_SalomeException);
3832 return _preMeshInfo->NbHexas();
3834 return _impl->NbHexas();
3837 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3839 Unexpect aCatch(SALOME_SalomeException);
3841 return _preMeshInfo->NbTriQuadHexas();
3843 return _impl->NbTriQuadraticHexas();
3846 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3848 Unexpect aCatch(SALOME_SalomeException);
3850 return _preMeshInfo->NbPyramids();
3852 return _impl->NbPyramids();
3855 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3857 Unexpect aCatch(SALOME_SalomeException);
3859 return _preMeshInfo->NbPrisms();
3861 return _impl->NbPrisms();
3864 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3866 Unexpect aCatch(SALOME_SalomeException);
3868 return _preMeshInfo->NbHexPrisms();
3870 return _impl->NbHexagonalPrisms();
3873 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3875 Unexpect aCatch(SALOME_SalomeException);
3877 return _preMeshInfo->NbPolyhedrons();
3879 return _impl->NbPolyhedrons();
3882 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3883 throw(SALOME::SALOME_Exception)
3885 Unexpect aCatch(SALOME_SalomeException);
3887 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3889 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3892 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3893 throw(SALOME::SALOME_Exception)
3895 Unexpect aCatch(SALOME_SalomeException);
3897 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3899 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3902 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3903 throw(SALOME::SALOME_Exception)
3905 Unexpect aCatch(SALOME_SalomeException);
3907 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3909 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3912 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3913 throw(SALOME::SALOME_Exception)
3915 Unexpect aCatch(SALOME_SalomeException);
3917 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3919 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3922 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3923 throw(SALOME::SALOME_Exception)
3925 Unexpect aCatch(SALOME_SalomeException);
3927 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3929 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3932 //=============================================================================
3934 * Returns nb of published sub-meshes
3936 //=============================================================================
3938 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3940 Unexpect aCatch(SALOME_SalomeException);
3941 return _mapSubMesh_i.size();
3944 //=============================================================================
3946 * Dumps mesh into a string
3948 //=============================================================================
3950 char* SMESH_Mesh_i::Dump()
3954 return CORBA::string_dup( os.str().c_str() );
3957 //=============================================================================
3959 * Method of SMESH_IDSource interface
3961 //=============================================================================
3963 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3965 return GetElementsId();
3968 //=============================================================================
3970 * Returns ids of all elements
3972 //=============================================================================
3974 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3975 throw (SALOME::SALOME_Exception)
3977 Unexpect aCatch(SALOME_SalomeException);
3979 _preMeshInfo->FullLoadFromFile();
3981 SMESH::long_array_var aResult = new SMESH::long_array();
3982 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3984 if ( aSMESHDS_Mesh == NULL )
3985 return aResult._retn();
3987 long nbElements = NbElements();
3988 aResult->length( nbElements );
3989 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3990 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3991 aResult[i] = anIt->next()->GetID();
3993 return aResult._retn();
3997 //=============================================================================
3999 * Returns ids of all elements of given type
4001 //=============================================================================
4003 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4004 throw (SALOME::SALOME_Exception)
4006 Unexpect aCatch(SALOME_SalomeException);
4008 _preMeshInfo->FullLoadFromFile();
4010 SMESH::long_array_var aResult = new SMESH::long_array();
4011 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4013 if ( aSMESHDS_Mesh == NULL )
4014 return aResult._retn();
4016 long nbElements = NbElements();
4018 // No sense in returning ids of elements along with ids of nodes:
4019 // when theElemType == SMESH::ALL, return node ids only if
4020 // there are no elements
4021 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4022 return GetNodesId();
4024 aResult->length( nbElements );
4028 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4029 while ( i < nbElements && anIt->more() )
4030 aResult[i++] = anIt->next()->GetID();
4032 aResult->length( i );
4034 return aResult._retn();
4037 //=============================================================================
4039 * Returns ids of all nodes
4041 //=============================================================================
4043 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4044 throw (SALOME::SALOME_Exception)
4046 Unexpect aCatch(SALOME_SalomeException);
4048 _preMeshInfo->FullLoadFromFile();
4050 SMESH::long_array_var aResult = new SMESH::long_array();
4051 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4053 if ( aSMESHDS_Mesh == NULL )
4054 return aResult._retn();
4056 long nbNodes = NbNodes();
4057 aResult->length( nbNodes );
4058 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4059 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4060 aResult[i] = anIt->next()->GetID();
4062 return aResult._retn();
4065 //=============================================================================
4069 //=============================================================================
4071 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4072 throw (SALOME::SALOME_Exception)
4074 SMESH::ElementType type = SMESH::ALL;
4078 _preMeshInfo->FullLoadFromFile();
4080 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4082 SMESH_CATCH( SMESH::throwCorbaException );
4087 //=============================================================================
4091 //=============================================================================
4093 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4094 throw (SALOME::SALOME_Exception)
4097 _preMeshInfo->FullLoadFromFile();
4099 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4101 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4103 return ( SMESH::EntityType ) e->GetEntityType();
4106 //=============================================================================
4110 //=============================================================================
4112 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4113 throw (SALOME::SALOME_Exception)
4116 _preMeshInfo->FullLoadFromFile();
4118 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4120 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4122 return ( SMESH::GeometryType ) e->GetGeomType();
4125 //=============================================================================
4127 * Returns ID of elements for given submesh
4129 //=============================================================================
4130 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4131 throw (SALOME::SALOME_Exception)
4133 SMESH::long_array_var aResult = new SMESH::long_array();
4137 _preMeshInfo->FullLoadFromFile();
4139 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4140 if(!SM) return aResult._retn();
4142 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4143 if(!SDSM) return aResult._retn();
4145 aResult->length(SDSM->NbElements());
4147 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4149 while ( eIt->more() ) {
4150 aResult[i++] = eIt->next()->GetID();
4153 SMESH_CATCH( SMESH::throwCorbaException );
4155 return aResult._retn();
4158 //=============================================================================
4160 * Returns ID of nodes for given submesh
4161 * If param all==true - returns all nodes, else -
4162 * returns only nodes on shapes.
4164 //=============================================================================
4166 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4168 throw (SALOME::SALOME_Exception)
4170 SMESH::long_array_var aResult = new SMESH::long_array();
4174 _preMeshInfo->FullLoadFromFile();
4176 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4177 if(!SM) return aResult._retn();
4179 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4180 if(!SDSM) return aResult._retn();
4183 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4184 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4185 while ( nIt->more() ) {
4186 const SMDS_MeshNode* elem = nIt->next();
4187 theElems.insert( elem->GetID() );
4190 else { // all nodes of submesh elements
4191 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4192 while ( eIt->more() ) {
4193 const SMDS_MeshElement* anElem = eIt->next();
4194 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4195 while ( nIt->more() ) {
4196 const SMDS_MeshElement* elem = nIt->next();
4197 theElems.insert( elem->GetID() );
4202 aResult->length(theElems.size());
4203 set<int>::iterator itElem;
4205 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4206 aResult[i++] = *itElem;
4208 SMESH_CATCH( SMESH::throwCorbaException );
4210 return aResult._retn();
4213 //=============================================================================
4215 * Returns type of elements for given submesh
4217 //=============================================================================
4219 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4220 throw (SALOME::SALOME_Exception)
4222 SMESH::ElementType type = SMESH::ALL;
4226 _preMeshInfo->FullLoadFromFile();
4228 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4229 if(!SM) return SMESH::ALL;
4231 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4232 if(!SDSM) return SMESH::ALL;
4234 if(SDSM->NbElements()==0)
4235 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4237 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4238 const SMDS_MeshElement* anElem = eIt->next();
4240 type = ( SMESH::ElementType ) anElem->GetType();
4242 SMESH_CATCH( SMESH::throwCorbaException );
4248 //=============================================================================
4250 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4252 //=============================================================================
4254 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4257 _preMeshInfo->FullLoadFromFile();
4259 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4260 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4265 //=============================================================================
4267 * Get XYZ coordinates of node as list of double
4268 * If there is not node for given ID - returns empty list
4270 //=============================================================================
4272 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4275 _preMeshInfo->FullLoadFromFile();
4277 SMESH::double_array_var aResult = new SMESH::double_array();
4278 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4279 if ( aSMESHDS_Mesh == NULL )
4280 return aResult._retn();
4283 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4285 return aResult._retn();
4289 aResult[0] = aNode->X();
4290 aResult[1] = aNode->Y();
4291 aResult[2] = aNode->Z();
4292 return aResult._retn();
4296 //=============================================================================
4298 * For given node returns list of IDs of inverse elements
4299 * If there is not node for given ID - returns empty list
4301 //=============================================================================
4303 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4306 _preMeshInfo->FullLoadFromFile();
4308 SMESH::long_array_var aResult = new SMESH::long_array();
4309 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4310 if ( aSMESHDS_Mesh == NULL )
4311 return aResult._retn();
4314 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4316 return aResult._retn();
4318 // find inverse elements
4319 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4320 aResult->length( aNode->NbInverseElements() );
4321 for( int i = 0; eIt->more(); ++i )
4323 const SMDS_MeshElement* elem = eIt->next();
4324 aResult[ i ] = elem->GetID();
4326 return aResult._retn();
4329 //=============================================================================
4331 * \brief Return position of a node on shape
4333 //=============================================================================
4335 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4338 _preMeshInfo->FullLoadFromFile();
4340 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4341 aNodePosition->shapeID = 0;
4342 aNodePosition->shapeType = GEOM::SHAPE;
4344 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4345 if ( !mesh ) return aNodePosition;
4347 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4349 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4351 aNodePosition->shapeID = aNode->getshapeId();
4352 switch ( pos->GetTypeOfPosition() ) {
4354 aNodePosition->shapeType = GEOM::EDGE;
4355 aNodePosition->params.length(1);
4356 aNodePosition->params[0] =
4357 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4360 aNodePosition->shapeType = GEOM::FACE;
4361 aNodePosition->params.length(2);
4362 aNodePosition->params[0] =
4363 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4364 aNodePosition->params[1] =
4365 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4367 case SMDS_TOP_VERTEX:
4368 aNodePosition->shapeType = GEOM::VERTEX;
4370 case SMDS_TOP_3DSPACE:
4371 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4372 aNodePosition->shapeType = GEOM::SOLID;
4373 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4374 aNodePosition->shapeType = GEOM::SHELL;
4380 return aNodePosition;
4383 //=============================================================================
4385 * \brief Return position of an element on shape
4387 //=============================================================================
4389 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4392 _preMeshInfo->FullLoadFromFile();
4394 SMESH::ElementPosition anElementPosition;
4395 anElementPosition.shapeID = 0;
4396 anElementPosition.shapeType = GEOM::SHAPE;
4398 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4399 if ( !mesh ) return anElementPosition;
4401 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4403 anElementPosition.shapeID = anElem->getshapeId();
4404 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4405 if ( !aSp.IsNull() ) {
4406 switch ( aSp.ShapeType() ) {
4408 anElementPosition.shapeType = GEOM::EDGE;
4411 anElementPosition.shapeType = GEOM::FACE;
4414 anElementPosition.shapeType = GEOM::VERTEX;
4417 anElementPosition.shapeType = GEOM::SOLID;
4420 anElementPosition.shapeType = GEOM::SHELL;
4426 return anElementPosition;
4429 //=============================================================================
4431 * If given element is node returns IDs of shape from position
4432 * If there is not node for given ID - returns -1
4434 //=============================================================================
4436 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4439 _preMeshInfo->FullLoadFromFile();
4441 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4442 if ( aSMESHDS_Mesh == NULL )
4446 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4448 return aNode->getshapeId();
4455 //=============================================================================
4457 * For given element returns ID of result shape after
4458 * ::FindShape() from SMESH_MeshEditor
4459 * If there is not element for given ID - returns -1
4461 //=============================================================================
4463 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4466 _preMeshInfo->FullLoadFromFile();
4468 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4469 if ( aSMESHDS_Mesh == NULL )
4472 // try to find element
4473 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4477 ::SMESH_MeshEditor aMeshEditor(_impl);
4478 int index = aMeshEditor.FindShape( elem );
4486 //=============================================================================
4488 * Returns number of nodes for given element
4489 * If there is not element for given ID - returns -1
4491 //=============================================================================
4493 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4496 _preMeshInfo->FullLoadFromFile();
4498 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4499 if ( aSMESHDS_Mesh == NULL ) return -1;
4500 // try to find element
4501 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4502 if(!elem) return -1;
4503 return elem->NbNodes();
4507 //=============================================================================
4509 * Returns ID of node by given index for given element
4510 * If there is not element for given ID - returns -1
4511 * If there is not node for given index - returns -2
4513 //=============================================================================
4515 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4518 _preMeshInfo->FullLoadFromFile();
4520 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4521 if ( aSMESHDS_Mesh == NULL ) return -1;
4522 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4523 if(!elem) return -1;
4524 if( index>=elem->NbNodes() || index<0 ) return -1;
4525 return elem->GetNode(index)->GetID();
4528 //=============================================================================
4530 * Returns IDs of nodes of given element
4532 //=============================================================================
4534 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4537 _preMeshInfo->FullLoadFromFile();
4539 SMESH::long_array_var aResult = new SMESH::long_array();
4540 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4542 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4544 aResult->length( elem->NbNodes() );
4545 for ( int i = 0; i < elem->NbNodes(); ++i )
4546 aResult[ i ] = elem->GetNode( i )->GetID();
4549 return aResult._retn();
4552 //=============================================================================
4554 * Returns true if given node is medium node
4555 * in given quadratic element
4557 //=============================================================================
4559 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4562 _preMeshInfo->FullLoadFromFile();
4564 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4565 if ( aSMESHDS_Mesh == NULL ) return false;
4567 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4568 if(!aNode) return false;
4569 // try to find element
4570 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4571 if(!elem) return false;
4573 return elem->IsMediumNode(aNode);
4577 //=============================================================================
4579 * Returns true if given node is medium node
4580 * in one of quadratic elements
4582 //=============================================================================
4584 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4585 SMESH::ElementType theElemType)
4588 _preMeshInfo->FullLoadFromFile();
4590 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4591 if ( aSMESHDS_Mesh == NULL ) return false;
4594 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4595 if(!aNode) return false;
4597 SMESH_MesherHelper aHelper( *(_impl) );
4599 SMDSAbs_ElementType aType;
4600 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4601 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4602 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4603 else aType = SMDSAbs_All;
4605 return aHelper.IsMedium(aNode,aType);
4609 //=============================================================================
4611 * Returns number of edges for given element
4613 //=============================================================================
4615 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4618 _preMeshInfo->FullLoadFromFile();
4620 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4621 if ( aSMESHDS_Mesh == NULL ) return -1;
4622 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4623 if(!elem) return -1;
4624 return elem->NbEdges();
4628 //=============================================================================
4630 * Returns number of faces for given element
4632 //=============================================================================
4634 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4637 _preMeshInfo->FullLoadFromFile();
4639 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4640 if ( aSMESHDS_Mesh == NULL ) return -1;
4641 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4642 if(!elem) return -1;
4643 return elem->NbFaces();
4646 //=======================================================================
4647 //function : GetElemFaceNodes
4648 //purpose : Returns nodes of given face (counted from zero) for given element.
4649 //=======================================================================
4651 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4652 CORBA::Short faceIndex)
4655 _preMeshInfo->FullLoadFromFile();
4657 SMESH::long_array_var aResult = new SMESH::long_array();
4658 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4660 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4662 SMDS_VolumeTool vtool( elem );
4663 if ( faceIndex < vtool.NbFaces() )
4665 aResult->length( vtool.NbFaceNodes( faceIndex ));
4666 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4667 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4668 aResult[ i ] = nn[ i ]->GetID();
4672 return aResult._retn();
4675 //=======================================================================
4676 //function : GetElemFaceNodes
4677 //purpose : Returns three components of normal of given mesh face.
4678 //=======================================================================
4680 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4681 CORBA::Boolean normalized)
4684 _preMeshInfo->FullLoadFromFile();
4686 SMESH::double_array_var aResult = new SMESH::double_array();
4688 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4691 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4693 aResult->length( 3 );
4694 aResult[ 0 ] = normal.X();
4695 aResult[ 1 ] = normal.Y();
4696 aResult[ 2 ] = normal.Z();
4699 return aResult._retn();
4702 //=======================================================================
4703 //function : FindElementByNodes
4704 //purpose : Returns an element based on all given nodes.
4705 //=======================================================================
4707 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4710 _preMeshInfo->FullLoadFromFile();
4712 CORBA::Long elemID(0);
4713 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4715 vector< const SMDS_MeshNode * > nn( nodes.length() );
4716 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4717 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4720 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4721 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4722 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4723 _impl->NbVolumes( ORDER_QUADRATIC )))
4724 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4726 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4731 //================================================================================
4733 * \brief Return elements including all given nodes.
4735 //================================================================================
4737 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4738 SMESH::ElementType elemType)
4741 _preMeshInfo->FullLoadFromFile();
4743 SMESH::long_array_var result = new SMESH::long_array();
4745 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4747 vector< const SMDS_MeshNode * > nn( nodes.length() );
4748 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4749 nn[i] = mesh->FindNode( nodes[i] );
4751 std::vector<const SMDS_MeshElement *> elems;
4752 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4753 result->length( elems.size() );
4754 for ( size_t i = 0; i < elems.size(); ++i )
4755 result[i] = elems[i]->GetID();
4757 return result._retn();
4760 //=============================================================================
4762 * Returns true if given element is polygon
4764 //=============================================================================
4766 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4769 _preMeshInfo->FullLoadFromFile();
4771 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4772 if ( aSMESHDS_Mesh == NULL ) return false;
4773 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4774 if(!elem) return false;
4775 return elem->IsPoly();
4779 //=============================================================================
4781 * Returns true if given element is quadratic
4783 //=============================================================================
4785 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4788 _preMeshInfo->FullLoadFromFile();
4790 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4791 if ( aSMESHDS_Mesh == NULL ) return false;
4792 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4793 if(!elem) return false;
4794 return elem->IsQuadratic();
4797 //=============================================================================
4799 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4801 //=============================================================================
4803 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4806 _preMeshInfo->FullLoadFromFile();
4808 if ( const SMDS_BallElement* ball =
4809 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4810 return ball->GetDiameter();
4815 //=============================================================================
4817 * Returns bary center for given element
4819 //=============================================================================
4821 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4824 _preMeshInfo->FullLoadFromFile();
4826 SMESH::double_array_var aResult = new SMESH::double_array();
4827 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4828 if ( aSMESHDS_Mesh == NULL )
4829 return aResult._retn();
4831 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4833 return aResult._retn();
4835 if(elem->GetType()==SMDSAbs_Volume) {
4836 SMDS_VolumeTool aTool;
4837 if(aTool.Set(elem)) {
4839 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4844 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4846 double x=0., y=0., z=0.;
4847 for(; anIt->more(); ) {
4849 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4863 return aResult._retn();
4866 //================================================================================
4868 * \brief Create a group of elements preventing computation of a sub-shape
4870 //================================================================================
4872 SMESH::ListOfGroups*
4873 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4874 const char* theGroupName )
4875 throw ( SALOME::SALOME_Exception )
4877 Unexpect aCatch(SALOME_SalomeException);
4879 if ( !theGroupName || strlen( theGroupName) == 0 )
4880 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4882 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4883 ::SMESH_MeshEditor::ElemFeatures elemType;
4885 // submesh by subshape id
4886 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4887 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4890 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4891 if ( error && !error->myBadElements.empty())
4893 // sort bad elements by type
4894 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4895 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4896 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4897 for ( ; elemIt != elemEnd; ++elemIt )
4899 const SMDS_MeshElement* elem = *elemIt;
4900 if ( !elem ) continue;
4902 if ( elem->GetID() < 1 )
4904 // elem is a temporary element, make a real element
4905 vector< const SMDS_MeshNode* > nodes;
4906 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4907 while ( nIt->more() && elem )
4909 nodes.push_back( nIt->next() );
4910 if ( nodes.back()->GetID() < 1 )
4911 elem = 0; // a temporary element on temporary nodes
4915 ::SMESH_MeshEditor editor( _impl );
4916 elem = editor.AddElement( nodes, elemType.Init( elem ));
4920 elemsByType[ elem->GetType() ].push_back( elem );
4923 // how many groups to create?
4925 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4926 nbTypes += int( !elemsByType[ i ].empty() );
4927 groups->length( nbTypes );
4930 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4932 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4933 if ( elems.empty() ) continue;
4935 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4936 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4938 SMESH::SMESH_Mesh_var mesh = _this();
4939 SALOMEDS::SObject_wrap aSO =
4940 _gen_i->PublishGroup( mesh, groups[ iG ],
4941 GEOM::GEOM_Object::_nil(), theGroupName);
4943 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4944 if ( !grp_i ) continue;
4946 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4947 for ( size_t iE = 0; iE < elems.size(); ++iE )
4948 grpDS->SMDSGroup().Add( elems[ iE ]);
4953 return groups._retn();
4956 //=============================================================================
4958 * Create and publish group servants if any groups were imported or created anyhow
4960 //=============================================================================
4962 void SMESH_Mesh_i::CreateGroupServants()
4964 SMESH::SMESH_Mesh_var aMesh = _this();
4967 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4968 while ( groupIt->more() )
4970 ::SMESH_Group* group = groupIt->next();
4971 int anId = group->GetGroupDS()->GetID();
4973 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4974 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4976 addedIDs.insert( anId );
4978 SMESH_GroupBase_i* aGroupImpl;
4980 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4981 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4983 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4984 shape = groupOnGeom->GetShape();
4987 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4990 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4991 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4992 aGroupImpl->Register();
4994 // register CORBA object for persistence
4995 int nextId = _gen_i->RegisterObject( groupVar );
4996 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4997 else { nextId = 0; } // avoid "unused variable" warning in release mode
4999 // publishing the groups in the study
5000 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5001 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5003 if ( !addedIDs.empty() )
5006 set<int>::iterator id = addedIDs.begin();
5007 for ( ; id != addedIDs.end(); ++id )
5009 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5010 int i = std::distance( _mapGroups.begin(), it );
5011 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5016 //=============================================================================
5018 * \brief Return groups cantained in _mapGroups by their IDs
5020 //=============================================================================
5022 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5024 int nbGroups = groupIDs.size();
5025 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5026 aList->length( nbGroups );
5028 list<int>::const_iterator ids = groupIDs.begin();
5029 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5031 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5032 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5033 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5035 aList->length( nbGroups );
5036 return aList._retn();
5039 //=============================================================================
5041 * \brief Return information about imported file
5043 //=============================================================================
5045 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5047 SMESH::MedFileInfo_var res( _medFileInfo );
5048 if ( !res.operator->() ) {
5049 res = new SMESH::MedFileInfo;
5051 res->fileSize = res->major = res->minor = res->release = -1;
5056 //=============================================================================
5058 * \brief Pass names of mesh groups from study to mesh DS
5060 //=============================================================================
5062 void SMESH_Mesh_i::checkGroupNames()
5064 int nbGrp = NbGroups();
5068 SMESH::ListOfGroups* grpList = 0;
5069 // avoid dump of "GetGroups"
5071 // store python dump into a local variable inside local scope
5072 SMESH::TPythonDump pDump; // do not delete this line of code
5073 grpList = GetGroups();
5076 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5077 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5080 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5081 if ( aGrpSO->_is_nil() )
5083 // correct name of the mesh group if necessary
5084 const char* guiName = aGrpSO->GetName();
5085 if ( strcmp(guiName, aGrp->GetName()) )
5086 aGrp->SetName( guiName );
5090 //=============================================================================
5092 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5094 //=============================================================================
5095 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5097 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5101 //=============================================================================
5103 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5105 //=============================================================================
5107 char* SMESH_Mesh_i::GetParameters()
5109 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5112 //=============================================================================
5114 * \brief Returns list of notebook variables used for last Mesh operation
5116 //=============================================================================
5117 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5119 SMESH::string_array_var aResult = new SMESH::string_array();
5120 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5122 CORBA::String_var aParameters = GetParameters();
5123 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5124 if ( aSections->length() > 0 ) {
5125 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5126 aResult->length( aVars.length() );
5127 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5128 aResult[i] = CORBA::string_dup( aVars[i] );
5131 return aResult._retn();
5134 //=======================================================================
5135 //function : GetTypes
5136 //purpose : Returns types of elements it contains
5137 //=======================================================================
5139 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5142 return _preMeshInfo->GetTypes();
5144 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5148 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5149 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5150 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5151 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5152 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5153 if (_impl->NbNodes() &&
5154 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5155 types->length( nbTypes );
5157 return types._retn();
5160 //=======================================================================
5161 //function : GetMesh
5162 //purpose : Returns self
5163 //=======================================================================
5165 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5167 return SMESH::SMESH_Mesh::_duplicate( _this() );
5170 //=======================================================================
5171 //function : IsMeshInfoCorrect
5172 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5173 // * happen if mesh data is not yet fully loaded from the file of study.
5174 //=======================================================================
5176 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5178 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5181 //=============================================================================
5183 * \brief Returns number of mesh elements per each \a EntityType
5185 //=============================================================================
5187 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5190 return _preMeshInfo->GetMeshInfo();
5192 SMESH::long_array_var aRes = new SMESH::long_array();
5193 aRes->length(SMESH::Entity_Last);
5194 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5196 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5198 return aRes._retn();
5199 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5200 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5201 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5202 return aRes._retn();
5205 //=============================================================================
5207 * \brief Returns number of mesh elements per each \a ElementType
5209 //=============================================================================
5211 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5213 SMESH::long_array_var aRes = new SMESH::long_array();
5214 aRes->length(SMESH::NB_ELEMENT_TYPES);
5215 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5218 const SMDS_MeshInfo* meshInfo = 0;
5220 meshInfo = _preMeshInfo;
5221 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5222 meshInfo = & meshDS->GetMeshInfo();
5225 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5226 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5228 return aRes._retn();
5231 //=============================================================================
5233 * Collect statistic of mesh elements given by iterator
5235 //=============================================================================
5237 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5238 SMESH::long_array& theInfo)
5240 if (!theItr) return;
5241 while (theItr->more())
5242 theInfo[ theItr->next()->GetEntityType() ]++;
5244 //=============================================================================
5246 * Returns mesh unstructed grid information.
5248 //=============================================================================
5250 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5252 SALOMEDS::TMPFile_var SeqFile;
5253 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5254 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5256 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5257 aWriter->WriteToOutputStringOn();
5258 aWriter->SetInputData(aGrid);
5259 aWriter->SetFileTypeToBinary();
5261 char* str = aWriter->GetOutputString();
5262 int size = aWriter->GetOutputStringLength();
5264 //Allocate octect buffer of required size
5265 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5266 //Copy ostrstream content to the octect buffer
5267 memcpy(OctetBuf, str, size);
5268 //Create and return TMPFile
5269 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5273 return SeqFile._retn();
5276 //=============================================================================
5277 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5278 * SMESH::ElementType type) */
5280 using namespace SMESH::Controls;
5281 //-----------------------------------------------------------------------------
5282 struct PredicateIterator : public SMDS_ElemIterator
5284 SMDS_ElemIteratorPtr _elemIter;
5285 PredicatePtr _predicate;
5286 const SMDS_MeshElement* _elem;
5288 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5289 PredicatePtr predicate):
5290 _elemIter(iterator), _predicate(predicate)
5298 virtual const SMDS_MeshElement* next()
5300 const SMDS_MeshElement* res = _elem;
5302 while ( _elemIter->more() && !_elem )
5304 _elem = _elemIter->next();
5305 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5312 //-----------------------------------------------------------------------------
5313 struct IDSourceIterator : public SMDS_ElemIterator
5315 const CORBA::Long* _idPtr;
5316 const CORBA::Long* _idEndPtr;
5317 SMESH::long_array_var _idArray;
5318 const SMDS_Mesh* _mesh;
5319 const SMDSAbs_ElementType _type;
5320 const SMDS_MeshElement* _elem;
5322 IDSourceIterator( const SMDS_Mesh* mesh,
5323 const CORBA::Long* ids,
5325 SMDSAbs_ElementType type):
5326 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5328 if ( _idPtr && nbIds && _mesh )
5331 IDSourceIterator( const SMDS_Mesh* mesh,
5332 SMESH::long_array* idArray,
5333 SMDSAbs_ElementType type):
5334 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5336 if ( idArray && _mesh )
5338 _idPtr = &_idArray[0];
5339 _idEndPtr = _idPtr + _idArray->length();
5347 virtual const SMDS_MeshElement* next()
5349 const SMDS_MeshElement* res = _elem;
5351 while ( _idPtr < _idEndPtr && !_elem )
5353 if ( _type == SMDSAbs_Node )
5355 _elem = _mesh->FindNode( *_idPtr++ );
5357 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5358 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5366 //-----------------------------------------------------------------------------
5368 struct NodeOfElemIterator : public SMDS_ElemIterator
5370 TColStd_MapOfInteger _checkedNodeIDs;
5371 SMDS_ElemIteratorPtr _elemIter;
5372 SMDS_ElemIteratorPtr _nodeIter;
5373 const SMDS_MeshElement* _node;
5375 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5377 if ( _elemIter && _elemIter->more() )
5379 _nodeIter = _elemIter->next()->nodesIterator();
5387 virtual const SMDS_MeshElement* next()
5389 const SMDS_MeshElement* res = _node;
5391 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5393 if ( _nodeIter->more() )
5395 _node = _nodeIter->next();
5396 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5401 _nodeIter = _elemIter->next()->nodesIterator();
5409 //=============================================================================
5411 * Return iterator on elements of given type in given object
5413 //=============================================================================
5415 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5416 SMESH::ElementType theType)
5418 SMDS_ElemIteratorPtr elemIt;
5419 bool typeOK = ( theType == SMESH::ALL );
5420 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5422 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5423 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5424 if ( !mesh_i ) return elemIt;
5425 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5427 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5429 elemIt = meshDS->elementsIterator( elemType );
5432 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5434 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5437 elemIt = sm->GetElements();
5438 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5440 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5441 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5445 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5447 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5448 if ( groupDS && ( elemType == groupDS->GetType() ||
5449 elemType == SMDSAbs_Node ||
5450 elemType == SMDSAbs_All ))
5452 elemIt = groupDS->GetElements();
5453 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5456 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5458 if ( filter_i->GetElementType() == theType ||
5459 elemType == SMDSAbs_Node ||
5460 elemType == SMDSAbs_All)
5462 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5463 if ( pred_i && pred_i->GetPredicate() )
5465 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5466 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5467 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5468 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5474 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5475 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5476 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5478 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5481 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5482 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5486 SMESH::long_array_var ids = theObject->GetIDs();
5487 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5489 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5492 if ( elemIt && elemIt->more() && !typeOK )
5494 if ( elemType == SMDSAbs_Node )
5496 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5500 elemIt = SMDS_ElemIteratorPtr();
5506 //=============================================================================
5507 namespace // Finding concurrent hypotheses
5508 //=============================================================================
5512 * \brief mapping of mesh dimension into shape type
5514 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5516 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5518 case 0: aType = TopAbs_VERTEX; break;
5519 case 1: aType = TopAbs_EDGE; break;
5520 case 2: aType = TopAbs_FACE; break;
5522 default:aType = TopAbs_SOLID; break;
5527 //-----------------------------------------------------------------------------
5529 * \brief Internal structure used to find concurent submeshes
5531 * It represents a pair < submesh, concurent dimension >, where
5532 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5533 * with another submesh. In other words, it is dimension of a hypothesis assigned
5540 int _dim; //!< a dimension the algo can build (concurrent dimension)
5541 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5542 TopTools_MapOfShape _shapeMap;
5543 SMESH_subMesh* _subMesh;
5544 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5546 //-----------------------------------------------------------------------------
5547 // Return the algorithm
5548 const SMESH_Algo* GetAlgo() const
5549 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5551 //-----------------------------------------------------------------------------
5553 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5555 const TopoDS_Shape& theShape)
5557 _subMesh = (SMESH_subMesh*)theSubMesh;
5558 SetShape( theDim, theShape );
5561 //-----------------------------------------------------------------------------
5563 void SetShape(const int theDim,
5564 const TopoDS_Shape& theShape)
5567 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5568 if (_dim >= _ownDim)
5569 _shapeMap.Add( theShape );
5571 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5572 for( ; anExp.More(); anExp.Next() )
5573 _shapeMap.Add( anExp.Current() );
5577 //-----------------------------------------------------------------------------
5578 //! Check sharing of sub-shapes
5579 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5580 const TopTools_MapOfShape& theToFind,
5581 const TopAbs_ShapeEnum theType)
5583 bool isShared = false;
5584 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5585 for (; !isShared && anItr.More(); anItr.Next() )
5587 const TopoDS_Shape aSubSh = anItr.Key();
5588 // check for case when concurrent dimensions are same
5589 isShared = theToFind.Contains( aSubSh );
5590 // check for sub-shape with concurrent dimension
5591 TopExp_Explorer anExp( aSubSh, theType );
5592 for ( ; !isShared && anExp.More(); anExp.Next() )
5593 isShared = theToFind.Contains( anExp.Current() );
5598 //-----------------------------------------------------------------------------
5599 //! check algorithms
5600 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5601 const SMESHDS_Hypothesis* theA2)
5603 if ( !theA1 || !theA2 ||
5604 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5605 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5606 return false; // one of the hypothesis is not algorithm
5607 // check algorithm names (should be equal)
5608 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5612 //-----------------------------------------------------------------------------
5613 //! Check if sub-shape hypotheses are concurrent
5614 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5616 if ( _subMesh == theOther->_subMesh )
5617 return false; // same sub-shape - should not be
5619 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5620 // any of the two submeshes is not on COMPOUND shape )
5621 // -> no concurrency
5622 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5623 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5624 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5625 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5626 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5629 // bool checkSubShape = ( _dim >= theOther->_dim )
5630 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5631 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5632 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5633 if ( !checkSubShape )
5636 // check algorithms to be same
5637 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5638 return true; // different algorithms -> concurrency !
5640 // check hypothesises for concurrence (skip first as algorithm)
5642 // pointers should be same, because it is referened from mesh hypothesis partition
5643 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5644 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5645 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5646 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5648 // the submeshes are concurrent if their algorithms has different parameters
5649 return nbSame != (int)theOther->_hypotheses.size() - 1;
5652 // Return true if algorithm of this SMESH_DimHyp is used if no
5653 // sub-mesh order is imposed by the user
5654 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5656 // NeedDiscreteBoundary() algo has a higher priority
5657 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5658 theOther->GetAlgo()->NeedDiscreteBoundary() )
5659 return !this->GetAlgo()->NeedDiscreteBoundary();
5661 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5664 }; // end of SMESH_DimHyp
5665 //-----------------------------------------------------------------------------
5667 typedef list<const SMESH_DimHyp*> TDimHypList;
5669 //-----------------------------------------------------------------------------
5671 void addDimHypInstance(const int theDim,
5672 const TopoDS_Shape& theShape,
5673 const SMESH_Algo* theAlgo,
5674 const SMESH_subMesh* theSubMesh,
5675 const list <const SMESHDS_Hypothesis*>& theHypList,
5676 TDimHypList* theDimHypListArr )
5678 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5679 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5680 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5681 dimHyp->_hypotheses.push_front(theAlgo);
5682 listOfdimHyp.push_back( dimHyp );
5685 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5686 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5687 theHypList.begin(), theHypList.end() );
5690 //-----------------------------------------------------------------------------
5691 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5692 TDimHypList& theListOfConcurr)
5694 if ( theListOfConcurr.empty() )
5696 theListOfConcurr.push_back( theDimHyp );
5700 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5701 while ( hypIt != theListOfConcurr.end() &&
5702 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5704 theListOfConcurr.insert( hypIt, theDimHyp );
5708 //-----------------------------------------------------------------------------
5709 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5710 const TDimHypList& theListOfDimHyp,
5711 TDimHypList& theListOfConcurrHyp,
5712 set<int>& theSetOfConcurrId )
5714 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5715 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5717 const SMESH_DimHyp* curDimHyp = *rIt;
5718 if ( curDimHyp == theDimHyp )
5719 break; // meet own dimHyp pointer in same dimension
5721 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5722 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5724 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5729 //-----------------------------------------------------------------------------
5730 void unionLists(TListOfInt& theListOfId,
5731 TListOfListOfInt& theListOfListOfId,
5734 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5735 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5737 continue; //skip already treated lists
5738 // check if other list has any same submesh object
5739 TListOfInt& otherListOfId = *it;
5740 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5741 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5744 // union two lists (from source into target)
5745 TListOfInt::iterator it2 = otherListOfId.begin();
5746 for ( ; it2 != otherListOfId.end(); it2++ ) {
5747 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5748 theListOfId.push_back(*it2);
5750 // clear source list
5751 otherListOfId.clear();
5754 //-----------------------------------------------------------------------------
5756 //! free memory allocated for dimension-hypothesis objects
5757 void removeDimHyps( TDimHypList* theArrOfList )
5759 for (int i = 0; i < 4; i++ ) {
5760 TDimHypList& listOfdimHyp = theArrOfList[i];
5761 TDimHypList::const_iterator it = listOfdimHyp.begin();
5762 for ( ; it != listOfdimHyp.end(); it++ )
5767 //-----------------------------------------------------------------------------
5769 * \brief find common submeshes with given submesh
5770 * \param theSubMeshList list of already collected submesh to check
5771 * \param theSubMesh given submesh to intersect with other
5772 * \param theCommonSubMeshes collected common submeshes
5774 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5775 const SMESH_subMesh* theSubMesh,
5776 set<const SMESH_subMesh*>& theCommon )
5780 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5781 for ( ; it != theSubMeshList.end(); it++ )
5782 theSubMesh->FindIntersection( *it, theCommon );
5783 theSubMeshList.push_back( theSubMesh );
5784 //theCommon.insert( theSubMesh );
5787 //-----------------------------------------------------------------------------
5788 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5790 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5791 for ( ; listsIt != smLists.end(); ++listsIt )
5793 const TListOfInt& smIDs = *listsIt;
5794 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5802 //=============================================================================
5804 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5806 //=============================================================================
5808 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5810 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5811 if ( isSubMeshInList( submeshID, anOrder ))
5814 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5815 return isSubMeshInList( submeshID, allConurrent );
5818 //=============================================================================
5820 * \brief Return submesh objects list in meshing order
5822 //=============================================================================
5824 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5826 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5828 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5830 return aResult._retn();
5832 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5833 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5834 anOrder.splice( anOrder.end(), allConurrent );
5837 TListOfListOfInt::iterator listIt = anOrder.begin();
5838 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5839 unionLists( *listIt, anOrder, listIndx + 1 );
5841 // convert submesh ids into interface instances
5842 // and dump command into python
5843 convertMeshOrder( anOrder, aResult, false );
5845 return aResult._retn();
5848 //=============================================================================
5850 * \brief Finds concurrent sub-meshes
5852 //=============================================================================
5854 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5856 TListOfListOfInt anOrder;
5857 ::SMESH_Mesh& mesh = GetImpl();
5859 // collect submeshes and detect concurrent algorithms and hypothesises
5860 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5862 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5863 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5864 ::SMESH_subMesh* sm = (*i_sm).second;
5866 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5868 // list of assigned hypothesises
5869 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5870 // Find out dimensions where the submesh can be concurrent.
5871 // We define the dimensions by algo of each of hypotheses in hypList
5872 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5873 for( ; hypIt != hypList.end(); hypIt++ ) {
5874 SMESH_Algo* anAlgo = 0;
5875 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5876 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5877 // hyp it-self is algo
5878 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5880 // try to find algorithm with help of sub-shapes
5881 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5882 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5883 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5886 continue; // no algorithm assigned to a current submesh
5888 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5889 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5891 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5892 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5893 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5895 } // end iterations on submesh
5897 // iterate on created dimension-hypotheses and check for concurrents
5898 for ( int i = 0; i < 4; i++ ) {
5899 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5900 // check for concurrents in own and other dimensions (step-by-step)
5901 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5902 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5903 const SMESH_DimHyp* dimHyp = *dhIt;
5904 TDimHypList listOfConcurr;
5905 set<int> setOfConcurrIds;
5906 // looking for concurrents and collect into own list
5907 for ( int j = i; j < 4; j++ )
5908 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5909 // check if any concurrents found
5910 if ( listOfConcurr.size() > 0 ) {
5911 // add own submesh to list of concurrent
5912 addInOrderOfPriority( dimHyp, listOfConcurr );
5913 list<int> listOfConcurrIds;
5914 TDimHypList::iterator hypIt = listOfConcurr.begin();
5915 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5916 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5917 anOrder.push_back( listOfConcurrIds );
5922 removeDimHyps(dimHypListArr);
5924 // now, minimise the number of concurrent groups
5925 // Here we assume that lists of submeshes can have same submesh
5926 // in case of multi-dimension algorithms, as result
5927 // list with common submesh has to be united into one list
5929 TListOfListOfInt::iterator listIt = anOrder.begin();
5930 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5931 unionLists( *listIt, anOrder, listIndx + 1 );
5937 //=============================================================================
5939 * \brief Set submesh object order
5940 * \param theSubMeshArray submesh array order
5942 //=============================================================================
5944 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5947 _preMeshInfo->ForgetOrLoad();
5950 ::SMESH_Mesh& mesh = GetImpl();
5952 TPythonDump aPythonDump; // prevent dump of called methods
5953 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5955 TListOfListOfInt subMeshOrder;
5956 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5958 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5959 TListOfInt subMeshIds;
5961 aPythonDump << ", ";
5962 aPythonDump << "[ ";
5963 // Collect subMeshes which should be clear
5964 // do it list-by-list, because modification of submesh order
5965 // take effect between concurrent submeshes only
5966 set<const SMESH_subMesh*> subMeshToClear;
5967 list<const SMESH_subMesh*> subMeshList;
5968 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5970 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5972 aPythonDump << ", ";
5973 aPythonDump << subMesh;
5974 subMeshIds.push_back( subMesh->GetId() );
5975 // detect common parts of submeshes
5976 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5977 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5979 aPythonDump << " ]";
5980 subMeshOrder.push_back( subMeshIds );
5982 // clear collected submeshes
5983 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5984 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5985 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5986 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5988 aPythonDump << " ])";
5990 mesh.SetMeshOrder( subMeshOrder );
5996 //=============================================================================
5998 * \brief Convert submesh ids into submesh interfaces
6000 //=============================================================================
6002 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6003 SMESH::submesh_array_array& theResOrder,
6004 const bool theIsDump)
6006 int nbSet = theIdsOrder.size();
6007 TPythonDump aPythonDump; // prevent dump of called methods
6009 aPythonDump << "[ ";
6010 theResOrder.length(nbSet);
6011 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6013 for( ; it != theIdsOrder.end(); it++ ) {
6014 // translate submesh identificators into submesh objects
6015 // takeing into account real number of concurrent lists
6016 const TListOfInt& aSubOrder = (*it);
6017 if (!aSubOrder.size())
6020 aPythonDump << "[ ";
6021 // convert shape indeces into interfaces
6022 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6023 aResSubSet->length(aSubOrder.size());
6024 TListOfInt::const_iterator subIt = aSubOrder.begin();
6026 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6027 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6029 SMESH::SMESH_subMesh_var subMesh =
6030 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6033 aPythonDump << ", ";
6034 aPythonDump << subMesh;
6036 aResSubSet[ j++ ] = subMesh;
6039 aPythonDump << " ]";
6041 theResOrder[ listIndx++ ] = aResSubSet;
6043 // correct number of lists
6044 theResOrder.length( listIndx );
6047 // finilise python dump
6048 aPythonDump << " ]";
6049 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6053 //================================================================================
6055 // Implementation of SMESH_MeshPartDS
6057 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6058 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6060 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6061 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6063 _meshDS = mesh_i->GetImpl().GetMeshDS();
6065 SetPersistentId( _meshDS->GetPersistentId() );
6067 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6069 // <meshPart> is the whole mesh
6070 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6072 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6073 myGroupSet = _meshDS->GetGroups();
6078 SMESH::long_array_var anIDs = meshPart->GetIDs();
6079 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6080 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6082 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6083 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6084 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6089 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6090 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6091 if ( _elements[ e->GetType() ].insert( e ).second )
6094 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6095 while ( nIt->more() )
6097 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6098 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6105 ShapeToMesh( _meshDS->ShapeToMesh() );
6107 _meshDS = 0; // to enforce iteration on _elements and _nodes
6110 // -------------------------------------------------------------------------------------
6111 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6112 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6115 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6116 for ( ; partIt != meshPart.end(); ++partIt )
6117 if ( const SMDS_MeshElement * e = *partIt )
6118 if ( _elements[ e->GetType() ].insert( e ).second )
6121 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6122 while ( nIt->more() )
6124 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6125 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6131 // -------------------------------------------------------------------------------------
6132 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6134 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6136 typedef SMDS_SetIterator
6137 <const SMDS_MeshElement*,
6138 TIDSortedElemSet::const_iterator,
6139 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6140 SMDS_MeshElement::GeomFilter
6143 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6145 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6146 _elements[type].end(),
6147 SMDS_MeshElement::GeomFilter( geomType )));
6149 // -------------------------------------------------------------------------------------
6150 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6152 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6154 typedef SMDS_SetIterator
6155 <const SMDS_MeshElement*,
6156 TIDSortedElemSet::const_iterator,
6157 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6158 SMDS_MeshElement::EntityFilter
6161 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6163 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6164 _elements[type].end(),
6165 SMDS_MeshElement::EntityFilter( entity )));
6167 // -------------------------------------------------------------------------------------
6168 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6170 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6171 if ( type == SMDSAbs_All && !_meshDS )
6173 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6175 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6176 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6178 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6180 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6181 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6183 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6184 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6186 // -------------------------------------------------------------------------------------
6187 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6188 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6190 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6191 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6192 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6194 // -------------------------------------------------------------------------------------
6195 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6196 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6197 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6198 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6199 #undef _GET_ITER_DEFINE
6201 // END Implementation of SMESH_MeshPartDS
6203 //================================================================================