1 // Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
101 int SMESH_Mesh_i::_idGenerator = 0;
103 //=============================================================================
107 //=============================================================================
109 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
111 : SALOME::GenericObj_i( thePOA )
115 _id = _idGenerator++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
131 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
132 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
133 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
135 aGroup->UnRegister();
136 SMESH::SMESH_GroupBase_var( itGr->second );
141 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
142 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
143 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
145 aSubMesh->UnRegister();
146 SMESH::SMESH_subMesh_var( itSM->second );
148 _mapSubMeshIor.clear();
150 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
151 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
152 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
153 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
154 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
155 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
158 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
162 // clear cached shapes if no more meshes remain; (the cache is blame,
163 // together with publishing, of spent time increasing in issue 22874)
164 if ( _impl->NbMeshes() == 1 )
165 _gen_i->GetShapeReader()->ClearClientBuffer();
167 delete _editor; _editor = NULL;
168 delete _previewEditor; _previewEditor = NULL;
169 delete _impl; _impl = NULL;
170 delete _preMeshInfo; _preMeshInfo = NULL;
173 //=============================================================================
177 * Associates <this> mesh with <theShape> and puts a reference
178 * to <theShape> into the current study;
179 * the previous shape is substituted by the new one.
181 //=============================================================================
183 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
184 throw (SALOME::SALOME_Exception)
186 Unexpect aCatch(SALOME_SalomeException);
188 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
190 catch(SALOME_Exception & S_ex) {
191 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
193 // to track changes of GEOM groups
194 SMESH::SMESH_Mesh_var mesh = _this();
195 addGeomGroupData( theShapeObject, mesh );
196 if ( !CORBA::is_nil( theShapeObject ))
197 _mainShapeTick = theShapeObject->GetTick();
200 //================================================================================
202 * \brief return true if mesh has a shape to build a shape on
204 //================================================================================
206 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
207 throw (SALOME::SALOME_Exception)
209 Unexpect aCatch(SALOME_SalomeException);
212 res = _impl->HasShapeToMesh();
214 catch(SALOME_Exception & S_ex) {
215 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
220 //=======================================================================
221 //function : GetShapeToMesh
223 //=======================================================================
225 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
226 throw (SALOME::SALOME_Exception)
228 Unexpect aCatch(SALOME_SalomeException);
229 GEOM::GEOM_Object_var aShapeObj;
231 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
234 aShapeObj = _gen_i->ShapeToGeomObject( S );
235 if ( aShapeObj->_is_nil() )
237 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
238 // find GEOM_Object by entry (IPAL52735)
239 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
240 for ( ; data != _geomGroupData.end(); ++data )
241 if ( data->_smeshObject->_is_equivalent( _this() ))
243 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
244 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
245 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
251 catch(SALOME_Exception & S_ex) {
252 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
254 return aShapeObj._retn();
257 //================================================================================
259 * \brief Replaces a shape in the mesh
261 //================================================================================
262 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom, GEOM::GEOM_Object_ptr theOldGeom)
263 throw (SALOME::SALOME_Exception)
265 GEOM_Client* geomClient = _gen_i->GetShapeReader();
266 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine(theOldGeom);
267 CORBA::String_var groupIOR = geomGen->GetStringFromIOR(theOldGeom);
268 geomClient->RemoveShapeFromBuffer(groupIOR.in());
269 _impl->UndefShapeToMesh();
270 SetShape(theNewGeom);
273 //================================================================================
275 * \brief Return false if the mesh is not yet fully loaded from the study file
277 //================================================================================
279 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
281 Unexpect aCatch(SALOME_SalomeException);
282 return !_preMeshInfo;
285 //================================================================================
287 * \brief Load full mesh data from the study file
289 //================================================================================
291 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
293 Unexpect aCatch(SALOME_SalomeException);
295 _preMeshInfo->FullLoadFromFile();
298 //================================================================================
300 * \brief Remove all nodes and elements
302 //================================================================================
304 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
306 Unexpect aCatch(SALOME_SalomeException);
308 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
312 //CheckGeomGroupModif(); // issue 20145
314 catch(SALOME_Exception & S_ex) {
315 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
318 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
320 SMESH::SMESH_Mesh_var mesh = _this();
321 _gen_i->UpdateIcons( mesh );
324 //================================================================================
326 * \brief Remove all nodes and elements for indicated shape
328 //================================================================================
330 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
331 throw (SALOME::SALOME_Exception)
333 Unexpect aCatch(SALOME_SalomeException);
335 _preMeshInfo->FullLoadFromFile();
338 _impl->ClearSubMesh( ShapeID );
340 catch(SALOME_Exception & S_ex) {
341 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
343 _impl->GetMeshDS()->Modified();
345 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
348 //=============================================================================
350 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
352 //=============================================================================
354 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
356 SMESH::DriverMED_ReadStatus res;
359 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
360 res = SMESH::DRS_OK; break;
361 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
362 res = SMESH::DRS_EMPTY; break;
363 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
364 res = SMESH::DRS_WARN_RENUMBER; break;
365 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
366 res = SMESH::DRS_WARN_SKIP_ELEM; break;
367 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
368 res = SMESH::DRS_WARN_DESCENDING; break;
369 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
371 res = SMESH::DRS_FAIL; break;
376 //=============================================================================
378 * Convert ::SMESH_ComputeError to SMESH::ComputeError
380 //=============================================================================
382 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
384 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
385 errVar->subShapeID = -1;
386 errVar->hasBadMesh = false;
388 if ( !errorPtr || errorPtr->IsOK() )
390 errVar->code = SMESH::COMPERR_OK;
394 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
395 errVar->comment = errorPtr->myComment.c_str();
397 return errVar._retn();
400 //=============================================================================
404 * Imports mesh data from MED file
406 //=============================================================================
408 SMESH::DriverMED_ReadStatus
409 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
410 throw ( SALOME::SALOME_Exception )
412 Unexpect aCatch(SALOME_SalomeException);
415 status = _impl->MEDToMesh( theFileName, theMeshName );
417 catch( SALOME_Exception& S_ex ) {
418 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
421 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
424 CreateGroupServants();
426 int major, minor, release;
427 major = minor = release = 0;
428 MED::GetMEDVersion(theFileName, major, minor, release);
429 _medFileInfo = new SMESH::MedFileInfo();
430 _medFileInfo->fileName = theFileName;
431 _medFileInfo->fileSize = 0;
432 _medFileInfo->major = major;
433 _medFileInfo->minor = minor;
434 _medFileInfo->release = release;
435 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
437 return ConvertDriverMEDReadStatus(status);
440 //================================================================================
442 * \brief Imports mesh data from the CGNS file
444 //================================================================================
446 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
447 const int theMeshIndex,
448 std::string& theMeshName )
449 throw ( SALOME::SALOME_Exception )
451 Unexpect aCatch(SALOME_SalomeException);
454 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
456 catch( SALOME_Exception& S_ex ) {
457 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
460 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
463 CreateGroupServants();
465 _medFileInfo = new SMESH::MedFileInfo();
466 _medFileInfo->fileName = theFileName;
467 _medFileInfo->major = 0;
468 _medFileInfo->minor = 0;
469 _medFileInfo->release = 0;
470 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
472 return ConvertDriverMEDReadStatus(status);
475 //================================================================================
477 * \brief Return string representation of a MED file version comprising nbDigits
479 //================================================================================
481 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
483 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
485 return CORBA::string_dup( ver.c_str() );
488 //================================================================================
490 * Return the list of med versions compatibles for write/append,
491 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
493 //================================================================================
494 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
496 SMESH::long_array_var aResult = new SMESH::long_array();
497 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
498 long nbver = mvok.size();
499 aResult->length( nbver );
500 for ( int i = 0; i < nbver; i++ )
501 aResult[i] = mvok[i];
502 return aResult._retn();
505 //=============================================================================
509 * Imports mesh data from MED file
511 //=============================================================================
513 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
514 throw ( SALOME::SALOME_Exception )
518 // Read mesh with name = <theMeshName> into SMESH_Mesh
519 _impl->UNVToMesh( theFileName );
521 CreateGroupServants();
523 _medFileInfo = new SMESH::MedFileInfo();
524 _medFileInfo->fileName = theFileName;
525 _medFileInfo->major = 0;
526 _medFileInfo->minor = 0;
527 _medFileInfo->release = 0;
528 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
530 SMESH_CATCH( SMESH::throwCorbaException );
535 //=============================================================================
539 * Imports mesh data from STL file
541 //=============================================================================
542 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
543 throw ( SALOME::SALOME_Exception )
547 // Read mesh with name = <theMeshName> into SMESH_Mesh
548 std::string name = _impl->STLToMesh( theFileName );
551 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
552 _gen_i->SetName( meshSO, name.c_str() );
554 _medFileInfo = new SMESH::MedFileInfo();
555 _medFileInfo->fileName = theFileName;
556 _medFileInfo->major = 0;
557 _medFileInfo->minor = 0;
558 _medFileInfo->release = 0;
559 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
561 SMESH_CATCH( SMESH::throwCorbaException );
566 //================================================================================
568 * \brief Function used in SMESH_CATCH by ImportGMFFile()
570 //================================================================================
574 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
576 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
580 //================================================================================
582 * \brief Imports data from a GMF file and returns an error description
584 //================================================================================
586 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
587 bool theMakeRequiredGroups )
588 throw (SALOME::SALOME_Exception)
590 SMESH_ComputeErrorPtr error;
593 #define SMESH_CAUGHT error =
596 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
598 _medFileInfo = new SMESH::MedFileInfo();
599 _medFileInfo->fileName = theFileName;
600 _medFileInfo->major = 0;
601 _medFileInfo->minor = 0;
602 _medFileInfo->release = 0;
603 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
605 SMESH_CATCH( exceptionToComputeError );
609 CreateGroupServants();
611 return ConvertComputeError( error );
614 //=============================================================================
618 //=============================================================================
620 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
622 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
623 (SMESH_Hypothesis::Hypothesis_Status theStatus)
626 RETURNCASE( HYP_OK );
627 RETURNCASE( HYP_MISSING );
628 RETURNCASE( HYP_CONCURRENT );
629 RETURNCASE( HYP_BAD_PARAMETER );
630 RETURNCASE( HYP_HIDDEN_ALGO );
631 RETURNCASE( HYP_HIDING_ALGO );
632 RETURNCASE( HYP_UNKNOWN_FATAL );
633 RETURNCASE( HYP_INCOMPATIBLE );
634 RETURNCASE( HYP_NOTCONFORM );
635 RETURNCASE( HYP_ALREADY_EXIST );
636 RETURNCASE( HYP_BAD_DIM );
637 RETURNCASE( HYP_BAD_SUBSHAPE );
638 RETURNCASE( HYP_BAD_GEOMETRY );
639 RETURNCASE( HYP_NEED_SHAPE );
640 RETURNCASE( HYP_INCOMPAT_HYPS );
643 return SMESH::HYP_UNKNOWN_FATAL;
646 //=============================================================================
650 * calls internal addHypothesis() and then adds a reference to <anHyp> under
651 * the SObject actually having a reference to <aSubShape>.
652 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
654 //=============================================================================
656 SMESH::Hypothesis_Status
657 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
658 SMESH::SMESH_Hypothesis_ptr anHyp,
659 CORBA::String_out anErrorText)
660 throw(SALOME::SALOME_Exception)
662 Unexpect aCatch(SALOME_SalomeException);
664 _preMeshInfo->ForgetOrLoad();
667 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
668 anErrorText = error.c_str();
670 SMESH::SMESH_Mesh_var mesh( _this() );
671 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
673 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
674 _gen_i->UpdateIcons( mesh );
676 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
678 // Update Python script
679 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
680 << aSubShape << ", " << anHyp << " )";
682 return ConvertHypothesisStatus(status);
685 //=============================================================================
689 //=============================================================================
691 SMESH_Hypothesis::Hypothesis_Status
692 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
693 SMESH::SMESH_Hypothesis_ptr anHyp,
694 std::string* anErrorText)
696 if(MYDEBUG) MESSAGE("addHypothesis");
698 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
699 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
701 if (CORBA::is_nil( anHyp ))
702 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
704 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
707 TopoDS_Shape myLocSubShape;
708 //use PseudoShape in case if mesh has no shape
710 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
712 myLocSubShape = _impl->GetShapeToMesh();
714 const int hypId = anHyp->GetId();
716 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
717 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
719 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
721 // assure there is a corresponding submesh
722 if ( !_impl->IsMainShape( myLocSubShape )) {
723 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
724 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
725 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
728 else if ( anErrorText )
730 *anErrorText = error;
733 catch(SALOME_Exception & S_ex)
735 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
740 //=============================================================================
744 //=============================================================================
746 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
747 SMESH::SMESH_Hypothesis_ptr anHyp)
748 throw(SALOME::SALOME_Exception)
750 Unexpect aCatch(SALOME_SalomeException);
752 _preMeshInfo->ForgetOrLoad();
754 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
755 SMESH::SMESH_Mesh_var mesh = _this();
757 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
759 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
760 _gen_i->UpdateIcons( mesh );
762 // Update Python script
763 if(_impl->HasShapeToMesh())
764 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
765 << aSubShape << ", " << anHyp << " )";
767 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
770 return ConvertHypothesisStatus(status);
773 //=============================================================================
777 //=============================================================================
779 SMESH_Hypothesis::Hypothesis_Status
780 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
781 SMESH::SMESH_Hypothesis_ptr anHyp)
783 if(MYDEBUG) MESSAGE("removeHypothesis()");
785 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
786 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
788 if (CORBA::is_nil( anHyp ))
789 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
792 _preMeshInfo->ForgetOrLoad();
794 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
797 TopoDS_Shape myLocSubShape;
798 //use PseudoShape in case if mesh has no shape
799 if( _impl->HasShapeToMesh() )
800 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
802 myLocSubShape = _impl->GetShapeToMesh();
804 const int hypId = anHyp->GetId();
805 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
806 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
808 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
812 catch(SALOME_Exception & S_ex)
814 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
819 //=============================================================================
823 //=============================================================================
825 SMESH::ListOfHypothesis *
826 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
827 throw(SALOME::SALOME_Exception)
829 Unexpect aCatch(SALOME_SalomeException);
830 if (MYDEBUG) MESSAGE("GetHypothesisList");
831 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
832 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
834 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
837 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
838 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
839 myLocSubShape = _impl->GetShapeToMesh();
840 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
841 int i = 0, n = aLocalList.size();
844 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
845 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
846 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
848 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
849 if ( id_hypptr != _mapHypo.end() )
850 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
854 catch(SALOME_Exception & S_ex) {
855 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
858 return aList._retn();
861 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
863 Unexpect aCatch(SALOME_SalomeException);
864 if (MYDEBUG) MESSAGE("GetSubMeshes");
866 SMESH::submesh_array_var aList = new SMESH::submesh_array();
869 TPythonDump aPythonDump;
870 if ( !_mapSubMeshIor.empty() )
874 aList->length( _mapSubMeshIor.size() );
876 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
877 for ( ; it != _mapSubMeshIor.end(); it++ ) {
878 if ( CORBA::is_nil( it->second )) continue;
879 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
881 if (i > 1) aPythonDump << ", ";
882 aPythonDump << it->second;
886 catch(SALOME_Exception & S_ex) {
887 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
890 // Update Python script
891 if ( !_mapSubMeshIor.empty() )
892 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
894 return aList._retn();
897 //=============================================================================
901 //=============================================================================
903 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
904 const char* theName )
905 throw(SALOME::SALOME_Exception)
907 Unexpect aCatch(SALOME_SalomeException);
908 if (CORBA::is_nil(aSubShape))
909 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
911 SMESH::SMESH_subMesh_var subMesh;
912 SMESH::SMESH_Mesh_var aMesh = _this();
914 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
916 //Get or Create the SMESH_subMesh object implementation
918 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
920 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
922 TopoDS_Iterator it( myLocSubShape );
924 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
926 subMesh = getSubMesh( subMeshId );
928 // create a new subMesh object servant if there is none for the shape
929 if ( subMesh->_is_nil() )
930 subMesh = createSubMesh( aSubShape );
931 if ( _gen_i->CanPublishInStudy( subMesh ))
933 SALOMEDS::SObject_wrap aSO =
934 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
935 if ( !aSO->_is_nil()) {
936 // Update Python script
937 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
938 << aSubShape << ", '" << theName << "' )";
942 catch(SALOME_Exception & S_ex) {
943 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
945 return subMesh._retn();
948 //=============================================================================
952 //=============================================================================
954 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
955 throw (SALOME::SALOME_Exception)
959 if ( theSubMesh->_is_nil() )
962 GEOM::GEOM_Object_var aSubShape;
963 // Remove submesh's SObject
964 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
965 if ( !anSO->_is_nil() ) {
966 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
967 SALOMEDS::SObject_wrap anObj, aRef;
968 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
969 anObj->ReferencedObject( aRef.inout() ))
971 CORBA::Object_var obj = aRef->GetObject();
972 aSubShape = GEOM::GEOM_Object::_narrow( obj );
974 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
975 // aSubShape = theSubMesh->GetSubShape();
977 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
978 builder->RemoveObjectWithChildren( anSO );
980 // Update Python script
981 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
984 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
986 _preMeshInfo->ForgetOrLoad();
988 SMESH_CATCH( SMESH::throwCorbaException );
991 //=============================================================================
995 //=============================================================================
997 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
998 const char* theName )
999 throw(SALOME::SALOME_Exception)
1001 Unexpect aCatch(SALOME_SalomeException);
1003 _preMeshInfo->FullLoadFromFile();
1005 SMESH::SMESH_Group_var aNewGroup =
1006 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1008 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1010 SMESH::SMESH_Mesh_var mesh = _this();
1011 SALOMEDS::SObject_wrap aSO =
1012 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1013 if ( !aSO->_is_nil())
1014 // Update Python script
1015 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1016 << theElemType << ", '" << theName << "' )";
1018 return aNewGroup._retn();
1021 //=============================================================================
1025 //=============================================================================
1026 SMESH::SMESH_GroupOnGeom_ptr
1027 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1028 const char* theName,
1029 GEOM::GEOM_Object_ptr theGeomObj)
1030 throw(SALOME::SALOME_Exception)
1032 Unexpect aCatch(SALOME_SalomeException);
1034 _preMeshInfo->FullLoadFromFile();
1036 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1038 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1039 if ( !aShape.IsNull() )
1042 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1044 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1046 SMESH::SMESH_Mesh_var mesh = _this();
1047 SALOMEDS::SObject_wrap aSO =
1048 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1049 if ( !aSO->_is_nil())
1050 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1051 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1055 return aNewGroup._retn();
1058 //================================================================================
1060 * \brief Creates a group whose contents is defined by filter
1061 * \param theElemType - group type
1062 * \param theName - group name
1063 * \param theFilter - the filter
1064 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1066 //================================================================================
1068 SMESH::SMESH_GroupOnFilter_ptr
1069 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1070 const char* theName,
1071 SMESH::Filter_ptr theFilter )
1072 throw (SALOME::SALOME_Exception)
1074 Unexpect aCatch(SALOME_SalomeException);
1076 _preMeshInfo->FullLoadFromFile();
1078 if ( CORBA::is_nil( theFilter ))
1079 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1081 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1083 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1085 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1086 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1089 if ( !aNewGroup->_is_nil() )
1090 aNewGroup->SetFilter( theFilter );
1092 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1094 SMESH::SMESH_Mesh_var mesh = _this();
1095 SALOMEDS::SObject_wrap aSO =
1096 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1098 if ( !aSO->_is_nil())
1099 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1100 << theElemType << ", '" << theName << "', " << theFilter << " )";
1102 return aNewGroup._retn();
1105 //=============================================================================
1109 //=============================================================================
1111 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1112 throw (SALOME::SALOME_Exception)
1114 if ( theGroup->_is_nil() )
1119 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1123 if ( aGroup->GetMeshServant() != this )
1124 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1125 SALOME::BAD_PARAM );
1127 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1128 if ( !aGroupSO->_is_nil() )
1130 // Update Python script
1131 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1133 // Remove group's SObject
1134 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1135 builder->RemoveObjectWithChildren( aGroupSO );
1137 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1139 // Remove the group from SMESH data structures
1140 removeGroup( aGroup->GetLocalID() );
1142 SMESH_CATCH( SMESH::throwCorbaException );
1145 //=============================================================================
1147 * Remove group with its contents
1149 //=============================================================================
1151 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1152 throw (SALOME::SALOME_Exception)
1156 _preMeshInfo->FullLoadFromFile();
1158 if ( theGroup->_is_nil() )
1161 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1162 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1163 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1166 vector<int> nodeIds; // to remove nodes becoming free
1167 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1168 if ( !isNodal && !theGroup->IsEmpty() )
1170 CORBA::Long elemID = theGroup->GetID( 1 );
1171 int nbElemNodes = GetElemNbNodes( elemID );
1172 if ( nbElemNodes > 0 )
1173 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1176 // Retrieve contents
1177 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1178 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1179 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1180 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1181 elems.assign( elemBeg, elemEnd );
1183 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1186 RemoveGroup( theGroup );
1189 for ( size_t i = 0; i < elems.size(); ++i )
1191 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1195 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1196 nodeIds.push_back( nIt->next()->GetID() );
1198 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1202 _impl->GetMeshDS()->RemoveElement( elems[i] );
1206 // Remove free nodes
1207 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1208 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1209 if ( n->NbInverseElements() == 0 )
1210 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1212 // Update Python script (theGroup must be alive for this)
1213 pyDump << SMESH::SMESH_Mesh_var(_this())
1214 << ".RemoveGroupWithContents( " << theGroup << " )";
1216 SMESH_CATCH( SMESH::throwCorbaException );
1219 //================================================================================
1221 * \brief Get the list of groups existing in the mesh
1222 * \retval SMESH::ListOfGroups * - list of groups
1224 //================================================================================
1226 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1228 Unexpect aCatch(SALOME_SalomeException);
1229 if (MYDEBUG) MESSAGE("GetGroups");
1231 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1234 TPythonDump aPythonDump;
1235 if ( !_mapGroups.empty() )
1237 aPythonDump << "[ ";
1239 aList->length( _mapGroups.size() );
1241 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1242 for ( ; it != _mapGroups.end(); it++ ) {
1243 if ( CORBA::is_nil( it->second )) continue;
1244 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1246 if (i > 1) aPythonDump << ", ";
1247 aPythonDump << it->second;
1251 catch(SALOME_Exception & S_ex) {
1252 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1254 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1256 return aList._retn();
1259 //=============================================================================
1261 * Get number of groups existing in the mesh
1263 //=============================================================================
1265 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1267 Unexpect aCatch(SALOME_SalomeException);
1268 return _mapGroups.size();
1271 //=============================================================================
1273 * New group including all mesh elements present in initial groups is created.
1275 //=============================================================================
1277 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1278 SMESH::SMESH_GroupBase_ptr theGroup2,
1279 const char* theName )
1280 throw (SALOME::SALOME_Exception)
1282 SMESH::SMESH_Group_var aResGrp;
1286 _preMeshInfo->FullLoadFromFile();
1288 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1289 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1291 if ( theGroup1->GetType() != theGroup2->GetType() )
1292 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1297 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1298 if ( aResGrp->_is_nil() )
1299 return SMESH::SMESH_Group::_nil();
1301 aResGrp->AddFrom( theGroup1 );
1302 aResGrp->AddFrom( theGroup2 );
1304 // Update Python script
1305 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1306 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1308 SMESH_CATCH( SMESH::throwCorbaException );
1310 return aResGrp._retn();
1313 //=============================================================================
1315 * \brief New group including all mesh elements present in initial groups is created.
1316 * \param theGroups list of groups
1317 * \param theName name of group to be created
1318 * \return pointer to the new group
1320 //=============================================================================
1322 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1323 const char* theName )
1324 throw (SALOME::SALOME_Exception)
1326 SMESH::SMESH_Group_var aResGrp;
1329 _preMeshInfo->FullLoadFromFile();
1332 return SMESH::SMESH_Group::_nil();
1337 SMESH::ElementType aType = SMESH::ALL;
1338 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1340 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1341 if ( CORBA::is_nil( aGrp ) )
1343 if ( aType == SMESH::ALL )
1344 aType = aGrp->GetType();
1345 else if ( aType != aGrp->GetType() )
1346 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1349 if ( aType == SMESH::ALL )
1350 return SMESH::SMESH_Group::_nil();
1355 aResGrp = CreateGroup( aType, theName );
1356 if ( aResGrp->_is_nil() )
1357 return SMESH::SMESH_Group::_nil();
1359 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1360 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1362 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1363 if ( !CORBA::is_nil( aGrp ) )
1365 aResGrp->AddFrom( aGrp );
1366 if ( g > 0 ) pyDump << ", ";
1370 pyDump << " ], '" << theName << "' )";
1372 SMESH_CATCH( SMESH::throwCorbaException );
1374 return aResGrp._retn();
1377 //=============================================================================
1379 * New group is created. All mesh elements that are
1380 * present in both initial groups are added to the new one.
1382 //=============================================================================
1384 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1385 SMESH::SMESH_GroupBase_ptr theGroup2,
1386 const char* theName )
1387 throw (SALOME::SALOME_Exception)
1389 SMESH::SMESH_Group_var aResGrp;
1394 _preMeshInfo->FullLoadFromFile();
1396 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1397 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1399 if ( theGroup1->GetType() != theGroup2->GetType() )
1400 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1404 // Create Intersection
1405 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1406 if ( aResGrp->_is_nil() )
1407 return aResGrp._retn();
1409 SMESHDS_GroupBase* groupDS1 = 0;
1410 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1411 groupDS1 = grp_i->GetGroupDS();
1413 SMESHDS_GroupBase* groupDS2 = 0;
1414 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1415 groupDS2 = grp_i->GetGroupDS();
1417 SMESHDS_Group* resGroupDS = 0;
1418 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1419 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1421 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1423 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1424 while ( elemIt1->more() )
1426 const SMDS_MeshElement* e = elemIt1->next();
1427 if ( groupDS2->Contains( e ))
1428 resGroupDS->SMDSGroup().Add( e );
1431 // Update Python script
1432 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1433 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1435 SMESH_CATCH( SMESH::throwCorbaException );
1437 return aResGrp._retn();
1440 //=============================================================================
1442 \brief Intersect list of groups. New group is created. All mesh elements that
1443 are present in all initial groups simultaneously are added to the new one.
1444 \param theGroups list of groups
1445 \param theName name of group to be created
1446 \return pointer on the group
1448 //=============================================================================
1449 SMESH::SMESH_Group_ptr
1450 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1451 const char* theName )
1452 throw (SALOME::SALOME_Exception)
1454 SMESH::SMESH_Group_var aResGrp;
1459 _preMeshInfo->FullLoadFromFile();
1462 return SMESH::SMESH_Group::_nil();
1464 // check types and get SMESHDS_GroupBase's
1465 SMESH::ElementType aType = SMESH::ALL;
1466 vector< SMESHDS_GroupBase* > groupVec;
1467 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1469 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1470 if ( CORBA::is_nil( aGrp ) )
1472 if ( aType == SMESH::ALL )
1473 aType = aGrp->GetType();
1474 else if ( aType != aGrp->GetType() )
1475 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1478 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1479 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1481 if ( grpDS->IsEmpty() )
1486 groupVec.push_back( grpDS );
1489 if ( aType == SMESH::ALL ) // all groups are nil
1490 return SMESH::SMESH_Group::_nil();
1495 aResGrp = CreateGroup( aType, theName );
1497 SMESHDS_Group* resGroupDS = 0;
1498 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1499 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1500 if ( !resGroupDS || groupVec.empty() )
1501 return aResGrp._retn();
1504 size_t i, nb = groupVec.size();
1505 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1506 while ( elemIt1->more() )
1508 const SMDS_MeshElement* e = elemIt1->next();
1510 for ( i = 1; ( i < nb && inAll ); ++i )
1511 inAll = groupVec[i]->Contains( e );
1514 resGroupDS->SMDSGroup().Add( e );
1517 // Update Python script
1518 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1519 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1521 SMESH_CATCH( SMESH::throwCorbaException );
1523 return aResGrp._retn();
1526 //=============================================================================
1528 * New group is created. All mesh elements that are present in
1529 * a main group but is not present in a tool group are added to the new one
1531 //=============================================================================
1533 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1534 SMESH::SMESH_GroupBase_ptr theGroup2,
1535 const char* theName )
1536 throw (SALOME::SALOME_Exception)
1538 SMESH::SMESH_Group_var aResGrp;
1543 _preMeshInfo->FullLoadFromFile();
1545 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1546 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1548 if ( theGroup1->GetType() != theGroup2->GetType() )
1549 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1553 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1554 if ( aResGrp->_is_nil() )
1555 return aResGrp._retn();
1557 SMESHDS_GroupBase* groupDS1 = 0;
1558 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1559 groupDS1 = grp_i->GetGroupDS();
1561 SMESHDS_GroupBase* groupDS2 = 0;
1562 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1563 groupDS2 = grp_i->GetGroupDS();
1565 SMESHDS_Group* resGroupDS = 0;
1566 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1567 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1569 if ( groupDS1 && groupDS2 && resGroupDS )
1571 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1572 while ( elemIt1->more() )
1574 const SMDS_MeshElement* e = elemIt1->next();
1575 if ( !groupDS2->Contains( e ))
1576 resGroupDS->SMDSGroup().Add( e );
1579 // Update Python script
1580 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1581 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1583 SMESH_CATCH( SMESH::throwCorbaException );
1585 return aResGrp._retn();
1588 //=============================================================================
1590 \brief Cut lists of groups. New group is created. All mesh elements that are
1591 present in main groups but do not present in tool groups are added to the new one
1592 \param theMainGroups list of main groups
1593 \param theToolGroups list of tool groups
1594 \param theName name of group to be created
1595 \return pointer on the group
1597 //=============================================================================
1598 SMESH::SMESH_Group_ptr
1599 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1600 const SMESH::ListOfGroups& theToolGroups,
1601 const char* theName )
1602 throw (SALOME::SALOME_Exception)
1604 SMESH::SMESH_Group_var aResGrp;
1609 _preMeshInfo->FullLoadFromFile();
1612 return SMESH::SMESH_Group::_nil();
1614 // check types and get SMESHDS_GroupBase's
1615 SMESH::ElementType aType = SMESH::ALL;
1616 vector< SMESHDS_GroupBase* > toolGroupVec;
1617 vector< SMDS_ElemIteratorPtr > mainIterVec;
1619 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1621 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1622 if ( CORBA::is_nil( aGrp ) )
1624 if ( aType == SMESH::ALL )
1625 aType = aGrp->GetType();
1626 else if ( aType != aGrp->GetType() )
1627 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1629 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1630 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1631 if ( !grpDS->IsEmpty() )
1632 mainIterVec.push_back( grpDS->GetElements() );
1634 if ( aType == SMESH::ALL ) // all main groups are nil
1635 return SMESH::SMESH_Group::_nil();
1636 if ( mainIterVec.empty() ) // all main groups are empty
1637 return aResGrp._retn();
1639 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1641 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1642 if ( CORBA::is_nil( aGrp ) )
1644 if ( aType != aGrp->GetType() )
1645 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1647 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1648 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1649 toolGroupVec.push_back( grpDS );
1655 aResGrp = CreateGroup( aType, theName );
1657 SMESHDS_Group* resGroupDS = 0;
1658 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1659 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1661 return aResGrp._retn();
1664 size_t i, nb = toolGroupVec.size();
1665 SMDS_ElemIteratorPtr mainElemIt
1666 ( new SMDS_IteratorOnIterators
1667 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1668 while ( mainElemIt->more() )
1670 const SMDS_MeshElement* e = mainElemIt->next();
1672 for ( i = 0; ( i < nb && !isIn ); ++i )
1673 isIn = toolGroupVec[i]->Contains( e );
1676 resGroupDS->SMDSGroup().Add( e );
1679 // Update Python script
1680 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1681 << ".CutListOfGroups( " << theMainGroups << ", "
1682 << theToolGroups << ", '" << theName << "' )";
1684 SMESH_CATCH( SMESH::throwCorbaException );
1686 return aResGrp._retn();
1689 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1691 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1692 bool & toStopChecking )
1694 toStopChecking = ( nbCommon < nbChecked );
1695 return nbCommon == nbNodes;
1697 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1698 bool & toStopChecking )
1700 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1701 return nbCommon == nbCorners;
1703 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1704 bool & toStopChecking )
1706 return nbCommon > 0;
1708 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1709 bool & toStopChecking )
1711 return nbCommon >= (nbNodes+1) / 2;
1715 //=============================================================================
1717 * Create a group of entities basing on nodes of other groups.
1718 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1719 * \param [in] anElemType - a type of elements to include to the new group.
1720 * \param [in] theName - a name of the new group.
1721 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1722 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1723 * new group provided that it is based on nodes of an element of \a aListOfGroups
1724 * \return SMESH_Group - the created group
1726 // IMP 19939, bug 22010, IMP 22635
1727 //=============================================================================
1729 SMESH::SMESH_Group_ptr
1730 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1731 SMESH::ElementType theElemType,
1732 const char* theName,
1733 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1734 CORBA::Boolean theUnderlyingOnly)
1735 throw (SALOME::SALOME_Exception)
1737 SMESH::SMESH_Group_var aResGrp;
1741 _preMeshInfo->FullLoadFromFile();
1743 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1745 if ( !theName || !aMeshDS )
1746 return SMESH::SMESH_Group::_nil();
1748 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1750 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1751 SMESH_Comment nbCoNoStr( "SMESH.");
1752 switch ( theNbCommonNodes ) {
1753 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1754 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1755 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1756 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1757 default: return aResGrp._retn();
1759 int nbChecked, nbCommon, nbNodes, nbCorners;
1765 aResGrp = CreateGroup( theElemType, theName );
1766 if ( aResGrp->_is_nil() )
1767 return SMESH::SMESH_Group::_nil();
1769 SMESHDS_GroupBase* groupBaseDS =
1770 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1771 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1773 vector<bool> isNodeInGroups;
1775 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1777 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1778 if ( CORBA::is_nil( aGrp ) )
1780 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1781 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1784 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1785 if ( !elIt ) continue;
1787 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1789 while ( elIt->more() ) {
1790 const SMDS_MeshElement* el = elIt->next();
1791 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1792 while ( nIt->more() )
1793 resGroupCore.Add( nIt->next() );
1796 // get elements of theElemType based on nodes of every element of group
1797 else if ( theUnderlyingOnly )
1799 while ( elIt->more() )
1801 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1802 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1803 TIDSortedElemSet checkedElems;
1804 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1805 while ( nIt->more() )
1807 const SMDS_MeshNode* n = nIt->next();
1808 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1809 // check nodes of elements of theElemType around el
1810 while ( elOfTypeIt->more() )
1812 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1813 if ( !checkedElems.insert( elOfType ).second ) continue;
1814 nbNodes = elOfType->NbNodes();
1815 nbCorners = elOfType->NbCornerNodes();
1817 bool toStopChecking = false;
1818 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1819 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1820 if ( elNodes.count( nIt2->next() ) &&
1821 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1823 resGroupCore.Add( elOfType );
1830 // get all nodes of elements of groups
1833 while ( elIt->more() )
1835 const SMDS_MeshElement* el = elIt->next(); // an element of group
1836 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1837 while ( nIt->more() )
1839 const SMDS_MeshNode* n = nIt->next();
1840 if ( n->GetID() >= (int) isNodeInGroups.size() )
1841 isNodeInGroups.resize( n->GetID() + 1, false );
1842 isNodeInGroups[ n->GetID() ] = true;
1848 // Get elements of theElemType based on a certain number of nodes of elements of groups
1849 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1851 const SMDS_MeshNode* n;
1852 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1853 const int isNodeInGroupsSize = isNodeInGroups.size();
1854 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1856 if ( !isNodeInGroups[ iN ] ||
1857 !( n = aMeshDS->FindNode( iN )))
1860 // check nodes of elements of theElemType around n
1861 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1862 while ( elOfTypeIt->more() )
1864 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1865 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1870 nbNodes = elOfType->NbNodes();
1871 nbCorners = elOfType->NbCornerNodes();
1873 bool toStopChecking = false;
1874 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1875 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1877 const int nID = nIt->next()->GetID();
1878 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1879 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1881 resGroupCore.Add( elOfType );
1889 // Update Python script
1890 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1891 << ".CreateDimGroup( "
1892 << theGroups << ", " << theElemType << ", '" << theName << "', "
1893 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1895 SMESH_CATCH( SMESH::throwCorbaException );
1897 return aResGrp._retn();
1900 //================================================================================
1902 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1903 * existing 1D elements as group boundaries.
1904 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1905 * adjacent faces is more than \a sharpAngle in degrees.
1906 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1907 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1908 * \return ListOfGroups - the created groups
1910 //================================================================================
1912 SMESH::ListOfGroups*
1913 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1914 CORBA::Boolean theCreateEdges,
1915 CORBA::Boolean theUseExistingEdges )
1916 throw (SALOME::SALOME_Exception)
1918 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1919 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1922 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1928 _preMeshInfo->FullLoadFromFile();
1930 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1932 std::vector< SMESH_MeshAlgos::Edge > edges =
1933 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1935 if ( theCreateEdges )
1937 std::vector<const SMDS_MeshNode *> nodes(2);
1938 for ( size_t i = 0; i < edges.size(); ++i )
1940 nodes[0] = edges[i]._node1;
1941 nodes[1] = edges[i]._node2;
1942 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1944 if ( edges[i]._medium )
1945 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1947 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1951 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1952 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1954 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1956 resultGroups->length( faceGroups.size() );
1957 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1959 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1960 _editor->GenerateGroupName("Group").c_str());
1961 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1963 SMESHDS_GroupBase* groupBaseDS =
1964 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1965 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1967 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1968 for ( size_t i = 0; i < faces.size(); ++i )
1969 groupCore.Add( faces[i] );
1972 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1973 << ".FaceGroupsSeparatedByEdges( "
1974 << TVar( theSharpAngle ) << ", "
1975 << theCreateEdges << ", "
1976 << theUseExistingEdges << " )";
1978 SMESH_CATCH( SMESH::throwCorbaException );
1979 return resultGroups._retn();
1983 //================================================================================
1985 * \brief Remember GEOM group data
1987 //================================================================================
1989 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1990 CORBA::Object_ptr theSmeshObj)
1992 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1995 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1996 if ( groupSO->_is_nil() )
1999 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2000 GEOM::GEOM_IGroupOperations_wrap groupOp =
2001 geomGen->GetIGroupOperations();
2002 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2005 _geomGroupData.push_back( TGeomGroupData() );
2006 TGeomGroupData & groupData = _geomGroupData.back();
2008 CORBA::String_var entry = groupSO->GetID();
2009 groupData._groupEntry = entry.in();
2011 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2012 groupData._indices.insert( ids[i] );
2014 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2015 // shape index in SMESHDS
2016 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2017 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2020 //================================================================================
2022 * Remove GEOM group data relating to removed smesh object
2024 //================================================================================
2026 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2028 list<TGeomGroupData>::iterator
2029 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2030 for ( ; data != dataEnd; ++data ) {
2031 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2032 _geomGroupData.erase( data );
2038 //================================================================================
2040 * \brief Return new group contents if it has been changed and update group data
2042 //================================================================================
2044 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
2046 TopoDS_Shape newShape;
2049 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2050 if ( !groupSO->_is_nil() )
2052 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2053 if ( CORBA::is_nil( groupObj )) return newShape;
2054 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2056 // get indices of group items
2057 set<int> curIndices;
2058 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2059 GEOM::GEOM_IGroupOperations_wrap groupOp =
2060 geomGen->GetIGroupOperations();
2061 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2062 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2063 curIndices.insert( ids[i] );
2065 if ( groupData._indices == curIndices )
2066 return newShape; // group not changed
2069 groupData._indices = curIndices;
2071 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2072 if ( !geomClient ) return newShape;
2073 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2074 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2075 newShape = _gen_i->GeomObjectToShape( geomGroup );
2078 if ( newShape.IsNull() ) {
2079 // geom group becomes empty - return empty compound
2080 TopoDS_Compound compound;
2081 BRep_Builder().MakeCompound(compound);
2082 newShape = compound;
2089 //-----------------------------------------------------------------------------
2091 * \brief Storage of shape and index used in CheckGeomGroupModif()
2093 struct TIndexedShape
2096 TopoDS_Shape _shape;
2097 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2099 //-----------------------------------------------------------------------------
2101 * \brief Data to re-create a group on geometry
2103 struct TGroupOnGeomData
2106 TopoDS_Shape _shape;
2107 SMDSAbs_ElementType _type;
2109 Quantity_Color _color;
2111 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2113 _oldID = group->GetID();
2114 _type = group->GetType();
2115 _name = group->GetStoreName();
2116 _color = group->GetColor();
2120 //-----------------------------------------------------------------------------
2122 * \brief Check if a filter is still valid after geometry removal
2124 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2126 if ( theFilter->_is_nil() )
2128 SMESH::Filter::Criteria_var criteria;
2129 theFilter->GetCriteria( criteria.out() );
2131 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2133 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2135 switch ( criteria[ iCr ].Type )
2137 case SMESH::FT_BelongToGeom:
2138 case SMESH::FT_BelongToPlane:
2139 case SMESH::FT_BelongToCylinder:
2140 case SMESH::FT_BelongToGenSurface:
2141 case SMESH::FT_LyingOnGeom:
2142 entry = thresholdID;
2144 case SMESH::FT_ConnectedElements:
2147 entry = thresholdID;
2153 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2154 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2155 if ( so->_is_nil() )
2157 CORBA::Object_var obj = so->GetObject();
2158 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2159 if ( gen->GeomObjectToShape( geom ).IsNull() )
2162 } // loop on criteria
2168 //=============================================================================
2170 * \brief Update data if geometry changes
2174 //=============================================================================
2176 void SMESH_Mesh_i::CheckGeomModif()
2178 SMESH::SMESH_Mesh_var me = _this();
2179 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2181 //bool removedFromClient = false;
2183 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2185 //removedFromClient = _impl->HasShapeToMesh();
2187 // try to find geometry by study reference
2188 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2189 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2190 if ( !meshSO->_is_nil() &&
2191 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2192 geomRefSO->ReferencedObject( geomSO.inout() ))
2194 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2195 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2198 if ( mainGO->_is_nil() && // geometry removed ==>
2199 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2201 // convert geom dependent groups into standalone ones
2202 CheckGeomGroupModif();
2204 _impl->ShapeToMesh( TopoDS_Shape() );
2206 // remove sub-meshes
2207 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2208 while ( i_sm != _mapSubMeshIor.end() )
2210 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2212 RemoveSubMesh( sm );
2214 // remove all children except groups in the study
2215 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2216 SALOMEDS::SObject_wrap so;
2217 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2218 if ( meshSO->FindSubObject( tag, so.inout() ))
2219 builder->RemoveObjectWithChildren( so );
2221 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2227 if ( !_impl->HasShapeToMesh() ) return;
2230 // Update after group modification
2232 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2233 mainGO->GetTick() == _mainShapeTick )
2235 int nb = NbNodes() + NbElements();
2236 CheckGeomGroupModif();
2237 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2238 _gen_i->UpdateIcons( me );
2242 // Update after shape transformation like Translate
2244 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2245 if ( !geomClient ) return;
2246 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2247 if ( geomGen->_is_nil() ) return;
2249 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2250 geomClient->RemoveShapeFromBuffer( ior.in() );
2252 // Update data taking into account that
2253 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2256 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2257 if ( newShape.IsNull() )
2260 // for the SHAPER-STUDY: the geometry may be updated, so, add a warning icon
2261 if (_mainShapeTick != mainGO->GetTick()) {
2262 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2263 if ( !meshSO->_is_nil())
2264 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_MESH_WARN");
2267 _mainShapeTick = mainGO->GetTick();
2269 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2271 // store data of groups on geometry
2272 std::vector< TGroupOnGeomData > groupsData;
2273 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2274 groupsData.reserve( groups.size() );
2275 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2276 for ( ; g != groups.end(); ++g )
2278 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2280 groupsData.push_back( TGroupOnGeomData( group ));
2283 SMESH::SMESH_GroupOnGeom_var gog;
2284 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2285 if ( i_grp != _mapGroups.end() )
2286 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2288 GEOM::GEOM_Object_var geom;
2289 if ( !gog->_is_nil() )
2290 geom = gog->GetShape();
2291 if ( !geom->_is_nil() )
2293 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2294 geomClient->RemoveShapeFromBuffer( ior.in() );
2295 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2299 // store assigned hypotheses
2300 std::vector< pair< int, THypList > > ids2Hyps;
2301 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2302 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2304 const TopoDS_Shape& s = s2hyps.Key();
2305 const THypList& hyps = s2hyps.ChangeValue();
2306 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2309 // change shape to mesh
2310 int oldNbSubShapes = meshDS->MaxShapeIndex();
2311 _impl->ShapeToMesh( TopoDS_Shape() );
2312 _impl->ShapeToMesh( newShape );
2314 // re-add shapes of geom groups
2315 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2316 for ( ; data != _geomGroupData.end(); ++data )
2318 TopoDS_Shape newShape = newGroupShape( *data );
2319 if ( !newShape.IsNull() )
2321 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2323 TopoDS_Compound compound;
2324 BRep_Builder().MakeCompound( compound );
2325 BRep_Builder().Add( compound, newShape );
2326 newShape = compound;
2328 _impl->GetSubMesh( newShape );
2331 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2332 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2333 SALOME::INTERNAL_ERROR );
2335 // re-assign hypotheses
2336 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2338 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2339 const THypList& hyps = ids2Hyps[i].second;
2340 THypList::const_iterator h = hyps.begin();
2341 for ( ; h != hyps.end(); ++h )
2342 _impl->AddHypothesis( s, (*h)->GetID() );
2345 // restore groups on geometry
2346 for ( size_t i = 0; i < groupsData.size(); ++i )
2348 const TGroupOnGeomData& data = groupsData[i];
2349 if ( data._shape.IsNull() )
2352 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2353 if ( i2g == _mapGroups.end() ) continue;
2355 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2356 if ( !gr_i ) continue;
2358 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2360 _mapGroups.erase( i2g );
2362 g->GetGroupDS()->SetColor( data._color );
2365 // update _mapSubMesh
2366 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2367 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2368 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2372 //=============================================================================
2374 * \brief Update objects depending on changed geom groups
2376 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2377 * issue 0020210: Update of a smesh group after modification of the associated geom group
2379 //=============================================================================
2381 void SMESH_Mesh_i::CheckGeomGroupModif()
2383 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2384 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2385 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2386 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2387 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2389 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2390 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2391 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2393 int nbValid = 0, nbRemoved = 0;
2394 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2395 for ( ; chItr->More(); chItr->Next() )
2397 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2398 if ( !smSO->_is_nil() &&
2399 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2400 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2402 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2403 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2404 if ( !geom->_non_existent() )
2407 continue; // keep the sub-mesh
2410 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2411 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2412 if ( !sm->_is_nil() && !sm->_non_existent() )
2414 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2415 if ( smGeom->_is_nil() )
2417 RemoveSubMesh( sm );
2424 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2425 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2429 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2430 builder->RemoveObjectWithChildren( rootSO );
2434 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2435 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2436 while ( i_gr != _mapGroups.end())
2438 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2440 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2441 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2442 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2443 bool isValidGeom = false;
2444 if ( !onGeom->_is_nil() )
2446 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2448 else if ( !onFilt->_is_nil() )
2450 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2454 isValidGeom = ( !groupSO->_is_nil() &&
2455 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2459 if ( !IsLoaded() || group->IsEmpty() )
2461 RemoveGroup( group );
2463 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2465 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2467 else // is it possible?
2469 builder->RemoveObjectWithChildren( refSO );
2475 if ( !_impl->HasShapeToMesh() ) return;
2477 CORBA::Long nbEntities = NbNodes() + NbElements();
2479 // Check if group contents changed
2481 typedef map< string, TopoDS_Shape > TEntry2Geom;
2482 TEntry2Geom newGroupContents;
2484 list<TGeomGroupData>::iterator
2485 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2486 for ( ; data != dataEnd; ++data )
2488 pair< TEntry2Geom::iterator, bool > it_new =
2489 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2490 bool processedGroup = !it_new.second;
2491 TopoDS_Shape& newShape = it_new.first->second;
2492 if ( !processedGroup )
2493 newShape = newGroupShape( *data );
2494 if ( newShape.IsNull() )
2495 continue; // no changes
2498 _preMeshInfo->ForgetOrLoad();
2500 if ( processedGroup ) { // update group indices
2501 list<TGeomGroupData>::iterator data2 = data;
2502 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2503 data->_indices = data2->_indices;
2506 // Update SMESH objects according to new GEOM group contents
2508 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2509 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2511 int oldID = submesh->GetId();
2512 if ( !_mapSubMeshIor.count( oldID ))
2514 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2516 // update hypotheses
2517 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2518 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2519 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2521 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2522 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2524 // care of submeshes
2525 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2526 int newID = newSubmesh->GetId();
2527 if ( newID != oldID ) {
2528 _mapSubMesh [ newID ] = newSubmesh;
2529 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2530 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2531 _mapSubMesh. erase(oldID);
2532 _mapSubMesh_i. erase(oldID);
2533 _mapSubMeshIor.erase(oldID);
2534 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2539 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2540 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2541 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2543 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2545 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2546 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2547 ds->SetShape( newShape );
2552 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2553 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2555 // Remove groups and submeshes basing on removed sub-shapes
2557 TopTools_MapOfShape newShapeMap;
2558 TopoDS_Iterator shapeIt( newShape );
2559 for ( ; shapeIt.More(); shapeIt.Next() )
2560 newShapeMap.Add( shapeIt.Value() );
2562 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2563 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2565 if ( newShapeMap.Contains( shapeIt.Value() ))
2567 TopTools_IndexedMapOfShape oldShapeMap;
2568 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2569 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2571 const TopoDS_Shape& oldShape = oldShapeMap(i);
2572 int oldInd = meshDS->ShapeToIndex( oldShape );
2574 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2575 if ( i_smIor != _mapSubMeshIor.end() ) {
2576 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2579 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2580 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2582 // check if a group bases on oldInd shape
2583 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2584 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2585 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2586 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2588 RemoveGroup( i_grp->second ); // several groups can base on same shape
2589 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2594 // Reassign hypotheses and update groups after setting the new shape to mesh
2596 // collect anassigned hypotheses
2597 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2598 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2599 TShapeHypList assignedHyps;
2600 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2602 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2603 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2604 if ( !hyps.empty() ) {
2605 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2606 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2607 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2610 // collect shapes supporting groups
2611 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2612 TShapeTypeList groupData;
2613 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2614 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2615 for ( ; grIt != groups.end(); ++grIt )
2617 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2619 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2621 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2623 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2624 _impl->ShapeToMesh( newShape );
2626 // reassign hypotheses
2627 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2628 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2630 TIndexedShape& geom = indS_hyps->first;
2631 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2632 int oldID = geom._index;
2633 int newID = meshDS->ShapeToIndex( geom._shape );
2634 if ( oldID == 1 ) { // main shape
2636 geom._shape = newShape;
2640 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2641 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2642 // care of sub-meshes
2643 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2644 if ( newID != oldID ) {
2645 _mapSubMesh [ newID ] = newSubmesh;
2646 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2647 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2648 _mapSubMesh. erase(oldID);
2649 _mapSubMesh_i. erase(oldID);
2650 _mapSubMeshIor.erase(oldID);
2651 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2655 TShapeTypeList::iterator geomType = groupData.begin();
2656 for ( ; geomType != groupData.end(); ++geomType )
2658 const TIndexedShape& geom = geomType->first;
2659 int oldID = geom._index;
2660 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2663 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2664 CORBA::String_var name = groupSO->GetName();
2666 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2667 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2668 /*id=*/-1, geom._shape ))
2669 group_i->changeLocalId( group->GetID() );
2672 break; // everything has been updated
2675 } // loop on group data
2679 CORBA::Long newNbEntities = NbNodes() + NbElements();
2680 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2681 if ( newNbEntities != nbEntities )
2683 // Add all SObjects with icons to soToUpdateIcons
2684 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2686 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2687 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2688 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2690 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2691 i_gr != _mapGroups.end(); ++i_gr ) // groups
2692 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2695 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2696 for ( ; so != soToUpdateIcons.end(); ++so )
2697 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2700 //=============================================================================
2702 * \brief Create standalone group from a group on geometry or filter
2704 //=============================================================================
2706 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2707 throw (SALOME::SALOME_Exception)
2709 SMESH::SMESH_Group_var aGroup;
2714 _preMeshInfo->FullLoadFromFile();
2716 if ( theGroup->_is_nil() )
2717 return aGroup._retn();
2719 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2721 return aGroup._retn();
2723 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2725 const int anId = aGroupToRem->GetLocalID();
2726 if ( !_impl->ConvertToStandalone( anId ) )
2727 return aGroup._retn();
2728 removeGeomGroupData( theGroup );
2730 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2732 // remove old instance of group from own map
2733 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2734 _mapGroups.erase( anId );
2736 SALOMEDS::StudyBuilder_var builder;
2737 SALOMEDS::SObject_wrap aGroupSO;
2738 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2739 if ( !aStudy->_is_nil() ) {
2740 builder = aStudy->NewBuilder();
2741 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2742 if ( !aGroupSO->_is_nil() )
2744 // remove reference to geometry
2745 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2746 for ( ; chItr->More(); chItr->Next() )
2748 // Remove group's child SObject
2749 SALOMEDS::SObject_wrap so = chItr->Value();
2750 builder->RemoveObject( so );
2752 // Update Python script
2753 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2754 << ".ConvertToStandalone( " << aGroupSO << " )";
2756 // change icon of Group on Filter
2759 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2760 // const int isEmpty = ( elemTypes->length() == 0 );
2763 SALOMEDS::GenericAttribute_wrap anAttr =
2764 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2765 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2766 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2772 // remember new group in own map
2773 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2774 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2776 // register CORBA object for persistence
2777 _gen_i->RegisterObject( aGroup );
2779 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2780 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2781 //aGroup->Register();
2782 aGroupToRem->UnRegister();
2784 SMESH_CATCH( SMESH::throwCorbaException );
2786 return aGroup._retn();
2789 //=============================================================================
2793 //=============================================================================
2795 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2797 if(MYDEBUG) MESSAGE( "createSubMesh" );
2798 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2799 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2802 SMESH_subMesh_i * subMeshServant;
2805 subMeshId = mySubMesh->GetId();
2806 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2808 else // "invalid sub-mesh"
2810 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2811 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2812 if ( _mapSubMesh.empty() )
2815 subMeshId = _mapSubMesh.begin()->first - 1;
2816 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2819 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2821 _mapSubMesh [subMeshId] = mySubMesh;
2822 _mapSubMesh_i [subMeshId] = subMeshServant;
2823 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2825 subMeshServant->Register();
2827 // register CORBA object for persistence
2828 int nextId = _gen_i->RegisterObject( subMesh );
2829 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2830 else { nextId = 0; } // avoid "unused variable" warning
2832 // to track changes of GEOM groups
2833 if ( subMeshId > 0 )
2834 addGeomGroupData( theSubShapeObject, subMesh );
2836 return subMesh._retn();
2839 //=======================================================================
2840 //function : getSubMesh
2842 //=======================================================================
2844 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2846 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2847 if ( it == _mapSubMeshIor.end() )
2848 return SMESH::SMESH_subMesh::_nil();
2850 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2853 //=============================================================================
2857 //=============================================================================
2859 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2860 GEOM::GEOM_Object_ptr theSubShapeObject )
2862 bool isHypChanged = false;
2863 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2864 return isHypChanged;
2866 const int subMeshId = theSubMesh->GetId();
2868 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2871 if (( _mapSubMesh.count( subMeshId )) &&
2872 ( sm = _impl->GetSubMeshContaining( subMeshId )))
2874 TopoDS_Shape S = sm->GetSubShape();
2877 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2878 isHypChanged = !hyps.empty();
2879 if ( isHypChanged && _preMeshInfo )
2880 _preMeshInfo->ForgetOrLoad();
2881 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2882 for ( ; hyp != hyps.end(); ++hyp )
2883 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2890 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2891 isHypChanged = ( aHypList->length() > 0 );
2892 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2893 removeHypothesis( theSubShapeObject, aHypList[i] );
2896 catch( const SALOME::SALOME_Exception& ) {
2897 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2899 removeGeomGroupData( theSubShapeObject );
2903 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2904 if ( id_smi != _mapSubMesh_i.end() )
2905 id_smi->second->UnRegister();
2907 // remove a CORBA object
2908 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2909 if ( id_smptr != _mapSubMeshIor.end() )
2910 SMESH::SMESH_subMesh_var( id_smptr->second );
2912 _mapSubMesh.erase(subMeshId);
2913 _mapSubMesh_i.erase(subMeshId);
2914 _mapSubMeshIor.erase(subMeshId);
2916 return isHypChanged;
2919 //=============================================================================
2923 //=============================================================================
2925 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2926 const char* theName,
2928 const TopoDS_Shape& theShape,
2929 const SMESH_PredicatePtr& thePredicate )
2931 std::string newName;
2932 if ( !theName || !theName[0] )
2934 std::set< std::string > presentNames;
2935 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2936 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2938 CORBA::String_var name = i_gr->second->GetName();
2939 presentNames.insert( name.in() );
2942 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2943 } while ( !presentNames.insert( newName ).second );
2944 theName = newName.c_str();
2946 SMESH::SMESH_GroupBase_var aGroup;
2947 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
2948 theID, theShape, thePredicate ))
2950 int anId = g->GetID();
2951 SMESH_GroupBase_i* aGroupImpl;
2952 if ( !theShape.IsNull() )
2953 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2954 else if ( thePredicate )
2955 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2957 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2959 aGroup = aGroupImpl->_this();
2960 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2961 aGroupImpl->Register();
2963 // register CORBA object for persistence
2964 int nextId = _gen_i->RegisterObject( aGroup );
2965 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2966 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
2968 // to track changes of GEOM groups
2969 if ( !theShape.IsNull() ) {
2970 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2971 addGeomGroupData( geom, aGroup );
2974 return aGroup._retn();
2977 //=============================================================================
2979 * SMESH_Mesh_i::removeGroup
2981 * Should be called by ~SMESH_Group_i()
2983 //=============================================================================
2985 void SMESH_Mesh_i::removeGroup( const int theId )
2987 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2988 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2989 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2990 _mapGroups.erase( theId );
2991 removeGeomGroupData( group );
2992 if ( !_impl->RemoveGroup( theId ))
2994 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2995 RemoveGroup( group );
2997 group->UnRegister();
3001 //=============================================================================
3005 //=============================================================================
3007 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3008 throw(SALOME::SALOME_Exception)
3010 SMESH::log_array_var aLog;
3014 _preMeshInfo->FullLoadFromFile();
3016 list < SMESHDS_Command * >logDS = _impl->GetLog();
3017 aLog = new SMESH::log_array;
3019 int lg = logDS.size();
3022 list < SMESHDS_Command * >::iterator its = logDS.begin();
3023 while(its != logDS.end()){
3024 SMESHDS_Command *com = *its;
3025 int comType = com->GetType();
3027 int lgcom = com->GetNumber();
3029 const list < int >&intList = com->GetIndexes();
3030 int inum = intList.size();
3032 list < int >::const_iterator ii = intList.begin();
3033 const list < double >&coordList = com->GetCoords();
3034 int rnum = coordList.size();
3036 list < double >::const_iterator ir = coordList.begin();
3037 aLog[indexLog].commandType = comType;
3038 aLog[indexLog].number = lgcom;
3039 aLog[indexLog].coords.length(rnum);
3040 aLog[indexLog].indexes.length(inum);
3041 for(int i = 0; i < rnum; i++){
3042 aLog[indexLog].coords[i] = *ir;
3043 //MESSAGE(" "<<i<<" "<<ir.Value());
3046 for(int i = 0; i < inum; i++){
3047 aLog[indexLog].indexes[i] = *ii;
3048 //MESSAGE(" "<<i<<" "<<ii.Value());
3057 SMESH_CATCH( SMESH::throwCorbaException );
3059 return aLog._retn();
3063 //=============================================================================
3067 //=============================================================================
3069 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3073 SMESH_CATCH( SMESH::throwCorbaException );
3076 //=============================================================================
3080 //=============================================================================
3082 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3087 //=============================================================================
3090 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3091 // issue 0020918: groups removal is caused by hyp modification
3092 // issue 0021208: to forget not loaded mesh data at hyp modification
3093 struct TCallUp_i : public SMESH_Mesh::TCallUp
3095 SMESH_Mesh_i* _mesh;
3096 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3097 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3098 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3099 virtual void Load () { _mesh->Load(); }
3103 //================================================================================
3105 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3107 //================================================================================
3109 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3112 _preMeshInfo->ForgetOrLoad();
3114 SMESH::SMESH_Mesh_var mesh = _this();
3115 _gen_i->UpdateIcons( mesh );
3117 // mark a hypothesis as valid after edition
3118 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3119 SALOMEDS::SObject_wrap hypRoot;
3120 if ( !smeshComp->_is_nil() &&
3121 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3123 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3124 for ( ; anIter->More(); anIter->Next() )
3126 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3127 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3128 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3129 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3130 _gen_i->HighLightInvalid( hyp, false );
3135 //=============================================================================
3139 //=============================================================================
3141 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3143 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3146 _impl->SetCallUp( new TCallUp_i(this));
3149 //=============================================================================
3153 //=============================================================================
3155 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3157 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3161 //=============================================================================
3163 * Return mesh editor
3165 //=============================================================================
3167 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3168 throw (SALOME::SALOME_Exception)
3170 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3174 _preMeshInfo->FullLoadFromFile();
3176 // Create MeshEditor
3178 _editor = new SMESH_MeshEditor_i( this, false );
3179 aMeshEdVar = _editor->_this();
3181 // Update Python script
3182 TPythonDump() << _editor << " = "
3183 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3185 SMESH_CATCH( SMESH::throwCorbaException );
3187 return aMeshEdVar._retn();
3190 //=============================================================================
3192 * Return mesh edition previewer
3194 //=============================================================================
3196 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3197 throw (SALOME::SALOME_Exception)
3199 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3203 _preMeshInfo->FullLoadFromFile();
3205 if ( !_previewEditor )
3206 _previewEditor = new SMESH_MeshEditor_i( this, true );
3207 aMeshEdVar = _previewEditor->_this();
3209 SMESH_CATCH( SMESH::throwCorbaException );
3211 return aMeshEdVar._retn();
3214 //================================================================================
3216 * \brief Return true if the mesh has been edited since a last total re-compute
3217 * and those modifications may prevent successful partial re-compute
3219 //================================================================================
3221 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3223 Unexpect aCatch(SALOME_SalomeException);
3224 return _impl->HasModificationsToDiscard();
3227 //================================================================================
3229 * \brief Returns a random unique color
3231 //================================================================================
3233 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3235 const int MAX_ATTEMPTS = 100;
3237 double tolerance = 0.5;
3238 SALOMEDS::Color col;
3242 // generate random color
3243 double red = (double)rand() / RAND_MAX;
3244 double green = (double)rand() / RAND_MAX;
3245 double blue = (double)rand() / RAND_MAX;
3246 // check existence in the list of the existing colors
3247 bool matched = false;
3248 std::list<SALOMEDS::Color>::const_iterator it;
3249 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3250 SALOMEDS::Color color = *it;
3251 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3252 matched = tol < tolerance;
3254 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3255 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3263 //=============================================================================
3265 * Sets auto-color mode. If it is on, groups get unique random colors
3267 //=============================================================================
3269 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3271 Unexpect aCatch(SALOME_SalomeException);
3272 _impl->SetAutoColor(theAutoColor);
3274 TPythonDump pyDump; // not to dump group->SetColor() from below code
3275 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3277 std::list<SALOMEDS::Color> aReservedColors;
3278 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3279 for ( ; it != _mapGroups.end(); it++ ) {
3280 if ( CORBA::is_nil( it->second )) continue;
3281 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3282 it->second->SetColor( aColor );
3283 aReservedColors.push_back( aColor );
3287 //=============================================================================
3289 * Returns true if auto-color mode is on
3291 //=============================================================================
3293 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3295 Unexpect aCatch(SALOME_SalomeException);
3296 return _impl->GetAutoColor();
3299 //=============================================================================
3301 * Checks if there are groups with equal names
3303 //=============================================================================
3305 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3307 return _impl->HasDuplicatedGroupNamesMED();
3310 //================================================================================
3312 * \brief Care of a file before exporting mesh into it
3314 //================================================================================
3316 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3318 SMESH_File aFile( file, false );
3320 if ( aFile.exists() ) {
3321 // existing filesystem node
3322 if ( !aFile.isDirectory() ) {
3323 if ( aFile.openForWriting() ) {
3324 if ( overwrite && ! aFile.remove()) {
3325 msg << "Can't replace " << aFile.getName();
3328 msg << "Can't write into " << aFile.getName();
3331 msg << "Location " << aFile.getName() << " is not a file";
3335 // nonexisting file; check if it can be created
3336 if ( !aFile.openForWriting() ) {
3337 msg << "You cannot create the file "
3339 << ". Check the directory existence and access rights";
3347 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3351 //================================================================================
3353 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3354 * \param file - file name
3355 * \param overwrite - to erase the file or not
3356 * \retval string - mesh name
3358 //================================================================================
3360 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3361 CORBA::Boolean overwrite)
3364 PrepareForWriting(file, overwrite);
3365 string aMeshName = "Mesh";
3366 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3367 if ( !aStudy->_is_nil() ) {
3368 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3369 if ( !aMeshSO->_is_nil() ) {
3370 CORBA::String_var name = aMeshSO->GetName();
3372 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3373 if ( !aStudy->GetProperties()->IsLocked() )
3375 SALOMEDS::GenericAttribute_wrap anAttr;
3376 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3377 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3378 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3379 ASSERT(!aFileName->_is_nil());
3380 aFileName->SetValue(file);
3381 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3382 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3383 ASSERT(!aFileType->_is_nil());
3384 aFileType->SetValue("FICHIERMED");
3388 // Update Python script
3389 // set name of mesh before export
3390 TPythonDump() << _gen_i << ".SetName("
3391 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3393 // check names of groups
3399 //================================================================================
3401 * \brief Export to MED file
3403 //================================================================================
3405 void SMESH_Mesh_i::ExportMED(const char* file,
3406 CORBA::Boolean auto_groups,
3407 CORBA::Long version,
3408 CORBA::Boolean overwrite,
3409 CORBA::Boolean autoDimension)
3410 throw(SALOME::SALOME_Exception)
3412 //MESSAGE("MED minor version: "<< minor);
3415 _preMeshInfo->FullLoadFromFile();
3417 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3418 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3420 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3422 << "auto_groups=" <<auto_groups << ", "
3423 << "minor=" << version << ", "
3424 << "overwrite=" << overwrite << ", "
3425 << "meshPart=None, "
3426 << "autoDimension=" << autoDimension << " )";
3428 SMESH_CATCH( SMESH::throwCorbaException );
3431 //================================================================================
3433 * \brief Export a mesh to a SAUV file
3435 //================================================================================
3437 void SMESH_Mesh_i::ExportSAUV (const char* file,
3438 CORBA::Boolean auto_groups)
3439 throw(SALOME::SALOME_Exception)
3441 Unexpect aCatch(SALOME_SalomeException);
3443 _preMeshInfo->FullLoadFromFile();
3445 string aMeshName = prepareMeshNameAndGroups(file, true);
3446 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3447 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3448 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3452 //================================================================================
3454 * \brief Export a mesh to a DAT file
3456 //================================================================================
3458 void SMESH_Mesh_i::ExportDAT (const char *file)
3459 throw(SALOME::SALOME_Exception)
3461 Unexpect aCatch(SALOME_SalomeException);
3463 _preMeshInfo->FullLoadFromFile();
3465 // Update Python script
3466 // check names of groups
3468 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3471 PrepareForWriting(file);
3472 _impl->ExportDAT(file);
3475 //================================================================================
3477 * \brief Export a mesh to an UNV file
3479 //================================================================================
3481 void SMESH_Mesh_i::ExportUNV (const char *file)
3482 throw(SALOME::SALOME_Exception)
3484 Unexpect aCatch(SALOME_SalomeException);
3486 _preMeshInfo->FullLoadFromFile();
3488 // Update Python script
3489 // check names of groups
3491 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3494 PrepareForWriting(file);
3495 _impl->ExportUNV(file);
3498 //================================================================================
3500 * \brief Export a mesh to an STL file
3502 //================================================================================
3504 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3505 throw(SALOME::SALOME_Exception)
3507 Unexpect aCatch(SALOME_SalomeException);
3509 _preMeshInfo->FullLoadFromFile();
3511 // Update Python script
3512 // check names of groups
3514 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3515 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3517 CORBA::String_var name;
3518 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3519 if ( !so->_is_nil() )
3520 name = so->GetName();
3523 PrepareForWriting( file );
3524 _impl->ExportSTL( file, isascii, name.in() );
3527 //================================================================================
3529 * \brief Export a part of mesh to a med file
3531 //================================================================================
3533 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3535 CORBA::Boolean auto_groups,
3536 CORBA::Long version,
3537 CORBA::Boolean overwrite,
3538 CORBA::Boolean autoDimension,
3539 const GEOM::ListOfFields& fields,
3540 const char* geomAssocFields,
3541 CORBA::Double ZTolerance)
3542 throw (SALOME::SALOME_Exception)
3544 MESSAGE("MED version: "<< version);
3547 _preMeshInfo->FullLoadFromFile();
3550 bool have0dField = false;
3551 if ( fields.length() > 0 )
3553 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3554 if ( shapeToMesh->_is_nil() )
3555 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3557 for ( size_t i = 0; i < fields.length(); ++i )
3559 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3560 THROW_SALOME_CORBA_EXCEPTION
3561 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3562 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3563 if ( fieldShape->_is_nil() )
3564 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3565 if ( !fieldShape->IsSame( shapeToMesh ) )
3566 THROW_SALOME_CORBA_EXCEPTION
3567 ( "Field defined not on shape", SALOME::BAD_PARAM);
3568 if ( fields[i]->GetDimension() == 0 )
3571 if ( geomAssocFields )
3572 for ( int i = 0; geomAssocFields[i]; ++i )
3573 switch ( geomAssocFields[i] ) {
3574 case 'v':case 'e':case 'f':case 's': break;
3575 case 'V':case 'E':case 'F':case 'S': break;
3576 default: THROW_SALOME_CORBA_EXCEPTION
3577 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3581 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3585 string aMeshName = "Mesh";
3586 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3587 if ( CORBA::is_nil( meshPart ) ||
3588 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3590 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3591 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3592 0, autoDimension, /*addODOnVertices=*/have0dField,
3594 meshDS = _impl->GetMeshDS();
3599 _preMeshInfo->FullLoadFromFile();
3601 PrepareForWriting(file, overwrite);
3603 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3604 if ( !SO->_is_nil() ) {
3605 CORBA::String_var name = SO->GetName();
3609 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3610 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3611 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3612 meshDS = tmpDSDeleter._obj = partDS;
3617 if ( _impl->HasShapeToMesh() )
3619 DriverMED_W_Field fieldWriter;
3620 fieldWriter.SetFile( file );
3621 fieldWriter.SetMeshName( aMeshName );
3622 fieldWriter.AddODOnVertices( have0dField );
3624 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3628 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3629 goList->length( fields.length() );
3630 for ( size_t i = 0; i < fields.length(); ++i )
3632 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3635 TPythonDump() << _this() << ".ExportPartToMED( "
3636 << meshPart << ", r'"
3638 << auto_groups << ", "
3640 << overwrite << ", "
3641 << autoDimension << ", "
3643 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3644 << TVar( ZTolerance )
3647 SMESH_CATCH( SMESH::throwCorbaException );
3650 //================================================================================
3652 * Write GEOM fields to MED file
3654 //================================================================================
3656 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3657 SMESHDS_Mesh* meshDS,
3658 const GEOM::ListOfFields& fields,
3659 const char* geomAssocFields)
3661 #define METH "SMESH_Mesh_i::exportMEDFields() "
3663 if (( fields.length() < 1 ) &&
3664 ( !geomAssocFields || !geomAssocFields[0] ))
3667 std::vector< std::vector< double > > dblVals;
3668 std::vector< std::vector< int > > intVals;
3669 std::vector< int > subIdsByDim[ 4 ];
3670 const double noneDblValue = 0.;
3671 const double noneIntValue = 0;
3673 for ( size_t iF = 0; iF < fields.length(); ++iF )
3677 int dim = fields[ iF ]->GetDimension();
3678 SMDSAbs_ElementType elemType;
3679 TopAbs_ShapeEnum shapeType;
3681 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3682 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3683 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3684 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3686 continue; // skip fields on whole shape
3688 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3689 if ( dataType == GEOM::FDT_String )
3691 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3692 if ( stepIDs->length() < 1 )
3694 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3695 if ( comps->length() < 1 )
3697 CORBA::String_var name = fields[ iF ]->GetName();
3699 if ( !fieldWriter.Set( meshDS,
3703 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3706 for ( size_t iC = 0; iC < comps->length(); ++iC )
3707 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3709 dblVals.resize( comps->length() );
3710 intVals.resize( comps->length() );
3712 // find sub-shape IDs
3714 std::vector< int >& subIds = subIdsByDim[ dim ];
3715 if ( subIds.empty() )
3716 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3717 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3718 subIds.push_back( id );
3722 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3726 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3728 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3729 if ( step->_is_nil() )
3732 CORBA::Long stamp = step->GetStamp();
3733 CORBA::Long id = step->GetID();
3734 fieldWriter.SetDtIt( int( stamp ), int( id ));
3736 // fill dblVals or intVals
3737 for ( size_t iC = 0; iC < comps->length(); ++iC )
3738 if ( dataType == GEOM::FDT_Double )
3740 dblVals[ iC ].clear();
3741 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3745 intVals[ iC ].clear();
3746 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3750 case GEOM::FDT_Double:
3752 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3753 if ( dblStep->_is_nil() ) continue;
3754 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3755 if ( vv->length() != subIds.size() * comps->length() )
3756 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3757 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3758 for ( size_t iC = 0; iC < comps->length(); ++iC )
3759 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3764 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3765 if ( intStep->_is_nil() ) continue;
3766 GEOM::ListOfLong_var vv = intStep->GetValues();
3767 if ( vv->length() != subIds.size() * comps->length() )
3768 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3769 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3770 for ( size_t iC = 0; iC < comps->length(); ++iC )
3771 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3774 case GEOM::FDT_Bool:
3776 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3777 if ( boolStep->_is_nil() ) continue;
3778 GEOM::short_array_var vv = boolStep->GetValues();
3779 if ( vv->length() != subIds.size() * comps->length() )
3780 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3781 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3782 for ( size_t iC = 0; iC < comps->length(); ++iC )
3783 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3789 // pass values to fieldWriter
3790 elemIt = fieldWriter.GetOrderedElems();
3791 if ( dataType == GEOM::FDT_Double )
3792 while ( elemIt->more() )
3794 const SMDS_MeshElement* e = elemIt->next();
3795 const int shapeID = e->getshapeId();
3796 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3797 for ( size_t iC = 0; iC < comps->length(); ++iC )
3798 fieldWriter.AddValue( noneDblValue );
3800 for ( size_t iC = 0; iC < comps->length(); ++iC )
3801 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3804 while ( elemIt->more() )
3806 const SMDS_MeshElement* e = elemIt->next();
3807 const int shapeID = e->getshapeId();
3808 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3809 for ( size_t iC = 0; iC < comps->length(); ++iC )
3810 fieldWriter.AddValue( (double) noneIntValue );
3812 for ( size_t iC = 0; iC < comps->length(); ++iC )
3813 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3817 fieldWriter.Perform();
3818 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3819 if ( res && res->IsKO() )
3821 if ( res->myComment.empty() )
3822 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3824 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3830 if ( !geomAssocFields || !geomAssocFields[0] )
3833 // write geomAssocFields
3835 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3836 shapeDim[ TopAbs_COMPOUND ] = 3;
3837 shapeDim[ TopAbs_COMPSOLID ] = 3;
3838 shapeDim[ TopAbs_SOLID ] = 3;
3839 shapeDim[ TopAbs_SHELL ] = 2;
3840 shapeDim[ TopAbs_FACE ] = 2;
3841 shapeDim[ TopAbs_WIRE ] = 1;
3842 shapeDim[ TopAbs_EDGE ] = 1;
3843 shapeDim[ TopAbs_VERTEX ] = 0;
3844 shapeDim[ TopAbs_SHAPE ] = 3;
3846 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3848 std::vector< std::string > compNames;
3849 switch ( geomAssocFields[ iF ]) {
3851 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3852 compNames.push_back( "dim" );
3855 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3858 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3861 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3865 compNames.push_back( "id" );
3866 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3867 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3869 fieldWriter.SetDtIt( -1, -1 );
3871 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3875 if ( compNames.size() == 2 ) // _vertices_
3876 while ( elemIt->more() )
3878 const SMDS_MeshElement* e = elemIt->next();
3879 const int shapeID = e->getshapeId();
3882 fieldWriter.AddValue( (double) -1 );
3883 fieldWriter.AddValue( (double) -1 );
3887 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3888 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3889 fieldWriter.AddValue( (double) shapeID );
3893 while ( elemIt->more() )
3895 const SMDS_MeshElement* e = elemIt->next();
3896 const int shapeID = e->getshapeId();
3898 fieldWriter.AddValue( (double) -1 );
3900 fieldWriter.AddValue( (double) shapeID );
3904 fieldWriter.Perform();
3905 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3906 if ( res && res->IsKO() )
3908 if ( res->myComment.empty() )
3909 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3911 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3914 } // loop on geomAssocFields
3919 //================================================================================
3921 * \brief Export a part of mesh to a DAT file
3923 //================================================================================
3925 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3927 throw (SALOME::SALOME_Exception)
3929 Unexpect aCatch(SALOME_SalomeException);
3931 _preMeshInfo->FullLoadFromFile();
3933 PrepareForWriting(file);
3935 SMESH_MeshPartDS partDS( meshPart );
3936 _impl->ExportDAT(file,&partDS);
3938 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3939 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3941 //================================================================================
3943 * \brief Export a part of mesh to an UNV file
3945 //================================================================================
3947 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3949 throw (SALOME::SALOME_Exception)
3951 Unexpect aCatch(SALOME_SalomeException);
3953 _preMeshInfo->FullLoadFromFile();
3955 PrepareForWriting(file);
3957 SMESH_MeshPartDS partDS( meshPart );
3958 _impl->ExportUNV(file, &partDS);
3960 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3961 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3963 //================================================================================
3965 * \brief Export a part of mesh to an STL file
3967 //================================================================================
3969 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3971 ::CORBA::Boolean isascii)
3972 throw (SALOME::SALOME_Exception)
3974 Unexpect aCatch(SALOME_SalomeException);
3976 _preMeshInfo->FullLoadFromFile();
3978 PrepareForWriting(file);
3980 CORBA::String_var name;
3981 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3982 if ( !so->_is_nil() )
3983 name = so->GetName();
3985 SMESH_MeshPartDS partDS( meshPart );
3986 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3988 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3989 << meshPart<< ", r'" << file << "', " << isascii << ")";
3992 //================================================================================
3994 * \brief Export a part of mesh to an STL file
3996 //================================================================================
3998 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4000 CORBA::Boolean overwrite,
4001 CORBA::Boolean groupElemsByType)
4002 throw (SALOME::SALOME_Exception)
4005 Unexpect aCatch(SALOME_SalomeException);
4007 _preMeshInfo->FullLoadFromFile();
4009 PrepareForWriting(file,overwrite);
4011 std::string meshName("");
4012 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4013 if ( !so->_is_nil() )
4015 CORBA::String_var name = so->GetName();
4016 meshName = name.in();
4020 SMESH_MeshPartDS partDS( meshPart );
4021 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4023 SMESH_CATCH( SMESH::throwCorbaException );
4025 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4026 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4028 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4032 //================================================================================
4034 * \brief Export a part of mesh to a GMF file
4036 //================================================================================
4038 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4040 bool withRequiredGroups)
4041 throw (SALOME::SALOME_Exception)
4043 Unexpect aCatch(SALOME_SalomeException);
4045 _preMeshInfo->FullLoadFromFile();
4047 PrepareForWriting(file,/*overwrite=*/true);
4049 SMESH_MeshPartDS partDS( meshPart );
4050 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4052 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4053 << meshPart<< ", r'"
4055 << withRequiredGroups << ")";
4058 //=============================================================================
4060 * Return computation progress [0.,1]
4062 //=============================================================================
4064 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4068 return _impl->GetComputeProgress();
4070 SMESH_CATCH( SMESH::doNothing );
4074 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4076 Unexpect aCatch(SALOME_SalomeException);
4078 return _preMeshInfo->NbNodes();
4080 return _impl->NbNodes();
4083 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4085 Unexpect aCatch(SALOME_SalomeException);
4087 return _preMeshInfo->NbElements();
4089 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4092 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4094 Unexpect aCatch(SALOME_SalomeException);
4096 return _preMeshInfo->Nb0DElements();
4098 return _impl->Nb0DElements();
4101 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4103 Unexpect aCatch(SALOME_SalomeException);
4105 return _preMeshInfo->NbBalls();
4107 return _impl->NbBalls();
4110 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4112 Unexpect aCatch(SALOME_SalomeException);
4114 return _preMeshInfo->NbEdges();
4116 return _impl->NbEdges();
4119 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4120 throw(SALOME::SALOME_Exception)
4122 Unexpect aCatch(SALOME_SalomeException);
4124 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4126 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4129 //=============================================================================
4131 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4133 Unexpect aCatch(SALOME_SalomeException);
4135 return _preMeshInfo->NbFaces();
4137 return _impl->NbFaces();
4140 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4142 Unexpect aCatch(SALOME_SalomeException);
4144 return _preMeshInfo->NbTriangles();
4146 return _impl->NbTriangles();
4149 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4151 Unexpect aCatch(SALOME_SalomeException);
4153 return _preMeshInfo->NbBiQuadTriangles();
4155 return _impl->NbBiQuadTriangles();
4158 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4160 Unexpect aCatch(SALOME_SalomeException);
4162 return _preMeshInfo->NbQuadrangles();
4164 return _impl->NbQuadrangles();
4167 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4169 Unexpect aCatch(SALOME_SalomeException);
4171 return _preMeshInfo->NbBiQuadQuadrangles();
4173 return _impl->NbBiQuadQuadrangles();
4176 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4178 Unexpect aCatch(SALOME_SalomeException);
4180 return _preMeshInfo->NbPolygons();
4182 return _impl->NbPolygons();
4185 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4187 Unexpect aCatch(SALOME_SalomeException);
4189 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4191 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4194 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4195 throw(SALOME::SALOME_Exception)
4197 Unexpect aCatch(SALOME_SalomeException);
4199 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4201 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4204 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4205 throw(SALOME::SALOME_Exception)
4207 Unexpect aCatch(SALOME_SalomeException);
4209 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4211 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4214 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4215 throw(SALOME::SALOME_Exception)
4217 Unexpect aCatch(SALOME_SalomeException);
4219 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4221 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4224 //=============================================================================
4226 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4228 Unexpect aCatch(SALOME_SalomeException);
4230 return _preMeshInfo->NbVolumes();
4232 return _impl->NbVolumes();
4235 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4237 Unexpect aCatch(SALOME_SalomeException);
4239 return _preMeshInfo->NbTetras();
4241 return _impl->NbTetras();
4244 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4246 Unexpect aCatch(SALOME_SalomeException);
4248 return _preMeshInfo->NbHexas();
4250 return _impl->NbHexas();
4253 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4255 Unexpect aCatch(SALOME_SalomeException);
4257 return _preMeshInfo->NbTriQuadHexas();
4259 return _impl->NbTriQuadraticHexas();
4262 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4264 Unexpect aCatch(SALOME_SalomeException);
4266 return _preMeshInfo->NbPyramids();
4268 return _impl->NbPyramids();
4271 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4273 Unexpect aCatch(SALOME_SalomeException);
4275 return _preMeshInfo->NbPrisms();
4277 return _impl->NbPrisms();
4280 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4282 Unexpect aCatch(SALOME_SalomeException);
4284 return _preMeshInfo->NbHexPrisms();
4286 return _impl->NbHexagonalPrisms();
4289 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4291 Unexpect aCatch(SALOME_SalomeException);
4293 return _preMeshInfo->NbPolyhedrons();
4295 return _impl->NbPolyhedrons();
4298 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4299 throw(SALOME::SALOME_Exception)
4301 Unexpect aCatch(SALOME_SalomeException);
4303 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4305 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4308 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4309 throw(SALOME::SALOME_Exception)
4311 Unexpect aCatch(SALOME_SalomeException);
4313 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4315 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4318 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4319 throw(SALOME::SALOME_Exception)
4321 Unexpect aCatch(SALOME_SalomeException);
4323 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4325 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4328 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4329 throw(SALOME::SALOME_Exception)
4331 Unexpect aCatch(SALOME_SalomeException);
4333 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4335 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4338 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4339 throw(SALOME::SALOME_Exception)
4341 Unexpect aCatch(SALOME_SalomeException);
4343 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4345 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4348 //=============================================================================
4350 * Returns nb of published sub-meshes
4352 //=============================================================================
4354 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4356 Unexpect aCatch(SALOME_SalomeException);
4357 return _mapSubMesh_i.size();
4360 //=============================================================================
4362 * Dumps mesh into a string
4364 //=============================================================================
4366 char* SMESH_Mesh_i::Dump()
4370 return CORBA::string_dup( os.str().c_str() );
4373 //=============================================================================
4375 * Method of SMESH_IDSource interface
4377 //=============================================================================
4379 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4381 return GetElementsId();
4384 //=============================================================================
4386 * Returns ids of all elements
4388 //=============================================================================
4390 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4391 throw (SALOME::SALOME_Exception)
4393 Unexpect aCatch(SALOME_SalomeException);
4395 _preMeshInfo->FullLoadFromFile();
4397 SMESH::long_array_var aResult = new SMESH::long_array();
4398 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4400 if ( aSMESHDS_Mesh == NULL )
4401 return aResult._retn();
4403 long nbElements = NbElements();
4404 aResult->length( nbElements );
4405 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4406 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4407 aResult[i] = anIt->next()->GetID();
4409 return aResult._retn();
4413 //=============================================================================
4415 * Returns ids of all elements of given type
4417 //=============================================================================
4419 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4420 throw (SALOME::SALOME_Exception)
4422 Unexpect aCatch(SALOME_SalomeException);
4424 _preMeshInfo->FullLoadFromFile();
4426 SMESH::long_array_var aResult = new SMESH::long_array();
4427 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4429 if ( aSMESHDS_Mesh == NULL )
4430 return aResult._retn();
4432 long nbElements = NbElements();
4434 // No sense in returning ids of elements along with ids of nodes:
4435 // when theElemType == SMESH::ALL, return node ids only if
4436 // there are no elements
4437 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4438 return GetNodesId();
4440 aResult->length( nbElements );
4444 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4445 while ( i < nbElements && anIt->more() )
4446 aResult[i++] = anIt->next()->GetID();
4448 aResult->length( i );
4450 return aResult._retn();
4453 //=============================================================================
4455 * Returns ids of all nodes
4457 //=============================================================================
4459 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4460 throw (SALOME::SALOME_Exception)
4462 Unexpect aCatch(SALOME_SalomeException);
4464 _preMeshInfo->FullLoadFromFile();
4466 SMESH::long_array_var aResult = new SMESH::long_array();
4467 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4469 if ( aMeshDS == NULL )
4470 return aResult._retn();
4472 long nbNodes = NbNodes();
4473 aResult->length( nbNodes );
4474 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4475 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4476 aResult[i] = anIt->next()->GetID();
4478 return aResult._retn();
4481 //=============================================================================
4485 //=============================================================================
4487 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4488 throw (SALOME::SALOME_Exception)
4490 SMESH::ElementType type = SMESH::ALL;
4494 _preMeshInfo->FullLoadFromFile();
4496 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4498 SMESH_CATCH( SMESH::throwCorbaException );
4503 //=============================================================================
4507 //=============================================================================
4509 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4510 throw (SALOME::SALOME_Exception)
4513 _preMeshInfo->FullLoadFromFile();
4515 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4517 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4519 return ( SMESH::EntityType ) e->GetEntityType();
4522 //=============================================================================
4526 //=============================================================================
4528 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4529 throw (SALOME::SALOME_Exception)
4532 _preMeshInfo->FullLoadFromFile();
4534 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4536 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4538 return ( SMESH::GeometryType ) e->GetGeomType();
4541 //=============================================================================
4543 * Returns ID of elements for given submesh
4545 //=============================================================================
4546 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4547 throw (SALOME::SALOME_Exception)
4549 SMESH::long_array_var aResult = new SMESH::long_array();
4553 _preMeshInfo->FullLoadFromFile();
4555 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4556 if(!SM) return aResult._retn();
4558 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4559 if(!SDSM) return aResult._retn();
4561 aResult->length(SDSM->NbElements());
4563 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4565 while ( eIt->more() ) {
4566 aResult[i++] = eIt->next()->GetID();
4569 SMESH_CATCH( SMESH::throwCorbaException );
4571 return aResult._retn();
4574 //=============================================================================
4576 * Returns ID of nodes for given submesh
4577 * If param all==true - returns all nodes, else -
4578 * returns only nodes on shapes.
4580 //=============================================================================
4582 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4584 throw (SALOME::SALOME_Exception)
4586 SMESH::long_array_var aResult = new SMESH::long_array();
4590 _preMeshInfo->FullLoadFromFile();
4592 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4593 if(!SM) return aResult._retn();
4595 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4596 if(!SDSM) return aResult._retn();
4599 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4600 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4601 while ( nIt->more() ) {
4602 const SMDS_MeshNode* elem = nIt->next();
4603 theElems.insert( elem->GetID() );
4606 else { // all nodes of submesh elements
4607 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4608 while ( eIt->more() ) {
4609 const SMDS_MeshElement* anElem = eIt->next();
4610 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4611 while ( nIt->more() ) {
4612 const SMDS_MeshElement* elem = nIt->next();
4613 theElems.insert( elem->GetID() );
4618 aResult->length(theElems.size());
4619 set<int>::iterator itElem;
4621 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4622 aResult[i++] = *itElem;
4624 SMESH_CATCH( SMESH::throwCorbaException );
4626 return aResult._retn();
4629 //=============================================================================
4631 * Returns type of elements for given submesh
4633 //=============================================================================
4635 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4636 throw (SALOME::SALOME_Exception)
4638 SMESH::ElementType type = SMESH::ALL;
4642 _preMeshInfo->FullLoadFromFile();
4644 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4645 if(!SM) return SMESH::ALL;
4647 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4648 if(!SDSM) return SMESH::ALL;
4650 if(SDSM->NbElements()==0)
4651 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4653 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4654 const SMDS_MeshElement* anElem = eIt->next();
4656 type = ( SMESH::ElementType ) anElem->GetType();
4658 SMESH_CATCH( SMESH::throwCorbaException );
4664 //=============================================================================
4666 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4668 //=============================================================================
4670 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4673 _preMeshInfo->FullLoadFromFile();
4675 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4676 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4681 //=============================================================================
4683 * Get XYZ coordinates of node as list of double
4684 * If there is not node for given ID - returns empty list
4686 //=============================================================================
4688 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4691 _preMeshInfo->FullLoadFromFile();
4693 SMESH::double_array_var aResult = new SMESH::double_array();
4694 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4695 if ( aMeshDS == NULL )
4696 return aResult._retn();
4699 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4701 return aResult._retn();
4705 aResult[0] = aNode->X();
4706 aResult[1] = aNode->Y();
4707 aResult[2] = aNode->Z();
4708 return aResult._retn();
4712 //=============================================================================
4714 * For given node returns list of IDs of inverse elements
4715 * If there is not node for given ID - returns empty list
4717 //=============================================================================
4719 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4720 SMESH::ElementType elemType)
4723 _preMeshInfo->FullLoadFromFile();
4725 SMESH::long_array_var aResult = new SMESH::long_array();
4726 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4727 if ( aMeshDS == NULL )
4728 return aResult._retn();
4731 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4733 return aResult._retn();
4735 // find inverse elements
4736 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4737 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4738 aResult->length( aNode->NbInverseElements( type ));
4739 for( int i = 0; eIt->more(); ++i )
4741 const SMDS_MeshElement* elem = eIt->next();
4742 aResult[ i ] = elem->GetID();
4744 return aResult._retn();
4747 //=============================================================================
4749 * \brief Return position of a node on shape
4751 //=============================================================================
4753 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4756 _preMeshInfo->FullLoadFromFile();
4758 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4759 aNodePosition->shapeID = 0;
4760 aNodePosition->shapeType = GEOM::SHAPE;
4762 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4763 if ( !mesh ) return aNodePosition;
4765 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4767 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4769 aNodePosition->shapeID = aNode->getshapeId();
4770 switch ( pos->GetTypeOfPosition() ) {
4772 aNodePosition->shapeType = GEOM::EDGE;
4773 aNodePosition->params.length(1);
4774 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4776 case SMDS_TOP_FACE: {
4777 SMDS_FacePositionPtr fPos = pos;
4778 aNodePosition->shapeType = GEOM::FACE;
4779 aNodePosition->params.length(2);
4780 aNodePosition->params[0] = fPos->GetUParameter();
4781 aNodePosition->params[1] = fPos->GetVParameter();
4784 case SMDS_TOP_VERTEX:
4785 aNodePosition->shapeType = GEOM::VERTEX;
4787 case SMDS_TOP_3DSPACE:
4788 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4789 aNodePosition->shapeType = GEOM::SOLID;
4790 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4791 aNodePosition->shapeType = GEOM::SHELL;
4797 return aNodePosition;
4800 //=============================================================================
4802 * \brief Return position of an element on shape
4804 //=============================================================================
4806 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4809 _preMeshInfo->FullLoadFromFile();
4811 SMESH::ElementPosition anElementPosition;
4812 anElementPosition.shapeID = 0;
4813 anElementPosition.shapeType = GEOM::SHAPE;
4815 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4816 if ( !mesh ) return anElementPosition;
4818 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4820 anElementPosition.shapeID = anElem->getshapeId();
4821 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4822 if ( !aSp.IsNull() ) {
4823 switch ( aSp.ShapeType() ) {
4825 anElementPosition.shapeType = GEOM::EDGE;
4828 anElementPosition.shapeType = GEOM::FACE;
4831 anElementPosition.shapeType = GEOM::VERTEX;
4834 anElementPosition.shapeType = GEOM::SOLID;
4837 anElementPosition.shapeType = GEOM::SHELL;
4843 return anElementPosition;
4846 //=============================================================================
4848 * If given element is node returns IDs of shape from position
4849 * If there is not node for given ID - returns -1
4851 //=============================================================================
4853 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4856 _preMeshInfo->FullLoadFromFile();
4858 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4859 if ( aMeshDS == NULL )
4863 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4865 return aNode->getshapeId();
4872 //=============================================================================
4874 * For given element returns ID of result shape after
4875 * ::FindShape() from SMESH_MeshEditor
4876 * If there is not element for given ID - returns -1
4878 //=============================================================================
4880 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4883 _preMeshInfo->FullLoadFromFile();
4885 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4886 if ( aMeshDS == NULL )
4889 // try to find element
4890 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4894 ::SMESH_MeshEditor aMeshEditor(_impl);
4895 int index = aMeshEditor.FindShape( elem );
4903 //=============================================================================
4905 * Returns number of nodes for given element
4906 * If there is not element for given ID - returns -1
4908 //=============================================================================
4910 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4913 _preMeshInfo->FullLoadFromFile();
4915 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4916 if ( aMeshDS == NULL ) return -1;
4917 // try to find element
4918 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4919 if(!elem) return -1;
4920 return elem->NbNodes();
4924 //=============================================================================
4926 * Returns ID of node by given index for given element
4927 * If there is not element for given ID - returns -1
4928 * If there is not node for given index - returns -2
4930 //=============================================================================
4932 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4935 _preMeshInfo->FullLoadFromFile();
4937 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4938 if ( aMeshDS == NULL ) return -1;
4939 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4940 if(!elem) return -1;
4941 if( index>=elem->NbNodes() || index<0 ) return -1;
4942 return elem->GetNode(index)->GetID();
4945 //=============================================================================
4947 * Returns IDs of nodes of given element
4949 //=============================================================================
4951 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4954 _preMeshInfo->FullLoadFromFile();
4956 SMESH::long_array_var aResult = new SMESH::long_array();
4957 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4959 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4961 aResult->length( elem->NbNodes() );
4962 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4963 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
4964 aResult[ i ] = n->GetID();
4967 return aResult._retn();
4970 //=============================================================================
4972 * Returns true if given node is medium node
4973 * in given quadratic element
4975 //=============================================================================
4977 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4980 _preMeshInfo->FullLoadFromFile();
4982 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4983 if ( aMeshDS == NULL ) return false;
4985 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4986 if(!aNode) return false;
4987 // try to find element
4988 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4989 if(!elem) return false;
4991 return elem->IsMediumNode(aNode);
4995 //=============================================================================
4997 * Returns true if given node is medium node
4998 * in one of quadratic elements
5000 //=============================================================================
5002 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5003 SMESH::ElementType theElemType)
5006 _preMeshInfo->FullLoadFromFile();
5008 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5009 if ( aMeshDS == NULL ) return false;
5012 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5013 if(!aNode) return false;
5015 SMESH_MesherHelper aHelper( *(_impl) );
5017 SMDSAbs_ElementType aType;
5018 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5019 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5020 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5021 else aType = SMDSAbs_All;
5023 return aHelper.IsMedium(aNode,aType);
5027 //=============================================================================
5029 * Returns number of edges for given element
5031 //=============================================================================
5033 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5036 _preMeshInfo->FullLoadFromFile();
5038 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5039 if ( aMeshDS == NULL ) return -1;
5040 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5041 if(!elem) return -1;
5042 return elem->NbEdges();
5046 //=============================================================================
5048 * Returns number of faces for given element
5050 //=============================================================================
5052 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5055 _preMeshInfo->FullLoadFromFile();
5057 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5058 if ( aMeshDS == NULL ) return -1;
5059 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5060 if(!elem) return -1;
5061 return elem->NbFaces();
5064 //=======================================================================
5065 //function : GetElemFaceNodes
5066 //purpose : Returns nodes of given face (counted from zero) for given element.
5067 //=======================================================================
5069 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5070 CORBA::Short faceIndex)
5073 _preMeshInfo->FullLoadFromFile();
5075 SMESH::long_array_var aResult = new SMESH::long_array();
5076 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5078 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5080 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5081 if ( faceIndex < vtool.NbFaces() )
5083 aResult->length( vtool.NbFaceNodes( faceIndex ));
5084 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5085 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5086 aResult[ i ] = nn[ i ]->GetID();
5090 return aResult._retn();
5093 //=======================================================================
5094 //function : GetFaceNormal
5095 //purpose : Returns three components of normal of given mesh face.
5096 //=======================================================================
5098 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5099 CORBA::Boolean normalized)
5102 _preMeshInfo->FullLoadFromFile();
5104 SMESH::double_array_var aResult = new SMESH::double_array();
5106 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5109 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5111 aResult->length( 3 );
5112 aResult[ 0 ] = normal.X();
5113 aResult[ 1 ] = normal.Y();
5114 aResult[ 2 ] = normal.Z();
5117 return aResult._retn();
5120 //=======================================================================
5121 //function : FindElementByNodes
5122 //purpose : Returns an element based on all given nodes.
5123 //=======================================================================
5125 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5128 _preMeshInfo->FullLoadFromFile();
5130 CORBA::Long elemID(0);
5131 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5133 vector< const SMDS_MeshNode * > nn( nodes.length() );
5134 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5135 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5138 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5139 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5140 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5141 _impl->NbVolumes( ORDER_QUADRATIC )))
5142 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5144 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5149 //================================================================================
5151 * \brief Return elements including all given nodes.
5153 //================================================================================
5155 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5156 SMESH::ElementType elemType)
5159 _preMeshInfo->FullLoadFromFile();
5161 SMESH::long_array_var result = new SMESH::long_array();
5163 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5165 vector< const SMDS_MeshNode * > nn( nodes.length() );
5166 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5167 nn[i] = mesh->FindNode( nodes[i] );
5169 std::vector<const SMDS_MeshElement *> elems;
5170 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5171 result->length( elems.size() );
5172 for ( size_t i = 0; i < elems.size(); ++i )
5173 result[i] = elems[i]->GetID();
5175 return result._retn();
5178 //=============================================================================
5180 * Returns true if given element is polygon
5182 //=============================================================================
5184 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5187 _preMeshInfo->FullLoadFromFile();
5189 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5190 if ( aMeshDS == NULL ) return false;
5191 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5192 if(!elem) return false;
5193 return elem->IsPoly();
5197 //=============================================================================
5199 * Returns true if given element is quadratic
5201 //=============================================================================
5203 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5206 _preMeshInfo->FullLoadFromFile();
5208 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5209 if ( aMeshDS == NULL ) return false;
5210 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5211 if(!elem) return false;
5212 return elem->IsQuadratic();
5215 //=============================================================================
5217 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5219 //=============================================================================
5221 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5224 _preMeshInfo->FullLoadFromFile();
5226 if ( const SMDS_BallElement* ball =
5227 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5228 return ball->GetDiameter();
5233 //=============================================================================
5235 * Returns bary center for given element
5237 //=============================================================================
5239 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5242 _preMeshInfo->FullLoadFromFile();
5244 SMESH::double_array_var aResult = new SMESH::double_array();
5245 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5246 if ( aMeshDS == NULL )
5247 return aResult._retn();
5249 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5251 return aResult._retn();
5253 if(elem->GetType()==SMDSAbs_Volume) {
5254 SMDS_VolumeTool aTool;
5255 if(aTool.Set(elem)) {
5257 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5262 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5264 double x=0., y=0., z=0.;
5265 for(; anIt->more(); ) {
5267 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5281 return aResult._retn();
5284 //================================================================================
5286 * \brief Create a group of elements preventing computation of a sub-shape
5288 //================================================================================
5290 SMESH::ListOfGroups*
5291 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5292 const char* theGroupName )
5293 throw ( SALOME::SALOME_Exception )
5295 Unexpect aCatch(SALOME_SalomeException);
5297 if ( !theGroupName || strlen( theGroupName) == 0 )
5298 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5300 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5301 ::SMESH_MeshEditor::ElemFeatures elemType;
5303 // submesh by subshape id
5304 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5305 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5308 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5309 if ( error && error->HasBadElems() )
5311 // sort bad elements by type
5312 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5313 const list<const SMDS_MeshElement*>& badElems =
5314 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5315 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5316 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5317 for ( ; elemIt != elemEnd; ++elemIt )
5319 const SMDS_MeshElement* elem = *elemIt;
5320 if ( !elem ) continue;
5322 if ( elem->GetID() < 1 )
5324 // elem is a temporary element, make a real element
5325 vector< const SMDS_MeshNode* > nodes;
5326 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5327 while ( nIt->more() && elem )
5329 nodes.push_back( nIt->next() );
5330 if ( nodes.back()->GetID() < 1 )
5331 elem = 0; // a temporary element on temporary nodes
5335 ::SMESH_MeshEditor editor( _impl );
5336 elem = editor.AddElement( nodes, elemType.Init( elem ));
5340 elemsByType[ elem->GetType() ].push_back( elem );
5343 // how many groups to create?
5345 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5346 nbTypes += int( !elemsByType[ i ].empty() );
5347 groups->length( nbTypes );
5350 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5352 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5353 if ( elems.empty() ) continue;
5355 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5356 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5358 SMESH::SMESH_Mesh_var mesh = _this();
5359 SALOMEDS::SObject_wrap aSO =
5360 _gen_i->PublishGroup( mesh, groups[ iG ],
5361 GEOM::GEOM_Object::_nil(), theGroupName);
5363 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5364 if ( !grp_i ) continue;
5366 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5367 for ( size_t iE = 0; iE < elems.size(); ++iE )
5368 grpDS->SMDSGroup().Add( elems[ iE ]);
5373 return groups._retn();
5376 //=============================================================================
5378 * Create and publish group servants if any groups were imported or created anyhow
5380 //=============================================================================
5382 void SMESH_Mesh_i::CreateGroupServants()
5384 SMESH::SMESH_Mesh_var aMesh = _this();
5387 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5388 while ( groupIt->more() )
5390 ::SMESH_Group* group = groupIt->next();
5391 int anId = group->GetID();
5393 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5394 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5396 addedIDs.insert( anId );
5398 SMESH_GroupBase_i* aGroupImpl;
5400 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5401 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5403 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5404 shape = groupOnGeom->GetShape();
5407 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5410 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5411 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5412 aGroupImpl->Register();
5414 // register CORBA object for persistence
5415 int nextId = _gen_i->RegisterObject( groupVar );
5416 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5417 else { nextId = 0; } // avoid "unused variable" warning in release mode
5419 // publishing the groups in the study
5420 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5421 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5423 if ( !addedIDs.empty() )
5426 set<int>::iterator id = addedIDs.begin();
5427 for ( ; id != addedIDs.end(); ++id )
5429 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5430 int i = std::distance( _mapGroups.begin(), it );
5431 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5436 //=============================================================================
5438 * \brief Return true if all sub-meshes are computed OK - to update an icon
5440 //=============================================================================
5442 bool SMESH_Mesh_i::IsComputedOK()
5444 return _impl->IsComputedOK();
5447 //=============================================================================
5449 * \brief Return groups cantained in _mapGroups by their IDs
5451 //=============================================================================
5453 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5455 int nbGroups = groupIDs.size();
5456 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5457 aList->length( nbGroups );
5459 list<int>::const_iterator ids = groupIDs.begin();
5460 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5462 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5463 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5464 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5466 aList->length( nbGroups );
5467 return aList._retn();
5470 //=============================================================================
5472 * \brief Return information about imported file
5474 //=============================================================================
5476 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5478 SMESH::MedFileInfo_var res( _medFileInfo );
5479 if ( !res.operator->() ) {
5480 res = new SMESH::MedFileInfo;
5482 res->fileSize = res->major = res->minor = res->release = -1;
5487 //=======================================================================
5488 //function : FileInfoToString
5489 //purpose : Persistence of file info
5490 //=======================================================================
5492 std::string SMESH_Mesh_i::FileInfoToString()
5495 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5497 s = SMESH_Comment( _medFileInfo->fileSize )
5498 << " " << _medFileInfo->major
5499 << " " << _medFileInfo->minor
5500 << " " << _medFileInfo->release
5501 << " " << _medFileInfo->fileName;
5506 //=======================================================================
5507 //function : FileInfoFromString
5508 //purpose : Persistence of file info
5509 //=======================================================================
5511 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5513 std::string size, major, minor, release, fileName;
5514 std::istringstream is(info);
5515 is >> size >> major >> minor >> release;
5516 fileName = info.data() + ( size.size() + 1 +
5519 release.size()+ 1 );
5521 _medFileInfo = new SMESH::MedFileInfo();
5522 _medFileInfo->fileName = fileName.c_str();
5523 _medFileInfo->fileSize = atoi( size.c_str() );
5524 _medFileInfo->major = atoi( major.c_str() );
5525 _medFileInfo->minor = atoi( minor.c_str() );
5526 _medFileInfo->release = atoi( release.c_str() );
5529 //=============================================================================
5531 * \brief Pass names of mesh groups from study to mesh DS
5533 //=============================================================================
5535 void SMESH_Mesh_i::checkGroupNames()
5537 int nbGrp = NbGroups();
5541 SMESH::ListOfGroups* grpList = 0;
5542 // avoid dump of "GetGroups"
5544 // store python dump into a local variable inside local scope
5545 SMESH::TPythonDump pDump; // do not delete this line of code
5546 grpList = GetGroups();
5549 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5550 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5553 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5554 if ( aGrpSO->_is_nil() )
5556 // correct name of the mesh group if necessary
5557 const char* guiName = aGrpSO->GetName();
5558 if ( strcmp(guiName, aGrp->GetName()) )
5559 aGrp->SetName( guiName );
5563 //=============================================================================
5565 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5567 //=============================================================================
5568 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5570 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5574 //=============================================================================
5576 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5578 //=============================================================================
5580 char* SMESH_Mesh_i::GetParameters()
5582 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5585 //=============================================================================
5587 * \brief Returns list of notebook variables used for last Mesh operation
5589 //=============================================================================
5590 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5592 SMESH::string_array_var aResult = new SMESH::string_array();
5593 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5595 CORBA::String_var aParameters = GetParameters();
5596 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5597 if ( aSections->length() > 0 ) {
5598 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5599 aResult->length( aVars.length() );
5600 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5601 aResult[i] = CORBA::string_dup( aVars[i] );
5604 return aResult._retn();
5607 //=======================================================================
5608 //function : GetTypes
5609 //purpose : Returns types of elements it contains
5610 //=======================================================================
5612 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5615 return _preMeshInfo->GetTypes();
5617 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5621 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5622 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5623 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5624 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5625 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5626 if (_impl->NbNodes() &&
5627 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5628 types->length( nbTypes );
5630 return types._retn();
5633 //=======================================================================
5634 //function : GetMesh
5635 //purpose : Returns self
5636 //=======================================================================
5638 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5640 return SMESH::SMESH_Mesh::_duplicate( _this() );
5643 //=======================================================================
5644 //function : IsMeshInfoCorrect
5645 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5646 // * happen if mesh data is not yet fully loaded from the file of study.
5647 //=======================================================================
5649 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5651 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5654 //=============================================================================
5656 * \brief Returns number of mesh elements per each \a EntityType
5658 //=============================================================================
5660 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5663 return _preMeshInfo->GetMeshInfo();
5665 SMESH::long_array_var aRes = new SMESH::long_array();
5666 aRes->length(SMESH::Entity_Last);
5667 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5669 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5671 return aRes._retn();
5672 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5673 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5674 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5675 return aRes._retn();
5678 //=============================================================================
5680 * \brief Returns number of mesh elements per each \a ElementType
5682 //=============================================================================
5684 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5686 SMESH::long_array_var aRes = new SMESH::long_array();
5687 aRes->length(SMESH::NB_ELEMENT_TYPES);
5688 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5691 const SMDS_MeshInfo* meshInfo = 0;
5693 meshInfo = _preMeshInfo;
5694 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5695 meshInfo = & meshDS->GetMeshInfo();
5698 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5699 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5701 return aRes._retn();
5704 //=============================================================================
5706 * Collect statistic of mesh elements given by iterator
5708 //=============================================================================
5710 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5711 SMESH::long_array& theInfo)
5713 if (!theItr) return;
5714 while (theItr->more())
5715 theInfo[ theItr->next()->GetEntityType() ]++;
5717 //=============================================================================
5719 * Returns mesh unstructed grid information.
5721 //=============================================================================
5723 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5725 SALOMEDS::TMPFile_var SeqFile;
5726 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5727 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5729 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5730 aWriter->WriteToOutputStringOn();
5731 aWriter->SetInputData(aGrid);
5732 aWriter->SetFileTypeToBinary();
5734 char* str = aWriter->GetOutputString();
5735 int size = aWriter->GetOutputStringLength();
5737 //Allocate octet buffer of required size
5738 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5739 //Copy ostrstream content to the octet buffer
5740 memcpy(OctetBuf, str, size);
5741 //Create and return TMPFile
5742 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5746 return SeqFile._retn();
5749 //=============================================================================
5750 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5751 * SMESH::ElementType type) */
5753 using namespace SMESH::Controls;
5754 //-----------------------------------------------------------------------------
5755 struct PredicateIterator : public SMDS_ElemIterator
5757 SMDS_ElemIteratorPtr _elemIter;
5758 PredicatePtr _predicate;
5759 const SMDS_MeshElement* _elem;
5760 SMDSAbs_ElementType _type;
5762 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5763 PredicatePtr predicate,
5764 SMDSAbs_ElementType type):
5765 _elemIter(iterator), _predicate(predicate), _type(type)
5773 virtual const SMDS_MeshElement* next()
5775 const SMDS_MeshElement* res = _elem;
5777 while ( _elemIter->more() && !_elem )
5779 if ((_elem = _elemIter->next()) &&
5780 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5781 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5788 //-----------------------------------------------------------------------------
5789 struct IDSourceIterator : public SMDS_ElemIterator
5791 const CORBA::Long* _idPtr;
5792 const CORBA::Long* _idEndPtr;
5793 SMESH::long_array_var _idArray;
5794 const SMDS_Mesh* _mesh;
5795 const SMDSAbs_ElementType _type;
5796 const SMDS_MeshElement* _elem;
5798 IDSourceIterator( const SMDS_Mesh* mesh,
5799 const CORBA::Long* ids,
5801 SMDSAbs_ElementType type):
5802 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5804 if ( _idPtr && nbIds && _mesh )
5807 IDSourceIterator( const SMDS_Mesh* mesh,
5808 SMESH::long_array* idArray,
5809 SMDSAbs_ElementType type):
5810 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5812 if ( idArray && _mesh )
5814 _idPtr = &_idArray[0];
5815 _idEndPtr = _idPtr + _idArray->length();
5823 virtual const SMDS_MeshElement* next()
5825 const SMDS_MeshElement* res = _elem;
5827 while ( _idPtr < _idEndPtr && !_elem )
5829 if ( _type == SMDSAbs_Node )
5831 _elem = _mesh->FindNode( *_idPtr++ );
5833 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5834 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5842 //-----------------------------------------------------------------------------
5844 struct NodeOfElemIterator : public SMDS_ElemIterator
5846 TColStd_MapOfInteger _checkedNodeIDs;
5847 SMDS_ElemIteratorPtr _elemIter;
5848 SMDS_ElemIteratorPtr _nodeIter;
5849 const SMDS_MeshElement* _node;
5851 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5853 if ( _elemIter && _elemIter->more() )
5855 _nodeIter = _elemIter->next()->nodesIterator();
5863 virtual const SMDS_MeshElement* next()
5865 const SMDS_MeshElement* res = _node;
5867 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5869 if ( _nodeIter->more() )
5871 _node = _nodeIter->next();
5872 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5877 _nodeIter = _elemIter->next()->nodesIterator();
5885 //=============================================================================
5887 * Return iterator on elements of given type in given object
5889 //=============================================================================
5891 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5892 SMESH::ElementType theType)
5894 SMDS_ElemIteratorPtr elemIt;
5895 bool typeOK = ( theType == SMESH::ALL );
5896 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5898 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5899 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5900 if ( !mesh_i ) return elemIt;
5901 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5903 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5905 elemIt = meshDS->elementsIterator( elemType );
5908 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5910 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5913 elemIt = sm->GetElements();
5914 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5916 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5917 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5921 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5923 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5924 if ( groupDS && ( elemType == groupDS->GetType() ||
5925 elemType == SMDSAbs_Node ||
5926 elemType == SMDSAbs_All ))
5928 elemIt = groupDS->GetElements();
5929 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5932 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5934 if ( filter_i->GetElementType() == theType ||
5935 filter_i->GetElementType() == SMESH::ALL ||
5936 elemType == SMDSAbs_Node ||
5937 elemType == SMDSAbs_All)
5939 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5940 if ( pred_i && pred_i->GetPredicate() )
5942 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5943 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5944 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
5945 elemIt = SMDS_ElemIteratorPtr
5946 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
5947 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
5953 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5954 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5955 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5957 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
5958 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5961 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5962 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
5966 SMESH::long_array_var ids = theObject->GetIDs();
5967 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
5969 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5972 if ( elemIt && elemIt->more() && !typeOK )
5974 if ( elemType == SMDSAbs_Node )
5976 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5980 elemIt = SMDS_ElemIteratorPtr();
5986 //=============================================================================
5987 namespace // Finding concurrent hypotheses
5988 //=============================================================================
5992 * \brief mapping of mesh dimension into shape type
5994 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5996 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5998 case 0: aType = TopAbs_VERTEX; break;
5999 case 1: aType = TopAbs_EDGE; break;
6000 case 2: aType = TopAbs_FACE; break;
6002 default:aType = TopAbs_SOLID; break;
6007 //-----------------------------------------------------------------------------
6009 * \brief Internal structure used to find concurrent submeshes
6011 * It represents a pair < submesh, concurrent dimension >, where
6012 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6013 * with another submesh. In other words, it is dimension of a hypothesis assigned
6020 int _dim; //!< a dimension the algo can build (concurrent dimension)
6021 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6022 TopTools_MapOfShape _shapeMap;
6023 SMESH_subMesh* _subMesh;
6024 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6026 //-----------------------------------------------------------------------------
6027 // Return the algorithm
6028 const SMESH_Algo* GetAlgo() const
6029 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6031 //-----------------------------------------------------------------------------
6033 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6035 const TopoDS_Shape& theShape)
6037 _subMesh = (SMESH_subMesh*)theSubMesh;
6038 SetShape( theDim, theShape );
6041 //-----------------------------------------------------------------------------
6043 void SetShape(const int theDim,
6044 const TopoDS_Shape& theShape)
6047 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6048 if (_dim >= _ownDim)
6049 _shapeMap.Add( theShape );
6051 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6052 for( ; anExp.More(); anExp.Next() )
6053 _shapeMap.Add( anExp.Current() );
6057 //-----------------------------------------------------------------------------
6058 //! Check sharing of sub-shapes
6059 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6060 const TopTools_MapOfShape& theToFind,
6061 const TopAbs_ShapeEnum theType)
6063 bool isShared = false;
6064 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6065 for (; !isShared && anItr.More(); anItr.Next() )
6067 const TopoDS_Shape aSubSh = anItr.Key();
6068 // check for case when concurrent dimensions are same
6069 isShared = theToFind.Contains( aSubSh );
6070 // check for sub-shape with concurrent dimension
6071 TopExp_Explorer anExp( aSubSh, theType );
6072 for ( ; !isShared && anExp.More(); anExp.Next() )
6073 isShared = theToFind.Contains( anExp.Current() );
6078 //-----------------------------------------------------------------------------
6079 //! check algorithms
6080 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6081 const SMESHDS_Hypothesis* theA2)
6083 if ( !theA1 || !theA2 ||
6084 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6085 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6086 return false; // one of the hypothesis is not algorithm
6087 // check algorithm names (should be equal)
6088 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6092 //-----------------------------------------------------------------------------
6093 //! Check if sub-shape hypotheses are concurrent
6094 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6096 if ( _subMesh == theOther->_subMesh )
6097 return false; // same sub-shape - should not be
6099 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6100 // any of the two submeshes is not on COMPOUND shape )
6101 // -> no concurrency
6102 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6103 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6104 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6105 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6106 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6109 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6110 if ( !checkSubShape )
6113 // check algorithms to be same
6114 const SMESH_Algo* a1 = this->GetAlgo();
6115 const SMESH_Algo* a2 = theOther->GetAlgo();
6116 bool isSame = checkAlgo( a1, a2 );
6120 return false; // pb?
6121 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6124 // check hypothesises for concurrence (skip first as algorithm)
6126 // pointers should be same, because it is referened from mesh hypothesis partition
6127 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6128 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6129 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6130 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6132 // the submeshes are concurrent if their algorithms has different parameters
6133 return nbSame != theOther->_hypotheses.size() - 1;
6136 // Return true if algorithm of this SMESH_DimHyp is used if no
6137 // sub-mesh order is imposed by the user
6138 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6140 // NeedDiscreteBoundary() algo has a higher priority
6141 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6142 theOther->GetAlgo()->NeedDiscreteBoundary() )
6143 return !this->GetAlgo()->NeedDiscreteBoundary();
6145 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6148 }; // end of SMESH_DimHyp
6149 //-----------------------------------------------------------------------------
6151 typedef list<const SMESH_DimHyp*> TDimHypList;
6153 //-----------------------------------------------------------------------------
6155 void addDimHypInstance(const int theDim,
6156 const TopoDS_Shape& theShape,
6157 const SMESH_Algo* theAlgo,
6158 const SMESH_subMesh* theSubMesh,
6159 const list <const SMESHDS_Hypothesis*>& theHypList,
6160 TDimHypList* theDimHypListArr )
6162 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6163 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6164 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6165 dimHyp->_hypotheses.push_front(theAlgo);
6166 listOfdimHyp.push_back( dimHyp );
6169 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6170 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6171 theHypList.begin(), theHypList.end() );
6174 //-----------------------------------------------------------------------------
6175 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6176 TDimHypList& theListOfConcurr)
6178 if ( theListOfConcurr.empty() )
6180 theListOfConcurr.push_back( theDimHyp );
6184 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6185 while ( hypIt != theListOfConcurr.end() &&
6186 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6188 theListOfConcurr.insert( hypIt, theDimHyp );
6192 //-----------------------------------------------------------------------------
6193 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6194 const TDimHypList& theListOfDimHyp,
6195 TDimHypList& theListOfConcurrHyp,
6196 set<int>& theSetOfConcurrId )
6198 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6199 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6201 const SMESH_DimHyp* curDimHyp = *rIt;
6202 if ( curDimHyp == theDimHyp )
6203 break; // meet own dimHyp pointer in same dimension
6205 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6206 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6208 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6213 //-----------------------------------------------------------------------------
6214 void unionLists(TListOfInt& theListOfId,
6215 TListOfListOfInt& theListOfListOfId,
6218 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6219 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6221 continue; //skip already treated lists
6222 // check if other list has any same submesh object
6223 TListOfInt& otherListOfId = *it;
6224 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6225 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6228 // union two lists (from source into target)
6229 TListOfInt::iterator it2 = otherListOfId.begin();
6230 for ( ; it2 != otherListOfId.end(); it2++ ) {
6231 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6232 theListOfId.push_back(*it2);
6234 // clear source list
6235 otherListOfId.clear();
6238 //-----------------------------------------------------------------------------
6240 //! free memory allocated for dimension-hypothesis objects
6241 void removeDimHyps( TDimHypList* theArrOfList )
6243 for (int i = 0; i < 4; i++ ) {
6244 TDimHypList& listOfdimHyp = theArrOfList[i];
6245 TDimHypList::const_iterator it = listOfdimHyp.begin();
6246 for ( ; it != listOfdimHyp.end(); it++ )
6251 //-----------------------------------------------------------------------------
6253 * \brief find common submeshes with given submesh
6254 * \param theSubMeshList list of already collected submesh to check
6255 * \param theSubMesh given submesh to intersect with other
6256 * \param theCommonSubMeshes collected common submeshes
6258 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6259 const SMESH_subMesh* theSubMesh,
6260 set<const SMESH_subMesh*>& theCommon )
6264 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6265 for ( ; it != theSubMeshList.end(); it++ )
6266 theSubMesh->FindIntersection( *it, theCommon );
6267 theSubMeshList.push_back( theSubMesh );
6268 //theCommon.insert( theSubMesh );
6271 //-----------------------------------------------------------------------------
6272 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6274 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6275 for ( ; listsIt != smLists.end(); ++listsIt )
6277 const TListOfInt& smIDs = *listsIt;
6278 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6286 //=============================================================================
6288 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6290 //=============================================================================
6292 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6294 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6295 if ( isSubMeshInList( submeshID, anOrder ))
6298 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6299 return isSubMeshInList( submeshID, allConurrent );
6302 //=============================================================================
6304 * \brief Return submesh objects list in meshing order
6306 //=============================================================================
6308 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6310 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6312 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6314 return aResult._retn();
6316 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6317 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6318 anOrder.splice( anOrder.end(), allConurrent );
6321 TListOfListOfInt::iterator listIt = anOrder.begin();
6322 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6323 unionLists( *listIt, anOrder, listIndx + 1 );
6325 // convert submesh ids into interface instances
6326 // and dump command into python
6327 convertMeshOrder( anOrder, aResult, false );
6329 return aResult._retn();
6332 //=============================================================================
6334 * \brief Finds concurrent sub-meshes
6336 //=============================================================================
6338 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6340 TListOfListOfInt anOrder;
6341 ::SMESH_Mesh& mesh = GetImpl();
6343 // collect submeshes and detect concurrent algorithms and hypothesises
6344 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6346 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6347 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6348 ::SMESH_subMesh* sm = (*i_sm).second;
6350 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6352 // list of assigned hypothesises
6353 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6354 // Find out dimensions where the submesh can be concurrent.
6355 // We define the dimensions by algo of each of hypotheses in hypList
6356 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6357 for( ; hypIt != hypList.end(); hypIt++ ) {
6358 SMESH_Algo* anAlgo = 0;
6359 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6360 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6361 // hyp it-self is algo
6362 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6364 // try to find algorithm with help of sub-shapes
6365 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6366 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6367 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6370 continue; // no algorithm assigned to a current submesh
6372 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6373 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6375 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6376 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6377 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6379 } // end iterations on submesh
6381 // iterate on created dimension-hypotheses and check for concurrents
6382 for ( int i = 0; i < 4; i++ ) {
6383 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6384 // check for concurrents in own and other dimensions (step-by-step)
6385 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6386 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6387 const SMESH_DimHyp* dimHyp = *dhIt;
6388 TDimHypList listOfConcurr;
6389 set<int> setOfConcurrIds;
6390 // looking for concurrents and collect into own list
6391 for ( int j = i; j < 4; j++ )
6392 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6393 // check if any concurrents found
6394 if ( listOfConcurr.size() > 0 ) {
6395 // add own submesh to list of concurrent
6396 addInOrderOfPriority( dimHyp, listOfConcurr );
6397 list<int> listOfConcurrIds;
6398 TDimHypList::iterator hypIt = listOfConcurr.begin();
6399 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6400 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6401 anOrder.push_back( listOfConcurrIds );
6406 removeDimHyps(dimHypListArr);
6408 // now, minimize the number of concurrent groups
6409 // Here we assume that lists of submeshes can have same submesh
6410 // in case of multi-dimension algorithms, as result
6411 // list with common submesh has to be united into one list
6413 TListOfListOfInt::iterator listIt = anOrder.begin();
6414 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6415 unionLists( *listIt, anOrder, listIndx + 1 );
6421 //=============================================================================
6423 * \brief Set submesh object order
6424 * \param theSubMeshArray submesh array order
6426 //=============================================================================
6428 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6431 _preMeshInfo->ForgetOrLoad();
6434 ::SMESH_Mesh& mesh = GetImpl();
6436 TPythonDump aPythonDump; // prevent dump of called methods
6437 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6439 TListOfListOfInt subMeshOrder;
6440 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6442 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6443 TListOfInt subMeshIds;
6445 aPythonDump << ", ";
6446 aPythonDump << "[ ";
6447 // Collect subMeshes which should be clear
6448 // do it list-by-list, because modification of submesh order
6449 // take effect between concurrent submeshes only
6450 set<const SMESH_subMesh*> subMeshToClear;
6451 list<const SMESH_subMesh*> subMeshList;
6452 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6454 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6456 aPythonDump << ", ";
6457 aPythonDump << subMesh;
6458 subMeshIds.push_back( subMesh->GetId() );
6459 // detect common parts of submeshes
6460 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6461 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6463 aPythonDump << " ]";
6464 subMeshOrder.push_back( subMeshIds );
6466 // clear collected sub-meshes
6467 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6468 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6469 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6471 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6472 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6473 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6476 aPythonDump << " ])";
6478 mesh.SetMeshOrder( subMeshOrder );
6481 SMESH::SMESH_Mesh_var me = _this();
6482 _gen_i->UpdateIcons( me );
6487 //=============================================================================
6489 * \brief Convert submesh ids into submesh interfaces
6491 //=============================================================================
6493 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6494 SMESH::submesh_array_array& theResOrder,
6495 const bool theIsDump)
6497 int nbSet = theIdsOrder.size();
6498 TPythonDump aPythonDump; // prevent dump of called methods
6500 aPythonDump << "[ ";
6501 theResOrder.length(nbSet);
6502 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6504 for( ; it != theIdsOrder.end(); it++ ) {
6505 // translate submesh identificators into submesh objects
6506 // takeing into account real number of concurrent lists
6507 const TListOfInt& aSubOrder = (*it);
6508 if (!aSubOrder.size())
6511 aPythonDump << "[ ";
6512 // convert shape indices into interfaces
6513 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6514 aResSubSet->length(aSubOrder.size());
6515 TListOfInt::const_iterator subIt = aSubOrder.begin();
6517 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6518 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6520 SMESH::SMESH_subMesh_var subMesh =
6521 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6524 aPythonDump << ", ";
6525 aPythonDump << subMesh;
6527 aResSubSet[ j++ ] = subMesh;
6530 aPythonDump << " ]";
6532 theResOrder[ listIndx++ ] = aResSubSet;
6534 // correct number of lists
6535 theResOrder.length( listIndx );
6538 // finilise python dump
6539 aPythonDump << " ]";
6540 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6544 namespace // utils used by SMESH_MeshPartDS
6547 * \brief Class used to access to protected data of SMDS_MeshInfo
6549 struct TMeshInfo : public SMDS_MeshInfo
6551 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6554 * \brief Element holing its ID only
6556 struct TElemID : public SMDS_LinearEdge
6558 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6562 //================================================================================
6564 // Implementation of SMESH_MeshPartDS
6566 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6567 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6569 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6570 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6573 _meshDS = mesh_i->GetImpl().GetMeshDS();
6575 SetPersistentId( _meshDS->GetPersistentId() );
6577 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6579 // <meshPart> is the whole mesh
6580 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6582 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6583 myGroupSet = _meshDS->GetGroups();
6588 SMESH::long_array_var anIDs = meshPart->GetIDs();
6589 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6590 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6592 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6593 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6594 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6599 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6600 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6601 if ( _elements[ e->GetType() ].insert( e ).second )
6604 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6605 while ( nIt->more() )
6607 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6608 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6615 ShapeToMesh( _meshDS->ShapeToMesh() );
6617 _meshDS = 0; // to enforce iteration on _elements and _nodes
6620 // -------------------------------------------------------------------------------------
6621 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6622 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6625 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6626 for ( ; partIt != meshPart.end(); ++partIt )
6627 if ( const SMDS_MeshElement * e = *partIt )
6628 if ( _elements[ e->GetType() ].insert( e ).second )
6631 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6632 while ( nIt->more() )
6634 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6635 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6641 // -------------------------------------------------------------------------------------
6642 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6644 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6646 TElemID elem( IDelem );
6647 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6648 if ( !_elements[ iType ].empty() )
6650 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6651 if ( it != _elements[ iType ].end() )
6656 // -------------------------------------------------------------------------------------
6657 bool SMESH_MeshPartDS::HasNumerationHoles()
6659 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6661 return ( MinNodeID() != 1 ||
6662 MaxNodeID() != NbNodes() ||
6663 MinElementID() != 1 ||
6664 MaxElementID() != NbElements() );
6666 // -------------------------------------------------------------------------------------
6667 int SMESH_MeshPartDS::MaxNodeID() const
6669 if ( _meshDS ) return _meshDS->MaxNodeID();
6670 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6672 // -------------------------------------------------------------------------------------
6673 int SMESH_MeshPartDS::MinNodeID() const
6675 if ( _meshDS ) return _meshDS->MinNodeID();
6676 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6678 // -------------------------------------------------------------------------------------
6679 int SMESH_MeshPartDS::MaxElementID() const
6681 if ( _meshDS ) return _meshDS->MaxElementID();
6683 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6684 if ( !_elements[ iType ].empty() )
6685 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6688 // -------------------------------------------------------------------------------------
6689 int SMESH_MeshPartDS::MinElementID() const
6691 if ( _meshDS ) return _meshDS->MinElementID();
6693 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6694 if ( !_elements[ iType ].empty() )
6695 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6698 // -------------------------------------------------------------------------------------
6699 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6701 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6703 typedef SMDS_SetIterator
6704 <const SMDS_MeshElement*,
6705 TIDSortedElemSet::const_iterator,
6706 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6707 SMDS_MeshElement::GeomFilter
6710 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6712 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6713 _elements[type].end(),
6714 SMDS_MeshElement::GeomFilter( geomType )));
6716 // -------------------------------------------------------------------------------------
6717 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6719 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6721 typedef SMDS_SetIterator
6722 <const SMDS_MeshElement*,
6723 TIDSortedElemSet::const_iterator,
6724 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6725 SMDS_MeshElement::EntityFilter
6728 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6730 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6731 _elements[type].end(),
6732 SMDS_MeshElement::EntityFilter( entity )));
6734 // -------------------------------------------------------------------------------------
6735 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6737 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6738 if ( type == SMDSAbs_All && !_meshDS )
6740 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6742 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6743 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6745 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6747 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6748 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6750 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6751 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6753 // -------------------------------------------------------------------------------------
6754 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6755 iterType SMESH_MeshPartDS::methName() const \
6757 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6758 return _meshDS ? _meshDS->methName() : iterType \
6759 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6761 // -------------------------------------------------------------------------------------
6762 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6763 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6764 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6765 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6766 #undef _GET_ITER_DEFINE
6768 // END Implementation of SMESH_MeshPartDS
6770 //================================================================================