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)
263 throw (SALOME::SALOME_Exception)
265 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
266 GEOM_Client* geomClient = _gen_i->GetShapeReader();
267 TCollection_AsciiString aIOR;
268 if (geomClient->Find(S, aIOR)) {
269 geomClient->RemoveShapeFromBuffer(aIOR);
271 _impl->UndefShapeToMesh();
272 SetShape(theNewGeom);
275 //================================================================================
277 * \brief Return false if the mesh is not yet fully loaded from the study file
279 //================================================================================
281 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
283 Unexpect aCatch(SALOME_SalomeException);
284 return !_preMeshInfo;
287 //================================================================================
289 * \brief Load full mesh data from the study file
291 //================================================================================
293 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
295 Unexpect aCatch(SALOME_SalomeException);
297 _preMeshInfo->FullLoadFromFile();
300 //================================================================================
302 * \brief Remove all nodes and elements
304 //================================================================================
306 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
308 Unexpect aCatch(SALOME_SalomeException);
310 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
314 //CheckGeomGroupModif(); // issue 20145
316 catch(SALOME_Exception & S_ex) {
317 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
320 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
322 SMESH::SMESH_Mesh_var mesh = _this();
323 _gen_i->UpdateIcons( mesh );
326 //================================================================================
328 * \brief Remove all nodes and elements for indicated shape
330 //================================================================================
332 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
333 throw (SALOME::SALOME_Exception)
335 Unexpect aCatch(SALOME_SalomeException);
337 _preMeshInfo->FullLoadFromFile();
340 _impl->ClearSubMesh( ShapeID );
342 catch(SALOME_Exception & S_ex) {
343 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
345 _impl->GetMeshDS()->Modified();
347 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
350 //=============================================================================
352 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
354 //=============================================================================
356 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
358 SMESH::DriverMED_ReadStatus res;
361 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
362 res = SMESH::DRS_OK; break;
363 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
364 res = SMESH::DRS_EMPTY; break;
365 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
366 res = SMESH::DRS_WARN_RENUMBER; break;
367 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
368 res = SMESH::DRS_WARN_SKIP_ELEM; break;
369 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
370 res = SMESH::DRS_WARN_DESCENDING; break;
371 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
373 res = SMESH::DRS_FAIL; break;
378 //=============================================================================
380 * Convert ::SMESH_ComputeError to SMESH::ComputeError
382 //=============================================================================
384 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
386 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
387 errVar->subShapeID = -1;
388 errVar->hasBadMesh = false;
390 if ( !errorPtr || errorPtr->IsOK() )
392 errVar->code = SMESH::COMPERR_OK;
396 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
397 errVar->comment = errorPtr->myComment.c_str();
399 return errVar._retn();
402 //=============================================================================
406 * Imports mesh data from MED file
408 //=============================================================================
410 SMESH::DriverMED_ReadStatus
411 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
412 throw ( SALOME::SALOME_Exception )
414 Unexpect aCatch(SALOME_SalomeException);
417 status = _impl->MEDToMesh( theFileName, theMeshName );
419 catch( SALOME_Exception& S_ex ) {
420 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
423 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
426 CreateGroupServants();
428 int major, minor, release;
429 major = minor = release = 0;
430 MED::GetMEDVersion(theFileName, major, minor, release);
431 _medFileInfo = new SMESH::MedFileInfo();
432 _medFileInfo->fileName = theFileName;
433 _medFileInfo->fileSize = 0;
434 _medFileInfo->major = major;
435 _medFileInfo->minor = minor;
436 _medFileInfo->release = release;
437 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
439 return ConvertDriverMEDReadStatus(status);
442 //================================================================================
444 * \brief Imports mesh data from the CGNS file
446 //================================================================================
448 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
449 const int theMeshIndex,
450 std::string& theMeshName )
451 throw ( SALOME::SALOME_Exception )
453 Unexpect aCatch(SALOME_SalomeException);
456 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
458 catch( SALOME_Exception& S_ex ) {
459 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
462 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
465 CreateGroupServants();
467 _medFileInfo = new SMESH::MedFileInfo();
468 _medFileInfo->fileName = theFileName;
469 _medFileInfo->major = 0;
470 _medFileInfo->minor = 0;
471 _medFileInfo->release = 0;
472 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
474 return ConvertDriverMEDReadStatus(status);
477 //================================================================================
479 * \brief Return string representation of a MED file version comprising nbDigits
481 //================================================================================
483 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
485 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
487 return CORBA::string_dup( ver.c_str() );
490 //================================================================================
492 * Return the list of med versions compatibles for write/append,
493 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
495 //================================================================================
496 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
498 SMESH::long_array_var aResult = new SMESH::long_array();
499 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
500 long nbver = mvok.size();
501 aResult->length( nbver );
502 for ( int i = 0; i < nbver; i++ )
503 aResult[i] = mvok[i];
504 return aResult._retn();
507 //=============================================================================
511 * Imports mesh data from MED file
513 //=============================================================================
515 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
516 throw ( SALOME::SALOME_Exception )
520 // Read mesh with name = <theMeshName> into SMESH_Mesh
521 _impl->UNVToMesh( theFileName );
523 CreateGroupServants();
525 _medFileInfo = new SMESH::MedFileInfo();
526 _medFileInfo->fileName = theFileName;
527 _medFileInfo->major = 0;
528 _medFileInfo->minor = 0;
529 _medFileInfo->release = 0;
530 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
532 SMESH_CATCH( SMESH::throwCorbaException );
537 //=============================================================================
541 * Imports mesh data from STL file
543 //=============================================================================
544 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
545 throw ( SALOME::SALOME_Exception )
549 // Read mesh with name = <theMeshName> into SMESH_Mesh
550 std::string name = _impl->STLToMesh( theFileName );
553 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
554 _gen_i->SetName( meshSO, name.c_str() );
556 _medFileInfo = new SMESH::MedFileInfo();
557 _medFileInfo->fileName = theFileName;
558 _medFileInfo->major = 0;
559 _medFileInfo->minor = 0;
560 _medFileInfo->release = 0;
561 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
563 SMESH_CATCH( SMESH::throwCorbaException );
568 //================================================================================
570 * \brief Function used in SMESH_CATCH by ImportGMFFile()
572 //================================================================================
576 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
578 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
582 //================================================================================
584 * \brief Imports data from a GMF file and returns an error description
586 //================================================================================
588 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
589 bool theMakeRequiredGroups )
590 throw (SALOME::SALOME_Exception)
592 SMESH_ComputeErrorPtr error;
595 #define SMESH_CAUGHT error =
598 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
600 _medFileInfo = new SMESH::MedFileInfo();
601 _medFileInfo->fileName = theFileName;
602 _medFileInfo->major = 0;
603 _medFileInfo->minor = 0;
604 _medFileInfo->release = 0;
605 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
607 SMESH_CATCH( exceptionToComputeError );
611 CreateGroupServants();
613 return ConvertComputeError( error );
616 //=============================================================================
620 //=============================================================================
622 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
624 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
625 (SMESH_Hypothesis::Hypothesis_Status theStatus)
628 RETURNCASE( HYP_OK );
629 RETURNCASE( HYP_MISSING );
630 RETURNCASE( HYP_CONCURRENT );
631 RETURNCASE( HYP_BAD_PARAMETER );
632 RETURNCASE( HYP_HIDDEN_ALGO );
633 RETURNCASE( HYP_HIDING_ALGO );
634 RETURNCASE( HYP_UNKNOWN_FATAL );
635 RETURNCASE( HYP_INCOMPATIBLE );
636 RETURNCASE( HYP_NOTCONFORM );
637 RETURNCASE( HYP_ALREADY_EXIST );
638 RETURNCASE( HYP_BAD_DIM );
639 RETURNCASE( HYP_BAD_SUBSHAPE );
640 RETURNCASE( HYP_BAD_GEOMETRY );
641 RETURNCASE( HYP_NEED_SHAPE );
642 RETURNCASE( HYP_INCOMPAT_HYPS );
645 return SMESH::HYP_UNKNOWN_FATAL;
648 //=============================================================================
652 * calls internal addHypothesis() and then adds a reference to <anHyp> under
653 * the SObject actually having a reference to <aSubShape>.
654 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
656 //=============================================================================
658 SMESH::Hypothesis_Status
659 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
660 SMESH::SMESH_Hypothesis_ptr anHyp,
661 CORBA::String_out anErrorText)
662 throw(SALOME::SALOME_Exception)
664 Unexpect aCatch(SALOME_SalomeException);
666 _preMeshInfo->ForgetOrLoad();
669 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
670 anErrorText = error.c_str();
672 SMESH::SMESH_Mesh_var mesh( _this() );
673 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
675 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
676 _gen_i->UpdateIcons( mesh );
678 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
680 // Update Python script
681 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
682 << aSubShape << ", " << anHyp << " )";
684 return ConvertHypothesisStatus(status);
687 //=============================================================================
691 //=============================================================================
693 SMESH_Hypothesis::Hypothesis_Status
694 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
695 SMESH::SMESH_Hypothesis_ptr anHyp,
696 std::string* anErrorText)
698 if(MYDEBUG) MESSAGE("addHypothesis");
700 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
701 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
703 if (CORBA::is_nil( anHyp ))
704 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
706 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
709 TopoDS_Shape myLocSubShape;
710 //use PseudoShape in case if mesh has no shape
712 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
714 myLocSubShape = _impl->GetShapeToMesh();
716 const int hypId = anHyp->GetId();
718 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
719 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
721 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
723 // assure there is a corresponding submesh
724 if ( !_impl->IsMainShape( myLocSubShape )) {
725 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
726 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
727 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
730 else if ( anErrorText )
732 *anErrorText = error;
735 catch(SALOME_Exception & S_ex)
737 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
742 //=============================================================================
746 //=============================================================================
748 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
749 SMESH::SMESH_Hypothesis_ptr anHyp)
750 throw(SALOME::SALOME_Exception)
752 Unexpect aCatch(SALOME_SalomeException);
754 _preMeshInfo->ForgetOrLoad();
756 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
757 SMESH::SMESH_Mesh_var mesh = _this();
759 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
761 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
762 _gen_i->UpdateIcons( mesh );
764 // Update Python script
765 if(_impl->HasShapeToMesh())
766 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
767 << aSubShape << ", " << anHyp << " )";
769 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
772 return ConvertHypothesisStatus(status);
775 //=============================================================================
779 //=============================================================================
781 SMESH_Hypothesis::Hypothesis_Status
782 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
783 SMESH::SMESH_Hypothesis_ptr anHyp)
785 if(MYDEBUG) MESSAGE("removeHypothesis()");
787 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
788 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
790 if (CORBA::is_nil( anHyp ))
791 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
794 _preMeshInfo->ForgetOrLoad();
796 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
799 TopoDS_Shape myLocSubShape;
800 //use PseudoShape in case if mesh has no shape
801 if( _impl->HasShapeToMesh() )
802 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
804 myLocSubShape = _impl->GetShapeToMesh();
806 const int hypId = anHyp->GetId();
807 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
808 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
810 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
814 catch(SALOME_Exception & S_ex)
816 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
821 //=============================================================================
825 //=============================================================================
827 SMESH::ListOfHypothesis *
828 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
829 throw(SALOME::SALOME_Exception)
831 Unexpect aCatch(SALOME_SalomeException);
832 if (MYDEBUG) MESSAGE("GetHypothesisList");
833 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
834 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
836 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
839 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
840 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
841 myLocSubShape = _impl->GetShapeToMesh();
842 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
843 int i = 0, n = aLocalList.size();
846 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
847 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
848 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
850 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
851 if ( id_hypptr != _mapHypo.end() )
852 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
856 catch(SALOME_Exception & S_ex) {
857 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
860 return aList._retn();
863 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
865 Unexpect aCatch(SALOME_SalomeException);
866 if (MYDEBUG) MESSAGE("GetSubMeshes");
868 SMESH::submesh_array_var aList = new SMESH::submesh_array();
871 TPythonDump aPythonDump;
872 if ( !_mapSubMeshIor.empty() )
876 aList->length( _mapSubMeshIor.size() );
878 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
879 for ( ; it != _mapSubMeshIor.end(); it++ ) {
880 if ( CORBA::is_nil( it->second )) continue;
881 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
883 if (i > 1) aPythonDump << ", ";
884 aPythonDump << it->second;
888 catch(SALOME_Exception & S_ex) {
889 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
892 // Update Python script
893 if ( !_mapSubMeshIor.empty() )
894 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
896 return aList._retn();
899 //=============================================================================
903 //=============================================================================
905 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
906 const char* theName )
907 throw(SALOME::SALOME_Exception)
909 Unexpect aCatch(SALOME_SalomeException);
910 if (CORBA::is_nil(aSubShape))
911 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
913 SMESH::SMESH_subMesh_var subMesh;
914 SMESH::SMESH_Mesh_var aMesh = _this();
916 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
918 //Get or Create the SMESH_subMesh object implementation
920 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
922 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
924 TopoDS_Iterator it( myLocSubShape );
926 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
928 subMesh = getSubMesh( subMeshId );
930 // create a new subMesh object servant if there is none for the shape
931 if ( subMesh->_is_nil() )
932 subMesh = createSubMesh( aSubShape );
933 if ( _gen_i->CanPublishInStudy( subMesh ))
935 SALOMEDS::SObject_wrap aSO =
936 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
937 if ( !aSO->_is_nil()) {
938 // Update Python script
939 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
940 << aSubShape << ", '" << theName << "' )";
944 catch(SALOME_Exception & S_ex) {
945 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
947 return subMesh._retn();
950 //=============================================================================
954 //=============================================================================
956 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
957 throw (SALOME::SALOME_Exception)
961 if ( theSubMesh->_is_nil() )
964 GEOM::GEOM_Object_var aSubShape;
965 // Remove submesh's SObject
966 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
967 if ( !anSO->_is_nil() ) {
968 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
969 SALOMEDS::SObject_wrap anObj, aRef;
970 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
971 anObj->ReferencedObject( aRef.inout() ))
973 CORBA::Object_var obj = aRef->GetObject();
974 aSubShape = GEOM::GEOM_Object::_narrow( obj );
976 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
977 // aSubShape = theSubMesh->GetSubShape();
979 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
980 builder->RemoveObjectWithChildren( anSO );
982 // Update Python script
983 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
986 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
988 _preMeshInfo->ForgetOrLoad();
990 SMESH_CATCH( SMESH::throwCorbaException );
993 //=============================================================================
997 //=============================================================================
999 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1000 const char* theName )
1001 throw(SALOME::SALOME_Exception)
1003 Unexpect aCatch(SALOME_SalomeException);
1005 _preMeshInfo->FullLoadFromFile();
1007 SMESH::SMESH_Group_var aNewGroup =
1008 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1010 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1012 SMESH::SMESH_Mesh_var mesh = _this();
1013 SALOMEDS::SObject_wrap aSO =
1014 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1015 if ( !aSO->_is_nil())
1016 // Update Python script
1017 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1018 << theElemType << ", '" << theName << "' )";
1020 return aNewGroup._retn();
1023 //=============================================================================
1027 //=============================================================================
1028 SMESH::SMESH_GroupOnGeom_ptr
1029 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1030 const char* theName,
1031 GEOM::GEOM_Object_ptr theGeomObj)
1032 throw(SALOME::SALOME_Exception)
1034 Unexpect aCatch(SALOME_SalomeException);
1036 _preMeshInfo->FullLoadFromFile();
1038 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1040 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1041 if ( !aShape.IsNull() )
1044 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1046 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1048 SMESH::SMESH_Mesh_var mesh = _this();
1049 SALOMEDS::SObject_wrap aSO =
1050 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1051 if ( !aSO->_is_nil())
1052 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1053 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1057 return aNewGroup._retn();
1060 //================================================================================
1062 * \brief Creates a group whose contents is defined by filter
1063 * \param theElemType - group type
1064 * \param theName - group name
1065 * \param theFilter - the filter
1066 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1068 //================================================================================
1070 SMESH::SMESH_GroupOnFilter_ptr
1071 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1072 const char* theName,
1073 SMESH::Filter_ptr theFilter )
1074 throw (SALOME::SALOME_Exception)
1076 Unexpect aCatch(SALOME_SalomeException);
1078 _preMeshInfo->FullLoadFromFile();
1080 if ( CORBA::is_nil( theFilter ))
1081 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1083 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1085 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1087 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1088 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1091 if ( !aNewGroup->_is_nil() )
1092 aNewGroup->SetFilter( theFilter );
1094 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1096 SMESH::SMESH_Mesh_var mesh = _this();
1097 SALOMEDS::SObject_wrap aSO =
1098 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1100 if ( !aSO->_is_nil())
1101 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1102 << theElemType << ", '" << theName << "', " << theFilter << " )";
1104 return aNewGroup._retn();
1107 //=============================================================================
1111 //=============================================================================
1113 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1114 throw (SALOME::SALOME_Exception)
1116 if ( theGroup->_is_nil() )
1121 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1125 if ( aGroup->GetMeshServant() != this )
1126 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1127 SALOME::BAD_PARAM );
1129 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1130 if ( !aGroupSO->_is_nil() )
1132 // Update Python script
1133 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1135 // Remove group's SObject
1136 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1137 builder->RemoveObjectWithChildren( aGroupSO );
1139 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1141 // Remove the group from SMESH data structures
1142 removeGroup( aGroup->GetLocalID() );
1144 SMESH_CATCH( SMESH::throwCorbaException );
1147 //=============================================================================
1149 * Remove group with its contents
1151 //=============================================================================
1153 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1154 throw (SALOME::SALOME_Exception)
1158 _preMeshInfo->FullLoadFromFile();
1160 if ( theGroup->_is_nil() )
1163 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1164 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1165 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1168 vector<int> nodeIds; // to remove nodes becoming free
1169 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1170 if ( !isNodal && !theGroup->IsEmpty() )
1172 CORBA::Long elemID = theGroup->GetID( 1 );
1173 int nbElemNodes = GetElemNbNodes( elemID );
1174 if ( nbElemNodes > 0 )
1175 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1178 // Retrieve contents
1179 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1180 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1181 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1182 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1183 elems.assign( elemBeg, elemEnd );
1185 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1188 RemoveGroup( theGroup );
1191 for ( size_t i = 0; i < elems.size(); ++i )
1193 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1197 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1198 nodeIds.push_back( nIt->next()->GetID() );
1200 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1204 _impl->GetMeshDS()->RemoveElement( elems[i] );
1208 // Remove free nodes
1209 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1210 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1211 if ( n->NbInverseElements() == 0 )
1212 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1214 // Update Python script (theGroup must be alive for this)
1215 pyDump << SMESH::SMESH_Mesh_var(_this())
1216 << ".RemoveGroupWithContents( " << theGroup << " )";
1218 SMESH_CATCH( SMESH::throwCorbaException );
1221 //================================================================================
1223 * \brief Get the list of groups existing in the mesh
1224 * \retval SMESH::ListOfGroups * - list of groups
1226 //================================================================================
1228 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1230 Unexpect aCatch(SALOME_SalomeException);
1231 if (MYDEBUG) MESSAGE("GetGroups");
1233 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1236 TPythonDump aPythonDump;
1237 if ( !_mapGroups.empty() )
1239 aPythonDump << "[ ";
1241 aList->length( _mapGroups.size() );
1243 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1244 for ( ; it != _mapGroups.end(); it++ ) {
1245 if ( CORBA::is_nil( it->second )) continue;
1246 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1248 if (i > 1) aPythonDump << ", ";
1249 aPythonDump << it->second;
1253 catch(SALOME_Exception & S_ex) {
1254 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1256 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1258 return aList._retn();
1261 //=============================================================================
1263 * Get number of groups existing in the mesh
1265 //=============================================================================
1267 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1269 Unexpect aCatch(SALOME_SalomeException);
1270 return _mapGroups.size();
1273 //=============================================================================
1275 * New group including all mesh elements present in initial groups is created.
1277 //=============================================================================
1279 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1280 SMESH::SMESH_GroupBase_ptr theGroup2,
1281 const char* theName )
1282 throw (SALOME::SALOME_Exception)
1284 SMESH::SMESH_Group_var aResGrp;
1288 _preMeshInfo->FullLoadFromFile();
1290 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1291 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1293 if ( theGroup1->GetType() != theGroup2->GetType() )
1294 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1299 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1300 if ( aResGrp->_is_nil() )
1301 return SMESH::SMESH_Group::_nil();
1303 aResGrp->AddFrom( theGroup1 );
1304 aResGrp->AddFrom( theGroup2 );
1306 // Update Python script
1307 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1308 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1310 SMESH_CATCH( SMESH::throwCorbaException );
1312 return aResGrp._retn();
1315 //=============================================================================
1317 * \brief New group including all mesh elements present in initial groups is created.
1318 * \param theGroups list of groups
1319 * \param theName name of group to be created
1320 * \return pointer to the new group
1322 //=============================================================================
1324 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1325 const char* theName )
1326 throw (SALOME::SALOME_Exception)
1328 SMESH::SMESH_Group_var aResGrp;
1331 _preMeshInfo->FullLoadFromFile();
1334 return SMESH::SMESH_Group::_nil();
1339 SMESH::ElementType aType = SMESH::ALL;
1340 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1342 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1343 if ( CORBA::is_nil( aGrp ) )
1345 if ( aType == SMESH::ALL )
1346 aType = aGrp->GetType();
1347 else if ( aType != aGrp->GetType() )
1348 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1351 if ( aType == SMESH::ALL )
1352 return SMESH::SMESH_Group::_nil();
1357 aResGrp = CreateGroup( aType, theName );
1358 if ( aResGrp->_is_nil() )
1359 return SMESH::SMESH_Group::_nil();
1361 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1362 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1364 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1365 if ( !CORBA::is_nil( aGrp ) )
1367 aResGrp->AddFrom( aGrp );
1368 if ( g > 0 ) pyDump << ", ";
1372 pyDump << " ], '" << theName << "' )";
1374 SMESH_CATCH( SMESH::throwCorbaException );
1376 return aResGrp._retn();
1379 //=============================================================================
1381 * New group is created. All mesh elements that are
1382 * present in both initial groups are added to the new one.
1384 //=============================================================================
1386 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1387 SMESH::SMESH_GroupBase_ptr theGroup2,
1388 const char* theName )
1389 throw (SALOME::SALOME_Exception)
1391 SMESH::SMESH_Group_var aResGrp;
1396 _preMeshInfo->FullLoadFromFile();
1398 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1399 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1401 if ( theGroup1->GetType() != theGroup2->GetType() )
1402 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1406 // Create Intersection
1407 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1408 if ( aResGrp->_is_nil() )
1409 return aResGrp._retn();
1411 SMESHDS_GroupBase* groupDS1 = 0;
1412 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1413 groupDS1 = grp_i->GetGroupDS();
1415 SMESHDS_GroupBase* groupDS2 = 0;
1416 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1417 groupDS2 = grp_i->GetGroupDS();
1419 SMESHDS_Group* resGroupDS = 0;
1420 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1421 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1423 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1425 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1426 while ( elemIt1->more() )
1428 const SMDS_MeshElement* e = elemIt1->next();
1429 if ( groupDS2->Contains( e ))
1430 resGroupDS->SMDSGroup().Add( e );
1433 // Update Python script
1434 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1435 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1437 SMESH_CATCH( SMESH::throwCorbaException );
1439 return aResGrp._retn();
1442 //=============================================================================
1444 \brief Intersect list of groups. New group is created. All mesh elements that
1445 are present in all initial groups simultaneously are added to the new one.
1446 \param theGroups list of groups
1447 \param theName name of group to be created
1448 \return pointer on the group
1450 //=============================================================================
1451 SMESH::SMESH_Group_ptr
1452 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1453 const char* theName )
1454 throw (SALOME::SALOME_Exception)
1456 SMESH::SMESH_Group_var aResGrp;
1461 _preMeshInfo->FullLoadFromFile();
1464 return SMESH::SMESH_Group::_nil();
1466 // check types and get SMESHDS_GroupBase's
1467 SMESH::ElementType aType = SMESH::ALL;
1468 vector< SMESHDS_GroupBase* > groupVec;
1469 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1471 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1472 if ( CORBA::is_nil( aGrp ) )
1474 if ( aType == SMESH::ALL )
1475 aType = aGrp->GetType();
1476 else if ( aType != aGrp->GetType() )
1477 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1480 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1481 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1483 if ( grpDS->IsEmpty() )
1488 groupVec.push_back( grpDS );
1491 if ( aType == SMESH::ALL ) // all groups are nil
1492 return SMESH::SMESH_Group::_nil();
1497 aResGrp = CreateGroup( aType, theName );
1499 SMESHDS_Group* resGroupDS = 0;
1500 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1501 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1502 if ( !resGroupDS || groupVec.empty() )
1503 return aResGrp._retn();
1506 size_t i, nb = groupVec.size();
1507 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1508 while ( elemIt1->more() )
1510 const SMDS_MeshElement* e = elemIt1->next();
1512 for ( i = 1; ( i < nb && inAll ); ++i )
1513 inAll = groupVec[i]->Contains( e );
1516 resGroupDS->SMDSGroup().Add( e );
1519 // Update Python script
1520 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1521 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1523 SMESH_CATCH( SMESH::throwCorbaException );
1525 return aResGrp._retn();
1528 //=============================================================================
1530 * New group is created. All mesh elements that are present in
1531 * a main group but is not present in a tool group are added to the new one
1533 //=============================================================================
1535 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1536 SMESH::SMESH_GroupBase_ptr theGroup2,
1537 const char* theName )
1538 throw (SALOME::SALOME_Exception)
1540 SMESH::SMESH_Group_var aResGrp;
1545 _preMeshInfo->FullLoadFromFile();
1547 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1548 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1550 if ( theGroup1->GetType() != theGroup2->GetType() )
1551 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1555 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1556 if ( aResGrp->_is_nil() )
1557 return aResGrp._retn();
1559 SMESHDS_GroupBase* groupDS1 = 0;
1560 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1561 groupDS1 = grp_i->GetGroupDS();
1563 SMESHDS_GroupBase* groupDS2 = 0;
1564 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1565 groupDS2 = grp_i->GetGroupDS();
1567 SMESHDS_Group* resGroupDS = 0;
1568 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1569 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1571 if ( groupDS1 && groupDS2 && resGroupDS )
1573 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1574 while ( elemIt1->more() )
1576 const SMDS_MeshElement* e = elemIt1->next();
1577 if ( !groupDS2->Contains( e ))
1578 resGroupDS->SMDSGroup().Add( e );
1581 // Update Python script
1582 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1583 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1585 SMESH_CATCH( SMESH::throwCorbaException );
1587 return aResGrp._retn();
1590 //=============================================================================
1592 \brief Cut lists of groups. New group is created. All mesh elements that are
1593 present in main groups but do not present in tool groups are added to the new one
1594 \param theMainGroups list of main groups
1595 \param theToolGroups list of tool groups
1596 \param theName name of group to be created
1597 \return pointer on the group
1599 //=============================================================================
1600 SMESH::SMESH_Group_ptr
1601 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1602 const SMESH::ListOfGroups& theToolGroups,
1603 const char* theName )
1604 throw (SALOME::SALOME_Exception)
1606 SMESH::SMESH_Group_var aResGrp;
1611 _preMeshInfo->FullLoadFromFile();
1614 return SMESH::SMESH_Group::_nil();
1616 // check types and get SMESHDS_GroupBase's
1617 SMESH::ElementType aType = SMESH::ALL;
1618 vector< SMESHDS_GroupBase* > toolGroupVec;
1619 vector< SMDS_ElemIteratorPtr > mainIterVec;
1621 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1623 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1624 if ( CORBA::is_nil( aGrp ) )
1626 if ( aType == SMESH::ALL )
1627 aType = aGrp->GetType();
1628 else if ( aType != aGrp->GetType() )
1629 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1631 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1632 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1633 if ( !grpDS->IsEmpty() )
1634 mainIterVec.push_back( grpDS->GetElements() );
1636 if ( aType == SMESH::ALL ) // all main groups are nil
1637 return SMESH::SMESH_Group::_nil();
1638 if ( mainIterVec.empty() ) // all main groups are empty
1639 return aResGrp._retn();
1641 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1643 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1644 if ( CORBA::is_nil( aGrp ) )
1646 if ( aType != aGrp->GetType() )
1647 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1649 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1650 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1651 toolGroupVec.push_back( grpDS );
1657 aResGrp = CreateGroup( aType, theName );
1659 SMESHDS_Group* resGroupDS = 0;
1660 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1661 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1663 return aResGrp._retn();
1666 size_t i, nb = toolGroupVec.size();
1667 SMDS_ElemIteratorPtr mainElemIt
1668 ( new SMDS_IteratorOnIterators
1669 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1670 while ( mainElemIt->more() )
1672 const SMDS_MeshElement* e = mainElemIt->next();
1674 for ( i = 0; ( i < nb && !isIn ); ++i )
1675 isIn = toolGroupVec[i]->Contains( e );
1678 resGroupDS->SMDSGroup().Add( e );
1681 // Update Python script
1682 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1683 << ".CutListOfGroups( " << theMainGroups << ", "
1684 << theToolGroups << ", '" << theName << "' )";
1686 SMESH_CATCH( SMESH::throwCorbaException );
1688 return aResGrp._retn();
1691 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1693 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1694 bool & toStopChecking )
1696 toStopChecking = ( nbCommon < nbChecked );
1697 return nbCommon == nbNodes;
1699 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1700 bool & toStopChecking )
1702 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1703 return nbCommon == nbCorners;
1705 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1706 bool & toStopChecking )
1708 return nbCommon > 0;
1710 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1711 bool & toStopChecking )
1713 return nbCommon >= (nbNodes+1) / 2;
1717 //=============================================================================
1719 * Create a group of entities basing on nodes of other groups.
1720 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1721 * \param [in] anElemType - a type of elements to include to the new group.
1722 * \param [in] theName - a name of the new group.
1723 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1724 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1725 * new group provided that it is based on nodes of an element of \a aListOfGroups
1726 * \return SMESH_Group - the created group
1728 // IMP 19939, bug 22010, IMP 22635
1729 //=============================================================================
1731 SMESH::SMESH_Group_ptr
1732 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1733 SMESH::ElementType theElemType,
1734 const char* theName,
1735 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1736 CORBA::Boolean theUnderlyingOnly)
1737 throw (SALOME::SALOME_Exception)
1739 SMESH::SMESH_Group_var aResGrp;
1743 _preMeshInfo->FullLoadFromFile();
1745 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1747 if ( !theName || !aMeshDS )
1748 return SMESH::SMESH_Group::_nil();
1750 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1752 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1753 SMESH_Comment nbCoNoStr( "SMESH.");
1754 switch ( theNbCommonNodes ) {
1755 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1756 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1757 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1758 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1759 default: return aResGrp._retn();
1761 int nbChecked, nbCommon, nbNodes, nbCorners;
1767 aResGrp = CreateGroup( theElemType, theName );
1768 if ( aResGrp->_is_nil() )
1769 return SMESH::SMESH_Group::_nil();
1771 SMESHDS_GroupBase* groupBaseDS =
1772 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1773 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1775 vector<bool> isNodeInGroups;
1777 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1779 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1780 if ( CORBA::is_nil( aGrp ) )
1782 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1783 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1786 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1787 if ( !elIt ) continue;
1789 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1791 while ( elIt->more() ) {
1792 const SMDS_MeshElement* el = elIt->next();
1793 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1794 while ( nIt->more() )
1795 resGroupCore.Add( nIt->next() );
1798 // get elements of theElemType based on nodes of every element of group
1799 else if ( theUnderlyingOnly )
1801 while ( elIt->more() )
1803 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1804 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1805 TIDSortedElemSet checkedElems;
1806 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1807 while ( nIt->more() )
1809 const SMDS_MeshNode* n = nIt->next();
1810 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1811 // check nodes of elements of theElemType around el
1812 while ( elOfTypeIt->more() )
1814 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1815 if ( !checkedElems.insert( elOfType ).second ) continue;
1816 nbNodes = elOfType->NbNodes();
1817 nbCorners = elOfType->NbCornerNodes();
1819 bool toStopChecking = false;
1820 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1821 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1822 if ( elNodes.count( nIt2->next() ) &&
1823 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1825 resGroupCore.Add( elOfType );
1832 // get all nodes of elements of groups
1835 while ( elIt->more() )
1837 const SMDS_MeshElement* el = elIt->next(); // an element of group
1838 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1839 while ( nIt->more() )
1841 const SMDS_MeshNode* n = nIt->next();
1842 if ( n->GetID() >= (int) isNodeInGroups.size() )
1843 isNodeInGroups.resize( n->GetID() + 1, false );
1844 isNodeInGroups[ n->GetID() ] = true;
1850 // Get elements of theElemType based on a certain number of nodes of elements of groups
1851 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1853 const SMDS_MeshNode* n;
1854 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1855 const int isNodeInGroupsSize = isNodeInGroups.size();
1856 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1858 if ( !isNodeInGroups[ iN ] ||
1859 !( n = aMeshDS->FindNode( iN )))
1862 // check nodes of elements of theElemType around n
1863 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1864 while ( elOfTypeIt->more() )
1866 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1867 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1872 nbNodes = elOfType->NbNodes();
1873 nbCorners = elOfType->NbCornerNodes();
1875 bool toStopChecking = false;
1876 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1877 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1879 const int nID = nIt->next()->GetID();
1880 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1881 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1883 resGroupCore.Add( elOfType );
1891 // Update Python script
1892 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1893 << ".CreateDimGroup( "
1894 << theGroups << ", " << theElemType << ", '" << theName << "', "
1895 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1897 SMESH_CATCH( SMESH::throwCorbaException );
1899 return aResGrp._retn();
1902 //================================================================================
1904 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1905 * existing 1D elements as group boundaries.
1906 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1907 * adjacent faces is more than \a sharpAngle in degrees.
1908 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1909 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1910 * \return ListOfGroups - the created groups
1912 //================================================================================
1914 SMESH::ListOfGroups*
1915 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1916 CORBA::Boolean theCreateEdges,
1917 CORBA::Boolean theUseExistingEdges )
1918 throw (SALOME::SALOME_Exception)
1920 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1921 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1924 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1930 _preMeshInfo->FullLoadFromFile();
1932 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1934 std::vector< SMESH_MeshAlgos::Edge > edges =
1935 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1937 if ( theCreateEdges )
1939 std::vector<const SMDS_MeshNode *> nodes(2);
1940 for ( size_t i = 0; i < edges.size(); ++i )
1942 nodes[0] = edges[i]._node1;
1943 nodes[1] = edges[i]._node2;
1944 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1946 if ( edges[i]._medium )
1947 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1949 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1953 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1954 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1956 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1958 resultGroups->length( faceGroups.size() );
1959 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1961 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1962 _editor->GenerateGroupName("Group").c_str());
1963 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1965 SMESHDS_GroupBase* groupBaseDS =
1966 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1967 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1969 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1970 for ( size_t i = 0; i < faces.size(); ++i )
1971 groupCore.Add( faces[i] );
1974 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1975 << ".FaceGroupsSeparatedByEdges( "
1976 << TVar( theSharpAngle ) << ", "
1977 << theCreateEdges << ", "
1978 << theUseExistingEdges << " )";
1980 SMESH_CATCH( SMESH::throwCorbaException );
1981 return resultGroups._retn();
1985 //================================================================================
1987 * \brief Remember GEOM group data
1989 //================================================================================
1991 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1992 CORBA::Object_ptr theSmeshObj)
1994 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1997 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1998 if ( groupSO->_is_nil() )
2001 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2002 GEOM::GEOM_IGroupOperations_wrap groupOp =
2003 geomGen->GetIGroupOperations();
2004 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2007 _geomGroupData.push_back( TGeomGroupData() );
2008 TGeomGroupData & groupData = _geomGroupData.back();
2010 CORBA::String_var entry = groupSO->GetID();
2011 groupData._groupEntry = entry.in();
2013 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2014 groupData._indices.insert( ids[i] );
2016 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2017 // shape index in SMESHDS
2018 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2019 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2022 //================================================================================
2024 * Remove GEOM group data relating to removed smesh object
2026 //================================================================================
2028 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2030 list<TGeomGroupData>::iterator
2031 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2032 for ( ; data != dataEnd; ++data ) {
2033 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2034 _geomGroupData.erase( data );
2040 //================================================================================
2042 * \brief Return new group contents if it has been changed and update group data
2044 //================================================================================
2046 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
2048 TopoDS_Shape newShape;
2051 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2052 if ( !groupSO->_is_nil() )
2054 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2055 if ( CORBA::is_nil( groupObj )) return newShape;
2056 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2058 // get indices of group items
2059 set<int> curIndices;
2060 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2061 GEOM::GEOM_IGroupOperations_wrap groupOp =
2062 geomGen->GetIGroupOperations();
2063 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2064 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2065 curIndices.insert( ids[i] );
2067 if ( groupData._indices == curIndices )
2068 return newShape; // group not changed
2071 groupData._indices = curIndices;
2073 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2074 if ( !geomClient ) return newShape;
2075 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2076 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2077 newShape = _gen_i->GeomObjectToShape( geomGroup );
2080 if ( newShape.IsNull() ) {
2081 // geom group becomes empty - return empty compound
2082 TopoDS_Compound compound;
2083 BRep_Builder().MakeCompound(compound);
2084 newShape = compound;
2091 //-----------------------------------------------------------------------------
2093 * \brief Storage of shape and index used in CheckGeomGroupModif()
2095 struct TIndexedShape
2098 TopoDS_Shape _shape;
2099 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2101 //-----------------------------------------------------------------------------
2103 * \brief Data to re-create a group on geometry
2105 struct TGroupOnGeomData
2108 TopoDS_Shape _shape;
2109 SMDSAbs_ElementType _type;
2111 Quantity_Color _color;
2113 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2115 _oldID = group->GetID();
2116 _type = group->GetType();
2117 _name = group->GetStoreName();
2118 _color = group->GetColor();
2122 //-----------------------------------------------------------------------------
2124 * \brief Check if a filter is still valid after geometry removal
2126 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2128 if ( theFilter->_is_nil() )
2130 SMESH::Filter::Criteria_var criteria;
2131 theFilter->GetCriteria( criteria.out() );
2133 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2135 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2137 switch ( criteria[ iCr ].Type )
2139 case SMESH::FT_BelongToGeom:
2140 case SMESH::FT_BelongToPlane:
2141 case SMESH::FT_BelongToCylinder:
2142 case SMESH::FT_BelongToGenSurface:
2143 case SMESH::FT_LyingOnGeom:
2144 entry = thresholdID;
2146 case SMESH::FT_ConnectedElements:
2149 entry = thresholdID;
2155 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2156 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2157 if ( so->_is_nil() )
2159 CORBA::Object_var obj = so->GetObject();
2160 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2161 if ( gen->GeomObjectToShape( geom ).IsNull() )
2164 } // loop on criteria
2170 //=============================================================================
2172 * \brief Update data if geometry changes
2176 //=============================================================================
2178 void SMESH_Mesh_i::CheckGeomModif()
2180 SMESH::SMESH_Mesh_var me = _this();
2181 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2183 //bool removedFromClient = false;
2185 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2187 //removedFromClient = _impl->HasShapeToMesh();
2189 // try to find geometry by study reference
2190 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2191 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2192 if ( !meshSO->_is_nil() &&
2193 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2194 geomRefSO->ReferencedObject( geomSO.inout() ))
2196 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2197 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2200 if ( mainGO->_is_nil() && // geometry removed ==>
2201 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2203 // convert geom dependent groups into standalone ones
2204 CheckGeomGroupModif();
2206 _impl->ShapeToMesh( TopoDS_Shape() );
2208 // remove sub-meshes
2209 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2210 while ( i_sm != _mapSubMeshIor.end() )
2212 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2214 RemoveSubMesh( sm );
2216 // remove all children except groups in the study
2217 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2218 SALOMEDS::SObject_wrap so;
2219 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2220 if ( meshSO->FindSubObject( tag, so.inout() ))
2221 builder->RemoveObjectWithChildren( so );
2223 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2229 if ( !_impl->HasShapeToMesh() ) return;
2232 // Update after group modification
2234 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2235 mainGO->GetTick() == _mainShapeTick )
2237 int nb = NbNodes() + NbElements();
2238 CheckGeomGroupModif();
2239 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2240 _gen_i->UpdateIcons( me );
2244 // Update after shape transformation like Translate
2246 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2247 if ( !geomClient ) return;
2248 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2249 if ( geomGen->_is_nil() ) return;
2251 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2252 geomClient->RemoveShapeFromBuffer( ior.in() );
2254 // Update data taking into account that
2255 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2258 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2259 if ( newShape.IsNull() )
2262 // for the SHAPER-STUDY: the geometry may be updated, so, add a warning icon
2263 if (_mainShapeTick != mainGO->GetTick()) {
2264 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2265 if ( !meshSO->_is_nil())
2266 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_MESH_WARN");
2269 _mainShapeTick = mainGO->GetTick();
2271 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2273 // store data of groups on geometry
2274 std::vector< TGroupOnGeomData > groupsData;
2275 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2276 groupsData.reserve( groups.size() );
2277 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2278 for ( ; g != groups.end(); ++g )
2280 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2282 groupsData.push_back( TGroupOnGeomData( group ));
2285 SMESH::SMESH_GroupOnGeom_var gog;
2286 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2287 if ( i_grp != _mapGroups.end() )
2288 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2290 GEOM::GEOM_Object_var geom;
2291 if ( !gog->_is_nil() )
2292 geom = gog->GetShape();
2293 if ( !geom->_is_nil() )
2295 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2296 geomClient->RemoveShapeFromBuffer( ior.in() );
2297 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2301 // store assigned hypotheses
2302 std::vector< pair< int, THypList > > ids2Hyps;
2303 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2304 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2306 const TopoDS_Shape& s = s2hyps.Key();
2307 const THypList& hyps = s2hyps.ChangeValue();
2308 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2311 // change shape to mesh
2312 int oldNbSubShapes = meshDS->MaxShapeIndex();
2313 _impl->ShapeToMesh( TopoDS_Shape() );
2314 _impl->ShapeToMesh( newShape );
2316 // re-add shapes of geom groups
2317 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2318 for ( ; data != _geomGroupData.end(); ++data )
2320 TopoDS_Shape newShape = newGroupShape( *data );
2321 if ( !newShape.IsNull() )
2323 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2325 TopoDS_Compound compound;
2326 BRep_Builder().MakeCompound( compound );
2327 BRep_Builder().Add( compound, newShape );
2328 newShape = compound;
2330 _impl->GetSubMesh( newShape );
2333 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2334 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2335 SALOME::INTERNAL_ERROR );
2337 // re-assign hypotheses
2338 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2340 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2341 const THypList& hyps = ids2Hyps[i].second;
2342 THypList::const_iterator h = hyps.begin();
2343 for ( ; h != hyps.end(); ++h )
2344 _impl->AddHypothesis( s, (*h)->GetID() );
2347 // restore groups on geometry
2348 for ( size_t i = 0; i < groupsData.size(); ++i )
2350 const TGroupOnGeomData& data = groupsData[i];
2351 if ( data._shape.IsNull() )
2354 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2355 if ( i2g == _mapGroups.end() ) continue;
2357 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2358 if ( !gr_i ) continue;
2360 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2362 _mapGroups.erase( i2g );
2364 g->GetGroupDS()->SetColor( data._color );
2367 // update _mapSubMesh
2368 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2369 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2370 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2374 //=============================================================================
2376 * \brief Update objects depending on changed geom groups
2378 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2379 * issue 0020210: Update of a smesh group after modification of the associated geom group
2381 //=============================================================================
2383 void SMESH_Mesh_i::CheckGeomGroupModif()
2385 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2386 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2387 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2388 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2389 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2391 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2392 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2393 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2395 int nbValid = 0, nbRemoved = 0;
2396 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2397 for ( ; chItr->More(); chItr->Next() )
2399 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2400 if ( !smSO->_is_nil() &&
2401 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2402 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2404 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2405 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2406 if ( !geom->_non_existent() )
2409 continue; // keep the sub-mesh
2412 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2413 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2414 if ( !sm->_is_nil() && !sm->_non_existent() )
2416 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2417 if ( smGeom->_is_nil() )
2419 RemoveSubMesh( sm );
2426 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2427 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2431 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2432 builder->RemoveObjectWithChildren( rootSO );
2436 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2437 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2438 while ( i_gr != _mapGroups.end())
2440 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2442 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2443 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2444 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2445 bool isValidGeom = false;
2446 if ( !onGeom->_is_nil() )
2448 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2450 else if ( !onFilt->_is_nil() )
2452 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2456 isValidGeom = ( !groupSO->_is_nil() &&
2457 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2461 if ( !IsLoaded() || group->IsEmpty() )
2463 RemoveGroup( group );
2465 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2467 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2469 else // is it possible?
2471 builder->RemoveObjectWithChildren( refSO );
2477 if ( !_impl->HasShapeToMesh() ) return;
2479 CORBA::Long nbEntities = NbNodes() + NbElements();
2481 // Check if group contents changed
2483 typedef map< string, TopoDS_Shape > TEntry2Geom;
2484 TEntry2Geom newGroupContents;
2486 list<TGeomGroupData>::iterator
2487 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2488 for ( ; data != dataEnd; ++data )
2490 pair< TEntry2Geom::iterator, bool > it_new =
2491 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2492 bool processedGroup = !it_new.second;
2493 TopoDS_Shape& newShape = it_new.first->second;
2494 if ( !processedGroup )
2495 newShape = newGroupShape( *data );
2496 if ( newShape.IsNull() )
2497 continue; // no changes
2500 _preMeshInfo->ForgetOrLoad();
2502 if ( processedGroup ) { // update group indices
2503 list<TGeomGroupData>::iterator data2 = data;
2504 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2505 data->_indices = data2->_indices;
2508 // Update SMESH objects according to new GEOM group contents
2510 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2511 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2513 int oldID = submesh->GetId();
2514 if ( !_mapSubMeshIor.count( oldID ))
2516 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2518 // update hypotheses
2519 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2520 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2521 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2523 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2524 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2526 // care of submeshes
2527 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2528 int newID = newSubmesh->GetId();
2529 if ( newID != oldID ) {
2530 _mapSubMesh [ newID ] = newSubmesh;
2531 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2532 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2533 _mapSubMesh. erase(oldID);
2534 _mapSubMesh_i. erase(oldID);
2535 _mapSubMeshIor.erase(oldID);
2536 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2541 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2542 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2543 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2545 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2547 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2548 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2549 ds->SetShape( newShape );
2554 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2555 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2557 // Remove groups and submeshes basing on removed sub-shapes
2559 TopTools_MapOfShape newShapeMap;
2560 TopoDS_Iterator shapeIt( newShape );
2561 for ( ; shapeIt.More(); shapeIt.Next() )
2562 newShapeMap.Add( shapeIt.Value() );
2564 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2565 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2567 if ( newShapeMap.Contains( shapeIt.Value() ))
2569 TopTools_IndexedMapOfShape oldShapeMap;
2570 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2571 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2573 const TopoDS_Shape& oldShape = oldShapeMap(i);
2574 int oldInd = meshDS->ShapeToIndex( oldShape );
2576 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2577 if ( i_smIor != _mapSubMeshIor.end() ) {
2578 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2581 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2582 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2584 // check if a group bases on oldInd shape
2585 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2586 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2587 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2588 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2590 RemoveGroup( i_grp->second ); // several groups can base on same shape
2591 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2596 // Reassign hypotheses and update groups after setting the new shape to mesh
2598 // collect anassigned hypotheses
2599 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2600 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2601 TShapeHypList assignedHyps;
2602 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2604 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2605 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2606 if ( !hyps.empty() ) {
2607 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2608 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2609 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2612 // collect shapes supporting groups
2613 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2614 TShapeTypeList groupData;
2615 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2616 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2617 for ( ; grIt != groups.end(); ++grIt )
2619 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2621 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2623 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2625 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2626 _impl->ShapeToMesh( newShape );
2628 // reassign hypotheses
2629 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2630 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2632 TIndexedShape& geom = indS_hyps->first;
2633 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2634 int oldID = geom._index;
2635 int newID = meshDS->ShapeToIndex( geom._shape );
2636 if ( oldID == 1 ) { // main shape
2638 geom._shape = newShape;
2642 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2643 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2644 // care of sub-meshes
2645 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2646 if ( newID != oldID ) {
2647 _mapSubMesh [ newID ] = newSubmesh;
2648 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2649 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2650 _mapSubMesh. erase(oldID);
2651 _mapSubMesh_i. erase(oldID);
2652 _mapSubMeshIor.erase(oldID);
2653 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2657 TShapeTypeList::iterator geomType = groupData.begin();
2658 for ( ; geomType != groupData.end(); ++geomType )
2660 const TIndexedShape& geom = geomType->first;
2661 int oldID = geom._index;
2662 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2665 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2666 CORBA::String_var name = groupSO->GetName();
2668 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2669 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2670 /*id=*/-1, geom._shape ))
2671 group_i->changeLocalId( group->GetID() );
2674 break; // everything has been updated
2677 } // loop on group data
2681 CORBA::Long newNbEntities = NbNodes() + NbElements();
2682 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2683 if ( newNbEntities != nbEntities )
2685 // Add all SObjects with icons to soToUpdateIcons
2686 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2688 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2689 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2690 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2692 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2693 i_gr != _mapGroups.end(); ++i_gr ) // groups
2694 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2697 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2698 for ( ; so != soToUpdateIcons.end(); ++so )
2699 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2702 //=============================================================================
2704 * \brief Create standalone group from a group on geometry or filter
2706 //=============================================================================
2708 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2709 throw (SALOME::SALOME_Exception)
2711 SMESH::SMESH_Group_var aGroup;
2716 _preMeshInfo->FullLoadFromFile();
2718 if ( theGroup->_is_nil() )
2719 return aGroup._retn();
2721 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2723 return aGroup._retn();
2725 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2727 const int anId = aGroupToRem->GetLocalID();
2728 if ( !_impl->ConvertToStandalone( anId ) )
2729 return aGroup._retn();
2730 removeGeomGroupData( theGroup );
2732 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2734 // remove old instance of group from own map
2735 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2736 _mapGroups.erase( anId );
2738 SALOMEDS::StudyBuilder_var builder;
2739 SALOMEDS::SObject_wrap aGroupSO;
2740 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2741 if ( !aStudy->_is_nil() ) {
2742 builder = aStudy->NewBuilder();
2743 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2744 if ( !aGroupSO->_is_nil() )
2746 // remove reference to geometry
2747 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2748 for ( ; chItr->More(); chItr->Next() )
2750 // Remove group's child SObject
2751 SALOMEDS::SObject_wrap so = chItr->Value();
2752 builder->RemoveObject( so );
2754 // Update Python script
2755 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2756 << ".ConvertToStandalone( " << aGroupSO << " )";
2758 // change icon of Group on Filter
2761 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2762 // const int isEmpty = ( elemTypes->length() == 0 );
2765 SALOMEDS::GenericAttribute_wrap anAttr =
2766 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2767 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2768 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2774 // remember new group in own map
2775 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2776 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2778 // register CORBA object for persistence
2779 _gen_i->RegisterObject( aGroup );
2781 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2782 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2783 //aGroup->Register();
2784 aGroupToRem->UnRegister();
2786 SMESH_CATCH( SMESH::throwCorbaException );
2788 return aGroup._retn();
2791 //=============================================================================
2795 //=============================================================================
2797 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2799 if(MYDEBUG) MESSAGE( "createSubMesh" );
2800 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2801 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2804 SMESH_subMesh_i * subMeshServant;
2807 subMeshId = mySubMesh->GetId();
2808 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2810 else // "invalid sub-mesh"
2812 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2813 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2814 if ( _mapSubMesh.empty() )
2817 subMeshId = _mapSubMesh.begin()->first - 1;
2818 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2821 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2823 _mapSubMesh [subMeshId] = mySubMesh;
2824 _mapSubMesh_i [subMeshId] = subMeshServant;
2825 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2827 subMeshServant->Register();
2829 // register CORBA object for persistence
2830 int nextId = _gen_i->RegisterObject( subMesh );
2831 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2832 else { nextId = 0; } // avoid "unused variable" warning
2834 // to track changes of GEOM groups
2835 if ( subMeshId > 0 )
2836 addGeomGroupData( theSubShapeObject, subMesh );
2838 return subMesh._retn();
2841 //=======================================================================
2842 //function : getSubMesh
2844 //=======================================================================
2846 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2848 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2849 if ( it == _mapSubMeshIor.end() )
2850 return SMESH::SMESH_subMesh::_nil();
2852 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2855 //=============================================================================
2859 //=============================================================================
2861 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2862 GEOM::GEOM_Object_ptr theSubShapeObject )
2864 bool isHypChanged = false;
2865 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2866 return isHypChanged;
2868 const int subMeshId = theSubMesh->GetId();
2870 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2873 if (( _mapSubMesh.count( subMeshId )) &&
2874 ( sm = _impl->GetSubMeshContaining( subMeshId )))
2876 TopoDS_Shape S = sm->GetSubShape();
2879 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2880 isHypChanged = !hyps.empty();
2881 if ( isHypChanged && _preMeshInfo )
2882 _preMeshInfo->ForgetOrLoad();
2883 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2884 for ( ; hyp != hyps.end(); ++hyp )
2885 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2892 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2893 isHypChanged = ( aHypList->length() > 0 );
2894 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2895 removeHypothesis( theSubShapeObject, aHypList[i] );
2898 catch( const SALOME::SALOME_Exception& ) {
2899 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2901 removeGeomGroupData( theSubShapeObject );
2905 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2906 if ( id_smi != _mapSubMesh_i.end() )
2907 id_smi->second->UnRegister();
2909 // remove a CORBA object
2910 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2911 if ( id_smptr != _mapSubMeshIor.end() )
2912 SMESH::SMESH_subMesh_var( id_smptr->second );
2914 _mapSubMesh.erase(subMeshId);
2915 _mapSubMesh_i.erase(subMeshId);
2916 _mapSubMeshIor.erase(subMeshId);
2918 return isHypChanged;
2921 //=============================================================================
2925 //=============================================================================
2927 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2928 const char* theName,
2930 const TopoDS_Shape& theShape,
2931 const SMESH_PredicatePtr& thePredicate )
2933 std::string newName;
2934 if ( !theName || !theName[0] )
2936 std::set< std::string > presentNames;
2937 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2938 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2940 CORBA::String_var name = i_gr->second->GetName();
2941 presentNames.insert( name.in() );
2944 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2945 } while ( !presentNames.insert( newName ).second );
2946 theName = newName.c_str();
2948 SMESH::SMESH_GroupBase_var aGroup;
2949 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
2950 theID, theShape, thePredicate ))
2952 int anId = g->GetID();
2953 SMESH_GroupBase_i* aGroupImpl;
2954 if ( !theShape.IsNull() )
2955 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2956 else if ( thePredicate )
2957 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2959 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2961 aGroup = aGroupImpl->_this();
2962 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2963 aGroupImpl->Register();
2965 // register CORBA object for persistence
2966 int nextId = _gen_i->RegisterObject( aGroup );
2967 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2968 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
2970 // to track changes of GEOM groups
2971 if ( !theShape.IsNull() ) {
2972 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2973 addGeomGroupData( geom, aGroup );
2976 return aGroup._retn();
2979 //=============================================================================
2981 * SMESH_Mesh_i::removeGroup
2983 * Should be called by ~SMESH_Group_i()
2985 //=============================================================================
2987 void SMESH_Mesh_i::removeGroup( const int theId )
2989 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2990 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2991 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2992 _mapGroups.erase( theId );
2993 removeGeomGroupData( group );
2994 if ( !_impl->RemoveGroup( theId ))
2996 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2997 RemoveGroup( group );
2999 group->UnRegister();
3003 //=============================================================================
3007 //=============================================================================
3009 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3010 throw(SALOME::SALOME_Exception)
3012 SMESH::log_array_var aLog;
3016 _preMeshInfo->FullLoadFromFile();
3018 list < SMESHDS_Command * >logDS = _impl->GetLog();
3019 aLog = new SMESH::log_array;
3021 int lg = logDS.size();
3024 list < SMESHDS_Command * >::iterator its = logDS.begin();
3025 while(its != logDS.end()){
3026 SMESHDS_Command *com = *its;
3027 int comType = com->GetType();
3029 int lgcom = com->GetNumber();
3031 const list < int >&intList = com->GetIndexes();
3032 int inum = intList.size();
3034 list < int >::const_iterator ii = intList.begin();
3035 const list < double >&coordList = com->GetCoords();
3036 int rnum = coordList.size();
3038 list < double >::const_iterator ir = coordList.begin();
3039 aLog[indexLog].commandType = comType;
3040 aLog[indexLog].number = lgcom;
3041 aLog[indexLog].coords.length(rnum);
3042 aLog[indexLog].indexes.length(inum);
3043 for(int i = 0; i < rnum; i++){
3044 aLog[indexLog].coords[i] = *ir;
3045 //MESSAGE(" "<<i<<" "<<ir.Value());
3048 for(int i = 0; i < inum; i++){
3049 aLog[indexLog].indexes[i] = *ii;
3050 //MESSAGE(" "<<i<<" "<<ii.Value());
3059 SMESH_CATCH( SMESH::throwCorbaException );
3061 return aLog._retn();
3065 //=============================================================================
3069 //=============================================================================
3071 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3075 SMESH_CATCH( SMESH::throwCorbaException );
3078 //=============================================================================
3082 //=============================================================================
3084 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3089 //=============================================================================
3092 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3093 // issue 0020918: groups removal is caused by hyp modification
3094 // issue 0021208: to forget not loaded mesh data at hyp modification
3095 struct TCallUp_i : public SMESH_Mesh::TCallUp
3097 SMESH_Mesh_i* _mesh;
3098 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3099 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3100 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3101 virtual void Load () { _mesh->Load(); }
3105 //================================================================================
3107 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3109 //================================================================================
3111 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3114 _preMeshInfo->ForgetOrLoad();
3116 SMESH::SMESH_Mesh_var mesh = _this();
3117 _gen_i->UpdateIcons( mesh );
3119 // mark a hypothesis as valid after edition
3120 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3121 SALOMEDS::SObject_wrap hypRoot;
3122 if ( !smeshComp->_is_nil() &&
3123 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3125 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3126 for ( ; anIter->More(); anIter->Next() )
3128 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3129 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3130 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3131 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3132 _gen_i->HighLightInvalid( hyp, false );
3137 //=============================================================================
3141 //=============================================================================
3143 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3145 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3148 _impl->SetCallUp( new TCallUp_i(this));
3151 //=============================================================================
3155 //=============================================================================
3157 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3159 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3163 //=============================================================================
3165 * Return mesh editor
3167 //=============================================================================
3169 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3170 throw (SALOME::SALOME_Exception)
3172 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3176 _preMeshInfo->FullLoadFromFile();
3178 // Create MeshEditor
3180 _editor = new SMESH_MeshEditor_i( this, false );
3181 aMeshEdVar = _editor->_this();
3183 // Update Python script
3184 TPythonDump() << _editor << " = "
3185 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3187 SMESH_CATCH( SMESH::throwCorbaException );
3189 return aMeshEdVar._retn();
3192 //=============================================================================
3194 * Return mesh edition previewer
3196 //=============================================================================
3198 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3199 throw (SALOME::SALOME_Exception)
3201 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3205 _preMeshInfo->FullLoadFromFile();
3207 if ( !_previewEditor )
3208 _previewEditor = new SMESH_MeshEditor_i( this, true );
3209 aMeshEdVar = _previewEditor->_this();
3211 SMESH_CATCH( SMESH::throwCorbaException );
3213 return aMeshEdVar._retn();
3216 //================================================================================
3218 * \brief Return true if the mesh has been edited since a last total re-compute
3219 * and those modifications may prevent successful partial re-compute
3221 //================================================================================
3223 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3225 Unexpect aCatch(SALOME_SalomeException);
3226 return _impl->HasModificationsToDiscard();
3229 //================================================================================
3231 * \brief Returns a random unique color
3233 //================================================================================
3235 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3237 const int MAX_ATTEMPTS = 100;
3239 double tolerance = 0.5;
3240 SALOMEDS::Color col;
3244 // generate random color
3245 double red = (double)rand() / RAND_MAX;
3246 double green = (double)rand() / RAND_MAX;
3247 double blue = (double)rand() / RAND_MAX;
3248 // check existence in the list of the existing colors
3249 bool matched = false;
3250 std::list<SALOMEDS::Color>::const_iterator it;
3251 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3252 SALOMEDS::Color color = *it;
3253 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3254 matched = tol < tolerance;
3256 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3257 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3265 //=============================================================================
3267 * Sets auto-color mode. If it is on, groups get unique random colors
3269 //=============================================================================
3271 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3273 Unexpect aCatch(SALOME_SalomeException);
3274 _impl->SetAutoColor(theAutoColor);
3276 TPythonDump pyDump; // not to dump group->SetColor() from below code
3277 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3279 std::list<SALOMEDS::Color> aReservedColors;
3280 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3281 for ( ; it != _mapGroups.end(); it++ ) {
3282 if ( CORBA::is_nil( it->second )) continue;
3283 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3284 it->second->SetColor( aColor );
3285 aReservedColors.push_back( aColor );
3289 //=============================================================================
3291 * Returns true if auto-color mode is on
3293 //=============================================================================
3295 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3297 Unexpect aCatch(SALOME_SalomeException);
3298 return _impl->GetAutoColor();
3301 //=============================================================================
3303 * Checks if there are groups with equal names
3305 //=============================================================================
3307 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3309 return _impl->HasDuplicatedGroupNamesMED();
3312 //================================================================================
3314 * \brief Care of a file before exporting mesh into it
3316 //================================================================================
3318 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3320 SMESH_File aFile( file, false );
3322 if ( aFile.exists() ) {
3323 // existing filesystem node
3324 if ( !aFile.isDirectory() ) {
3325 if ( aFile.openForWriting() ) {
3326 if ( overwrite && ! aFile.remove()) {
3327 msg << "Can't replace " << aFile.getName();
3330 msg << "Can't write into " << aFile.getName();
3333 msg << "Location " << aFile.getName() << " is not a file";
3337 // nonexisting file; check if it can be created
3338 if ( !aFile.openForWriting() ) {
3339 msg << "You cannot create the file "
3341 << ". Check the directory existence and access rights";
3349 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3353 //================================================================================
3355 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3356 * \param file - file name
3357 * \param overwrite - to erase the file or not
3358 * \retval string - mesh name
3360 //================================================================================
3362 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3363 CORBA::Boolean overwrite)
3366 PrepareForWriting(file, overwrite);
3367 string aMeshName = "Mesh";
3368 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3369 if ( !aStudy->_is_nil() ) {
3370 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3371 if ( !aMeshSO->_is_nil() ) {
3372 CORBA::String_var name = aMeshSO->GetName();
3374 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3375 if ( !aStudy->GetProperties()->IsLocked() )
3377 SALOMEDS::GenericAttribute_wrap anAttr;
3378 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3379 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3380 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3381 ASSERT(!aFileName->_is_nil());
3382 aFileName->SetValue(file);
3383 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3384 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3385 ASSERT(!aFileType->_is_nil());
3386 aFileType->SetValue("FICHIERMED");
3390 // Update Python script
3391 // set name of mesh before export
3392 TPythonDump() << _gen_i << ".SetName("
3393 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3395 // check names of groups
3401 //================================================================================
3403 * \brief Export to MED file
3405 //================================================================================
3407 void SMESH_Mesh_i::ExportMED(const char* file,
3408 CORBA::Boolean auto_groups,
3409 CORBA::Long version,
3410 CORBA::Boolean overwrite,
3411 CORBA::Boolean autoDimension)
3412 throw(SALOME::SALOME_Exception)
3414 //MESSAGE("MED minor version: "<< minor);
3417 _preMeshInfo->FullLoadFromFile();
3419 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3420 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3422 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3424 << "auto_groups=" <<auto_groups << ", "
3425 << "minor=" << version << ", "
3426 << "overwrite=" << overwrite << ", "
3427 << "meshPart=None, "
3428 << "autoDimension=" << autoDimension << " )";
3430 SMESH_CATCH( SMESH::throwCorbaException );
3433 //================================================================================
3435 * \brief Export a mesh to a SAUV file
3437 //================================================================================
3439 void SMESH_Mesh_i::ExportSAUV (const char* file,
3440 CORBA::Boolean auto_groups)
3441 throw(SALOME::SALOME_Exception)
3443 Unexpect aCatch(SALOME_SalomeException);
3445 _preMeshInfo->FullLoadFromFile();
3447 string aMeshName = prepareMeshNameAndGroups(file, true);
3448 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3449 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3450 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3454 //================================================================================
3456 * \brief Export a mesh to a DAT file
3458 //================================================================================
3460 void SMESH_Mesh_i::ExportDAT (const char *file)
3461 throw(SALOME::SALOME_Exception)
3463 Unexpect aCatch(SALOME_SalomeException);
3465 _preMeshInfo->FullLoadFromFile();
3467 // Update Python script
3468 // check names of groups
3470 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3473 PrepareForWriting(file);
3474 _impl->ExportDAT(file);
3477 //================================================================================
3479 * \brief Export a mesh to an UNV file
3481 //================================================================================
3483 void SMESH_Mesh_i::ExportUNV (const char *file)
3484 throw(SALOME::SALOME_Exception)
3486 Unexpect aCatch(SALOME_SalomeException);
3488 _preMeshInfo->FullLoadFromFile();
3490 // Update Python script
3491 // check names of groups
3493 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3496 PrepareForWriting(file);
3497 _impl->ExportUNV(file);
3500 //================================================================================
3502 * \brief Export a mesh to an STL file
3504 //================================================================================
3506 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3507 throw(SALOME::SALOME_Exception)
3509 Unexpect aCatch(SALOME_SalomeException);
3511 _preMeshInfo->FullLoadFromFile();
3513 // Update Python script
3514 // check names of groups
3516 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3517 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3519 CORBA::String_var name;
3520 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3521 if ( !so->_is_nil() )
3522 name = so->GetName();
3525 PrepareForWriting( file );
3526 _impl->ExportSTL( file, isascii, name.in() );
3529 //================================================================================
3531 * \brief Export a part of mesh to a med file
3533 //================================================================================
3535 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3537 CORBA::Boolean auto_groups,
3538 CORBA::Long version,
3539 CORBA::Boolean overwrite,
3540 CORBA::Boolean autoDimension,
3541 const GEOM::ListOfFields& fields,
3542 const char* geomAssocFields,
3543 CORBA::Double ZTolerance)
3544 throw (SALOME::SALOME_Exception)
3546 MESSAGE("MED version: "<< version);
3549 _preMeshInfo->FullLoadFromFile();
3552 bool have0dField = false;
3553 if ( fields.length() > 0 )
3555 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3556 if ( shapeToMesh->_is_nil() )
3557 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3559 for ( size_t i = 0; i < fields.length(); ++i )
3561 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3562 THROW_SALOME_CORBA_EXCEPTION
3563 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3564 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3565 if ( fieldShape->_is_nil() )
3566 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3567 if ( !fieldShape->IsSame( shapeToMesh ) )
3568 THROW_SALOME_CORBA_EXCEPTION
3569 ( "Field defined not on shape", SALOME::BAD_PARAM);
3570 if ( fields[i]->GetDimension() == 0 )
3573 if ( geomAssocFields )
3574 for ( int i = 0; geomAssocFields[i]; ++i )
3575 switch ( geomAssocFields[i] ) {
3576 case 'v':case 'e':case 'f':case 's': break;
3577 case 'V':case 'E':case 'F':case 'S': break;
3578 default: THROW_SALOME_CORBA_EXCEPTION
3579 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3583 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3587 string aMeshName = "Mesh";
3588 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3589 if ( CORBA::is_nil( meshPart ) ||
3590 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3592 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3593 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3594 0, autoDimension, /*addODOnVertices=*/have0dField,
3596 meshDS = _impl->GetMeshDS();
3601 _preMeshInfo->FullLoadFromFile();
3603 PrepareForWriting(file, overwrite);
3605 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3606 if ( !SO->_is_nil() ) {
3607 CORBA::String_var name = SO->GetName();
3611 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3612 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3613 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3614 meshDS = tmpDSDeleter._obj = partDS;
3619 if ( _impl->HasShapeToMesh() )
3621 DriverMED_W_Field fieldWriter;
3622 fieldWriter.SetFile( file );
3623 fieldWriter.SetMeshName( aMeshName );
3624 fieldWriter.AddODOnVertices( have0dField );
3626 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3630 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3631 goList->length( fields.length() );
3632 for ( size_t i = 0; i < fields.length(); ++i )
3634 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3637 TPythonDump() << _this() << ".ExportPartToMED( "
3638 << meshPart << ", r'"
3640 << auto_groups << ", "
3642 << overwrite << ", "
3643 << autoDimension << ", "
3645 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3646 << TVar( ZTolerance )
3649 SMESH_CATCH( SMESH::throwCorbaException );
3652 //================================================================================
3654 * Write GEOM fields to MED file
3656 //================================================================================
3658 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3659 SMESHDS_Mesh* meshDS,
3660 const GEOM::ListOfFields& fields,
3661 const char* geomAssocFields)
3663 #define METH "SMESH_Mesh_i::exportMEDFields() "
3665 if (( fields.length() < 1 ) &&
3666 ( !geomAssocFields || !geomAssocFields[0] ))
3669 std::vector< std::vector< double > > dblVals;
3670 std::vector< std::vector< int > > intVals;
3671 std::vector< int > subIdsByDim[ 4 ];
3672 const double noneDblValue = 0.;
3673 const double noneIntValue = 0;
3675 for ( size_t iF = 0; iF < fields.length(); ++iF )
3679 int dim = fields[ iF ]->GetDimension();
3680 SMDSAbs_ElementType elemType;
3681 TopAbs_ShapeEnum shapeType;
3683 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3684 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3685 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3686 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3688 continue; // skip fields on whole shape
3690 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3691 if ( dataType == GEOM::FDT_String )
3693 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3694 if ( stepIDs->length() < 1 )
3696 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3697 if ( comps->length() < 1 )
3699 CORBA::String_var name = fields[ iF ]->GetName();
3701 if ( !fieldWriter.Set( meshDS,
3705 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3708 for ( size_t iC = 0; iC < comps->length(); ++iC )
3709 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3711 dblVals.resize( comps->length() );
3712 intVals.resize( comps->length() );
3714 // find sub-shape IDs
3716 std::vector< int >& subIds = subIdsByDim[ dim ];
3717 if ( subIds.empty() )
3718 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3719 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3720 subIds.push_back( id );
3724 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3728 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3730 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3731 if ( step->_is_nil() )
3734 CORBA::Long stamp = step->GetStamp();
3735 CORBA::Long id = step->GetID();
3736 fieldWriter.SetDtIt( int( stamp ), int( id ));
3738 // fill dblVals or intVals
3739 for ( size_t iC = 0; iC < comps->length(); ++iC )
3740 if ( dataType == GEOM::FDT_Double )
3742 dblVals[ iC ].clear();
3743 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3747 intVals[ iC ].clear();
3748 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3752 case GEOM::FDT_Double:
3754 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3755 if ( dblStep->_is_nil() ) continue;
3756 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3757 if ( vv->length() != subIds.size() * comps->length() )
3758 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3759 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3760 for ( size_t iC = 0; iC < comps->length(); ++iC )
3761 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3766 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3767 if ( intStep->_is_nil() ) continue;
3768 GEOM::ListOfLong_var vv = intStep->GetValues();
3769 if ( vv->length() != subIds.size() * comps->length() )
3770 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3771 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3772 for ( size_t iC = 0; iC < comps->length(); ++iC )
3773 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3776 case GEOM::FDT_Bool:
3778 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3779 if ( boolStep->_is_nil() ) continue;
3780 GEOM::short_array_var vv = boolStep->GetValues();
3781 if ( vv->length() != subIds.size() * comps->length() )
3782 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3783 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3784 for ( size_t iC = 0; iC < comps->length(); ++iC )
3785 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3791 // pass values to fieldWriter
3792 elemIt = fieldWriter.GetOrderedElems();
3793 if ( dataType == GEOM::FDT_Double )
3794 while ( elemIt->more() )
3796 const SMDS_MeshElement* e = elemIt->next();
3797 const int shapeID = e->getshapeId();
3798 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3799 for ( size_t iC = 0; iC < comps->length(); ++iC )
3800 fieldWriter.AddValue( noneDblValue );
3802 for ( size_t iC = 0; iC < comps->length(); ++iC )
3803 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3806 while ( elemIt->more() )
3808 const SMDS_MeshElement* e = elemIt->next();
3809 const int shapeID = e->getshapeId();
3810 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3811 for ( size_t iC = 0; iC < comps->length(); ++iC )
3812 fieldWriter.AddValue( (double) noneIntValue );
3814 for ( size_t iC = 0; iC < comps->length(); ++iC )
3815 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3819 fieldWriter.Perform();
3820 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3821 if ( res && res->IsKO() )
3823 if ( res->myComment.empty() )
3824 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3826 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3832 if ( !geomAssocFields || !geomAssocFields[0] )
3835 // write geomAssocFields
3837 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3838 shapeDim[ TopAbs_COMPOUND ] = 3;
3839 shapeDim[ TopAbs_COMPSOLID ] = 3;
3840 shapeDim[ TopAbs_SOLID ] = 3;
3841 shapeDim[ TopAbs_SHELL ] = 2;
3842 shapeDim[ TopAbs_FACE ] = 2;
3843 shapeDim[ TopAbs_WIRE ] = 1;
3844 shapeDim[ TopAbs_EDGE ] = 1;
3845 shapeDim[ TopAbs_VERTEX ] = 0;
3846 shapeDim[ TopAbs_SHAPE ] = 3;
3848 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3850 std::vector< std::string > compNames;
3851 switch ( geomAssocFields[ iF ]) {
3853 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3854 compNames.push_back( "dim" );
3857 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3860 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3863 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3867 compNames.push_back( "id" );
3868 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3869 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3871 fieldWriter.SetDtIt( -1, -1 );
3873 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3877 if ( compNames.size() == 2 ) // _vertices_
3878 while ( elemIt->more() )
3880 const SMDS_MeshElement* e = elemIt->next();
3881 const int shapeID = e->getshapeId();
3884 fieldWriter.AddValue( (double) -1 );
3885 fieldWriter.AddValue( (double) -1 );
3889 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3890 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3891 fieldWriter.AddValue( (double) shapeID );
3895 while ( elemIt->more() )
3897 const SMDS_MeshElement* e = elemIt->next();
3898 const int shapeID = e->getshapeId();
3900 fieldWriter.AddValue( (double) -1 );
3902 fieldWriter.AddValue( (double) shapeID );
3906 fieldWriter.Perform();
3907 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3908 if ( res && res->IsKO() )
3910 if ( res->myComment.empty() )
3911 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3913 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3916 } // loop on geomAssocFields
3921 //================================================================================
3923 * \brief Export a part of mesh to a DAT file
3925 //================================================================================
3927 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3929 throw (SALOME::SALOME_Exception)
3931 Unexpect aCatch(SALOME_SalomeException);
3933 _preMeshInfo->FullLoadFromFile();
3935 PrepareForWriting(file);
3937 SMESH_MeshPartDS partDS( meshPart );
3938 _impl->ExportDAT(file,&partDS);
3940 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3941 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3943 //================================================================================
3945 * \brief Export a part of mesh to an UNV file
3947 //================================================================================
3949 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3951 throw (SALOME::SALOME_Exception)
3953 Unexpect aCatch(SALOME_SalomeException);
3955 _preMeshInfo->FullLoadFromFile();
3957 PrepareForWriting(file);
3959 SMESH_MeshPartDS partDS( meshPart );
3960 _impl->ExportUNV(file, &partDS);
3962 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3963 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3965 //================================================================================
3967 * \brief Export a part of mesh to an STL file
3969 //================================================================================
3971 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3973 ::CORBA::Boolean isascii)
3974 throw (SALOME::SALOME_Exception)
3976 Unexpect aCatch(SALOME_SalomeException);
3978 _preMeshInfo->FullLoadFromFile();
3980 PrepareForWriting(file);
3982 CORBA::String_var name;
3983 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3984 if ( !so->_is_nil() )
3985 name = so->GetName();
3987 SMESH_MeshPartDS partDS( meshPart );
3988 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3990 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3991 << meshPart<< ", r'" << file << "', " << isascii << ")";
3994 //================================================================================
3996 * \brief Export a part of mesh to an STL file
3998 //================================================================================
4000 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4002 CORBA::Boolean overwrite,
4003 CORBA::Boolean groupElemsByType)
4004 throw (SALOME::SALOME_Exception)
4007 Unexpect aCatch(SALOME_SalomeException);
4009 _preMeshInfo->FullLoadFromFile();
4011 PrepareForWriting(file,overwrite);
4013 std::string meshName("");
4014 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4015 if ( !so->_is_nil() )
4017 CORBA::String_var name = so->GetName();
4018 meshName = name.in();
4022 SMESH_MeshPartDS partDS( meshPart );
4023 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4025 SMESH_CATCH( SMESH::throwCorbaException );
4027 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4028 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4030 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4034 //================================================================================
4036 * \brief Export a part of mesh to a GMF file
4038 //================================================================================
4040 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4042 bool withRequiredGroups)
4043 throw (SALOME::SALOME_Exception)
4045 Unexpect aCatch(SALOME_SalomeException);
4047 _preMeshInfo->FullLoadFromFile();
4049 PrepareForWriting(file,/*overwrite=*/true);
4051 SMESH_MeshPartDS partDS( meshPart );
4052 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4054 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4055 << meshPart<< ", r'"
4057 << withRequiredGroups << ")";
4060 //=============================================================================
4062 * Return computation progress [0.,1]
4064 //=============================================================================
4066 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4070 return _impl->GetComputeProgress();
4072 SMESH_CATCH( SMESH::doNothing );
4076 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4078 Unexpect aCatch(SALOME_SalomeException);
4080 return _preMeshInfo->NbNodes();
4082 return _impl->NbNodes();
4085 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4087 Unexpect aCatch(SALOME_SalomeException);
4089 return _preMeshInfo->NbElements();
4091 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4094 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4096 Unexpect aCatch(SALOME_SalomeException);
4098 return _preMeshInfo->Nb0DElements();
4100 return _impl->Nb0DElements();
4103 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4105 Unexpect aCatch(SALOME_SalomeException);
4107 return _preMeshInfo->NbBalls();
4109 return _impl->NbBalls();
4112 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4114 Unexpect aCatch(SALOME_SalomeException);
4116 return _preMeshInfo->NbEdges();
4118 return _impl->NbEdges();
4121 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4122 throw(SALOME::SALOME_Exception)
4124 Unexpect aCatch(SALOME_SalomeException);
4126 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4128 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4131 //=============================================================================
4133 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4135 Unexpect aCatch(SALOME_SalomeException);
4137 return _preMeshInfo->NbFaces();
4139 return _impl->NbFaces();
4142 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4144 Unexpect aCatch(SALOME_SalomeException);
4146 return _preMeshInfo->NbTriangles();
4148 return _impl->NbTriangles();
4151 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4153 Unexpect aCatch(SALOME_SalomeException);
4155 return _preMeshInfo->NbBiQuadTriangles();
4157 return _impl->NbBiQuadTriangles();
4160 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4162 Unexpect aCatch(SALOME_SalomeException);
4164 return _preMeshInfo->NbQuadrangles();
4166 return _impl->NbQuadrangles();
4169 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4171 Unexpect aCatch(SALOME_SalomeException);
4173 return _preMeshInfo->NbBiQuadQuadrangles();
4175 return _impl->NbBiQuadQuadrangles();
4178 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4180 Unexpect aCatch(SALOME_SalomeException);
4182 return _preMeshInfo->NbPolygons();
4184 return _impl->NbPolygons();
4187 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4189 Unexpect aCatch(SALOME_SalomeException);
4191 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4193 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4196 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4197 throw(SALOME::SALOME_Exception)
4199 Unexpect aCatch(SALOME_SalomeException);
4201 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4203 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4206 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4207 throw(SALOME::SALOME_Exception)
4209 Unexpect aCatch(SALOME_SalomeException);
4211 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4213 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4216 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4217 throw(SALOME::SALOME_Exception)
4219 Unexpect aCatch(SALOME_SalomeException);
4221 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4223 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4226 //=============================================================================
4228 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4230 Unexpect aCatch(SALOME_SalomeException);
4232 return _preMeshInfo->NbVolumes();
4234 return _impl->NbVolumes();
4237 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4239 Unexpect aCatch(SALOME_SalomeException);
4241 return _preMeshInfo->NbTetras();
4243 return _impl->NbTetras();
4246 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4248 Unexpect aCatch(SALOME_SalomeException);
4250 return _preMeshInfo->NbHexas();
4252 return _impl->NbHexas();
4255 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4257 Unexpect aCatch(SALOME_SalomeException);
4259 return _preMeshInfo->NbTriQuadHexas();
4261 return _impl->NbTriQuadraticHexas();
4264 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4266 Unexpect aCatch(SALOME_SalomeException);
4268 return _preMeshInfo->NbPyramids();
4270 return _impl->NbPyramids();
4273 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4275 Unexpect aCatch(SALOME_SalomeException);
4277 return _preMeshInfo->NbPrisms();
4279 return _impl->NbPrisms();
4282 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4284 Unexpect aCatch(SALOME_SalomeException);
4286 return _preMeshInfo->NbHexPrisms();
4288 return _impl->NbHexagonalPrisms();
4291 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4293 Unexpect aCatch(SALOME_SalomeException);
4295 return _preMeshInfo->NbPolyhedrons();
4297 return _impl->NbPolyhedrons();
4300 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4301 throw(SALOME::SALOME_Exception)
4303 Unexpect aCatch(SALOME_SalomeException);
4305 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4307 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4310 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4311 throw(SALOME::SALOME_Exception)
4313 Unexpect aCatch(SALOME_SalomeException);
4315 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4317 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4320 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4321 throw(SALOME::SALOME_Exception)
4323 Unexpect aCatch(SALOME_SalomeException);
4325 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4327 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4330 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4331 throw(SALOME::SALOME_Exception)
4333 Unexpect aCatch(SALOME_SalomeException);
4335 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4337 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4340 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4341 throw(SALOME::SALOME_Exception)
4343 Unexpect aCatch(SALOME_SalomeException);
4345 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4347 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4350 //=============================================================================
4352 * Returns nb of published sub-meshes
4354 //=============================================================================
4356 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4358 Unexpect aCatch(SALOME_SalomeException);
4359 return _mapSubMesh_i.size();
4362 //=============================================================================
4364 * Dumps mesh into a string
4366 //=============================================================================
4368 char* SMESH_Mesh_i::Dump()
4372 return CORBA::string_dup( os.str().c_str() );
4375 //=============================================================================
4377 * Method of SMESH_IDSource interface
4379 //=============================================================================
4381 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4383 return GetElementsId();
4386 //=============================================================================
4388 * Returns ids of all elements
4390 //=============================================================================
4392 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4393 throw (SALOME::SALOME_Exception)
4395 Unexpect aCatch(SALOME_SalomeException);
4397 _preMeshInfo->FullLoadFromFile();
4399 SMESH::long_array_var aResult = new SMESH::long_array();
4400 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4402 if ( aSMESHDS_Mesh == NULL )
4403 return aResult._retn();
4405 long nbElements = NbElements();
4406 aResult->length( nbElements );
4407 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4408 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4409 aResult[i] = anIt->next()->GetID();
4411 return aResult._retn();
4415 //=============================================================================
4417 * Returns ids of all elements of given type
4419 //=============================================================================
4421 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4422 throw (SALOME::SALOME_Exception)
4424 Unexpect aCatch(SALOME_SalomeException);
4426 _preMeshInfo->FullLoadFromFile();
4428 SMESH::long_array_var aResult = new SMESH::long_array();
4429 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4431 if ( aSMESHDS_Mesh == NULL )
4432 return aResult._retn();
4434 long nbElements = NbElements();
4436 // No sense in returning ids of elements along with ids of nodes:
4437 // when theElemType == SMESH::ALL, return node ids only if
4438 // there are no elements
4439 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4440 return GetNodesId();
4442 aResult->length( nbElements );
4446 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4447 while ( i < nbElements && anIt->more() )
4448 aResult[i++] = anIt->next()->GetID();
4450 aResult->length( i );
4452 return aResult._retn();
4455 //=============================================================================
4457 * Returns ids of all nodes
4459 //=============================================================================
4461 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4462 throw (SALOME::SALOME_Exception)
4464 Unexpect aCatch(SALOME_SalomeException);
4466 _preMeshInfo->FullLoadFromFile();
4468 SMESH::long_array_var aResult = new SMESH::long_array();
4469 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4471 if ( aMeshDS == NULL )
4472 return aResult._retn();
4474 long nbNodes = NbNodes();
4475 aResult->length( nbNodes );
4476 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4477 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4478 aResult[i] = anIt->next()->GetID();
4480 return aResult._retn();
4483 //=============================================================================
4487 //=============================================================================
4489 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4490 throw (SALOME::SALOME_Exception)
4492 SMESH::ElementType type = SMESH::ALL;
4496 _preMeshInfo->FullLoadFromFile();
4498 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4500 SMESH_CATCH( SMESH::throwCorbaException );
4505 //=============================================================================
4509 //=============================================================================
4511 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4512 throw (SALOME::SALOME_Exception)
4515 _preMeshInfo->FullLoadFromFile();
4517 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4519 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4521 return ( SMESH::EntityType ) e->GetEntityType();
4524 //=============================================================================
4528 //=============================================================================
4530 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4531 throw (SALOME::SALOME_Exception)
4534 _preMeshInfo->FullLoadFromFile();
4536 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4538 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4540 return ( SMESH::GeometryType ) e->GetGeomType();
4543 //=============================================================================
4545 * Returns ID of elements for given submesh
4547 //=============================================================================
4548 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4549 throw (SALOME::SALOME_Exception)
4551 SMESH::long_array_var aResult = new SMESH::long_array();
4555 _preMeshInfo->FullLoadFromFile();
4557 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4558 if(!SM) return aResult._retn();
4560 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4561 if(!SDSM) return aResult._retn();
4563 aResult->length(SDSM->NbElements());
4565 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4567 while ( eIt->more() ) {
4568 aResult[i++] = eIt->next()->GetID();
4571 SMESH_CATCH( SMESH::throwCorbaException );
4573 return aResult._retn();
4576 //=============================================================================
4578 * Returns ID of nodes for given submesh
4579 * If param all==true - returns all nodes, else -
4580 * returns only nodes on shapes.
4582 //=============================================================================
4584 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4586 throw (SALOME::SALOME_Exception)
4588 SMESH::long_array_var aResult = new SMESH::long_array();
4592 _preMeshInfo->FullLoadFromFile();
4594 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4595 if(!SM) return aResult._retn();
4597 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4598 if(!SDSM) return aResult._retn();
4601 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4602 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4603 while ( nIt->more() ) {
4604 const SMDS_MeshNode* elem = nIt->next();
4605 theElems.insert( elem->GetID() );
4608 else { // all nodes of submesh elements
4609 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4610 while ( eIt->more() ) {
4611 const SMDS_MeshElement* anElem = eIt->next();
4612 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4613 while ( nIt->more() ) {
4614 const SMDS_MeshElement* elem = nIt->next();
4615 theElems.insert( elem->GetID() );
4620 aResult->length(theElems.size());
4621 set<int>::iterator itElem;
4623 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4624 aResult[i++] = *itElem;
4626 SMESH_CATCH( SMESH::throwCorbaException );
4628 return aResult._retn();
4631 //=============================================================================
4633 * Returns type of elements for given submesh
4635 //=============================================================================
4637 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4638 throw (SALOME::SALOME_Exception)
4640 SMESH::ElementType type = SMESH::ALL;
4644 _preMeshInfo->FullLoadFromFile();
4646 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4647 if(!SM) return SMESH::ALL;
4649 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4650 if(!SDSM) return SMESH::ALL;
4652 if(SDSM->NbElements()==0)
4653 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4655 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4656 const SMDS_MeshElement* anElem = eIt->next();
4658 type = ( SMESH::ElementType ) anElem->GetType();
4660 SMESH_CATCH( SMESH::throwCorbaException );
4666 //=============================================================================
4668 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4670 //=============================================================================
4672 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4675 _preMeshInfo->FullLoadFromFile();
4677 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4678 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4683 //=============================================================================
4685 * Get XYZ coordinates of node as list of double
4686 * If there is not node for given ID - returns empty list
4688 //=============================================================================
4690 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4693 _preMeshInfo->FullLoadFromFile();
4695 SMESH::double_array_var aResult = new SMESH::double_array();
4696 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4697 if ( aMeshDS == NULL )
4698 return aResult._retn();
4701 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4703 return aResult._retn();
4707 aResult[0] = aNode->X();
4708 aResult[1] = aNode->Y();
4709 aResult[2] = aNode->Z();
4710 return aResult._retn();
4714 //=============================================================================
4716 * For given node returns list of IDs of inverse elements
4717 * If there is not node for given ID - returns empty list
4719 //=============================================================================
4721 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4722 SMESH::ElementType elemType)
4725 _preMeshInfo->FullLoadFromFile();
4727 SMESH::long_array_var aResult = new SMESH::long_array();
4728 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4729 if ( aMeshDS == NULL )
4730 return aResult._retn();
4733 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4735 return aResult._retn();
4737 // find inverse elements
4738 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4739 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4740 aResult->length( aNode->NbInverseElements( type ));
4741 for( int i = 0; eIt->more(); ++i )
4743 const SMDS_MeshElement* elem = eIt->next();
4744 aResult[ i ] = elem->GetID();
4746 return aResult._retn();
4749 //=============================================================================
4751 * \brief Return position of a node on shape
4753 //=============================================================================
4755 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4758 _preMeshInfo->FullLoadFromFile();
4760 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4761 aNodePosition->shapeID = 0;
4762 aNodePosition->shapeType = GEOM::SHAPE;
4764 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4765 if ( !mesh ) return aNodePosition;
4767 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4769 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4771 aNodePosition->shapeID = aNode->getshapeId();
4772 switch ( pos->GetTypeOfPosition() ) {
4774 aNodePosition->shapeType = GEOM::EDGE;
4775 aNodePosition->params.length(1);
4776 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4778 case SMDS_TOP_FACE: {
4779 SMDS_FacePositionPtr fPos = pos;
4780 aNodePosition->shapeType = GEOM::FACE;
4781 aNodePosition->params.length(2);
4782 aNodePosition->params[0] = fPos->GetUParameter();
4783 aNodePosition->params[1] = fPos->GetVParameter();
4786 case SMDS_TOP_VERTEX:
4787 aNodePosition->shapeType = GEOM::VERTEX;
4789 case SMDS_TOP_3DSPACE:
4790 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4791 aNodePosition->shapeType = GEOM::SOLID;
4792 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4793 aNodePosition->shapeType = GEOM::SHELL;
4799 return aNodePosition;
4802 //=============================================================================
4804 * \brief Return position of an element on shape
4806 //=============================================================================
4808 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4811 _preMeshInfo->FullLoadFromFile();
4813 SMESH::ElementPosition anElementPosition;
4814 anElementPosition.shapeID = 0;
4815 anElementPosition.shapeType = GEOM::SHAPE;
4817 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4818 if ( !mesh ) return anElementPosition;
4820 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4822 anElementPosition.shapeID = anElem->getshapeId();
4823 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4824 if ( !aSp.IsNull() ) {
4825 switch ( aSp.ShapeType() ) {
4827 anElementPosition.shapeType = GEOM::EDGE;
4830 anElementPosition.shapeType = GEOM::FACE;
4833 anElementPosition.shapeType = GEOM::VERTEX;
4836 anElementPosition.shapeType = GEOM::SOLID;
4839 anElementPosition.shapeType = GEOM::SHELL;
4845 return anElementPosition;
4848 //=============================================================================
4850 * If given element is node returns IDs of shape from position
4851 * If there is not node for given ID - returns -1
4853 //=============================================================================
4855 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4858 _preMeshInfo->FullLoadFromFile();
4860 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4861 if ( aMeshDS == NULL )
4865 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4867 return aNode->getshapeId();
4874 //=============================================================================
4876 * For given element returns ID of result shape after
4877 * ::FindShape() from SMESH_MeshEditor
4878 * If there is not element for given ID - returns -1
4880 //=============================================================================
4882 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4885 _preMeshInfo->FullLoadFromFile();
4887 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4888 if ( aMeshDS == NULL )
4891 // try to find element
4892 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4896 ::SMESH_MeshEditor aMeshEditor(_impl);
4897 int index = aMeshEditor.FindShape( elem );
4905 //=============================================================================
4907 * Returns number of nodes for given element
4908 * If there is not element for given ID - returns -1
4910 //=============================================================================
4912 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4915 _preMeshInfo->FullLoadFromFile();
4917 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4918 if ( aMeshDS == NULL ) return -1;
4919 // try to find element
4920 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4921 if(!elem) return -1;
4922 return elem->NbNodes();
4926 //=============================================================================
4928 * Returns ID of node by given index for given element
4929 * If there is not element for given ID - returns -1
4930 * If there is not node for given index - returns -2
4932 //=============================================================================
4934 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4937 _preMeshInfo->FullLoadFromFile();
4939 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4940 if ( aMeshDS == NULL ) return -1;
4941 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4942 if(!elem) return -1;
4943 if( index>=elem->NbNodes() || index<0 ) return -1;
4944 return elem->GetNode(index)->GetID();
4947 //=============================================================================
4949 * Returns IDs of nodes of given element
4951 //=============================================================================
4953 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4956 _preMeshInfo->FullLoadFromFile();
4958 SMESH::long_array_var aResult = new SMESH::long_array();
4959 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4961 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4963 aResult->length( elem->NbNodes() );
4964 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4965 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
4966 aResult[ i ] = n->GetID();
4969 return aResult._retn();
4972 //=============================================================================
4974 * Returns true if given node is medium node
4975 * in given quadratic element
4977 //=============================================================================
4979 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4982 _preMeshInfo->FullLoadFromFile();
4984 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4985 if ( aMeshDS == NULL ) return false;
4987 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4988 if(!aNode) return false;
4989 // try to find element
4990 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4991 if(!elem) return false;
4993 return elem->IsMediumNode(aNode);
4997 //=============================================================================
4999 * Returns true if given node is medium node
5000 * in one of quadratic elements
5002 //=============================================================================
5004 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5005 SMESH::ElementType theElemType)
5008 _preMeshInfo->FullLoadFromFile();
5010 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5011 if ( aMeshDS == NULL ) return false;
5014 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5015 if(!aNode) return false;
5017 SMESH_MesherHelper aHelper( *(_impl) );
5019 SMDSAbs_ElementType aType;
5020 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5021 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5022 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5023 else aType = SMDSAbs_All;
5025 return aHelper.IsMedium(aNode,aType);
5029 //=============================================================================
5031 * Returns number of edges for given element
5033 //=============================================================================
5035 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5038 _preMeshInfo->FullLoadFromFile();
5040 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5041 if ( aMeshDS == NULL ) return -1;
5042 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5043 if(!elem) return -1;
5044 return elem->NbEdges();
5048 //=============================================================================
5050 * Returns number of faces for given element
5052 //=============================================================================
5054 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5057 _preMeshInfo->FullLoadFromFile();
5059 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5060 if ( aMeshDS == NULL ) return -1;
5061 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5062 if(!elem) return -1;
5063 return elem->NbFaces();
5066 //=======================================================================
5067 //function : GetElemFaceNodes
5068 //purpose : Returns nodes of given face (counted from zero) for given element.
5069 //=======================================================================
5071 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5072 CORBA::Short faceIndex)
5075 _preMeshInfo->FullLoadFromFile();
5077 SMESH::long_array_var aResult = new SMESH::long_array();
5078 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5080 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5082 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5083 if ( faceIndex < vtool.NbFaces() )
5085 aResult->length( vtool.NbFaceNodes( faceIndex ));
5086 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5087 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5088 aResult[ i ] = nn[ i ]->GetID();
5092 return aResult._retn();
5095 //=======================================================================
5096 //function : GetFaceNormal
5097 //purpose : Returns three components of normal of given mesh face.
5098 //=======================================================================
5100 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5101 CORBA::Boolean normalized)
5104 _preMeshInfo->FullLoadFromFile();
5106 SMESH::double_array_var aResult = new SMESH::double_array();
5108 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5111 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5113 aResult->length( 3 );
5114 aResult[ 0 ] = normal.X();
5115 aResult[ 1 ] = normal.Y();
5116 aResult[ 2 ] = normal.Z();
5119 return aResult._retn();
5122 //=======================================================================
5123 //function : FindElementByNodes
5124 //purpose : Returns an element based on all given nodes.
5125 //=======================================================================
5127 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5130 _preMeshInfo->FullLoadFromFile();
5132 CORBA::Long elemID(0);
5133 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5135 vector< const SMDS_MeshNode * > nn( nodes.length() );
5136 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5137 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5140 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5141 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5142 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5143 _impl->NbVolumes( ORDER_QUADRATIC )))
5144 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5146 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5151 //================================================================================
5153 * \brief Return elements including all given nodes.
5155 //================================================================================
5157 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5158 SMESH::ElementType elemType)
5161 _preMeshInfo->FullLoadFromFile();
5163 SMESH::long_array_var result = new SMESH::long_array();
5165 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5167 vector< const SMDS_MeshNode * > nn( nodes.length() );
5168 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5169 nn[i] = mesh->FindNode( nodes[i] );
5171 std::vector<const SMDS_MeshElement *> elems;
5172 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5173 result->length( elems.size() );
5174 for ( size_t i = 0; i < elems.size(); ++i )
5175 result[i] = elems[i]->GetID();
5177 return result._retn();
5180 //=============================================================================
5182 * Returns true if given element is polygon
5184 //=============================================================================
5186 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5189 _preMeshInfo->FullLoadFromFile();
5191 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5192 if ( aMeshDS == NULL ) return false;
5193 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5194 if(!elem) return false;
5195 return elem->IsPoly();
5199 //=============================================================================
5201 * Returns true if given element is quadratic
5203 //=============================================================================
5205 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5208 _preMeshInfo->FullLoadFromFile();
5210 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5211 if ( aMeshDS == NULL ) return false;
5212 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5213 if(!elem) return false;
5214 return elem->IsQuadratic();
5217 //=============================================================================
5219 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5221 //=============================================================================
5223 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5226 _preMeshInfo->FullLoadFromFile();
5228 if ( const SMDS_BallElement* ball =
5229 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5230 return ball->GetDiameter();
5235 //=============================================================================
5237 * Returns bary center for given element
5239 //=============================================================================
5241 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5244 _preMeshInfo->FullLoadFromFile();
5246 SMESH::double_array_var aResult = new SMESH::double_array();
5247 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5248 if ( aMeshDS == NULL )
5249 return aResult._retn();
5251 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5253 return aResult._retn();
5255 if(elem->GetType()==SMDSAbs_Volume) {
5256 SMDS_VolumeTool aTool;
5257 if(aTool.Set(elem)) {
5259 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5264 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5266 double x=0., y=0., z=0.;
5267 for(; anIt->more(); ) {
5269 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5283 return aResult._retn();
5286 //================================================================================
5288 * \brief Create a group of elements preventing computation of a sub-shape
5290 //================================================================================
5292 SMESH::ListOfGroups*
5293 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5294 const char* theGroupName )
5295 throw ( SALOME::SALOME_Exception )
5297 Unexpect aCatch(SALOME_SalomeException);
5299 if ( !theGroupName || strlen( theGroupName) == 0 )
5300 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5302 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5303 ::SMESH_MeshEditor::ElemFeatures elemType;
5305 // submesh by subshape id
5306 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5307 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5310 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5311 if ( error && error->HasBadElems() )
5313 // sort bad elements by type
5314 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5315 const list<const SMDS_MeshElement*>& badElems =
5316 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5317 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5318 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5319 for ( ; elemIt != elemEnd; ++elemIt )
5321 const SMDS_MeshElement* elem = *elemIt;
5322 if ( !elem ) continue;
5324 if ( elem->GetID() < 1 )
5326 // elem is a temporary element, make a real element
5327 vector< const SMDS_MeshNode* > nodes;
5328 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5329 while ( nIt->more() && elem )
5331 nodes.push_back( nIt->next() );
5332 if ( nodes.back()->GetID() < 1 )
5333 elem = 0; // a temporary element on temporary nodes
5337 ::SMESH_MeshEditor editor( _impl );
5338 elem = editor.AddElement( nodes, elemType.Init( elem ));
5342 elemsByType[ elem->GetType() ].push_back( elem );
5345 // how many groups to create?
5347 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5348 nbTypes += int( !elemsByType[ i ].empty() );
5349 groups->length( nbTypes );
5352 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5354 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5355 if ( elems.empty() ) continue;
5357 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5358 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5360 SMESH::SMESH_Mesh_var mesh = _this();
5361 SALOMEDS::SObject_wrap aSO =
5362 _gen_i->PublishGroup( mesh, groups[ iG ],
5363 GEOM::GEOM_Object::_nil(), theGroupName);
5365 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5366 if ( !grp_i ) continue;
5368 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5369 for ( size_t iE = 0; iE < elems.size(); ++iE )
5370 grpDS->SMDSGroup().Add( elems[ iE ]);
5375 return groups._retn();
5378 //=============================================================================
5380 * Create and publish group servants if any groups were imported or created anyhow
5382 //=============================================================================
5384 void SMESH_Mesh_i::CreateGroupServants()
5386 SMESH::SMESH_Mesh_var aMesh = _this();
5389 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5390 while ( groupIt->more() )
5392 ::SMESH_Group* group = groupIt->next();
5393 int anId = group->GetID();
5395 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5396 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5398 addedIDs.insert( anId );
5400 SMESH_GroupBase_i* aGroupImpl;
5402 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5403 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5405 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5406 shape = groupOnGeom->GetShape();
5409 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5412 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5413 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5414 aGroupImpl->Register();
5416 // register CORBA object for persistence
5417 int nextId = _gen_i->RegisterObject( groupVar );
5418 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5419 else { nextId = 0; } // avoid "unused variable" warning in release mode
5421 // publishing the groups in the study
5422 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5423 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5425 if ( !addedIDs.empty() )
5428 set<int>::iterator id = addedIDs.begin();
5429 for ( ; id != addedIDs.end(); ++id )
5431 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5432 int i = std::distance( _mapGroups.begin(), it );
5433 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5438 //=============================================================================
5440 * \brief Return true if all sub-meshes are computed OK - to update an icon
5442 //=============================================================================
5444 bool SMESH_Mesh_i::IsComputedOK()
5446 return _impl->IsComputedOK();
5449 //=============================================================================
5451 * \brief Return groups cantained in _mapGroups by their IDs
5453 //=============================================================================
5455 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5457 int nbGroups = groupIDs.size();
5458 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5459 aList->length( nbGroups );
5461 list<int>::const_iterator ids = groupIDs.begin();
5462 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5464 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5465 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5466 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5468 aList->length( nbGroups );
5469 return aList._retn();
5472 //=============================================================================
5474 * \brief Return information about imported file
5476 //=============================================================================
5478 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5480 SMESH::MedFileInfo_var res( _medFileInfo );
5481 if ( !res.operator->() ) {
5482 res = new SMESH::MedFileInfo;
5484 res->fileSize = res->major = res->minor = res->release = -1;
5489 //=======================================================================
5490 //function : FileInfoToString
5491 //purpose : Persistence of file info
5492 //=======================================================================
5494 std::string SMESH_Mesh_i::FileInfoToString()
5497 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5499 s = SMESH_Comment( _medFileInfo->fileSize )
5500 << " " << _medFileInfo->major
5501 << " " << _medFileInfo->minor
5502 << " " << _medFileInfo->release
5503 << " " << _medFileInfo->fileName;
5508 //=======================================================================
5509 //function : FileInfoFromString
5510 //purpose : Persistence of file info
5511 //=======================================================================
5513 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5515 std::string size, major, minor, release, fileName;
5516 std::istringstream is(info);
5517 is >> size >> major >> minor >> release;
5518 fileName = info.data() + ( size.size() + 1 +
5521 release.size()+ 1 );
5523 _medFileInfo = new SMESH::MedFileInfo();
5524 _medFileInfo->fileName = fileName.c_str();
5525 _medFileInfo->fileSize = atoi( size.c_str() );
5526 _medFileInfo->major = atoi( major.c_str() );
5527 _medFileInfo->minor = atoi( minor.c_str() );
5528 _medFileInfo->release = atoi( release.c_str() );
5531 //=============================================================================
5533 * \brief Pass names of mesh groups from study to mesh DS
5535 //=============================================================================
5537 void SMESH_Mesh_i::checkGroupNames()
5539 int nbGrp = NbGroups();
5543 SMESH::ListOfGroups* grpList = 0;
5544 // avoid dump of "GetGroups"
5546 // store python dump into a local variable inside local scope
5547 SMESH::TPythonDump pDump; // do not delete this line of code
5548 grpList = GetGroups();
5551 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5552 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5555 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5556 if ( aGrpSO->_is_nil() )
5558 // correct name of the mesh group if necessary
5559 const char* guiName = aGrpSO->GetName();
5560 if ( strcmp(guiName, aGrp->GetName()) )
5561 aGrp->SetName( guiName );
5565 //=============================================================================
5567 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5569 //=============================================================================
5570 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5572 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5576 //=============================================================================
5578 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5580 //=============================================================================
5582 char* SMESH_Mesh_i::GetParameters()
5584 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5587 //=============================================================================
5589 * \brief Returns list of notebook variables used for last Mesh operation
5591 //=============================================================================
5592 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5594 SMESH::string_array_var aResult = new SMESH::string_array();
5595 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5597 CORBA::String_var aParameters = GetParameters();
5598 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5599 if ( aSections->length() > 0 ) {
5600 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5601 aResult->length( aVars.length() );
5602 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5603 aResult[i] = CORBA::string_dup( aVars[i] );
5606 return aResult._retn();
5609 //=======================================================================
5610 //function : GetTypes
5611 //purpose : Returns types of elements it contains
5612 //=======================================================================
5614 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5617 return _preMeshInfo->GetTypes();
5619 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5623 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5624 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5625 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5626 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5627 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5628 if (_impl->NbNodes() &&
5629 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5630 types->length( nbTypes );
5632 return types._retn();
5635 //=======================================================================
5636 //function : GetMesh
5637 //purpose : Returns self
5638 //=======================================================================
5640 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5642 return SMESH::SMESH_Mesh::_duplicate( _this() );
5645 //=======================================================================
5646 //function : IsMeshInfoCorrect
5647 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5648 // * happen if mesh data is not yet fully loaded from the file of study.
5649 //=======================================================================
5651 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5653 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5656 //=============================================================================
5658 * \brief Returns number of mesh elements per each \a EntityType
5660 //=============================================================================
5662 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5665 return _preMeshInfo->GetMeshInfo();
5667 SMESH::long_array_var aRes = new SMESH::long_array();
5668 aRes->length(SMESH::Entity_Last);
5669 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5671 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5673 return aRes._retn();
5674 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5675 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5676 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5677 return aRes._retn();
5680 //=============================================================================
5682 * \brief Returns number of mesh elements per each \a ElementType
5684 //=============================================================================
5686 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5688 SMESH::long_array_var aRes = new SMESH::long_array();
5689 aRes->length(SMESH::NB_ELEMENT_TYPES);
5690 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5693 const SMDS_MeshInfo* meshInfo = 0;
5695 meshInfo = _preMeshInfo;
5696 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5697 meshInfo = & meshDS->GetMeshInfo();
5700 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5701 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5703 return aRes._retn();
5706 //=============================================================================
5708 * Collect statistic of mesh elements given by iterator
5710 //=============================================================================
5712 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5713 SMESH::long_array& theInfo)
5715 if (!theItr) return;
5716 while (theItr->more())
5717 theInfo[ theItr->next()->GetEntityType() ]++;
5719 //=============================================================================
5721 * Returns mesh unstructed grid information.
5723 //=============================================================================
5725 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5727 SALOMEDS::TMPFile_var SeqFile;
5728 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5729 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5731 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5732 aWriter->WriteToOutputStringOn();
5733 aWriter->SetInputData(aGrid);
5734 aWriter->SetFileTypeToBinary();
5736 char* str = aWriter->GetOutputString();
5737 int size = aWriter->GetOutputStringLength();
5739 //Allocate octet buffer of required size
5740 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5741 //Copy ostrstream content to the octet buffer
5742 memcpy(OctetBuf, str, size);
5743 //Create and return TMPFile
5744 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5748 return SeqFile._retn();
5751 //=============================================================================
5752 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5753 * SMESH::ElementType type) */
5755 using namespace SMESH::Controls;
5756 //-----------------------------------------------------------------------------
5757 struct PredicateIterator : public SMDS_ElemIterator
5759 SMDS_ElemIteratorPtr _elemIter;
5760 PredicatePtr _predicate;
5761 const SMDS_MeshElement* _elem;
5762 SMDSAbs_ElementType _type;
5764 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5765 PredicatePtr predicate,
5766 SMDSAbs_ElementType type):
5767 _elemIter(iterator), _predicate(predicate), _type(type)
5775 virtual const SMDS_MeshElement* next()
5777 const SMDS_MeshElement* res = _elem;
5779 while ( _elemIter->more() && !_elem )
5781 if ((_elem = _elemIter->next()) &&
5782 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5783 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5790 //-----------------------------------------------------------------------------
5791 struct IDSourceIterator : public SMDS_ElemIterator
5793 const CORBA::Long* _idPtr;
5794 const CORBA::Long* _idEndPtr;
5795 SMESH::long_array_var _idArray;
5796 const SMDS_Mesh* _mesh;
5797 const SMDSAbs_ElementType _type;
5798 const SMDS_MeshElement* _elem;
5800 IDSourceIterator( const SMDS_Mesh* mesh,
5801 const CORBA::Long* ids,
5803 SMDSAbs_ElementType type):
5804 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5806 if ( _idPtr && nbIds && _mesh )
5809 IDSourceIterator( const SMDS_Mesh* mesh,
5810 SMESH::long_array* idArray,
5811 SMDSAbs_ElementType type):
5812 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5814 if ( idArray && _mesh )
5816 _idPtr = &_idArray[0];
5817 _idEndPtr = _idPtr + _idArray->length();
5825 virtual const SMDS_MeshElement* next()
5827 const SMDS_MeshElement* res = _elem;
5829 while ( _idPtr < _idEndPtr && !_elem )
5831 if ( _type == SMDSAbs_Node )
5833 _elem = _mesh->FindNode( *_idPtr++ );
5835 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5836 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5844 //-----------------------------------------------------------------------------
5846 struct NodeOfElemIterator : public SMDS_ElemIterator
5848 TColStd_MapOfInteger _checkedNodeIDs;
5849 SMDS_ElemIteratorPtr _elemIter;
5850 SMDS_ElemIteratorPtr _nodeIter;
5851 const SMDS_MeshElement* _node;
5853 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5855 if ( _elemIter && _elemIter->more() )
5857 _nodeIter = _elemIter->next()->nodesIterator();
5865 virtual const SMDS_MeshElement* next()
5867 const SMDS_MeshElement* res = _node;
5869 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5871 if ( _nodeIter->more() )
5873 _node = _nodeIter->next();
5874 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5879 _nodeIter = _elemIter->next()->nodesIterator();
5887 //=============================================================================
5889 * Return iterator on elements of given type in given object
5891 //=============================================================================
5893 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5894 SMESH::ElementType theType)
5896 SMDS_ElemIteratorPtr elemIt;
5897 bool typeOK = ( theType == SMESH::ALL );
5898 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5900 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5901 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5902 if ( !mesh_i ) return elemIt;
5903 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5905 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5907 elemIt = meshDS->elementsIterator( elemType );
5910 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5912 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5915 elemIt = sm->GetElements();
5916 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5918 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5919 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5923 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5925 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5926 if ( groupDS && ( elemType == groupDS->GetType() ||
5927 elemType == SMDSAbs_Node ||
5928 elemType == SMDSAbs_All ))
5930 elemIt = groupDS->GetElements();
5931 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5934 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5936 if ( filter_i->GetElementType() == theType ||
5937 filter_i->GetElementType() == SMESH::ALL ||
5938 elemType == SMDSAbs_Node ||
5939 elemType == SMDSAbs_All)
5941 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5942 if ( pred_i && pred_i->GetPredicate() )
5944 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5945 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5946 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
5947 elemIt = SMDS_ElemIteratorPtr
5948 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
5949 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
5955 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5956 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5957 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5959 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
5960 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5963 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5964 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
5968 SMESH::long_array_var ids = theObject->GetIDs();
5969 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
5971 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5974 if ( elemIt && elemIt->more() && !typeOK )
5976 if ( elemType == SMDSAbs_Node )
5978 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5982 elemIt = SMDS_ElemIteratorPtr();
5988 //=============================================================================
5989 namespace // Finding concurrent hypotheses
5990 //=============================================================================
5994 * \brief mapping of mesh dimension into shape type
5996 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5998 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6000 case 0: aType = TopAbs_VERTEX; break;
6001 case 1: aType = TopAbs_EDGE; break;
6002 case 2: aType = TopAbs_FACE; break;
6004 default:aType = TopAbs_SOLID; break;
6009 //-----------------------------------------------------------------------------
6011 * \brief Internal structure used to find concurrent submeshes
6013 * It represents a pair < submesh, concurrent dimension >, where
6014 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6015 * with another submesh. In other words, it is dimension of a hypothesis assigned
6022 int _dim; //!< a dimension the algo can build (concurrent dimension)
6023 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6024 TopTools_MapOfShape _shapeMap;
6025 SMESH_subMesh* _subMesh;
6026 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6028 //-----------------------------------------------------------------------------
6029 // Return the algorithm
6030 const SMESH_Algo* GetAlgo() const
6031 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6033 //-----------------------------------------------------------------------------
6035 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6037 const TopoDS_Shape& theShape)
6039 _subMesh = (SMESH_subMesh*)theSubMesh;
6040 SetShape( theDim, theShape );
6043 //-----------------------------------------------------------------------------
6045 void SetShape(const int theDim,
6046 const TopoDS_Shape& theShape)
6049 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6050 if (_dim >= _ownDim)
6051 _shapeMap.Add( theShape );
6053 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6054 for( ; anExp.More(); anExp.Next() )
6055 _shapeMap.Add( anExp.Current() );
6059 //-----------------------------------------------------------------------------
6060 //! Check sharing of sub-shapes
6061 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6062 const TopTools_MapOfShape& theToFind,
6063 const TopAbs_ShapeEnum theType)
6065 bool isShared = false;
6066 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6067 for (; !isShared && anItr.More(); anItr.Next() )
6069 const TopoDS_Shape aSubSh = anItr.Key();
6070 // check for case when concurrent dimensions are same
6071 isShared = theToFind.Contains( aSubSh );
6072 // check for sub-shape with concurrent dimension
6073 TopExp_Explorer anExp( aSubSh, theType );
6074 for ( ; !isShared && anExp.More(); anExp.Next() )
6075 isShared = theToFind.Contains( anExp.Current() );
6080 //-----------------------------------------------------------------------------
6081 //! check algorithms
6082 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6083 const SMESHDS_Hypothesis* theA2)
6085 if ( !theA1 || !theA2 ||
6086 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6087 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6088 return false; // one of the hypothesis is not algorithm
6089 // check algorithm names (should be equal)
6090 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6094 //-----------------------------------------------------------------------------
6095 //! Check if sub-shape hypotheses are concurrent
6096 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6098 if ( _subMesh == theOther->_subMesh )
6099 return false; // same sub-shape - should not be
6101 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6102 // any of the two submeshes is not on COMPOUND shape )
6103 // -> no concurrency
6104 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6105 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6106 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6107 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6108 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6111 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6112 if ( !checkSubShape )
6115 // check algorithms to be same
6116 const SMESH_Algo* a1 = this->GetAlgo();
6117 const SMESH_Algo* a2 = theOther->GetAlgo();
6118 bool isSame = checkAlgo( a1, a2 );
6122 return false; // pb?
6123 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6126 // check hypothesises for concurrence (skip first as algorithm)
6128 // pointers should be same, because it is referened from mesh hypothesis partition
6129 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6130 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6131 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6132 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6134 // the submeshes are concurrent if their algorithms has different parameters
6135 return nbSame != theOther->_hypotheses.size() - 1;
6138 // Return true if algorithm of this SMESH_DimHyp is used if no
6139 // sub-mesh order is imposed by the user
6140 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6142 // NeedDiscreteBoundary() algo has a higher priority
6143 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6144 theOther->GetAlgo()->NeedDiscreteBoundary() )
6145 return !this->GetAlgo()->NeedDiscreteBoundary();
6147 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6150 }; // end of SMESH_DimHyp
6151 //-----------------------------------------------------------------------------
6153 typedef list<const SMESH_DimHyp*> TDimHypList;
6155 //-----------------------------------------------------------------------------
6157 void addDimHypInstance(const int theDim,
6158 const TopoDS_Shape& theShape,
6159 const SMESH_Algo* theAlgo,
6160 const SMESH_subMesh* theSubMesh,
6161 const list <const SMESHDS_Hypothesis*>& theHypList,
6162 TDimHypList* theDimHypListArr )
6164 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6165 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6166 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6167 dimHyp->_hypotheses.push_front(theAlgo);
6168 listOfdimHyp.push_back( dimHyp );
6171 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6172 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6173 theHypList.begin(), theHypList.end() );
6176 //-----------------------------------------------------------------------------
6177 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6178 TDimHypList& theListOfConcurr)
6180 if ( theListOfConcurr.empty() )
6182 theListOfConcurr.push_back( theDimHyp );
6186 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6187 while ( hypIt != theListOfConcurr.end() &&
6188 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6190 theListOfConcurr.insert( hypIt, theDimHyp );
6194 //-----------------------------------------------------------------------------
6195 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6196 const TDimHypList& theListOfDimHyp,
6197 TDimHypList& theListOfConcurrHyp,
6198 set<int>& theSetOfConcurrId )
6200 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6201 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6203 const SMESH_DimHyp* curDimHyp = *rIt;
6204 if ( curDimHyp == theDimHyp )
6205 break; // meet own dimHyp pointer in same dimension
6207 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6208 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6210 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6215 //-----------------------------------------------------------------------------
6216 void unionLists(TListOfInt& theListOfId,
6217 TListOfListOfInt& theListOfListOfId,
6220 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6221 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6223 continue; //skip already treated lists
6224 // check if other list has any same submesh object
6225 TListOfInt& otherListOfId = *it;
6226 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6227 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6230 // union two lists (from source into target)
6231 TListOfInt::iterator it2 = otherListOfId.begin();
6232 for ( ; it2 != otherListOfId.end(); it2++ ) {
6233 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6234 theListOfId.push_back(*it2);
6236 // clear source list
6237 otherListOfId.clear();
6240 //-----------------------------------------------------------------------------
6242 //! free memory allocated for dimension-hypothesis objects
6243 void removeDimHyps( TDimHypList* theArrOfList )
6245 for (int i = 0; i < 4; i++ ) {
6246 TDimHypList& listOfdimHyp = theArrOfList[i];
6247 TDimHypList::const_iterator it = listOfdimHyp.begin();
6248 for ( ; it != listOfdimHyp.end(); it++ )
6253 //-----------------------------------------------------------------------------
6255 * \brief find common submeshes with given submesh
6256 * \param theSubMeshList list of already collected submesh to check
6257 * \param theSubMesh given submesh to intersect with other
6258 * \param theCommonSubMeshes collected common submeshes
6260 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6261 const SMESH_subMesh* theSubMesh,
6262 set<const SMESH_subMesh*>& theCommon )
6266 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6267 for ( ; it != theSubMeshList.end(); it++ )
6268 theSubMesh->FindIntersection( *it, theCommon );
6269 theSubMeshList.push_back( theSubMesh );
6270 //theCommon.insert( theSubMesh );
6273 //-----------------------------------------------------------------------------
6274 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6276 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6277 for ( ; listsIt != smLists.end(); ++listsIt )
6279 const TListOfInt& smIDs = *listsIt;
6280 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6288 //=============================================================================
6290 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6292 //=============================================================================
6294 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6296 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6297 if ( isSubMeshInList( submeshID, anOrder ))
6300 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6301 return isSubMeshInList( submeshID, allConurrent );
6304 //=============================================================================
6306 * \brief Return submesh objects list in meshing order
6308 //=============================================================================
6310 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6312 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6314 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6316 return aResult._retn();
6318 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6319 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6320 anOrder.splice( anOrder.end(), allConurrent );
6323 TListOfListOfInt::iterator listIt = anOrder.begin();
6324 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6325 unionLists( *listIt, anOrder, listIndx + 1 );
6327 // convert submesh ids into interface instances
6328 // and dump command into python
6329 convertMeshOrder( anOrder, aResult, false );
6331 return aResult._retn();
6334 //=============================================================================
6336 * \brief Finds concurrent sub-meshes
6338 //=============================================================================
6340 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6342 TListOfListOfInt anOrder;
6343 ::SMESH_Mesh& mesh = GetImpl();
6345 // collect submeshes and detect concurrent algorithms and hypothesises
6346 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6348 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6349 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6350 ::SMESH_subMesh* sm = (*i_sm).second;
6352 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6354 // list of assigned hypothesises
6355 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6356 // Find out dimensions where the submesh can be concurrent.
6357 // We define the dimensions by algo of each of hypotheses in hypList
6358 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6359 for( ; hypIt != hypList.end(); hypIt++ ) {
6360 SMESH_Algo* anAlgo = 0;
6361 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6362 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6363 // hyp it-self is algo
6364 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6366 // try to find algorithm with help of sub-shapes
6367 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6368 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6369 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6372 continue; // no algorithm assigned to a current submesh
6374 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6375 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6377 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6378 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6379 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6381 } // end iterations on submesh
6383 // iterate on created dimension-hypotheses and check for concurrents
6384 for ( int i = 0; i < 4; i++ ) {
6385 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6386 // check for concurrents in own and other dimensions (step-by-step)
6387 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6388 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6389 const SMESH_DimHyp* dimHyp = *dhIt;
6390 TDimHypList listOfConcurr;
6391 set<int> setOfConcurrIds;
6392 // looking for concurrents and collect into own list
6393 for ( int j = i; j < 4; j++ )
6394 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6395 // check if any concurrents found
6396 if ( listOfConcurr.size() > 0 ) {
6397 // add own submesh to list of concurrent
6398 addInOrderOfPriority( dimHyp, listOfConcurr );
6399 list<int> listOfConcurrIds;
6400 TDimHypList::iterator hypIt = listOfConcurr.begin();
6401 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6402 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6403 anOrder.push_back( listOfConcurrIds );
6408 removeDimHyps(dimHypListArr);
6410 // now, minimize the number of concurrent groups
6411 // Here we assume that lists of submeshes can have same submesh
6412 // in case of multi-dimension algorithms, as result
6413 // list with common submesh has to be united into one list
6415 TListOfListOfInt::iterator listIt = anOrder.begin();
6416 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6417 unionLists( *listIt, anOrder, listIndx + 1 );
6423 //=============================================================================
6425 * \brief Set submesh object order
6426 * \param theSubMeshArray submesh array order
6428 //=============================================================================
6430 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6433 _preMeshInfo->ForgetOrLoad();
6436 ::SMESH_Mesh& mesh = GetImpl();
6438 TPythonDump aPythonDump; // prevent dump of called methods
6439 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6441 TListOfListOfInt subMeshOrder;
6442 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6444 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6445 TListOfInt subMeshIds;
6447 aPythonDump << ", ";
6448 aPythonDump << "[ ";
6449 // Collect subMeshes which should be clear
6450 // do it list-by-list, because modification of submesh order
6451 // take effect between concurrent submeshes only
6452 set<const SMESH_subMesh*> subMeshToClear;
6453 list<const SMESH_subMesh*> subMeshList;
6454 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6456 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6458 aPythonDump << ", ";
6459 aPythonDump << subMesh;
6460 subMeshIds.push_back( subMesh->GetId() );
6461 // detect common parts of submeshes
6462 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6463 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6465 aPythonDump << " ]";
6466 subMeshOrder.push_back( subMeshIds );
6468 // clear collected sub-meshes
6469 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6470 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6471 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6473 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6474 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6475 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6478 aPythonDump << " ])";
6480 mesh.SetMeshOrder( subMeshOrder );
6483 SMESH::SMESH_Mesh_var me = _this();
6484 _gen_i->UpdateIcons( me );
6489 //=============================================================================
6491 * \brief Convert submesh ids into submesh interfaces
6493 //=============================================================================
6495 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6496 SMESH::submesh_array_array& theResOrder,
6497 const bool theIsDump)
6499 int nbSet = theIdsOrder.size();
6500 TPythonDump aPythonDump; // prevent dump of called methods
6502 aPythonDump << "[ ";
6503 theResOrder.length(nbSet);
6504 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6506 for( ; it != theIdsOrder.end(); it++ ) {
6507 // translate submesh identificators into submesh objects
6508 // takeing into account real number of concurrent lists
6509 const TListOfInt& aSubOrder = (*it);
6510 if (!aSubOrder.size())
6513 aPythonDump << "[ ";
6514 // convert shape indices into interfaces
6515 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6516 aResSubSet->length(aSubOrder.size());
6517 TListOfInt::const_iterator subIt = aSubOrder.begin();
6519 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6520 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6522 SMESH::SMESH_subMesh_var subMesh =
6523 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6526 aPythonDump << ", ";
6527 aPythonDump << subMesh;
6529 aResSubSet[ j++ ] = subMesh;
6532 aPythonDump << " ]";
6534 theResOrder[ listIndx++ ] = aResSubSet;
6536 // correct number of lists
6537 theResOrder.length( listIndx );
6540 // finilise python dump
6541 aPythonDump << " ]";
6542 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6546 namespace // utils used by SMESH_MeshPartDS
6549 * \brief Class used to access to protected data of SMDS_MeshInfo
6551 struct TMeshInfo : public SMDS_MeshInfo
6553 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6556 * \brief Element holing its ID only
6558 struct TElemID : public SMDS_LinearEdge
6560 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6564 //================================================================================
6566 // Implementation of SMESH_MeshPartDS
6568 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6569 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6571 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6572 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6575 _meshDS = mesh_i->GetImpl().GetMeshDS();
6577 SetPersistentId( _meshDS->GetPersistentId() );
6579 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6581 // <meshPart> is the whole mesh
6582 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6584 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6585 myGroupSet = _meshDS->GetGroups();
6590 SMESH::long_array_var anIDs = meshPart->GetIDs();
6591 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6592 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6594 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6595 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6596 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6601 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6602 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6603 if ( _elements[ e->GetType() ].insert( e ).second )
6606 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6607 while ( nIt->more() )
6609 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6610 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6617 ShapeToMesh( _meshDS->ShapeToMesh() );
6619 _meshDS = 0; // to enforce iteration on _elements and _nodes
6622 // -------------------------------------------------------------------------------------
6623 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6624 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6627 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6628 for ( ; partIt != meshPart.end(); ++partIt )
6629 if ( const SMDS_MeshElement * e = *partIt )
6630 if ( _elements[ e->GetType() ].insert( e ).second )
6633 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6634 while ( nIt->more() )
6636 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6637 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6643 // -------------------------------------------------------------------------------------
6644 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6646 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6648 TElemID elem( IDelem );
6649 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6650 if ( !_elements[ iType ].empty() )
6652 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6653 if ( it != _elements[ iType ].end() )
6658 // -------------------------------------------------------------------------------------
6659 bool SMESH_MeshPartDS::HasNumerationHoles()
6661 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6663 return ( MinNodeID() != 1 ||
6664 MaxNodeID() != NbNodes() ||
6665 MinElementID() != 1 ||
6666 MaxElementID() != NbElements() );
6668 // -------------------------------------------------------------------------------------
6669 int SMESH_MeshPartDS::MaxNodeID() const
6671 if ( _meshDS ) return _meshDS->MaxNodeID();
6672 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6674 // -------------------------------------------------------------------------------------
6675 int SMESH_MeshPartDS::MinNodeID() const
6677 if ( _meshDS ) return _meshDS->MinNodeID();
6678 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6680 // -------------------------------------------------------------------------------------
6681 int SMESH_MeshPartDS::MaxElementID() const
6683 if ( _meshDS ) return _meshDS->MaxElementID();
6685 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6686 if ( !_elements[ iType ].empty() )
6687 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6690 // -------------------------------------------------------------------------------------
6691 int SMESH_MeshPartDS::MinElementID() const
6693 if ( _meshDS ) return _meshDS->MinElementID();
6695 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6696 if ( !_elements[ iType ].empty() )
6697 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6700 // -------------------------------------------------------------------------------------
6701 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6703 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6705 typedef SMDS_SetIterator
6706 <const SMDS_MeshElement*,
6707 TIDSortedElemSet::const_iterator,
6708 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6709 SMDS_MeshElement::GeomFilter
6712 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6714 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6715 _elements[type].end(),
6716 SMDS_MeshElement::GeomFilter( geomType )));
6718 // -------------------------------------------------------------------------------------
6719 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6721 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6723 typedef SMDS_SetIterator
6724 <const SMDS_MeshElement*,
6725 TIDSortedElemSet::const_iterator,
6726 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6727 SMDS_MeshElement::EntityFilter
6730 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6732 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6733 _elements[type].end(),
6734 SMDS_MeshElement::EntityFilter( entity )));
6736 // -------------------------------------------------------------------------------------
6737 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6739 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6740 if ( type == SMDSAbs_All && !_meshDS )
6742 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6744 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6745 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6747 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6749 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6750 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6752 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6753 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6755 // -------------------------------------------------------------------------------------
6756 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6757 iterType SMESH_MeshPartDS::methName() const \
6759 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6760 return _meshDS ? _meshDS->methName() : iterType \
6761 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6763 // -------------------------------------------------------------------------------------
6764 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6765 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6766 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6767 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6768 #undef _GET_ITER_DEFINE
6770 // END Implementation of SMESH_MeshPartDS
6772 //================================================================================