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_DataMapOfShapeShape.hxx>
76 #include <TopTools_MapIteratorOfMapOfShape.hxx>
77 #include <TopTools_MapOfShape.hxx>
78 #include <TopoDS_Compound.hxx>
85 #include <vtkUnstructuredGridWriter.h>
87 // to pass CORBA exception through SMESH_TRY
88 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
90 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 static int MYDEBUG = 0;
95 static int MYDEBUG = 0;
99 using SMESH::TPythonDump;
102 int SMESH_Mesh_i::_idGenerator = 0;
104 //=============================================================================
108 //=============================================================================
110 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
112 : SALOME::GenericObj_i( thePOA )
116 _id = _idGenerator++;
118 _previewEditor = NULL;
123 //=============================================================================
127 //=============================================================================
129 SMESH_Mesh_i::~SMESH_Mesh_i()
132 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
133 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
134 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
136 aGroup->UnRegister();
137 SMESH::SMESH_GroupBase_var( itGr->second );
142 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
143 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
144 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
146 aSubMesh->UnRegister();
147 SMESH::SMESH_subMesh_var( itSM->second );
149 _mapSubMeshIor.clear();
151 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
152 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
153 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
154 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
155 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
156 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
159 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
163 // clear cached shapes if no more meshes remain; (the cache is blame,
164 // together with publishing, of spent time increasing in issue 22874)
165 if ( _impl->NbMeshes() == 1 )
166 _gen_i->GetShapeReader()->ClearClientBuffer();
168 delete _editor; _editor = NULL;
169 delete _previewEditor; _previewEditor = NULL;
170 delete _impl; _impl = NULL;
171 delete _preMeshInfo; _preMeshInfo = NULL;
174 //=============================================================================
178 * Associates <this> mesh with <theShape> and puts a reference
179 * to <theShape> into the current study;
180 * the previous shape is substituted by the new one.
182 //=============================================================================
184 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
185 throw (SALOME::SALOME_Exception)
187 Unexpect aCatch(SALOME_SalomeException);
189 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
191 catch(SALOME_Exception & S_ex) {
192 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
194 // to track changes of GEOM groups
195 SMESH::SMESH_Mesh_var mesh = _this();
196 addGeomGroupData( theShapeObject, mesh );
197 if ( !CORBA::is_nil( theShapeObject ))
198 _mainShapeTick = theShapeObject->GetTick();
201 //================================================================================
203 * \brief return true if mesh has a shape to build a shape on
205 //================================================================================
207 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
208 throw (SALOME::SALOME_Exception)
210 Unexpect aCatch(SALOME_SalomeException);
213 res = _impl->HasShapeToMesh();
215 catch(SALOME_Exception & S_ex) {
216 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
221 //=======================================================================
222 //function : GetShapeToMesh
224 //=======================================================================
226 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
227 throw (SALOME::SALOME_Exception)
229 Unexpect aCatch(SALOME_SalomeException);
230 GEOM::GEOM_Object_var aShapeObj;
232 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
236 if ( aShapeObj->_is_nil() )
238 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
239 // find GEOM_Object by entry (IPAL52735)
240 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
241 for ( ; data != _geomGroupData.end(); ++data )
242 if ( data->_smeshObject->_is_equivalent( _this() ))
244 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
245 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
246 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
252 catch(SALOME_Exception & S_ex) {
253 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
255 return aShapeObj._retn();
258 //================================================================================
260 * \brief Replaces a shape in the mesh
262 //================================================================================
263 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
264 throw (SALOME::SALOME_Exception)
266 TopoDS_Shape S = _impl->GetShapeToMesh();
267 GEOM_Client* geomClient = _gen_i->GetShapeReader();
268 TCollection_AsciiString aIOR;
269 if (geomClient->Find(S, aIOR)) {
270 geomClient->RemoveShapeFromBuffer(aIOR);
273 // re-assign global hypotheses to the new shape
275 CheckGeomModif( true );
278 //================================================================================
280 * \brief Return false if the mesh is not yet fully loaded from the study file
282 //================================================================================
284 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
286 Unexpect aCatch(SALOME_SalomeException);
287 return !_preMeshInfo;
290 //================================================================================
292 * \brief Load full mesh data from the study file
294 //================================================================================
296 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
298 Unexpect aCatch(SALOME_SalomeException);
300 _preMeshInfo->FullLoadFromFile();
303 //================================================================================
305 * \brief Remove all nodes and elements
307 //================================================================================
309 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
311 Unexpect aCatch(SALOME_SalomeException);
313 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
317 //CheckGeomGroupModif(); // issue 20145
319 catch(SALOME_Exception & S_ex) {
320 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
323 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
325 SMESH::SMESH_Mesh_var mesh = _this();
326 _gen_i->UpdateIcons( mesh );
329 //================================================================================
331 * \brief Remove all nodes and elements for indicated shape
333 //================================================================================
335 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
336 throw (SALOME::SALOME_Exception)
338 Unexpect aCatch(SALOME_SalomeException);
340 _preMeshInfo->FullLoadFromFile();
343 _impl->ClearSubMesh( ShapeID );
345 catch(SALOME_Exception & S_ex) {
346 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
348 _impl->GetMeshDS()->Modified();
350 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
353 //=============================================================================
355 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
357 //=============================================================================
359 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
361 SMESH::DriverMED_ReadStatus res;
364 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
365 res = SMESH::DRS_OK; break;
366 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
367 res = SMESH::DRS_EMPTY; break;
368 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
369 res = SMESH::DRS_WARN_RENUMBER; break;
370 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
371 res = SMESH::DRS_WARN_SKIP_ELEM; break;
372 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
373 res = SMESH::DRS_WARN_DESCENDING; break;
374 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
376 res = SMESH::DRS_FAIL; break;
381 //=============================================================================
383 * Convert ::SMESH_ComputeError to SMESH::ComputeError
385 //=============================================================================
387 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
389 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
390 errVar->subShapeID = -1;
391 errVar->hasBadMesh = false;
393 if ( !errorPtr || errorPtr->IsOK() )
395 errVar->code = SMESH::COMPERR_OK;
399 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
400 errVar->comment = errorPtr->myComment.c_str();
402 return errVar._retn();
405 //=============================================================================
409 * Imports mesh data from MED file
411 //=============================================================================
413 SMESH::DriverMED_ReadStatus
414 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
415 throw ( SALOME::SALOME_Exception )
417 Unexpect aCatch(SALOME_SalomeException);
420 status = _impl->MEDToMesh( theFileName, theMeshName );
422 catch( SALOME_Exception& S_ex ) {
423 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
426 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
429 CreateGroupServants();
431 int major, minor, release;
432 major = minor = release = 0;
433 MED::GetMEDVersion(theFileName, major, minor, release);
434 _medFileInfo = new SMESH::MedFileInfo();
435 _medFileInfo->fileName = theFileName;
436 _medFileInfo->fileSize = 0;
437 _medFileInfo->major = major;
438 _medFileInfo->minor = minor;
439 _medFileInfo->release = release;
440 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
442 return ConvertDriverMEDReadStatus(status);
445 //================================================================================
447 * \brief Imports mesh data from the CGNS file
449 //================================================================================
451 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
452 const int theMeshIndex,
453 std::string& theMeshName )
454 throw ( SALOME::SALOME_Exception )
456 Unexpect aCatch(SALOME_SalomeException);
459 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
461 catch( SALOME_Exception& S_ex ) {
462 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
465 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
468 CreateGroupServants();
470 _medFileInfo = new SMESH::MedFileInfo();
471 _medFileInfo->fileName = theFileName;
472 _medFileInfo->major = 0;
473 _medFileInfo->minor = 0;
474 _medFileInfo->release = 0;
475 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
477 return ConvertDriverMEDReadStatus(status);
480 //================================================================================
482 * \brief Return string representation of a MED file version comprising nbDigits
484 //================================================================================
486 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
488 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
490 return CORBA::string_dup( ver.c_str() );
493 //================================================================================
495 * Return the list of med versions compatibles for write/append,
496 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
498 //================================================================================
499 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
501 SMESH::long_array_var aResult = new SMESH::long_array();
502 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
503 long nbver = mvok.size();
504 aResult->length( nbver );
505 for ( int i = 0; i < nbver; i++ )
506 aResult[i] = mvok[i];
507 return aResult._retn();
510 //=============================================================================
514 * Imports mesh data from MED file
516 //=============================================================================
518 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
519 throw ( SALOME::SALOME_Exception )
523 // Read mesh with name = <theMeshName> into SMESH_Mesh
524 _impl->UNVToMesh( theFileName );
526 CreateGroupServants();
528 _medFileInfo = new SMESH::MedFileInfo();
529 _medFileInfo->fileName = theFileName;
530 _medFileInfo->major = 0;
531 _medFileInfo->minor = 0;
532 _medFileInfo->release = 0;
533 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
535 SMESH_CATCH( SMESH::throwCorbaException );
540 //=============================================================================
544 * Imports mesh data from STL file
546 //=============================================================================
547 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
548 throw ( SALOME::SALOME_Exception )
552 // Read mesh with name = <theMeshName> into SMESH_Mesh
553 std::string name = _impl->STLToMesh( theFileName );
556 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
557 _gen_i->SetName( meshSO, name.c_str() );
559 _medFileInfo = new SMESH::MedFileInfo();
560 _medFileInfo->fileName = theFileName;
561 _medFileInfo->major = 0;
562 _medFileInfo->minor = 0;
563 _medFileInfo->release = 0;
564 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
566 SMESH_CATCH( SMESH::throwCorbaException );
571 //================================================================================
573 * \brief Function used in SMESH_CATCH by ImportGMFFile()
575 //================================================================================
579 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
581 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
585 //================================================================================
587 * \brief Imports data from a GMF file and returns an error description
589 //================================================================================
591 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
592 bool theMakeRequiredGroups )
593 throw (SALOME::SALOME_Exception)
595 SMESH_ComputeErrorPtr error;
598 #define SMESH_CAUGHT error =
601 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
603 _medFileInfo = new SMESH::MedFileInfo();
604 _medFileInfo->fileName = theFileName;
605 _medFileInfo->major = 0;
606 _medFileInfo->minor = 0;
607 _medFileInfo->release = 0;
608 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
610 SMESH_CATCH( exceptionToComputeError );
614 CreateGroupServants();
616 return ConvertComputeError( error );
619 //=============================================================================
623 //=============================================================================
625 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
627 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
628 (SMESH_Hypothesis::Hypothesis_Status theStatus)
631 RETURNCASE( HYP_OK );
632 RETURNCASE( HYP_MISSING );
633 RETURNCASE( HYP_CONCURRENT );
634 RETURNCASE( HYP_BAD_PARAMETER );
635 RETURNCASE( HYP_HIDDEN_ALGO );
636 RETURNCASE( HYP_HIDING_ALGO );
637 RETURNCASE( HYP_UNKNOWN_FATAL );
638 RETURNCASE( HYP_INCOMPATIBLE );
639 RETURNCASE( HYP_NOTCONFORM );
640 RETURNCASE( HYP_ALREADY_EXIST );
641 RETURNCASE( HYP_BAD_DIM );
642 RETURNCASE( HYP_BAD_SUBSHAPE );
643 RETURNCASE( HYP_BAD_GEOMETRY );
644 RETURNCASE( HYP_NEED_SHAPE );
645 RETURNCASE( HYP_INCOMPAT_HYPS );
648 return SMESH::HYP_UNKNOWN_FATAL;
651 //=============================================================================
655 * calls internal addHypothesis() and then adds a reference to <anHyp> under
656 * the SObject actually having a reference to <aSubShape>.
657 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
659 //=============================================================================
661 SMESH::Hypothesis_Status
662 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
663 SMESH::SMESH_Hypothesis_ptr anHyp,
664 CORBA::String_out anErrorText)
665 throw(SALOME::SALOME_Exception)
667 Unexpect aCatch(SALOME_SalomeException);
669 _preMeshInfo->ForgetOrLoad();
672 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
673 anErrorText = error.c_str();
675 SMESH::SMESH_Mesh_var mesh( _this() );
676 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
678 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
679 _gen_i->UpdateIcons( mesh );
681 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
683 // Update Python script
684 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
685 << aSubShape << ", " << anHyp << " )";
687 return ConvertHypothesisStatus(status);
690 //=============================================================================
694 //=============================================================================
696 SMESH_Hypothesis::Hypothesis_Status
697 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
698 SMESH::SMESH_Hypothesis_ptr anHyp,
699 std::string* anErrorText)
701 if(MYDEBUG) MESSAGE("addHypothesis");
703 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
704 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
706 if (CORBA::is_nil( anHyp ))
707 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
709 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
712 TopoDS_Shape myLocSubShape;
713 //use PseudoShape in case if mesh has no shape
715 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
717 myLocSubShape = _impl->GetShapeToMesh();
719 const int hypId = anHyp->GetId();
721 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
722 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
724 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
726 // assure there is a corresponding submesh
727 if ( !_impl->IsMainShape( myLocSubShape )) {
728 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
729 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
730 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
733 else if ( anErrorText )
735 *anErrorText = error;
738 catch(SALOME_Exception & S_ex)
740 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
745 //=============================================================================
749 //=============================================================================
751 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
752 SMESH::SMESH_Hypothesis_ptr anHyp)
753 throw(SALOME::SALOME_Exception)
755 Unexpect aCatch(SALOME_SalomeException);
757 _preMeshInfo->ForgetOrLoad();
759 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
760 SMESH::SMESH_Mesh_var mesh = _this();
762 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
764 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
765 _gen_i->UpdateIcons( mesh );
767 // Update Python script
768 if(_impl->HasShapeToMesh())
769 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
770 << aSubShape << ", " << anHyp << " )";
772 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
775 return ConvertHypothesisStatus(status);
778 //=============================================================================
782 //=============================================================================
784 SMESH_Hypothesis::Hypothesis_Status
785 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
786 SMESH::SMESH_Hypothesis_ptr anHyp)
788 if(MYDEBUG) MESSAGE("removeHypothesis()");
790 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
791 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
793 if (CORBA::is_nil( anHyp ))
794 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
797 _preMeshInfo->ForgetOrLoad();
799 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
802 TopoDS_Shape myLocSubShape;
803 //use PseudoShape in case if mesh has no shape
804 if( _impl->HasShapeToMesh() )
805 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
807 myLocSubShape = _impl->GetShapeToMesh();
809 const int hypId = anHyp->GetId();
810 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
811 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
813 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
817 catch(SALOME_Exception & S_ex)
819 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
824 //=============================================================================
828 //=============================================================================
830 SMESH::ListOfHypothesis *
831 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
832 throw(SALOME::SALOME_Exception)
834 Unexpect aCatch(SALOME_SalomeException);
835 if (MYDEBUG) MESSAGE("GetHypothesisList");
836 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
837 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
839 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
842 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
843 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
844 myLocSubShape = _impl->GetShapeToMesh();
845 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
846 int i = 0, n = aLocalList.size();
849 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
850 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
851 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
853 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
854 if ( id_hypptr != _mapHypo.end() )
855 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
859 catch(SALOME_Exception & S_ex) {
860 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
863 return aList._retn();
866 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
868 Unexpect aCatch(SALOME_SalomeException);
869 if (MYDEBUG) MESSAGE("GetSubMeshes");
871 SMESH::submesh_array_var aList = new SMESH::submesh_array();
874 TPythonDump aPythonDump;
875 if ( !_mapSubMeshIor.empty() )
879 aList->length( _mapSubMeshIor.size() );
881 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
882 for ( ; it != _mapSubMeshIor.end(); it++ ) {
883 if ( CORBA::is_nil( it->second )) continue;
884 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
886 if (i > 1) aPythonDump << ", ";
887 aPythonDump << it->second;
891 catch(SALOME_Exception & S_ex) {
892 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
895 // Update Python script
896 if ( !_mapSubMeshIor.empty() )
897 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
899 return aList._retn();
902 //=============================================================================
906 //=============================================================================
908 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
909 const char* theName )
910 throw(SALOME::SALOME_Exception)
912 Unexpect aCatch(SALOME_SalomeException);
913 if (CORBA::is_nil(aSubShape))
914 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
916 SMESH::SMESH_subMesh_var subMesh;
917 SMESH::SMESH_Mesh_var aMesh = _this();
919 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
921 //Get or Create the SMESH_subMesh object implementation
923 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
925 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
927 TopoDS_Iterator it( myLocSubShape );
929 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
931 subMesh = getSubMesh( subMeshId );
933 // create a new subMesh object servant if there is none for the shape
934 if ( subMesh->_is_nil() )
935 subMesh = createSubMesh( aSubShape );
936 if ( _gen_i->CanPublishInStudy( subMesh ))
938 SALOMEDS::SObject_wrap aSO =
939 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
940 if ( !aSO->_is_nil()) {
941 // Update Python script
942 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
943 << aSubShape << ", '" << theName << "' )";
947 catch(SALOME_Exception & S_ex) {
948 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
950 return subMesh._retn();
953 //=============================================================================
957 //=============================================================================
959 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
960 throw (SALOME::SALOME_Exception)
964 if ( theSubMesh->_is_nil() )
967 GEOM::GEOM_Object_var aSubShape;
968 // Remove submesh's SObject
969 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
970 if ( !anSO->_is_nil() ) {
971 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
972 SALOMEDS::SObject_wrap anObj, aRef;
973 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
974 anObj->ReferencedObject( aRef.inout() ))
976 CORBA::Object_var obj = aRef->GetObject();
977 aSubShape = GEOM::GEOM_Object::_narrow( obj );
979 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
980 // aSubShape = theSubMesh->GetSubShape();
982 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
983 builder->RemoveObjectWithChildren( anSO );
985 // Update Python script
986 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
989 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
991 _preMeshInfo->ForgetOrLoad();
993 SMESH_CATCH( SMESH::throwCorbaException );
996 //=============================================================================
1000 //=============================================================================
1002 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1003 const char* theName )
1004 throw(SALOME::SALOME_Exception)
1006 Unexpect aCatch(SALOME_SalomeException);
1008 _preMeshInfo->FullLoadFromFile();
1010 SMESH::SMESH_Group_var aNewGroup =
1011 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1013 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1015 SMESH::SMESH_Mesh_var mesh = _this();
1016 SALOMEDS::SObject_wrap aSO =
1017 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1018 if ( !aSO->_is_nil())
1019 // Update Python script
1020 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1021 << theElemType << ", '" << theName << "' )";
1023 return aNewGroup._retn();
1026 //=============================================================================
1030 //=============================================================================
1031 SMESH::SMESH_GroupOnGeom_ptr
1032 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1033 const char* theName,
1034 GEOM::GEOM_Object_ptr theGeomObj)
1035 throw(SALOME::SALOME_Exception)
1037 Unexpect aCatch(SALOME_SalomeException);
1039 _preMeshInfo->FullLoadFromFile();
1041 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1043 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1044 if ( !aShape.IsNull() )
1047 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1049 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1051 SMESH::SMESH_Mesh_var mesh = _this();
1052 SALOMEDS::SObject_wrap aSO =
1053 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1054 if ( !aSO->_is_nil())
1055 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1056 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1060 return aNewGroup._retn();
1063 //================================================================================
1065 * \brief Creates a group whose contents is defined by filter
1066 * \param theElemType - group type
1067 * \param theName - group name
1068 * \param theFilter - the filter
1069 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1071 //================================================================================
1073 SMESH::SMESH_GroupOnFilter_ptr
1074 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1075 const char* theName,
1076 SMESH::Filter_ptr theFilter )
1077 throw (SALOME::SALOME_Exception)
1079 Unexpect aCatch(SALOME_SalomeException);
1081 _preMeshInfo->FullLoadFromFile();
1083 if ( CORBA::is_nil( theFilter ))
1084 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1086 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1088 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1090 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1091 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1094 if ( !aNewGroup->_is_nil() )
1095 aNewGroup->SetFilter( theFilter );
1097 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1099 SMESH::SMESH_Mesh_var mesh = _this();
1100 SALOMEDS::SObject_wrap aSO =
1101 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1103 if ( !aSO->_is_nil())
1104 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1105 << theElemType << ", '" << theName << "', " << theFilter << " )";
1107 return aNewGroup._retn();
1110 //=============================================================================
1114 //=============================================================================
1116 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1117 throw (SALOME::SALOME_Exception)
1119 if ( theGroup->_is_nil() )
1124 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1128 if ( aGroup->GetMeshServant() != this )
1129 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1130 SALOME::BAD_PARAM );
1132 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1133 if ( !aGroupSO->_is_nil() )
1135 // Update Python script
1136 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1138 // Remove group's SObject
1139 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1140 builder->RemoveObjectWithChildren( aGroupSO );
1142 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1144 // Remove the group from SMESH data structures
1145 removeGroup( aGroup->GetLocalID() );
1147 SMESH_CATCH( SMESH::throwCorbaException );
1150 //=============================================================================
1152 * Remove group with its contents
1154 //=============================================================================
1156 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1157 throw (SALOME::SALOME_Exception)
1161 _preMeshInfo->FullLoadFromFile();
1163 if ( theGroup->_is_nil() )
1166 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1167 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1168 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1171 vector<int> nodeIds; // to remove nodes becoming free
1172 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1173 if ( !isNodal && !theGroup->IsEmpty() )
1175 CORBA::Long elemID = theGroup->GetID( 1 );
1176 int nbElemNodes = GetElemNbNodes( elemID );
1177 if ( nbElemNodes > 0 )
1178 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1181 // Retrieve contents
1182 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1183 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1184 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1185 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1186 elems.assign( elemBeg, elemEnd );
1188 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1191 RemoveGroup( theGroup );
1194 for ( size_t i = 0; i < elems.size(); ++i )
1196 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1200 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1201 nodeIds.push_back( nIt->next()->GetID() );
1203 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1207 _impl->GetMeshDS()->RemoveElement( elems[i] );
1211 // Remove free nodes
1212 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1213 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1214 if ( n->NbInverseElements() == 0 )
1215 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1217 // Update Python script (theGroup must be alive for this)
1218 pyDump << SMESH::SMESH_Mesh_var(_this())
1219 << ".RemoveGroupWithContents( " << theGroup << " )";
1221 SMESH_CATCH( SMESH::throwCorbaException );
1224 //================================================================================
1226 * \brief Get the list of groups existing in the mesh
1227 * \retval SMESH::ListOfGroups * - list of groups
1229 //================================================================================
1231 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1233 Unexpect aCatch(SALOME_SalomeException);
1234 if (MYDEBUG) MESSAGE("GetGroups");
1236 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1239 TPythonDump aPythonDump;
1240 if ( !_mapGroups.empty() )
1242 aPythonDump << "[ ";
1244 aList->length( _mapGroups.size() );
1246 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1247 for ( ; it != _mapGroups.end(); it++ ) {
1248 if ( CORBA::is_nil( it->second )) continue;
1249 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1251 if (i > 1) aPythonDump << ", ";
1252 aPythonDump << it->second;
1256 catch(SALOME_Exception & S_ex) {
1257 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1259 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1261 return aList._retn();
1264 //=============================================================================
1266 * Get number of groups existing in the mesh
1268 //=============================================================================
1270 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1272 Unexpect aCatch(SALOME_SalomeException);
1273 return _mapGroups.size();
1276 //=============================================================================
1278 * New group including all mesh elements present in initial groups is created.
1280 //=============================================================================
1282 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1283 SMESH::SMESH_GroupBase_ptr theGroup2,
1284 const char* theName )
1285 throw (SALOME::SALOME_Exception)
1287 SMESH::SMESH_Group_var aResGrp;
1291 _preMeshInfo->FullLoadFromFile();
1293 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1294 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1296 if ( theGroup1->GetType() != theGroup2->GetType() )
1297 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1302 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1303 if ( aResGrp->_is_nil() )
1304 return SMESH::SMESH_Group::_nil();
1306 aResGrp->AddFrom( theGroup1 );
1307 aResGrp->AddFrom( theGroup2 );
1309 // Update Python script
1310 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1311 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1313 SMESH_CATCH( SMESH::throwCorbaException );
1315 return aResGrp._retn();
1318 //=============================================================================
1320 * \brief New group including all mesh elements present in initial groups is created.
1321 * \param theGroups list of groups
1322 * \param theName name of group to be created
1323 * \return pointer to the new group
1325 //=============================================================================
1327 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1328 const char* theName )
1329 throw (SALOME::SALOME_Exception)
1331 SMESH::SMESH_Group_var aResGrp;
1334 _preMeshInfo->FullLoadFromFile();
1337 return SMESH::SMESH_Group::_nil();
1342 SMESH::ElementType aType = SMESH::ALL;
1343 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1345 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1346 if ( CORBA::is_nil( aGrp ) )
1348 if ( aType == SMESH::ALL )
1349 aType = aGrp->GetType();
1350 else if ( aType != aGrp->GetType() )
1351 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1354 if ( aType == SMESH::ALL )
1355 return SMESH::SMESH_Group::_nil();
1360 aResGrp = CreateGroup( aType, theName );
1361 if ( aResGrp->_is_nil() )
1362 return SMESH::SMESH_Group::_nil();
1364 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1365 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1367 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1368 if ( !CORBA::is_nil( aGrp ) )
1370 aResGrp->AddFrom( aGrp );
1371 if ( g > 0 ) pyDump << ", ";
1375 pyDump << " ], '" << theName << "' )";
1377 SMESH_CATCH( SMESH::throwCorbaException );
1379 return aResGrp._retn();
1382 //=============================================================================
1384 * New group is created. All mesh elements that are
1385 * present in both initial groups are added to the new one.
1387 //=============================================================================
1389 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1390 SMESH::SMESH_GroupBase_ptr theGroup2,
1391 const char* theName )
1392 throw (SALOME::SALOME_Exception)
1394 SMESH::SMESH_Group_var aResGrp;
1399 _preMeshInfo->FullLoadFromFile();
1401 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1402 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1404 if ( theGroup1->GetType() != theGroup2->GetType() )
1405 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1409 // Create Intersection
1410 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1411 if ( aResGrp->_is_nil() )
1412 return aResGrp._retn();
1414 SMESHDS_GroupBase* groupDS1 = 0;
1415 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1416 groupDS1 = grp_i->GetGroupDS();
1418 SMESHDS_GroupBase* groupDS2 = 0;
1419 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1420 groupDS2 = grp_i->GetGroupDS();
1422 SMESHDS_Group* resGroupDS = 0;
1423 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1424 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1426 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1428 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1429 while ( elemIt1->more() )
1431 const SMDS_MeshElement* e = elemIt1->next();
1432 if ( groupDS2->Contains( e ))
1433 resGroupDS->SMDSGroup().Add( e );
1436 // Update Python script
1437 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1438 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1440 SMESH_CATCH( SMESH::throwCorbaException );
1442 return aResGrp._retn();
1445 //=============================================================================
1447 \brief Intersect list of groups. New group is created. All mesh elements that
1448 are present in all initial groups simultaneously are added to the new one.
1449 \param theGroups list of groups
1450 \param theName name of group to be created
1451 \return pointer on the group
1453 //=============================================================================
1454 SMESH::SMESH_Group_ptr
1455 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1456 const char* theName )
1457 throw (SALOME::SALOME_Exception)
1459 SMESH::SMESH_Group_var aResGrp;
1464 _preMeshInfo->FullLoadFromFile();
1467 return SMESH::SMESH_Group::_nil();
1469 // check types and get SMESHDS_GroupBase's
1470 SMESH::ElementType aType = SMESH::ALL;
1471 vector< SMESHDS_GroupBase* > groupVec;
1472 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1474 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1475 if ( CORBA::is_nil( aGrp ) )
1477 if ( aType == SMESH::ALL )
1478 aType = aGrp->GetType();
1479 else if ( aType != aGrp->GetType() )
1480 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1483 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1484 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1486 if ( grpDS->IsEmpty() )
1491 groupVec.push_back( grpDS );
1494 if ( aType == SMESH::ALL ) // all groups are nil
1495 return SMESH::SMESH_Group::_nil();
1500 aResGrp = CreateGroup( aType, theName );
1502 SMESHDS_Group* resGroupDS = 0;
1503 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1504 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1505 if ( !resGroupDS || groupVec.empty() )
1506 return aResGrp._retn();
1509 size_t i, nb = groupVec.size();
1510 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1511 while ( elemIt1->more() )
1513 const SMDS_MeshElement* e = elemIt1->next();
1515 for ( i = 1; ( i < nb && inAll ); ++i )
1516 inAll = groupVec[i]->Contains( e );
1519 resGroupDS->SMDSGroup().Add( e );
1522 // Update Python script
1523 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1524 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1526 SMESH_CATCH( SMESH::throwCorbaException );
1528 return aResGrp._retn();
1531 //=============================================================================
1533 * New group is created. All mesh elements that are present in
1534 * a main group but is not present in a tool group are added to the new one
1536 //=============================================================================
1538 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1539 SMESH::SMESH_GroupBase_ptr theGroup2,
1540 const char* theName )
1541 throw (SALOME::SALOME_Exception)
1543 SMESH::SMESH_Group_var aResGrp;
1548 _preMeshInfo->FullLoadFromFile();
1550 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1551 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1553 if ( theGroup1->GetType() != theGroup2->GetType() )
1554 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1558 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1559 if ( aResGrp->_is_nil() )
1560 return aResGrp._retn();
1562 SMESHDS_GroupBase* groupDS1 = 0;
1563 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1564 groupDS1 = grp_i->GetGroupDS();
1566 SMESHDS_GroupBase* groupDS2 = 0;
1567 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1568 groupDS2 = grp_i->GetGroupDS();
1570 SMESHDS_Group* resGroupDS = 0;
1571 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1572 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1574 if ( groupDS1 && groupDS2 && resGroupDS )
1576 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1577 while ( elemIt1->more() )
1579 const SMDS_MeshElement* e = elemIt1->next();
1580 if ( !groupDS2->Contains( e ))
1581 resGroupDS->SMDSGroup().Add( e );
1584 // Update Python script
1585 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1586 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1588 SMESH_CATCH( SMESH::throwCorbaException );
1590 return aResGrp._retn();
1593 //=============================================================================
1595 \brief Cut lists of groups. New group is created. All mesh elements that are
1596 present in main groups but do not present in tool groups are added to the new one
1597 \param theMainGroups list of main groups
1598 \param theToolGroups list of tool groups
1599 \param theName name of group to be created
1600 \return pointer on the group
1602 //=============================================================================
1603 SMESH::SMESH_Group_ptr
1604 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1605 const SMESH::ListOfGroups& theToolGroups,
1606 const char* theName )
1607 throw (SALOME::SALOME_Exception)
1609 SMESH::SMESH_Group_var aResGrp;
1614 _preMeshInfo->FullLoadFromFile();
1617 return SMESH::SMESH_Group::_nil();
1619 // check types and get SMESHDS_GroupBase's
1620 SMESH::ElementType aType = SMESH::ALL;
1621 vector< SMESHDS_GroupBase* > toolGroupVec;
1622 vector< SMDS_ElemIteratorPtr > mainIterVec;
1624 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1626 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1627 if ( CORBA::is_nil( aGrp ) )
1629 if ( aType == SMESH::ALL )
1630 aType = aGrp->GetType();
1631 else if ( aType != aGrp->GetType() )
1632 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1634 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1635 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1636 if ( !grpDS->IsEmpty() )
1637 mainIterVec.push_back( grpDS->GetElements() );
1639 if ( aType == SMESH::ALL ) // all main groups are nil
1640 return SMESH::SMESH_Group::_nil();
1641 if ( mainIterVec.empty() ) // all main groups are empty
1642 return aResGrp._retn();
1644 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1646 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1647 if ( CORBA::is_nil( aGrp ) )
1649 if ( aType != aGrp->GetType() )
1650 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1652 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1653 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1654 toolGroupVec.push_back( grpDS );
1660 aResGrp = CreateGroup( aType, theName );
1662 SMESHDS_Group* resGroupDS = 0;
1663 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1664 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1666 return aResGrp._retn();
1669 size_t i, nb = toolGroupVec.size();
1670 SMDS_ElemIteratorPtr mainElemIt
1671 ( new SMDS_IteratorOnIterators
1672 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1673 while ( mainElemIt->more() )
1675 const SMDS_MeshElement* e = mainElemIt->next();
1677 for ( i = 0; ( i < nb && !isIn ); ++i )
1678 isIn = toolGroupVec[i]->Contains( e );
1681 resGroupDS->SMDSGroup().Add( e );
1684 // Update Python script
1685 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1686 << ".CutListOfGroups( " << theMainGroups << ", "
1687 << theToolGroups << ", '" << theName << "' )";
1689 SMESH_CATCH( SMESH::throwCorbaException );
1691 return aResGrp._retn();
1694 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1696 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1697 bool & toStopChecking )
1699 toStopChecking = ( nbCommon < nbChecked );
1700 return nbCommon == nbNodes;
1702 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1703 bool & toStopChecking )
1705 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1706 return nbCommon == nbCorners;
1708 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1709 bool & toStopChecking )
1711 return nbCommon > 0;
1713 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1714 bool & toStopChecking )
1716 return nbCommon >= (nbNodes+1) / 2;
1720 //=============================================================================
1722 * Create a group of entities basing on nodes of other groups.
1723 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1724 * \param [in] anElemType - a type of elements to include to the new group.
1725 * \param [in] theName - a name of the new group.
1726 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1727 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1728 * new group provided that it is based on nodes of an element of \a aListOfGroups
1729 * \return SMESH_Group - the created group
1731 // IMP 19939, bug 22010, IMP 22635
1732 //=============================================================================
1734 SMESH::SMESH_Group_ptr
1735 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1736 SMESH::ElementType theElemType,
1737 const char* theName,
1738 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1739 CORBA::Boolean theUnderlyingOnly)
1740 throw (SALOME::SALOME_Exception)
1742 SMESH::SMESH_Group_var aResGrp;
1746 _preMeshInfo->FullLoadFromFile();
1748 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1750 if ( !theName || !aMeshDS )
1751 return SMESH::SMESH_Group::_nil();
1753 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1755 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1756 SMESH_Comment nbCoNoStr( "SMESH.");
1757 switch ( theNbCommonNodes ) {
1758 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1759 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1760 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1761 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1762 default: return aResGrp._retn();
1764 int nbChecked, nbCommon, nbNodes, nbCorners;
1770 aResGrp = CreateGroup( theElemType, theName );
1771 if ( aResGrp->_is_nil() )
1772 return SMESH::SMESH_Group::_nil();
1774 SMESHDS_GroupBase* groupBaseDS =
1775 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1776 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1778 vector<bool> isNodeInGroups;
1780 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1782 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1783 if ( CORBA::is_nil( aGrp ) )
1785 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1786 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1789 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1790 if ( !elIt ) continue;
1792 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1794 while ( elIt->more() ) {
1795 const SMDS_MeshElement* el = elIt->next();
1796 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1797 while ( nIt->more() )
1798 resGroupCore.Add( nIt->next() );
1801 // get elements of theElemType based on nodes of every element of group
1802 else if ( theUnderlyingOnly )
1804 while ( elIt->more() )
1806 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1807 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1808 TIDSortedElemSet checkedElems;
1809 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1810 while ( nIt->more() )
1812 const SMDS_MeshNode* n = nIt->next();
1813 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1814 // check nodes of elements of theElemType around el
1815 while ( elOfTypeIt->more() )
1817 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1818 if ( !checkedElems.insert( elOfType ).second ) continue;
1819 nbNodes = elOfType->NbNodes();
1820 nbCorners = elOfType->NbCornerNodes();
1822 bool toStopChecking = false;
1823 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1824 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1825 if ( elNodes.count( nIt2->next() ) &&
1826 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1828 resGroupCore.Add( elOfType );
1835 // get all nodes of elements of groups
1838 while ( elIt->more() )
1840 const SMDS_MeshElement* el = elIt->next(); // an element of group
1841 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1842 while ( nIt->more() )
1844 const SMDS_MeshNode* n = nIt->next();
1845 if ( n->GetID() >= (int) isNodeInGroups.size() )
1846 isNodeInGroups.resize( n->GetID() + 1, false );
1847 isNodeInGroups[ n->GetID() ] = true;
1853 // Get elements of theElemType based on a certain number of nodes of elements of groups
1854 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1856 const SMDS_MeshNode* n;
1857 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1858 const int isNodeInGroupsSize = isNodeInGroups.size();
1859 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1861 if ( !isNodeInGroups[ iN ] ||
1862 !( n = aMeshDS->FindNode( iN )))
1865 // check nodes of elements of theElemType around n
1866 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1867 while ( elOfTypeIt->more() )
1869 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1870 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1875 nbNodes = elOfType->NbNodes();
1876 nbCorners = elOfType->NbCornerNodes();
1878 bool toStopChecking = false;
1879 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1880 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1882 const int nID = nIt->next()->GetID();
1883 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1884 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1886 resGroupCore.Add( elOfType );
1894 // Update Python script
1895 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1896 << ".CreateDimGroup( "
1897 << theGroups << ", " << theElemType << ", '" << theName << "', "
1898 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1900 SMESH_CATCH( SMESH::throwCorbaException );
1902 return aResGrp._retn();
1905 //================================================================================
1907 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1908 * existing 1D elements as group boundaries.
1909 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1910 * adjacent faces is more than \a sharpAngle in degrees.
1911 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1912 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1913 * \return ListOfGroups - the created groups
1915 //================================================================================
1917 SMESH::ListOfGroups*
1918 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1919 CORBA::Boolean theCreateEdges,
1920 CORBA::Boolean theUseExistingEdges )
1921 throw (SALOME::SALOME_Exception)
1923 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1924 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1927 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1933 _preMeshInfo->FullLoadFromFile();
1935 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1937 std::vector< SMESH_MeshAlgos::Edge > edges =
1938 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1940 if ( theCreateEdges )
1942 std::vector<const SMDS_MeshNode *> nodes(2);
1943 for ( size_t i = 0; i < edges.size(); ++i )
1945 nodes[0] = edges[i]._node1;
1946 nodes[1] = edges[i]._node2;
1947 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1949 if ( edges[i]._medium )
1950 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1952 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1956 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1957 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1959 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1961 resultGroups->length( faceGroups.size() );
1962 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1964 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1965 _editor->GenerateGroupName("Group").c_str());
1966 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1968 SMESHDS_GroupBase* groupBaseDS =
1969 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1970 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1972 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1973 for ( size_t i = 0; i < faces.size(); ++i )
1974 groupCore.Add( faces[i] );
1977 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1978 << ".FaceGroupsSeparatedByEdges( "
1979 << TVar( theSharpAngle ) << ", "
1980 << theCreateEdges << ", "
1981 << theUseExistingEdges << " )";
1983 SMESH_CATCH( SMESH::throwCorbaException );
1984 return resultGroups._retn();
1988 //================================================================================
1990 * \brief Remember GEOM group data
1992 //================================================================================
1994 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1995 CORBA::Object_ptr theSmeshObj)
1997 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2000 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2001 if ( groupSO->_is_nil() )
2004 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2005 GEOM::GEOM_IGroupOperations_ptr groupOp =
2006 geomGen->GetIGroupOperations();
2007 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2010 _geomGroupData.push_back( TGeomGroupData() );
2011 TGeomGroupData & groupData = _geomGroupData.back();
2013 CORBA::String_var entry = groupSO->GetID();
2014 groupData._groupEntry = entry.in();
2016 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2017 groupData._indices.insert( ids[i] );
2019 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2020 // shape index in SMESHDS
2021 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2022 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2025 //================================================================================
2027 * Remove GEOM group data relating to removed smesh object
2029 //================================================================================
2031 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2033 list<TGeomGroupData>::iterator
2034 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2035 for ( ; data != dataEnd; ++data ) {
2036 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2037 _geomGroupData.erase( data );
2043 //================================================================================
2045 * \brief Return new group contents if it has been changed and update group data
2047 //================================================================================
2048 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2050 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2052 TopoDS_Shape newShape;
2054 if ( how == IS_BREAK_LINK )
2056 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2057 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2058 if ( !meshSO->_is_nil() &&
2059 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2060 geomRefSO->ReferencedObject( geomSO.inout() ))
2062 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2063 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2064 newShape = _gen_i->GeomObjectToShape( geom );
2070 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2071 if ( !groupSO->_is_nil() )
2073 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2074 if ( CORBA::is_nil( groupObj )) return newShape;
2075 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2077 // get indices of group items
2078 set<int> curIndices;
2079 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2080 GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
2081 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2082 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2083 curIndices.insert( ids[i] );
2085 if ( how == ONLY_IF_CHANGED && groupData._indices == curIndices )
2086 return newShape; // group not changed
2089 groupData._indices = curIndices;
2091 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2092 if ( !geomClient ) return newShape;
2093 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2094 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2095 newShape = _gen_i->GeomObjectToShape( geomGroup );
2098 if ( newShape.IsNull() ) {
2099 // geom group becomes empty - return empty compound
2100 TopoDS_Compound compound;
2101 BRep_Builder().MakeCompound(compound);
2102 newShape = compound;
2109 //-----------------------------------------------------------------------------
2111 * \brief Storage of shape and index used in CheckGeomGroupModif()
2113 struct TIndexedShape
2116 TopoDS_Shape _shape;
2117 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2119 //-----------------------------------------------------------------------------
2121 * \brief Data to re-create a group on geometry
2123 struct TGroupOnGeomData
2126 TopoDS_Shape _shape;
2127 SMDSAbs_ElementType _type;
2129 Quantity_Color _color;
2131 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2133 _oldID = group->GetID();
2134 _type = group->GetType();
2135 _name = group->GetStoreName();
2136 _color = group->GetColor();
2140 //-----------------------------------------------------------------------------
2142 * \brief Check if a filter is still valid after geometry removal
2144 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2146 if ( theFilter->_is_nil() )
2148 SMESH::Filter::Criteria_var criteria;
2149 theFilter->GetCriteria( criteria.out() );
2151 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2153 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2155 switch ( criteria[ iCr ].Type )
2157 case SMESH::FT_BelongToGeom:
2158 case SMESH::FT_BelongToPlane:
2159 case SMESH::FT_BelongToCylinder:
2160 case SMESH::FT_BelongToGenSurface:
2161 case SMESH::FT_LyingOnGeom:
2162 entry = thresholdID;
2164 case SMESH::FT_ConnectedElements:
2167 entry = thresholdID;
2173 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2174 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2175 if ( so->_is_nil() )
2177 CORBA::Object_var obj = so->GetObject();
2178 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2179 if ( gen->GeomObjectToShape( geom ).IsNull() )
2182 } // loop on criteria
2188 //=============================================================================
2190 * \brief Update data if geometry changes
2194 //=============================================================================
2196 void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
2198 SMESH::SMESH_Mesh_var me = _this();
2199 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2201 TPythonDump dumpNothing; // prevent any dump
2203 //bool removedFromClient = false;
2205 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2207 //removedFromClient = _impl->HasShapeToMesh();
2209 // try to find geometry by study reference
2210 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2211 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2212 if ( !meshSO->_is_nil() &&
2213 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2214 geomRefSO->ReferencedObject( geomSO.inout() ))
2216 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2217 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2220 if ( mainGO->_is_nil() && // geometry removed ==>
2221 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2223 // convert geom dependent groups into standalone ones
2224 CheckGeomGroupModif();
2226 _impl->ShapeToMesh( TopoDS_Shape() );
2228 // remove sub-meshes
2229 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2230 while ( i_sm != _mapSubMeshIor.end() )
2232 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2234 RemoveSubMesh( sm );
2236 // remove all children except groups in the study
2237 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2238 SALOMEDS::SObject_wrap so;
2239 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2240 if ( meshSO->FindSubObject( tag, so.inout() ))
2241 builder->RemoveObjectWithChildren( so );
2243 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2249 if ( !_impl->HasShapeToMesh() ) return;
2252 // Update after group modification
2254 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2255 mainGO->GetTick() == _mainShapeTick )
2257 int nb = NbNodes() + NbElements();
2258 CheckGeomGroupModif();
2259 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2260 _gen_i->UpdateIcons( me );
2264 // Update after shape modification
2266 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2267 if ( !geomClient ) return;
2268 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2269 if ( geomGen->_is_nil() ) return;
2271 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2272 geomClient->RemoveShapeFromBuffer( ior.in() );
2274 // Update data taking into account that if topology doesn't change
2275 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2278 _preMeshInfo->ForgetAllData();
2281 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2282 if ( newShape.IsNull() )
2285 _mainShapeTick = mainGO->GetTick();
2287 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2289 // store data of groups on geometry
2290 std::vector< TGroupOnGeomData > groupsData;
2291 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2292 groupsData.reserve( groups.size() );
2293 TopTools_DataMapOfShapeShape old2newShapeMap;
2294 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2295 for ( ; g != groups.end(); ++g )
2297 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2299 groupsData.push_back( TGroupOnGeomData( group ));
2302 SMESH::SMESH_GroupOnGeom_var gog;
2303 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2304 if ( i_grp != _mapGroups.end() )
2305 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2307 GEOM::GEOM_Object_var geom;
2308 if ( !gog->_is_nil() )
2312 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2313 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2314 if ( !grpSO->_is_nil() &&
2315 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2316 geomRefSO->ReferencedObject( geomSO.inout() ))
2318 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2319 geom = GEOM::GEOM_Object::_narrow( geomObj );
2324 geom = gog->GetShape();
2327 if ( !geom->_is_nil() )
2329 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2330 geomClient->RemoveShapeFromBuffer( ior.in() );
2331 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2332 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2334 else if ( old2newShapeMap.IsBound( group->GetShape() ))
2336 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2340 // store assigned hypotheses
2341 std::vector< pair< int, THypList > > ids2Hyps;
2342 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2343 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2345 const TopoDS_Shape& s = s2hyps.Key();
2346 const THypList& hyps = s2hyps.ChangeValue();
2347 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2350 // count shapes excluding compounds corresponding to geom groups
2351 int oldNbSubShapes = meshDS->MaxShapeIndex();
2352 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2354 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2355 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2359 // check if shape topology changes - save shape type per shape ID
2360 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2361 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2362 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2364 // change shape to mesh
2365 _impl->ShapeToMesh( TopoDS_Shape() );
2366 _impl->ShapeToMesh( newShape );
2368 // check if shape topology changes - check new shape types
2369 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2370 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2372 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2373 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2376 // re-add shapes (compounds) of geom groups
2377 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2378 for ( ; data != _geomGroupData.end(); ++data )
2380 TopoDS_Shape newShape = newGroupShape( *data, isBreakLink ? IS_BREAK_LINK : MAIN_TRANSFORMED );
2381 if ( !newShape.IsNull() )
2383 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2385 TopoDS_Compound compound;
2386 BRep_Builder().MakeCompound( compound );
2387 BRep_Builder().Add( compound, newShape );
2388 newShape = compound;
2390 _impl->GetSubMesh( newShape );
2394 // re-assign hypotheses
2395 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2397 if ( !sameTopology && ids2Hyps[i].first != 1 )
2398 continue; // assign only global hypos
2399 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2400 const THypList& hyps = ids2Hyps[i].second;
2401 THypList::const_iterator h = hyps.begin();
2402 for ( ; h != hyps.end(); ++h )
2403 _impl->AddHypothesis( s, (*h)->GetID() );
2406 if ( !sameTopology )
2408 // remove invalid study sub-objects
2409 CheckGeomGroupModif();
2413 // restore groups on geometry
2414 for ( size_t i = 0; i < groupsData.size(); ++i )
2416 const TGroupOnGeomData& data = groupsData[i];
2417 if ( data._shape.IsNull() )
2420 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2421 if ( i2g == _mapGroups.end() ) continue;
2423 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2424 if ( !gr_i ) continue;
2426 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2428 _mapGroups.erase( i2g );
2430 g->GetGroupDS()->SetColor( data._color );
2433 // update _mapSubMesh
2434 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2435 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2436 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2439 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
2442 //=============================================================================
2444 * \brief Update objects depending on changed geom groups
2446 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2447 * issue 0020210: Update of a smesh group after modification of the associated geom group
2449 //=============================================================================
2451 void SMESH_Mesh_i::CheckGeomGroupModif()
2453 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2454 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2455 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2456 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2457 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2459 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2460 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2461 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2463 int nbValid = 0, nbRemoved = 0;
2464 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2465 for ( ; chItr->More(); chItr->Next() )
2467 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2468 if ( !smSO->_is_nil() &&
2469 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2470 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2472 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2473 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2474 if ( !geom->_non_existent() )
2477 continue; // keep the sub-mesh
2480 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2481 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2482 if ( !sm->_is_nil() && !sm->_non_existent() )
2484 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2485 if ( smGeom->_is_nil() )
2487 RemoveSubMesh( sm );
2494 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2495 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2499 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2500 builder->RemoveObjectWithChildren( rootSO );
2504 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2505 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2506 while ( i_gr != _mapGroups.end())
2508 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2510 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2511 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2512 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2513 bool isValidGeom = false;
2514 if ( !onGeom->_is_nil() )
2516 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2518 else if ( !onFilt->_is_nil() )
2520 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2524 isValidGeom = ( !groupSO->_is_nil() &&
2525 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2529 if ( !IsLoaded() || group->IsEmpty() )
2531 RemoveGroup( group );
2533 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2535 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2537 else // is it possible?
2539 builder->RemoveObjectWithChildren( refSO );
2545 if ( !_impl->HasShapeToMesh() ) return;
2547 CORBA::Long nbEntities = NbNodes() + NbElements();
2549 // Check if group contents changed
2551 typedef map< string, TopoDS_Shape > TEntry2Geom;
2552 TEntry2Geom newGroupContents;
2554 list<TGeomGroupData>::iterator
2555 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2556 for ( ; data != dataEnd; ++data )
2558 pair< TEntry2Geom::iterator, bool > it_new =
2559 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2560 bool processedGroup = !it_new.second;
2561 TopoDS_Shape& newShape = it_new.first->second;
2562 if ( !processedGroup )
2563 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2564 if ( newShape.IsNull() )
2565 continue; // no changes
2568 _preMeshInfo->ForgetOrLoad();
2570 if ( processedGroup ) { // update group indices
2571 list<TGeomGroupData>::iterator data2 = data;
2572 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2573 data->_indices = data2->_indices;
2576 // Update SMESH objects according to new GEOM group contents
2578 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2579 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2581 int oldID = submesh->GetId();
2582 if ( !_mapSubMeshIor.count( oldID ))
2584 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2586 // update hypotheses
2587 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2588 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2589 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2591 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2592 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2594 // care of submeshes
2595 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2596 int newID = newSubmesh->GetId();
2597 if ( newID != oldID ) {
2598 _mapSubMesh [ newID ] = newSubmesh;
2599 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2600 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2601 _mapSubMesh. erase(oldID);
2602 _mapSubMesh_i. erase(oldID);
2603 _mapSubMeshIor.erase(oldID);
2604 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2609 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2610 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2611 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2613 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2615 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2616 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2617 ds->SetShape( newShape );
2622 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2623 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2625 // Remove groups and submeshes basing on removed sub-shapes
2627 TopTools_MapOfShape newShapeMap;
2628 TopoDS_Iterator shapeIt( newShape );
2629 for ( ; shapeIt.More(); shapeIt.Next() )
2630 newShapeMap.Add( shapeIt.Value() );
2632 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2633 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2635 if ( newShapeMap.Contains( shapeIt.Value() ))
2637 TopTools_IndexedMapOfShape oldShapeMap;
2638 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2639 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2641 const TopoDS_Shape& oldShape = oldShapeMap(i);
2642 int oldInd = meshDS->ShapeToIndex( oldShape );
2644 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2645 if ( i_smIor != _mapSubMeshIor.end() ) {
2646 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2649 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2650 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2652 // check if a group bases on oldInd shape
2653 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2654 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2655 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2656 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2658 RemoveGroup( i_grp->second ); // several groups can base on same shape
2659 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2664 // Reassign hypotheses and update groups after setting the new shape to mesh
2666 // collect anassigned hypotheses
2667 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2668 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2669 TShapeHypList assignedHyps;
2670 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2672 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2673 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2674 if ( !hyps.empty() ) {
2675 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2676 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2677 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2680 // collect shapes supporting groups
2681 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2682 TShapeTypeList groupData;
2683 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2684 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2685 for ( ; grIt != groups.end(); ++grIt )
2687 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2689 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2691 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2693 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2694 _impl->ShapeToMesh( newShape );
2696 // reassign hypotheses
2697 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2698 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2700 TIndexedShape& geom = indS_hyps->first;
2701 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2702 int oldID = geom._index;
2703 int newID = meshDS->ShapeToIndex( geom._shape );
2704 if ( oldID == 1 ) { // main shape
2706 geom._shape = newShape;
2710 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2711 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2712 // care of sub-meshes
2713 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2714 if ( newID != oldID ) {
2715 _mapSubMesh [ newID ] = newSubmesh;
2716 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2717 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2718 _mapSubMesh. erase(oldID);
2719 _mapSubMesh_i. erase(oldID);
2720 _mapSubMeshIor.erase(oldID);
2721 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2725 TShapeTypeList::iterator geomType = groupData.begin();
2726 for ( ; geomType != groupData.end(); ++geomType )
2728 const TIndexedShape& geom = geomType->first;
2729 int oldID = geom._index;
2730 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2733 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2734 CORBA::String_var name = groupSO->GetName();
2736 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2737 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2738 /*id=*/-1, geom._shape ))
2739 group_i->changeLocalId( group->GetID() );
2742 break; // everything has been updated
2745 } // loop on group data
2749 CORBA::Long newNbEntities = NbNodes() + NbElements();
2750 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2751 if ( newNbEntities != nbEntities )
2753 // Add all SObjects with icons to soToUpdateIcons
2754 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2756 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2757 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2758 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2760 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2761 i_gr != _mapGroups.end(); ++i_gr ) // groups
2762 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2765 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2766 for ( ; so != soToUpdateIcons.end(); ++so )
2767 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2770 //=============================================================================
2772 * \brief Create standalone group from a group on geometry or filter
2774 //=============================================================================
2776 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2777 throw (SALOME::SALOME_Exception)
2779 SMESH::SMESH_Group_var aGroup;
2784 _preMeshInfo->FullLoadFromFile();
2786 if ( theGroup->_is_nil() )
2787 return aGroup._retn();
2789 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2791 return aGroup._retn();
2793 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2795 const int anId = aGroupToRem->GetLocalID();
2796 if ( !_impl->ConvertToStandalone( anId ) )
2797 return aGroup._retn();
2798 removeGeomGroupData( theGroup );
2800 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2802 // remove old instance of group from own map
2803 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2804 _mapGroups.erase( anId );
2806 SALOMEDS::StudyBuilder_var builder;
2807 SALOMEDS::SObject_wrap aGroupSO;
2808 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2809 if ( !aStudy->_is_nil() ) {
2810 builder = aStudy->NewBuilder();
2811 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2812 if ( !aGroupSO->_is_nil() )
2814 // remove reference to geometry
2815 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2816 for ( ; chItr->More(); chItr->Next() )
2818 // Remove group's child SObject
2819 SALOMEDS::SObject_wrap so = chItr->Value();
2820 builder->RemoveObject( so );
2822 // Update Python script
2823 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2824 << ".ConvertToStandalone( " << aGroupSO << " )";
2826 // change icon of Group on Filter
2829 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2830 // const int isEmpty = ( elemTypes->length() == 0 );
2833 SALOMEDS::GenericAttribute_wrap anAttr =
2834 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2835 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2836 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2842 // remember new group in own map
2843 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2844 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2846 // register CORBA object for persistence
2847 _gen_i->RegisterObject( aGroup );
2849 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2850 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2851 //aGroup->Register();
2852 aGroupToRem->UnRegister();
2854 SMESH_CATCH( SMESH::throwCorbaException );
2856 return aGroup._retn();
2859 //=============================================================================
2863 //=============================================================================
2865 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2867 if(MYDEBUG) MESSAGE( "createSubMesh" );
2868 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2869 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2872 SMESH_subMesh_i * subMeshServant;
2875 subMeshId = mySubMesh->GetId();
2876 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2878 else // "invalid sub-mesh"
2880 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2881 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2882 if ( _mapSubMesh.empty() )
2885 subMeshId = _mapSubMesh.begin()->first - 1;
2886 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2889 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2891 _mapSubMesh [subMeshId] = mySubMesh;
2892 _mapSubMesh_i [subMeshId] = subMeshServant;
2893 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2895 subMeshServant->Register();
2897 // register CORBA object for persistence
2898 int nextId = _gen_i->RegisterObject( subMesh );
2899 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2900 else { nextId = 0; } // avoid "unused variable" warning
2902 // to track changes of GEOM groups
2903 if ( subMeshId > 0 )
2904 addGeomGroupData( theSubShapeObject, subMesh );
2906 return subMesh._retn();
2909 //=======================================================================
2910 //function : getSubMesh
2912 //=======================================================================
2914 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2916 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2917 if ( it == _mapSubMeshIor.end() )
2918 return SMESH::SMESH_subMesh::_nil();
2920 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2923 //=============================================================================
2927 //=============================================================================
2929 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2930 GEOM::GEOM_Object_ptr theSubShapeObject )
2932 bool isHypChanged = false;
2933 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2934 return isHypChanged;
2936 const int subMeshId = theSubMesh->GetId();
2938 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2941 if (( _mapSubMesh.count( subMeshId )) &&
2942 ( sm = _impl->GetSubMeshContaining( subMeshId )))
2944 TopoDS_Shape S = sm->GetSubShape();
2947 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2948 isHypChanged = !hyps.empty();
2949 if ( isHypChanged && _preMeshInfo )
2950 _preMeshInfo->ForgetOrLoad();
2951 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2952 for ( ; hyp != hyps.end(); ++hyp )
2953 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2960 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2961 isHypChanged = ( aHypList->length() > 0 );
2962 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2963 removeHypothesis( theSubShapeObject, aHypList[i] );
2966 catch( const SALOME::SALOME_Exception& ) {
2967 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2969 removeGeomGroupData( theSubShapeObject );
2973 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2974 if ( id_smi != _mapSubMesh_i.end() )
2975 id_smi->second->UnRegister();
2977 // remove a CORBA object
2978 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2979 if ( id_smptr != _mapSubMeshIor.end() )
2980 SMESH::SMESH_subMesh_var( id_smptr->second );
2982 _mapSubMesh.erase(subMeshId);
2983 _mapSubMesh_i.erase(subMeshId);
2984 _mapSubMeshIor.erase(subMeshId);
2986 return isHypChanged;
2989 //=============================================================================
2993 //=============================================================================
2995 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2996 const char* theName,
2998 const TopoDS_Shape& theShape,
2999 const SMESH_PredicatePtr& thePredicate )
3001 std::string newName;
3002 if ( !theName || !theName[0] )
3004 std::set< std::string > presentNames;
3005 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3006 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3008 CORBA::String_var name = i_gr->second->GetName();
3009 presentNames.insert( name.in() );
3012 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3013 } while ( !presentNames.insert( newName ).second );
3014 theName = newName.c_str();
3016 SMESH::SMESH_GroupBase_var aGroup;
3017 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3018 theID, theShape, thePredicate ))
3020 int anId = g->GetID();
3021 SMESH_GroupBase_i* aGroupImpl;
3022 if ( !theShape.IsNull() )
3023 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3024 else if ( thePredicate )
3025 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3027 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3029 aGroup = aGroupImpl->_this();
3030 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3031 aGroupImpl->Register();
3033 // register CORBA object for persistence
3034 int nextId = _gen_i->RegisterObject( aGroup );
3035 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3036 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3038 // to track changes of GEOM groups
3039 if ( !theShape.IsNull() ) {
3040 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3041 addGeomGroupData( geom, aGroup );
3044 return aGroup._retn();
3047 //=============================================================================
3049 * SMESH_Mesh_i::removeGroup
3051 * Should be called by ~SMESH_Group_i()
3053 //=============================================================================
3055 void SMESH_Mesh_i::removeGroup( const int theId )
3057 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3058 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3059 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3060 _mapGroups.erase( theId );
3061 removeGeomGroupData( group );
3062 if ( !_impl->RemoveGroup( theId ))
3064 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3065 RemoveGroup( group );
3067 group->UnRegister();
3071 //=============================================================================
3075 //=============================================================================
3077 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3078 throw(SALOME::SALOME_Exception)
3080 SMESH::log_array_var aLog;
3084 _preMeshInfo->FullLoadFromFile();
3086 list < SMESHDS_Command * >logDS = _impl->GetLog();
3087 aLog = new SMESH::log_array;
3089 int lg = logDS.size();
3092 list < SMESHDS_Command * >::iterator its = logDS.begin();
3093 while(its != logDS.end()){
3094 SMESHDS_Command *com = *its;
3095 int comType = com->GetType();
3097 int lgcom = com->GetNumber();
3099 const list < int >&intList = com->GetIndexes();
3100 int inum = intList.size();
3102 list < int >::const_iterator ii = intList.begin();
3103 const list < double >&coordList = com->GetCoords();
3104 int rnum = coordList.size();
3106 list < double >::const_iterator ir = coordList.begin();
3107 aLog[indexLog].commandType = comType;
3108 aLog[indexLog].number = lgcom;
3109 aLog[indexLog].coords.length(rnum);
3110 aLog[indexLog].indexes.length(inum);
3111 for(int i = 0; i < rnum; i++){
3112 aLog[indexLog].coords[i] = *ir;
3113 //MESSAGE(" "<<i<<" "<<ir.Value());
3116 for(int i = 0; i < inum; i++){
3117 aLog[indexLog].indexes[i] = *ii;
3118 //MESSAGE(" "<<i<<" "<<ii.Value());
3127 SMESH_CATCH( SMESH::throwCorbaException );
3129 return aLog._retn();
3133 //=============================================================================
3137 //=============================================================================
3139 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3143 SMESH_CATCH( SMESH::throwCorbaException );
3146 //=============================================================================
3150 //=============================================================================
3152 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3157 //=============================================================================
3160 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3161 // issue 0020918: groups removal is caused by hyp modification
3162 // issue 0021208: to forget not loaded mesh data at hyp modification
3163 struct TCallUp_i : public SMESH_Mesh::TCallUp
3165 SMESH_Mesh_i* _mesh;
3166 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3167 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3168 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3169 virtual void Load () { _mesh->Load(); }
3173 //================================================================================
3175 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3177 //================================================================================
3179 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3182 _preMeshInfo->ForgetOrLoad();
3184 SMESH::SMESH_Mesh_var mesh = _this();
3185 _gen_i->UpdateIcons( mesh );
3187 // mark a hypothesis as valid after edition
3188 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3189 SALOMEDS::SObject_wrap hypRoot;
3190 if ( !smeshComp->_is_nil() &&
3191 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3193 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3194 for ( ; anIter->More(); anIter->Next() )
3196 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3197 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3198 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3199 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3200 _gen_i->HighLightInvalid( hyp, false );
3205 //=============================================================================
3209 //=============================================================================
3211 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3213 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3216 _impl->SetCallUp( new TCallUp_i(this));
3219 //=============================================================================
3223 //=============================================================================
3225 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3227 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3231 //=============================================================================
3233 * Return mesh editor
3235 //=============================================================================
3237 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3238 throw (SALOME::SALOME_Exception)
3240 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3244 _preMeshInfo->FullLoadFromFile();
3246 // Create MeshEditor
3248 _editor = new SMESH_MeshEditor_i( this, false );
3249 aMeshEdVar = _editor->_this();
3251 // Update Python script
3252 TPythonDump() << _editor << " = "
3253 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3255 SMESH_CATCH( SMESH::throwCorbaException );
3257 return aMeshEdVar._retn();
3260 //=============================================================================
3262 * Return mesh edition previewer
3264 //=============================================================================
3266 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3267 throw (SALOME::SALOME_Exception)
3269 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3273 _preMeshInfo->FullLoadFromFile();
3275 if ( !_previewEditor )
3276 _previewEditor = new SMESH_MeshEditor_i( this, true );
3277 aMeshEdVar = _previewEditor->_this();
3279 SMESH_CATCH( SMESH::throwCorbaException );
3281 return aMeshEdVar._retn();
3284 //================================================================================
3286 * \brief Return true if the mesh has been edited since a last total re-compute
3287 * and those modifications may prevent successful partial re-compute
3289 //================================================================================
3291 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3293 Unexpect aCatch(SALOME_SalomeException);
3294 return _impl->HasModificationsToDiscard();
3297 //================================================================================
3299 * \brief Returns a random unique color
3301 //================================================================================
3303 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3305 const int MAX_ATTEMPTS = 100;
3307 double tolerance = 0.5;
3308 SALOMEDS::Color col;
3312 // generate random color
3313 double red = (double)rand() / RAND_MAX;
3314 double green = (double)rand() / RAND_MAX;
3315 double blue = (double)rand() / RAND_MAX;
3316 // check existence in the list of the existing colors
3317 bool matched = false;
3318 std::list<SALOMEDS::Color>::const_iterator it;
3319 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3320 SALOMEDS::Color color = *it;
3321 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3322 matched = tol < tolerance;
3324 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3325 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3333 //=============================================================================
3335 * Sets auto-color mode. If it is on, groups get unique random colors
3337 //=============================================================================
3339 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3341 Unexpect aCatch(SALOME_SalomeException);
3342 _impl->SetAutoColor(theAutoColor);
3344 TPythonDump pyDump; // not to dump group->SetColor() from below code
3345 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3347 std::list<SALOMEDS::Color> aReservedColors;
3348 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3349 for ( ; it != _mapGroups.end(); it++ ) {
3350 if ( CORBA::is_nil( it->second )) continue;
3351 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3352 it->second->SetColor( aColor );
3353 aReservedColors.push_back( aColor );
3357 //=============================================================================
3359 * Returns true if auto-color mode is on
3361 //=============================================================================
3363 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3365 Unexpect aCatch(SALOME_SalomeException);
3366 return _impl->GetAutoColor();
3369 //=============================================================================
3371 * Checks if there are groups with equal names
3373 //=============================================================================
3375 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3377 return _impl->HasDuplicatedGroupNamesMED();
3380 //================================================================================
3382 * \brief Care of a file before exporting mesh into it
3384 //================================================================================
3386 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3388 SMESH_File aFile( file, false );
3390 if ( aFile.exists() ) {
3391 // existing filesystem node
3392 if ( !aFile.isDirectory() ) {
3393 if ( aFile.openForWriting() ) {
3394 if ( overwrite && ! aFile.remove()) {
3395 msg << "Can't replace " << aFile.getName();
3398 msg << "Can't write into " << aFile.getName();
3401 msg << "Location " << aFile.getName() << " is not a file";
3405 // nonexisting file; check if it can be created
3406 if ( !aFile.openForWriting() ) {
3407 msg << "You cannot create the file "
3409 << ". Check the directory existence and access rights";
3417 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3421 //================================================================================
3423 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3424 * \param file - file name
3425 * \param overwrite - to erase the file or not
3426 * \retval string - mesh name
3428 //================================================================================
3430 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3431 CORBA::Boolean overwrite)
3434 PrepareForWriting(file, overwrite);
3435 string aMeshName = "Mesh";
3436 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3437 if ( !aStudy->_is_nil() ) {
3438 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3439 if ( !aMeshSO->_is_nil() ) {
3440 CORBA::String_var name = aMeshSO->GetName();
3442 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3443 if ( !aStudy->GetProperties()->IsLocked() )
3445 SALOMEDS::GenericAttribute_wrap anAttr;
3446 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3447 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3448 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3449 ASSERT(!aFileName->_is_nil());
3450 aFileName->SetValue(file);
3451 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3452 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3453 ASSERT(!aFileType->_is_nil());
3454 aFileType->SetValue("FICHIERMED");
3458 // Update Python script
3459 // set name of mesh before export
3460 TPythonDump() << _gen_i << ".SetName("
3461 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3463 // check names of groups
3469 //================================================================================
3471 * \brief Export to MED file
3473 //================================================================================
3475 void SMESH_Mesh_i::ExportMED(const char* file,
3476 CORBA::Boolean auto_groups,
3477 CORBA::Long version,
3478 CORBA::Boolean overwrite,
3479 CORBA::Boolean autoDimension)
3480 throw(SALOME::SALOME_Exception)
3482 //MESSAGE("MED minor version: "<< minor);
3485 _preMeshInfo->FullLoadFromFile();
3487 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3488 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3490 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3492 << "auto_groups=" <<auto_groups << ", "
3493 << "minor=" << version << ", "
3494 << "overwrite=" << overwrite << ", "
3495 << "meshPart=None, "
3496 << "autoDimension=" << autoDimension << " )";
3498 SMESH_CATCH( SMESH::throwCorbaException );
3501 //================================================================================
3503 * \brief Export a mesh to a SAUV file
3505 //================================================================================
3507 void SMESH_Mesh_i::ExportSAUV (const char* file,
3508 CORBA::Boolean auto_groups)
3509 throw(SALOME::SALOME_Exception)
3511 Unexpect aCatch(SALOME_SalomeException);
3513 _preMeshInfo->FullLoadFromFile();
3515 string aMeshName = prepareMeshNameAndGroups(file, true);
3516 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3517 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3518 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3522 //================================================================================
3524 * \brief Export a mesh to a DAT file
3526 //================================================================================
3528 void SMESH_Mesh_i::ExportDAT (const char *file)
3529 throw(SALOME::SALOME_Exception)
3531 Unexpect aCatch(SALOME_SalomeException);
3533 _preMeshInfo->FullLoadFromFile();
3535 // Update Python script
3536 // check names of groups
3538 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3541 PrepareForWriting(file);
3542 _impl->ExportDAT(file);
3545 //================================================================================
3547 * \brief Export a mesh to an UNV file
3549 //================================================================================
3551 void SMESH_Mesh_i::ExportUNV (const char *file)
3552 throw(SALOME::SALOME_Exception)
3554 Unexpect aCatch(SALOME_SalomeException);
3556 _preMeshInfo->FullLoadFromFile();
3558 // Update Python script
3559 // check names of groups
3561 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3564 PrepareForWriting(file);
3565 _impl->ExportUNV(file);
3568 //================================================================================
3570 * \brief Export a mesh to an STL file
3572 //================================================================================
3574 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3575 throw(SALOME::SALOME_Exception)
3577 Unexpect aCatch(SALOME_SalomeException);
3579 _preMeshInfo->FullLoadFromFile();
3581 // Update Python script
3582 // check names of groups
3584 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3585 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3587 CORBA::String_var name;
3588 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3589 if ( !so->_is_nil() )
3590 name = so->GetName();
3593 PrepareForWriting( file );
3594 _impl->ExportSTL( file, isascii, name.in() );
3597 //================================================================================
3599 * \brief Export a part of mesh to a med file
3601 //================================================================================
3603 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3605 CORBA::Boolean auto_groups,
3606 CORBA::Long version,
3607 CORBA::Boolean overwrite,
3608 CORBA::Boolean autoDimension,
3609 const GEOM::ListOfFields& fields,
3610 const char* geomAssocFields,
3611 CORBA::Double ZTolerance)
3612 throw (SALOME::SALOME_Exception)
3614 MESSAGE("MED version: "<< version);
3617 _preMeshInfo->FullLoadFromFile();
3620 bool have0dField = false;
3621 if ( fields.length() > 0 )
3623 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3624 if ( shapeToMesh->_is_nil() )
3625 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3627 for ( size_t i = 0; i < fields.length(); ++i )
3629 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3630 THROW_SALOME_CORBA_EXCEPTION
3631 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3632 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3633 if ( fieldShape->_is_nil() )
3634 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3635 if ( !fieldShape->IsSame( shapeToMesh ) )
3636 THROW_SALOME_CORBA_EXCEPTION
3637 ( "Field defined not on shape", SALOME::BAD_PARAM);
3638 if ( fields[i]->GetDimension() == 0 )
3641 if ( geomAssocFields )
3642 for ( int i = 0; geomAssocFields[i]; ++i )
3643 switch ( geomAssocFields[i] ) {
3644 case 'v':case 'e':case 'f':case 's': break;
3645 case 'V':case 'E':case 'F':case 'S': break;
3646 default: THROW_SALOME_CORBA_EXCEPTION
3647 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3651 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3655 string aMeshName = "Mesh";
3656 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3657 if ( CORBA::is_nil( meshPart ) ||
3658 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3660 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3661 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3662 0, autoDimension, /*addODOnVertices=*/have0dField,
3664 meshDS = _impl->GetMeshDS();
3669 _preMeshInfo->FullLoadFromFile();
3671 PrepareForWriting(file, overwrite);
3673 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3674 if ( !SO->_is_nil() ) {
3675 CORBA::String_var name = SO->GetName();
3679 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3680 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3681 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3682 meshDS = tmpDSDeleter._obj = partDS;
3687 if ( _impl->HasShapeToMesh() )
3689 DriverMED_W_Field fieldWriter;
3690 fieldWriter.SetFile( file );
3691 fieldWriter.SetMeshName( aMeshName );
3692 fieldWriter.AddODOnVertices( have0dField );
3694 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3698 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3699 goList->length( fields.length() );
3700 for ( size_t i = 0; i < fields.length(); ++i )
3702 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3705 TPythonDump() << _this() << ".ExportPartToMED( "
3706 << meshPart << ", r'"
3708 << auto_groups << ", "
3710 << overwrite << ", "
3711 << autoDimension << ", "
3713 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3714 << TVar( ZTolerance )
3717 SMESH_CATCH( SMESH::throwCorbaException );
3720 //================================================================================
3722 * Write GEOM fields to MED file
3724 //================================================================================
3726 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3727 SMESHDS_Mesh* meshDS,
3728 const GEOM::ListOfFields& fields,
3729 const char* geomAssocFields)
3731 #define METH "SMESH_Mesh_i::exportMEDFields() "
3733 if (( fields.length() < 1 ) &&
3734 ( !geomAssocFields || !geomAssocFields[0] ))
3737 std::vector< std::vector< double > > dblVals;
3738 std::vector< std::vector< int > > intVals;
3739 std::vector< int > subIdsByDim[ 4 ];
3740 const double noneDblValue = 0.;
3741 const double noneIntValue = 0;
3743 for ( size_t iF = 0; iF < fields.length(); ++iF )
3747 int dim = fields[ iF ]->GetDimension();
3748 SMDSAbs_ElementType elemType;
3749 TopAbs_ShapeEnum shapeType;
3751 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3752 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3753 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3754 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3756 continue; // skip fields on whole shape
3758 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3759 if ( dataType == GEOM::FDT_String )
3761 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3762 if ( stepIDs->length() < 1 )
3764 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3765 if ( comps->length() < 1 )
3767 CORBA::String_var name = fields[ iF ]->GetName();
3769 if ( !fieldWriter.Set( meshDS,
3773 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3776 for ( size_t iC = 0; iC < comps->length(); ++iC )
3777 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3779 dblVals.resize( comps->length() );
3780 intVals.resize( comps->length() );
3782 // find sub-shape IDs
3784 std::vector< int >& subIds = subIdsByDim[ dim ];
3785 if ( subIds.empty() )
3786 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3787 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3788 subIds.push_back( id );
3792 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3796 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3798 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3799 if ( step->_is_nil() )
3802 CORBA::Long stamp = step->GetStamp();
3803 CORBA::Long id = step->GetID();
3804 fieldWriter.SetDtIt( int( stamp ), int( id ));
3806 // fill dblVals or intVals
3807 for ( size_t iC = 0; iC < comps->length(); ++iC )
3808 if ( dataType == GEOM::FDT_Double )
3810 dblVals[ iC ].clear();
3811 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3815 intVals[ iC ].clear();
3816 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3820 case GEOM::FDT_Double:
3822 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3823 if ( dblStep->_is_nil() ) continue;
3824 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3825 if ( vv->length() != subIds.size() * comps->length() )
3826 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3827 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3828 for ( size_t iC = 0; iC < comps->length(); ++iC )
3829 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3834 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3835 if ( intStep->_is_nil() ) continue;
3836 GEOM::ListOfLong_var vv = intStep->GetValues();
3837 if ( vv->length() != subIds.size() * comps->length() )
3838 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3839 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3840 for ( size_t iC = 0; iC < comps->length(); ++iC )
3841 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3844 case GEOM::FDT_Bool:
3846 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3847 if ( boolStep->_is_nil() ) continue;
3848 GEOM::short_array_var vv = boolStep->GetValues();
3849 if ( vv->length() != subIds.size() * comps->length() )
3850 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3851 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3852 for ( size_t iC = 0; iC < comps->length(); ++iC )
3853 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3859 // pass values to fieldWriter
3860 elemIt = fieldWriter.GetOrderedElems();
3861 if ( dataType == GEOM::FDT_Double )
3862 while ( elemIt->more() )
3864 const SMDS_MeshElement* e = elemIt->next();
3865 const int shapeID = e->getshapeId();
3866 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3867 for ( size_t iC = 0; iC < comps->length(); ++iC )
3868 fieldWriter.AddValue( noneDblValue );
3870 for ( size_t iC = 0; iC < comps->length(); ++iC )
3871 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3874 while ( elemIt->more() )
3876 const SMDS_MeshElement* e = elemIt->next();
3877 const int shapeID = e->getshapeId();
3878 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3879 for ( size_t iC = 0; iC < comps->length(); ++iC )
3880 fieldWriter.AddValue( (double) noneIntValue );
3882 for ( size_t iC = 0; iC < comps->length(); ++iC )
3883 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3887 fieldWriter.Perform();
3888 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3889 if ( res && res->IsKO() )
3891 if ( res->myComment.empty() )
3892 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3894 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3900 if ( !geomAssocFields || !geomAssocFields[0] )
3903 // write geomAssocFields
3905 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3906 shapeDim[ TopAbs_COMPOUND ] = 3;
3907 shapeDim[ TopAbs_COMPSOLID ] = 3;
3908 shapeDim[ TopAbs_SOLID ] = 3;
3909 shapeDim[ TopAbs_SHELL ] = 2;
3910 shapeDim[ TopAbs_FACE ] = 2;
3911 shapeDim[ TopAbs_WIRE ] = 1;
3912 shapeDim[ TopAbs_EDGE ] = 1;
3913 shapeDim[ TopAbs_VERTEX ] = 0;
3914 shapeDim[ TopAbs_SHAPE ] = 3;
3916 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3918 std::vector< std::string > compNames;
3919 switch ( geomAssocFields[ iF ]) {
3921 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3922 compNames.push_back( "dim" );
3925 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3928 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3931 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3935 compNames.push_back( "id" );
3936 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3937 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3939 fieldWriter.SetDtIt( -1, -1 );
3941 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3945 if ( compNames.size() == 2 ) // _vertices_
3946 while ( elemIt->more() )
3948 const SMDS_MeshElement* e = elemIt->next();
3949 const int shapeID = e->getshapeId();
3952 fieldWriter.AddValue( (double) -1 );
3953 fieldWriter.AddValue( (double) -1 );
3957 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3958 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3959 fieldWriter.AddValue( (double) shapeID );
3963 while ( elemIt->more() )
3965 const SMDS_MeshElement* e = elemIt->next();
3966 const int shapeID = e->getshapeId();
3968 fieldWriter.AddValue( (double) -1 );
3970 fieldWriter.AddValue( (double) shapeID );
3974 fieldWriter.Perform();
3975 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3976 if ( res && res->IsKO() )
3978 if ( res->myComment.empty() )
3979 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3981 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3984 } // loop on geomAssocFields
3989 //================================================================================
3991 * \brief Export a part of mesh to a DAT file
3993 //================================================================================
3995 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3997 throw (SALOME::SALOME_Exception)
3999 Unexpect aCatch(SALOME_SalomeException);
4001 _preMeshInfo->FullLoadFromFile();
4003 PrepareForWriting(file);
4005 SMESH_MeshPartDS partDS( meshPart );
4006 _impl->ExportDAT(file,&partDS);
4008 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4009 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4011 //================================================================================
4013 * \brief Export a part of mesh to an UNV file
4015 //================================================================================
4017 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4019 throw (SALOME::SALOME_Exception)
4021 Unexpect aCatch(SALOME_SalomeException);
4023 _preMeshInfo->FullLoadFromFile();
4025 PrepareForWriting(file);
4027 SMESH_MeshPartDS partDS( meshPart );
4028 _impl->ExportUNV(file, &partDS);
4030 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4031 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4033 //================================================================================
4035 * \brief Export a part of mesh to an STL file
4037 //================================================================================
4039 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4041 ::CORBA::Boolean isascii)
4042 throw (SALOME::SALOME_Exception)
4044 Unexpect aCatch(SALOME_SalomeException);
4046 _preMeshInfo->FullLoadFromFile();
4048 PrepareForWriting(file);
4050 CORBA::String_var name;
4051 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4052 if ( !so->_is_nil() )
4053 name = so->GetName();
4055 SMESH_MeshPartDS partDS( meshPart );
4056 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4058 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4059 << meshPart<< ", r'" << file << "', " << isascii << ")";
4062 //================================================================================
4064 * \brief Export a part of mesh to an STL file
4066 //================================================================================
4068 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4070 CORBA::Boolean overwrite,
4071 CORBA::Boolean groupElemsByType)
4072 throw (SALOME::SALOME_Exception)
4075 Unexpect aCatch(SALOME_SalomeException);
4077 _preMeshInfo->FullLoadFromFile();
4079 PrepareForWriting(file,overwrite);
4081 std::string meshName("");
4082 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4083 if ( !so->_is_nil() )
4085 CORBA::String_var name = so->GetName();
4086 meshName = name.in();
4090 SMESH_MeshPartDS partDS( meshPart );
4091 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4093 SMESH_CATCH( SMESH::throwCorbaException );
4095 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4096 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4098 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4102 //================================================================================
4104 * \brief Export a part of mesh to a GMF file
4106 //================================================================================
4108 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4110 bool withRequiredGroups)
4111 throw (SALOME::SALOME_Exception)
4113 Unexpect aCatch(SALOME_SalomeException);
4115 _preMeshInfo->FullLoadFromFile();
4117 PrepareForWriting(file,/*overwrite=*/true);
4119 SMESH_MeshPartDS partDS( meshPart );
4120 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4122 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4123 << meshPart<< ", r'"
4125 << withRequiredGroups << ")";
4128 //=============================================================================
4130 * Return computation progress [0.,1]
4132 //=============================================================================
4134 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4138 return _impl->GetComputeProgress();
4140 SMESH_CATCH( SMESH::doNothing );
4144 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4146 Unexpect aCatch(SALOME_SalomeException);
4148 return _preMeshInfo->NbNodes();
4150 return _impl->NbNodes();
4153 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4155 Unexpect aCatch(SALOME_SalomeException);
4157 return _preMeshInfo->NbElements();
4159 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4162 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4164 Unexpect aCatch(SALOME_SalomeException);
4166 return _preMeshInfo->Nb0DElements();
4168 return _impl->Nb0DElements();
4171 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4173 Unexpect aCatch(SALOME_SalomeException);
4175 return _preMeshInfo->NbBalls();
4177 return _impl->NbBalls();
4180 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4182 Unexpect aCatch(SALOME_SalomeException);
4184 return _preMeshInfo->NbEdges();
4186 return _impl->NbEdges();
4189 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4190 throw(SALOME::SALOME_Exception)
4192 Unexpect aCatch(SALOME_SalomeException);
4194 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4196 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4199 //=============================================================================
4201 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4203 Unexpect aCatch(SALOME_SalomeException);
4205 return _preMeshInfo->NbFaces();
4207 return _impl->NbFaces();
4210 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4212 Unexpect aCatch(SALOME_SalomeException);
4214 return _preMeshInfo->NbTriangles();
4216 return _impl->NbTriangles();
4219 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4221 Unexpect aCatch(SALOME_SalomeException);
4223 return _preMeshInfo->NbBiQuadTriangles();
4225 return _impl->NbBiQuadTriangles();
4228 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4230 Unexpect aCatch(SALOME_SalomeException);
4232 return _preMeshInfo->NbQuadrangles();
4234 return _impl->NbQuadrangles();
4237 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4239 Unexpect aCatch(SALOME_SalomeException);
4241 return _preMeshInfo->NbBiQuadQuadrangles();
4243 return _impl->NbBiQuadQuadrangles();
4246 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4248 Unexpect aCatch(SALOME_SalomeException);
4250 return _preMeshInfo->NbPolygons();
4252 return _impl->NbPolygons();
4255 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4257 Unexpect aCatch(SALOME_SalomeException);
4259 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4261 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4264 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4265 throw(SALOME::SALOME_Exception)
4267 Unexpect aCatch(SALOME_SalomeException);
4269 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4271 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4274 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4275 throw(SALOME::SALOME_Exception)
4277 Unexpect aCatch(SALOME_SalomeException);
4279 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4281 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4284 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4285 throw(SALOME::SALOME_Exception)
4287 Unexpect aCatch(SALOME_SalomeException);
4289 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4291 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4294 //=============================================================================
4296 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4298 Unexpect aCatch(SALOME_SalomeException);
4300 return _preMeshInfo->NbVolumes();
4302 return _impl->NbVolumes();
4305 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4307 Unexpect aCatch(SALOME_SalomeException);
4309 return _preMeshInfo->NbTetras();
4311 return _impl->NbTetras();
4314 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4316 Unexpect aCatch(SALOME_SalomeException);
4318 return _preMeshInfo->NbHexas();
4320 return _impl->NbHexas();
4323 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4325 Unexpect aCatch(SALOME_SalomeException);
4327 return _preMeshInfo->NbTriQuadHexas();
4329 return _impl->NbTriQuadraticHexas();
4332 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4334 Unexpect aCatch(SALOME_SalomeException);
4336 return _preMeshInfo->NbPyramids();
4338 return _impl->NbPyramids();
4341 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4343 Unexpect aCatch(SALOME_SalomeException);
4345 return _preMeshInfo->NbPrisms();
4347 return _impl->NbPrisms();
4350 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4352 Unexpect aCatch(SALOME_SalomeException);
4354 return _preMeshInfo->NbHexPrisms();
4356 return _impl->NbHexagonalPrisms();
4359 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4361 Unexpect aCatch(SALOME_SalomeException);
4363 return _preMeshInfo->NbPolyhedrons();
4365 return _impl->NbPolyhedrons();
4368 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4369 throw(SALOME::SALOME_Exception)
4371 Unexpect aCatch(SALOME_SalomeException);
4373 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4375 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4378 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4379 throw(SALOME::SALOME_Exception)
4381 Unexpect aCatch(SALOME_SalomeException);
4383 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4385 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4388 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4389 throw(SALOME::SALOME_Exception)
4391 Unexpect aCatch(SALOME_SalomeException);
4393 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4395 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4398 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4399 throw(SALOME::SALOME_Exception)
4401 Unexpect aCatch(SALOME_SalomeException);
4403 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4405 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4408 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4409 throw(SALOME::SALOME_Exception)
4411 Unexpect aCatch(SALOME_SalomeException);
4413 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4415 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4418 //=============================================================================
4420 * Returns nb of published sub-meshes
4422 //=============================================================================
4424 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4426 Unexpect aCatch(SALOME_SalomeException);
4427 return _mapSubMesh_i.size();
4430 //=============================================================================
4432 * Dumps mesh into a string
4434 //=============================================================================
4436 char* SMESH_Mesh_i::Dump()
4440 return CORBA::string_dup( os.str().c_str() );
4443 //=============================================================================
4445 * Method of SMESH_IDSource interface
4447 //=============================================================================
4449 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4451 return GetElementsId();
4454 //=============================================================================
4456 * Returns ids of all elements
4458 //=============================================================================
4460 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4461 throw (SALOME::SALOME_Exception)
4463 Unexpect aCatch(SALOME_SalomeException);
4465 _preMeshInfo->FullLoadFromFile();
4467 SMESH::long_array_var aResult = new SMESH::long_array();
4468 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4470 if ( aSMESHDS_Mesh == NULL )
4471 return aResult._retn();
4473 long nbElements = NbElements();
4474 aResult->length( nbElements );
4475 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4476 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4477 aResult[i] = anIt->next()->GetID();
4479 return aResult._retn();
4483 //=============================================================================
4485 * Returns ids of all elements of given type
4487 //=============================================================================
4489 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4490 throw (SALOME::SALOME_Exception)
4492 Unexpect aCatch(SALOME_SalomeException);
4494 _preMeshInfo->FullLoadFromFile();
4496 SMESH::long_array_var aResult = new SMESH::long_array();
4497 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4499 if ( aSMESHDS_Mesh == NULL )
4500 return aResult._retn();
4502 long nbElements = NbElements();
4504 // No sense in returning ids of elements along with ids of nodes:
4505 // when theElemType == SMESH::ALL, return node ids only if
4506 // there are no elements
4507 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4508 return GetNodesId();
4510 aResult->length( nbElements );
4514 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4515 while ( i < nbElements && anIt->more() )
4516 aResult[i++] = anIt->next()->GetID();
4518 aResult->length( i );
4520 return aResult._retn();
4523 //=============================================================================
4525 * Returns ids of all nodes
4527 //=============================================================================
4529 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4530 throw (SALOME::SALOME_Exception)
4532 Unexpect aCatch(SALOME_SalomeException);
4534 _preMeshInfo->FullLoadFromFile();
4536 SMESH::long_array_var aResult = new SMESH::long_array();
4537 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4539 if ( aMeshDS == NULL )
4540 return aResult._retn();
4542 long nbNodes = NbNodes();
4543 aResult->length( nbNodes );
4544 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4545 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4546 aResult[i] = anIt->next()->GetID();
4548 return aResult._retn();
4551 //=============================================================================
4555 //=============================================================================
4557 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4558 throw (SALOME::SALOME_Exception)
4560 SMESH::ElementType type = SMESH::ALL;
4564 _preMeshInfo->FullLoadFromFile();
4566 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4568 SMESH_CATCH( SMESH::throwCorbaException );
4573 //=============================================================================
4577 //=============================================================================
4579 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4580 throw (SALOME::SALOME_Exception)
4583 _preMeshInfo->FullLoadFromFile();
4585 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4587 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4589 return ( SMESH::EntityType ) e->GetEntityType();
4592 //=============================================================================
4596 //=============================================================================
4598 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4599 throw (SALOME::SALOME_Exception)
4602 _preMeshInfo->FullLoadFromFile();
4604 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4606 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4608 return ( SMESH::GeometryType ) e->GetGeomType();
4611 //=============================================================================
4613 * Returns ID of elements for given submesh
4615 //=============================================================================
4616 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4617 throw (SALOME::SALOME_Exception)
4619 SMESH::long_array_var aResult = new SMESH::long_array();
4623 _preMeshInfo->FullLoadFromFile();
4625 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4626 if(!SM) return aResult._retn();
4628 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4629 if(!SDSM) return aResult._retn();
4631 aResult->length(SDSM->NbElements());
4633 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4635 while ( eIt->more() ) {
4636 aResult[i++] = eIt->next()->GetID();
4639 SMESH_CATCH( SMESH::throwCorbaException );
4641 return aResult._retn();
4644 //=============================================================================
4646 * Returns ID of nodes for given submesh
4647 * If param all==true - returns all nodes, else -
4648 * returns only nodes on shapes.
4650 //=============================================================================
4652 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4654 throw (SALOME::SALOME_Exception)
4656 SMESH::long_array_var aResult = new SMESH::long_array();
4660 _preMeshInfo->FullLoadFromFile();
4662 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4663 if(!SM) return aResult._retn();
4665 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4666 if(!SDSM) return aResult._retn();
4669 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4670 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4671 while ( nIt->more() ) {
4672 const SMDS_MeshNode* elem = nIt->next();
4673 theElems.insert( elem->GetID() );
4676 else { // all nodes of submesh elements
4677 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4678 while ( eIt->more() ) {
4679 const SMDS_MeshElement* anElem = eIt->next();
4680 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4681 while ( nIt->more() ) {
4682 const SMDS_MeshElement* elem = nIt->next();
4683 theElems.insert( elem->GetID() );
4688 aResult->length(theElems.size());
4689 set<int>::iterator itElem;
4691 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4692 aResult[i++] = *itElem;
4694 SMESH_CATCH( SMESH::throwCorbaException );
4696 return aResult._retn();
4699 //=============================================================================
4701 * Returns type of elements for given submesh
4703 //=============================================================================
4705 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4706 throw (SALOME::SALOME_Exception)
4708 SMESH::ElementType type = SMESH::ALL;
4712 _preMeshInfo->FullLoadFromFile();
4714 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4715 if(!SM) return SMESH::ALL;
4717 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4718 if(!SDSM) return SMESH::ALL;
4720 if(SDSM->NbElements()==0)
4721 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4723 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4724 const SMDS_MeshElement* anElem = eIt->next();
4726 type = ( SMESH::ElementType ) anElem->GetType();
4728 SMESH_CATCH( SMESH::throwCorbaException );
4734 //=============================================================================
4736 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4738 //=============================================================================
4740 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4743 _preMeshInfo->FullLoadFromFile();
4745 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4746 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4751 //=============================================================================
4753 * Get XYZ coordinates of node as list of double
4754 * If there is not node for given ID - returns empty list
4756 //=============================================================================
4758 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4761 _preMeshInfo->FullLoadFromFile();
4763 SMESH::double_array_var aResult = new SMESH::double_array();
4764 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4765 if ( aMeshDS == NULL )
4766 return aResult._retn();
4769 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4771 return aResult._retn();
4775 aResult[0] = aNode->X();
4776 aResult[1] = aNode->Y();
4777 aResult[2] = aNode->Z();
4778 return aResult._retn();
4782 //=============================================================================
4784 * For given node returns list of IDs of inverse elements
4785 * If there is not node for given ID - returns empty list
4787 //=============================================================================
4789 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4790 SMESH::ElementType elemType)
4793 _preMeshInfo->FullLoadFromFile();
4795 SMESH::long_array_var aResult = new SMESH::long_array();
4796 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4797 if ( aMeshDS == NULL )
4798 return aResult._retn();
4801 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4803 return aResult._retn();
4805 // find inverse elements
4806 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4807 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4808 aResult->length( aNode->NbInverseElements( type ));
4809 for( int i = 0; eIt->more(); ++i )
4811 const SMDS_MeshElement* elem = eIt->next();
4812 aResult[ i ] = elem->GetID();
4814 return aResult._retn();
4817 //=============================================================================
4819 * \brief Return position of a node on shape
4821 //=============================================================================
4823 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4826 _preMeshInfo->FullLoadFromFile();
4828 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4829 aNodePosition->shapeID = 0;
4830 aNodePosition->shapeType = GEOM::SHAPE;
4832 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4833 if ( !mesh ) return aNodePosition;
4835 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4837 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4839 aNodePosition->shapeID = aNode->getshapeId();
4840 switch ( pos->GetTypeOfPosition() ) {
4842 aNodePosition->shapeType = GEOM::EDGE;
4843 aNodePosition->params.length(1);
4844 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4846 case SMDS_TOP_FACE: {
4847 SMDS_FacePositionPtr fPos = pos;
4848 aNodePosition->shapeType = GEOM::FACE;
4849 aNodePosition->params.length(2);
4850 aNodePosition->params[0] = fPos->GetUParameter();
4851 aNodePosition->params[1] = fPos->GetVParameter();
4854 case SMDS_TOP_VERTEX:
4855 aNodePosition->shapeType = GEOM::VERTEX;
4857 case SMDS_TOP_3DSPACE:
4858 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4859 aNodePosition->shapeType = GEOM::SOLID;
4860 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4861 aNodePosition->shapeType = GEOM::SHELL;
4867 return aNodePosition;
4870 //=============================================================================
4872 * \brief Return position of an element on shape
4874 //=============================================================================
4876 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4879 _preMeshInfo->FullLoadFromFile();
4881 SMESH::ElementPosition anElementPosition;
4882 anElementPosition.shapeID = 0;
4883 anElementPosition.shapeType = GEOM::SHAPE;
4885 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4886 if ( !mesh ) return anElementPosition;
4888 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4890 anElementPosition.shapeID = anElem->getshapeId();
4891 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4892 if ( !aSp.IsNull() ) {
4893 switch ( aSp.ShapeType() ) {
4895 anElementPosition.shapeType = GEOM::EDGE;
4898 anElementPosition.shapeType = GEOM::FACE;
4901 anElementPosition.shapeType = GEOM::VERTEX;
4904 anElementPosition.shapeType = GEOM::SOLID;
4907 anElementPosition.shapeType = GEOM::SHELL;
4913 return anElementPosition;
4916 //=============================================================================
4918 * If given element is node returns IDs of shape from position
4919 * If there is not node for given ID - returns -1
4921 //=============================================================================
4923 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4926 _preMeshInfo->FullLoadFromFile();
4928 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4929 if ( aMeshDS == NULL )
4933 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4935 return aNode->getshapeId();
4942 //=============================================================================
4944 * For given element returns ID of result shape after
4945 * ::FindShape() from SMESH_MeshEditor
4946 * If there is not element for given ID - returns -1
4948 //=============================================================================
4950 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4953 _preMeshInfo->FullLoadFromFile();
4955 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4956 if ( aMeshDS == NULL )
4959 // try to find element
4960 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4964 ::SMESH_MeshEditor aMeshEditor(_impl);
4965 int index = aMeshEditor.FindShape( elem );
4973 //=============================================================================
4975 * Returns number of nodes for given element
4976 * If there is not element for given ID - returns -1
4978 //=============================================================================
4980 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4983 _preMeshInfo->FullLoadFromFile();
4985 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4986 if ( aMeshDS == NULL ) return -1;
4987 // try to find element
4988 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4989 if(!elem) return -1;
4990 return elem->NbNodes();
4994 //=============================================================================
4996 * Returns ID of node by given index for given element
4997 * If there is not element for given ID - returns -1
4998 * If there is not node for given index - returns -2
5000 //=============================================================================
5002 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5005 _preMeshInfo->FullLoadFromFile();
5007 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5008 if ( aMeshDS == NULL ) return -1;
5009 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5010 if(!elem) return -1;
5011 if( index>=elem->NbNodes() || index<0 ) return -1;
5012 return elem->GetNode(index)->GetID();
5015 //=============================================================================
5017 * Returns IDs of nodes of given element
5019 //=============================================================================
5021 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5024 _preMeshInfo->FullLoadFromFile();
5026 SMESH::long_array_var aResult = new SMESH::long_array();
5027 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5029 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5031 aResult->length( elem->NbNodes() );
5032 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5033 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5034 aResult[ i ] = n->GetID();
5037 return aResult._retn();
5040 //=============================================================================
5042 * Returns true if given node is medium node
5043 * in given quadratic element
5045 //=============================================================================
5047 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5050 _preMeshInfo->FullLoadFromFile();
5052 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5053 if ( aMeshDS == NULL ) return false;
5055 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5056 if(!aNode) return false;
5057 // try to find element
5058 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5059 if(!elem) return false;
5061 return elem->IsMediumNode(aNode);
5065 //=============================================================================
5067 * Returns true if given node is medium node
5068 * in one of quadratic elements
5070 //=============================================================================
5072 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5073 SMESH::ElementType theElemType)
5076 _preMeshInfo->FullLoadFromFile();
5078 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5079 if ( aMeshDS == NULL ) return false;
5082 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5083 if(!aNode) return false;
5085 SMESH_MesherHelper aHelper( *(_impl) );
5087 SMDSAbs_ElementType aType;
5088 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5089 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5090 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5091 else aType = SMDSAbs_All;
5093 return aHelper.IsMedium(aNode,aType);
5097 //=============================================================================
5099 * Returns number of edges for given element
5101 //=============================================================================
5103 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5106 _preMeshInfo->FullLoadFromFile();
5108 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5109 if ( aMeshDS == NULL ) return -1;
5110 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5111 if(!elem) return -1;
5112 return elem->NbEdges();
5116 //=============================================================================
5118 * Returns number of faces for given element
5120 //=============================================================================
5122 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5125 _preMeshInfo->FullLoadFromFile();
5127 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5128 if ( aMeshDS == NULL ) return -1;
5129 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5130 if(!elem) return -1;
5131 return elem->NbFaces();
5134 //=======================================================================
5135 //function : GetElemFaceNodes
5136 //purpose : Returns nodes of given face (counted from zero) for given element.
5137 //=======================================================================
5139 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5140 CORBA::Short faceIndex)
5143 _preMeshInfo->FullLoadFromFile();
5145 SMESH::long_array_var aResult = new SMESH::long_array();
5146 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5148 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5150 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5151 if ( faceIndex < vtool.NbFaces() )
5153 aResult->length( vtool.NbFaceNodes( faceIndex ));
5154 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5155 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5156 aResult[ i ] = nn[ i ]->GetID();
5160 return aResult._retn();
5163 //=======================================================================
5164 //function : GetFaceNormal
5165 //purpose : Returns three components of normal of given mesh face.
5166 //=======================================================================
5168 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5169 CORBA::Boolean normalized)
5172 _preMeshInfo->FullLoadFromFile();
5174 SMESH::double_array_var aResult = new SMESH::double_array();
5176 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5179 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5181 aResult->length( 3 );
5182 aResult[ 0 ] = normal.X();
5183 aResult[ 1 ] = normal.Y();
5184 aResult[ 2 ] = normal.Z();
5187 return aResult._retn();
5190 //=======================================================================
5191 //function : FindElementByNodes
5192 //purpose : Returns an element based on all given nodes.
5193 //=======================================================================
5195 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5198 _preMeshInfo->FullLoadFromFile();
5200 CORBA::Long elemID(0);
5201 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5203 vector< const SMDS_MeshNode * > nn( nodes.length() );
5204 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5205 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5208 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5209 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5210 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5211 _impl->NbVolumes( ORDER_QUADRATIC )))
5212 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5214 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5219 //================================================================================
5221 * \brief Return elements including all given nodes.
5223 //================================================================================
5225 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5226 SMESH::ElementType elemType)
5229 _preMeshInfo->FullLoadFromFile();
5231 SMESH::long_array_var result = new SMESH::long_array();
5233 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5235 vector< const SMDS_MeshNode * > nn( nodes.length() );
5236 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5237 nn[i] = mesh->FindNode( nodes[i] );
5239 std::vector<const SMDS_MeshElement *> elems;
5240 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5241 result->length( elems.size() );
5242 for ( size_t i = 0; i < elems.size(); ++i )
5243 result[i] = elems[i]->GetID();
5245 return result._retn();
5248 //=============================================================================
5250 * Returns true if given element is polygon
5252 //=============================================================================
5254 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5257 _preMeshInfo->FullLoadFromFile();
5259 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5260 if ( aMeshDS == NULL ) return false;
5261 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5262 if(!elem) return false;
5263 return elem->IsPoly();
5267 //=============================================================================
5269 * Returns true if given element is quadratic
5271 //=============================================================================
5273 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5276 _preMeshInfo->FullLoadFromFile();
5278 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5279 if ( aMeshDS == NULL ) return false;
5280 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5281 if(!elem) return false;
5282 return elem->IsQuadratic();
5285 //=============================================================================
5287 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5289 //=============================================================================
5291 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5294 _preMeshInfo->FullLoadFromFile();
5296 if ( const SMDS_BallElement* ball =
5297 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5298 return ball->GetDiameter();
5303 //=============================================================================
5305 * Returns bary center for given element
5307 //=============================================================================
5309 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5312 _preMeshInfo->FullLoadFromFile();
5314 SMESH::double_array_var aResult = new SMESH::double_array();
5315 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5316 if ( aMeshDS == NULL )
5317 return aResult._retn();
5319 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5321 return aResult._retn();
5323 if(elem->GetType()==SMDSAbs_Volume) {
5324 SMDS_VolumeTool aTool;
5325 if(aTool.Set(elem)) {
5327 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5332 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5334 double x=0., y=0., z=0.;
5335 for(; anIt->more(); ) {
5337 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5351 return aResult._retn();
5354 //================================================================================
5356 * \brief Create a group of elements preventing computation of a sub-shape
5358 //================================================================================
5360 SMESH::ListOfGroups*
5361 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5362 const char* theGroupName )
5363 throw ( SALOME::SALOME_Exception )
5365 Unexpect aCatch(SALOME_SalomeException);
5367 if ( !theGroupName || strlen( theGroupName) == 0 )
5368 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5370 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5371 ::SMESH_MeshEditor::ElemFeatures elemType;
5373 // submesh by subshape id
5374 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5375 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5378 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5379 if ( error && error->HasBadElems() )
5381 // sort bad elements by type
5382 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5383 const list<const SMDS_MeshElement*>& badElems =
5384 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5385 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5386 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5387 for ( ; elemIt != elemEnd; ++elemIt )
5389 const SMDS_MeshElement* elem = *elemIt;
5390 if ( !elem ) continue;
5392 if ( elem->GetID() < 1 )
5394 // elem is a temporary element, make a real element
5395 vector< const SMDS_MeshNode* > nodes;
5396 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5397 while ( nIt->more() && elem )
5399 nodes.push_back( nIt->next() );
5400 if ( nodes.back()->GetID() < 1 )
5401 elem = 0; // a temporary element on temporary nodes
5405 ::SMESH_MeshEditor editor( _impl );
5406 elem = editor.AddElement( nodes, elemType.Init( elem ));
5410 elemsByType[ elem->GetType() ].push_back( elem );
5413 // how many groups to create?
5415 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5416 nbTypes += int( !elemsByType[ i ].empty() );
5417 groups->length( nbTypes );
5420 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5422 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5423 if ( elems.empty() ) continue;
5425 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5426 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5428 SMESH::SMESH_Mesh_var mesh = _this();
5429 SALOMEDS::SObject_wrap aSO =
5430 _gen_i->PublishGroup( mesh, groups[ iG ],
5431 GEOM::GEOM_Object::_nil(), theGroupName);
5433 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5434 if ( !grp_i ) continue;
5436 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5437 for ( size_t iE = 0; iE < elems.size(); ++iE )
5438 grpDS->SMDSGroup().Add( elems[ iE ]);
5443 return groups._retn();
5446 //=============================================================================
5448 * Create and publish group servants if any groups were imported or created anyhow
5450 //=============================================================================
5452 void SMESH_Mesh_i::CreateGroupServants()
5454 SMESH::SMESH_Mesh_var aMesh = _this();
5457 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5458 while ( groupIt->more() )
5460 ::SMESH_Group* group = groupIt->next();
5461 int anId = group->GetID();
5463 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5464 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5466 addedIDs.insert( anId );
5468 SMESH_GroupBase_i* aGroupImpl;
5470 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5471 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5473 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5474 shape = groupOnGeom->GetShape();
5477 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5480 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5481 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5482 aGroupImpl->Register();
5484 // register CORBA object for persistence
5485 int nextId = _gen_i->RegisterObject( groupVar );
5486 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5487 else { nextId = 0; } // avoid "unused variable" warning in release mode
5489 // publishing the groups in the study
5490 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5491 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5493 if ( !addedIDs.empty() )
5496 set<int>::iterator id = addedIDs.begin();
5497 for ( ; id != addedIDs.end(); ++id )
5499 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5500 int i = std::distance( _mapGroups.begin(), it );
5501 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5506 //=============================================================================
5508 * \brief Return true if all sub-meshes are computed OK - to update an icon
5510 //=============================================================================
5512 bool SMESH_Mesh_i::IsComputedOK()
5514 return _impl->IsComputedOK();
5517 //=============================================================================
5519 * \brief Return groups cantained in _mapGroups by their IDs
5521 //=============================================================================
5523 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5525 int nbGroups = groupIDs.size();
5526 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5527 aList->length( nbGroups );
5529 list<int>::const_iterator ids = groupIDs.begin();
5530 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5532 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5533 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5534 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5536 aList->length( nbGroups );
5537 return aList._retn();
5540 //=============================================================================
5542 * \brief Return information about imported file
5544 //=============================================================================
5546 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5548 SMESH::MedFileInfo_var res( _medFileInfo );
5549 if ( !res.operator->() ) {
5550 res = new SMESH::MedFileInfo;
5552 res->fileSize = res->major = res->minor = res->release = -1;
5557 //=======================================================================
5558 //function : FileInfoToString
5559 //purpose : Persistence of file info
5560 //=======================================================================
5562 std::string SMESH_Mesh_i::FileInfoToString()
5565 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5567 s = SMESH_Comment( _medFileInfo->fileSize )
5568 << " " << _medFileInfo->major
5569 << " " << _medFileInfo->minor
5570 << " " << _medFileInfo->release
5571 << " " << _medFileInfo->fileName;
5576 //=======================================================================
5577 //function : FileInfoFromString
5578 //purpose : Persistence of file info
5579 //=======================================================================
5581 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5583 std::string size, major, minor, release, fileName;
5584 std::istringstream is(info);
5585 is >> size >> major >> minor >> release;
5586 fileName = info.data() + ( size.size() + 1 +
5589 release.size()+ 1 );
5591 _medFileInfo = new SMESH::MedFileInfo();
5592 _medFileInfo->fileName = fileName.c_str();
5593 _medFileInfo->fileSize = atoi( size.c_str() );
5594 _medFileInfo->major = atoi( major.c_str() );
5595 _medFileInfo->minor = atoi( minor.c_str() );
5596 _medFileInfo->release = atoi( release.c_str() );
5599 //=============================================================================
5601 * \brief Pass names of mesh groups from study to mesh DS
5603 //=============================================================================
5605 void SMESH_Mesh_i::checkGroupNames()
5607 int nbGrp = NbGroups();
5611 SMESH::ListOfGroups* grpList = 0;
5612 // avoid dump of "GetGroups"
5614 // store python dump into a local variable inside local scope
5615 SMESH::TPythonDump pDump; // do not delete this line of code
5616 grpList = GetGroups();
5619 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5620 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5623 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5624 if ( aGrpSO->_is_nil() )
5626 // correct name of the mesh group if necessary
5627 const char* guiName = aGrpSO->GetName();
5628 if ( strcmp(guiName, aGrp->GetName()) )
5629 aGrp->SetName( guiName );
5633 //=============================================================================
5635 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5637 //=============================================================================
5638 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5640 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5644 //=============================================================================
5646 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5648 //=============================================================================
5650 char* SMESH_Mesh_i::GetParameters()
5652 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5655 //=============================================================================
5657 * \brief Returns list of notebook variables used for last Mesh operation
5659 //=============================================================================
5660 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5662 SMESH::string_array_var aResult = new SMESH::string_array();
5663 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5665 CORBA::String_var aParameters = GetParameters();
5666 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5667 if ( aSections->length() > 0 ) {
5668 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5669 aResult->length( aVars.length() );
5670 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5671 aResult[i] = CORBA::string_dup( aVars[i] );
5674 return aResult._retn();
5677 //=======================================================================
5678 //function : GetTypes
5679 //purpose : Returns types of elements it contains
5680 //=======================================================================
5682 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5685 return _preMeshInfo->GetTypes();
5687 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5691 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5692 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5693 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5694 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5695 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5696 if (_impl->NbNodes() &&
5697 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5698 types->length( nbTypes );
5700 return types._retn();
5703 //=======================================================================
5704 //function : GetMesh
5705 //purpose : Returns self
5706 //=======================================================================
5708 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5710 return SMESH::SMESH_Mesh::_duplicate( _this() );
5713 //=======================================================================
5714 //function : IsMeshInfoCorrect
5715 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5716 // * happen if mesh data is not yet fully loaded from the file of study.
5717 //=======================================================================
5719 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5721 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5724 //=============================================================================
5726 * \brief Returns number of mesh elements per each \a EntityType
5728 //=============================================================================
5730 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5733 return _preMeshInfo->GetMeshInfo();
5735 SMESH::long_array_var aRes = new SMESH::long_array();
5736 aRes->length(SMESH::Entity_Last);
5737 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5739 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5741 return aRes._retn();
5742 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5743 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5744 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5745 return aRes._retn();
5748 //=============================================================================
5750 * \brief Returns number of mesh elements per each \a ElementType
5752 //=============================================================================
5754 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5756 SMESH::long_array_var aRes = new SMESH::long_array();
5757 aRes->length(SMESH::NB_ELEMENT_TYPES);
5758 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5761 const SMDS_MeshInfo* meshInfo = 0;
5763 meshInfo = _preMeshInfo;
5764 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5765 meshInfo = & meshDS->GetMeshInfo();
5768 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5769 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5771 return aRes._retn();
5774 //=============================================================================
5776 * Collect statistic of mesh elements given by iterator
5778 //=============================================================================
5780 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5781 SMESH::long_array& theInfo)
5783 if (!theItr) return;
5784 while (theItr->more())
5785 theInfo[ theItr->next()->GetEntityType() ]++;
5787 //=============================================================================
5789 * Returns mesh unstructed grid information.
5791 //=============================================================================
5793 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5795 SALOMEDS::TMPFile_var SeqFile;
5796 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5797 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5799 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5800 aWriter->WriteToOutputStringOn();
5801 aWriter->SetInputData(aGrid);
5802 aWriter->SetFileTypeToBinary();
5804 char* str = aWriter->GetOutputString();
5805 int size = aWriter->GetOutputStringLength();
5807 //Allocate octet buffer of required size
5808 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5809 //Copy ostrstream content to the octet buffer
5810 memcpy(OctetBuf, str, size);
5811 //Create and return TMPFile
5812 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5816 return SeqFile._retn();
5819 //=============================================================================
5820 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5821 * SMESH::ElementType type) */
5823 using namespace SMESH::Controls;
5824 //-----------------------------------------------------------------------------
5825 struct PredicateIterator : public SMDS_ElemIterator
5827 SMDS_ElemIteratorPtr _elemIter;
5828 PredicatePtr _predicate;
5829 const SMDS_MeshElement* _elem;
5830 SMDSAbs_ElementType _type;
5832 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5833 PredicatePtr predicate,
5834 SMDSAbs_ElementType type):
5835 _elemIter(iterator), _predicate(predicate), _type(type)
5843 virtual const SMDS_MeshElement* next()
5845 const SMDS_MeshElement* res = _elem;
5847 while ( _elemIter->more() && !_elem )
5849 if ((_elem = _elemIter->next()) &&
5850 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5851 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5858 //-----------------------------------------------------------------------------
5859 struct IDSourceIterator : public SMDS_ElemIterator
5861 const CORBA::Long* _idPtr;
5862 const CORBA::Long* _idEndPtr;
5863 SMESH::long_array_var _idArray;
5864 const SMDS_Mesh* _mesh;
5865 const SMDSAbs_ElementType _type;
5866 const SMDS_MeshElement* _elem;
5868 IDSourceIterator( const SMDS_Mesh* mesh,
5869 const CORBA::Long* ids,
5871 SMDSAbs_ElementType type):
5872 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5874 if ( _idPtr && nbIds && _mesh )
5877 IDSourceIterator( const SMDS_Mesh* mesh,
5878 SMESH::long_array* idArray,
5879 SMDSAbs_ElementType type):
5880 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5882 if ( idArray && _mesh )
5884 _idPtr = &_idArray[0];
5885 _idEndPtr = _idPtr + _idArray->length();
5893 virtual const SMDS_MeshElement* next()
5895 const SMDS_MeshElement* res = _elem;
5897 while ( _idPtr < _idEndPtr && !_elem )
5899 if ( _type == SMDSAbs_Node )
5901 _elem = _mesh->FindNode( *_idPtr++ );
5903 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5904 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5912 //-----------------------------------------------------------------------------
5914 struct NodeOfElemIterator : public SMDS_ElemIterator
5916 TColStd_MapOfInteger _checkedNodeIDs;
5917 SMDS_ElemIteratorPtr _elemIter;
5918 SMDS_ElemIteratorPtr _nodeIter;
5919 const SMDS_MeshElement* _node;
5921 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5923 if ( _elemIter && _elemIter->more() )
5925 _nodeIter = _elemIter->next()->nodesIterator();
5933 virtual const SMDS_MeshElement* next()
5935 const SMDS_MeshElement* res = _node;
5937 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5939 if ( _nodeIter->more() )
5941 _node = _nodeIter->next();
5942 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5947 _nodeIter = _elemIter->next()->nodesIterator();
5955 //=============================================================================
5957 * Return iterator on elements of given type in given object
5959 //=============================================================================
5961 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5962 SMESH::ElementType theType)
5964 SMDS_ElemIteratorPtr elemIt;
5965 bool typeOK = ( theType == SMESH::ALL );
5966 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5968 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5969 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5970 if ( !mesh_i ) return elemIt;
5971 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5973 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5975 elemIt = meshDS->elementsIterator( elemType );
5978 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5980 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5983 elemIt = sm->GetElements();
5984 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5986 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5987 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5991 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5993 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5994 if ( groupDS && ( elemType == groupDS->GetType() ||
5995 elemType == SMDSAbs_Node ||
5996 elemType == SMDSAbs_All ))
5998 elemIt = groupDS->GetElements();
5999 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6002 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6004 if ( filter_i->GetElementType() == theType ||
6005 filter_i->GetElementType() == SMESH::ALL ||
6006 elemType == SMDSAbs_Node ||
6007 elemType == SMDSAbs_All)
6009 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6010 if ( pred_i && pred_i->GetPredicate() )
6012 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6013 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6014 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6015 elemIt = SMDS_ElemIteratorPtr
6016 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6017 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6023 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6024 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6025 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6027 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6028 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6031 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6032 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6036 SMESH::long_array_var ids = theObject->GetIDs();
6037 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6039 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6042 if ( elemIt && elemIt->more() && !typeOK )
6044 if ( elemType == SMDSAbs_Node )
6046 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6050 elemIt = SMDS_ElemIteratorPtr();
6056 //=============================================================================
6057 namespace // Finding concurrent hypotheses
6058 //=============================================================================
6062 * \brief mapping of mesh dimension into shape type
6064 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6066 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6068 case 0: aType = TopAbs_VERTEX; break;
6069 case 1: aType = TopAbs_EDGE; break;
6070 case 2: aType = TopAbs_FACE; break;
6072 default:aType = TopAbs_SOLID; break;
6077 //-----------------------------------------------------------------------------
6079 * \brief Internal structure used to find concurrent submeshes
6081 * It represents a pair < submesh, concurrent dimension >, where
6082 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6083 * with another submesh. In other words, it is dimension of a hypothesis assigned
6090 int _dim; //!< a dimension the algo can build (concurrent dimension)
6091 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6092 TopTools_MapOfShape _shapeMap;
6093 SMESH_subMesh* _subMesh;
6094 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6096 //-----------------------------------------------------------------------------
6097 // Return the algorithm
6098 const SMESH_Algo* GetAlgo() const
6099 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6101 //-----------------------------------------------------------------------------
6103 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6105 const TopoDS_Shape& theShape)
6107 _subMesh = (SMESH_subMesh*)theSubMesh;
6108 SetShape( theDim, theShape );
6111 //-----------------------------------------------------------------------------
6113 void SetShape(const int theDim,
6114 const TopoDS_Shape& theShape)
6117 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6118 if (_dim >= _ownDim)
6119 _shapeMap.Add( theShape );
6121 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6122 for( ; anExp.More(); anExp.Next() )
6123 _shapeMap.Add( anExp.Current() );
6127 //-----------------------------------------------------------------------------
6128 //! Check sharing of sub-shapes
6129 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6130 const TopTools_MapOfShape& theToFind,
6131 const TopAbs_ShapeEnum theType)
6133 bool isShared = false;
6134 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6135 for (; !isShared && anItr.More(); anItr.Next() )
6137 const TopoDS_Shape aSubSh = anItr.Key();
6138 // check for case when concurrent dimensions are same
6139 isShared = theToFind.Contains( aSubSh );
6140 // check for sub-shape with concurrent dimension
6141 TopExp_Explorer anExp( aSubSh, theType );
6142 for ( ; !isShared && anExp.More(); anExp.Next() )
6143 isShared = theToFind.Contains( anExp.Current() );
6148 //-----------------------------------------------------------------------------
6149 //! check algorithms
6150 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6151 const SMESHDS_Hypothesis* theA2)
6153 if ( !theA1 || !theA2 ||
6154 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6155 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6156 return false; // one of the hypothesis is not algorithm
6157 // check algorithm names (should be equal)
6158 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6162 //-----------------------------------------------------------------------------
6163 //! Check if sub-shape hypotheses are concurrent
6164 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6166 if ( _subMesh == theOther->_subMesh )
6167 return false; // same sub-shape - should not be
6169 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6170 // any of the two submeshes is not on COMPOUND shape )
6171 // -> no concurrency
6172 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6173 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6174 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6175 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6176 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6179 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6180 if ( !checkSubShape )
6183 // check algorithms to be same
6184 const SMESH_Algo* a1 = this->GetAlgo();
6185 const SMESH_Algo* a2 = theOther->GetAlgo();
6186 bool isSame = checkAlgo( a1, a2 );
6190 return false; // pb?
6191 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6194 // check hypothesises for concurrence (skip first as algorithm)
6196 // pointers should be same, because it is referened from mesh hypothesis partition
6197 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6198 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6199 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6200 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6202 // the submeshes are concurrent if their algorithms has different parameters
6203 return nbSame != theOther->_hypotheses.size() - 1;
6206 // Return true if algorithm of this SMESH_DimHyp is used if no
6207 // sub-mesh order is imposed by the user
6208 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6210 // NeedDiscreteBoundary() algo has a higher priority
6211 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6212 theOther->GetAlgo()->NeedDiscreteBoundary() )
6213 return !this->GetAlgo()->NeedDiscreteBoundary();
6215 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6218 }; // end of SMESH_DimHyp
6219 //-----------------------------------------------------------------------------
6221 typedef list<const SMESH_DimHyp*> TDimHypList;
6223 //-----------------------------------------------------------------------------
6225 void addDimHypInstance(const int theDim,
6226 const TopoDS_Shape& theShape,
6227 const SMESH_Algo* theAlgo,
6228 const SMESH_subMesh* theSubMesh,
6229 const list <const SMESHDS_Hypothesis*>& theHypList,
6230 TDimHypList* theDimHypListArr )
6232 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6233 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6234 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6235 dimHyp->_hypotheses.push_front(theAlgo);
6236 listOfdimHyp.push_back( dimHyp );
6239 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6240 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6241 theHypList.begin(), theHypList.end() );
6244 //-----------------------------------------------------------------------------
6245 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6246 TDimHypList& theListOfConcurr)
6248 if ( theListOfConcurr.empty() )
6250 theListOfConcurr.push_back( theDimHyp );
6254 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6255 while ( hypIt != theListOfConcurr.end() &&
6256 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6258 theListOfConcurr.insert( hypIt, theDimHyp );
6262 //-----------------------------------------------------------------------------
6263 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6264 const TDimHypList& theListOfDimHyp,
6265 TDimHypList& theListOfConcurrHyp,
6266 set<int>& theSetOfConcurrId )
6268 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6269 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6271 const SMESH_DimHyp* curDimHyp = *rIt;
6272 if ( curDimHyp == theDimHyp )
6273 break; // meet own dimHyp pointer in same dimension
6275 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6276 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6278 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6283 //-----------------------------------------------------------------------------
6284 void unionLists(TListOfInt& theListOfId,
6285 TListOfListOfInt& theListOfListOfId,
6288 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6289 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6291 continue; //skip already treated lists
6292 // check if other list has any same submesh object
6293 TListOfInt& otherListOfId = *it;
6294 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6295 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6298 // union two lists (from source into target)
6299 TListOfInt::iterator it2 = otherListOfId.begin();
6300 for ( ; it2 != otherListOfId.end(); it2++ ) {
6301 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6302 theListOfId.push_back(*it2);
6304 // clear source list
6305 otherListOfId.clear();
6308 //-----------------------------------------------------------------------------
6310 //! free memory allocated for dimension-hypothesis objects
6311 void removeDimHyps( TDimHypList* theArrOfList )
6313 for (int i = 0; i < 4; i++ ) {
6314 TDimHypList& listOfdimHyp = theArrOfList[i];
6315 TDimHypList::const_iterator it = listOfdimHyp.begin();
6316 for ( ; it != listOfdimHyp.end(); it++ )
6321 //-----------------------------------------------------------------------------
6323 * \brief find common submeshes with given submesh
6324 * \param theSubMeshList list of already collected submesh to check
6325 * \param theSubMesh given submesh to intersect with other
6326 * \param theCommonSubMeshes collected common submeshes
6328 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6329 const SMESH_subMesh* theSubMesh,
6330 set<const SMESH_subMesh*>& theCommon )
6334 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6335 for ( ; it != theSubMeshList.end(); it++ )
6336 theSubMesh->FindIntersection( *it, theCommon );
6337 theSubMeshList.push_back( theSubMesh );
6338 //theCommon.insert( theSubMesh );
6341 //-----------------------------------------------------------------------------
6342 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6344 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6345 for ( ; listsIt != smLists.end(); ++listsIt )
6347 const TListOfInt& smIDs = *listsIt;
6348 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6356 //=============================================================================
6358 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6360 //=============================================================================
6362 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6364 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6365 if ( isSubMeshInList( submeshID, anOrder ))
6368 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6369 return isSubMeshInList( submeshID, allConurrent );
6372 //=============================================================================
6374 * \brief Return submesh objects list in meshing order
6376 //=============================================================================
6378 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6380 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6382 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6384 return aResult._retn();
6386 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6387 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6388 anOrder.splice( anOrder.end(), allConurrent );
6391 TListOfListOfInt::iterator listIt = anOrder.begin();
6392 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6393 unionLists( *listIt, anOrder, listIndx + 1 );
6395 // convert submesh ids into interface instances
6396 // and dump command into python
6397 convertMeshOrder( anOrder, aResult, false );
6399 return aResult._retn();
6402 //=============================================================================
6404 * \brief Finds concurrent sub-meshes
6406 //=============================================================================
6408 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6410 TListOfListOfInt anOrder;
6411 ::SMESH_Mesh& mesh = GetImpl();
6413 // collect submeshes and detect concurrent algorithms and hypothesises
6414 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6416 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6417 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6418 ::SMESH_subMesh* sm = (*i_sm).second;
6420 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6422 // list of assigned hypothesises
6423 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6424 // Find out dimensions where the submesh can be concurrent.
6425 // We define the dimensions by algo of each of hypotheses in hypList
6426 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6427 for( ; hypIt != hypList.end(); hypIt++ ) {
6428 SMESH_Algo* anAlgo = 0;
6429 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6430 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6431 // hyp it-self is algo
6432 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6434 // try to find algorithm with help of sub-shapes
6435 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6436 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6437 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6440 continue; // no algorithm assigned to a current submesh
6442 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6443 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6445 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6446 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6447 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6449 } // end iterations on submesh
6451 // iterate on created dimension-hypotheses and check for concurrents
6452 for ( int i = 0; i < 4; i++ ) {
6453 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6454 // check for concurrents in own and other dimensions (step-by-step)
6455 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6456 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6457 const SMESH_DimHyp* dimHyp = *dhIt;
6458 TDimHypList listOfConcurr;
6459 set<int> setOfConcurrIds;
6460 // looking for concurrents and collect into own list
6461 for ( int j = i; j < 4; j++ )
6462 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6463 // check if any concurrents found
6464 if ( listOfConcurr.size() > 0 ) {
6465 // add own submesh to list of concurrent
6466 addInOrderOfPriority( dimHyp, listOfConcurr );
6467 list<int> listOfConcurrIds;
6468 TDimHypList::iterator hypIt = listOfConcurr.begin();
6469 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6470 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6471 anOrder.push_back( listOfConcurrIds );
6476 removeDimHyps(dimHypListArr);
6478 // now, minimize the number of concurrent groups
6479 // Here we assume that lists of submeshes can have same submesh
6480 // in case of multi-dimension algorithms, as result
6481 // list with common submesh has to be united into one list
6483 TListOfListOfInt::iterator listIt = anOrder.begin();
6484 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6485 unionLists( *listIt, anOrder, listIndx + 1 );
6491 //=============================================================================
6493 * \brief Set submesh object order
6494 * \param theSubMeshArray submesh array order
6496 //=============================================================================
6498 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6501 _preMeshInfo->ForgetOrLoad();
6504 ::SMESH_Mesh& mesh = GetImpl();
6506 TPythonDump aPythonDump; // prevent dump of called methods
6507 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6509 TListOfListOfInt subMeshOrder;
6510 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6512 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6513 TListOfInt subMeshIds;
6515 aPythonDump << ", ";
6516 aPythonDump << "[ ";
6517 // Collect subMeshes which should be clear
6518 // do it list-by-list, because modification of submesh order
6519 // take effect between concurrent submeshes only
6520 set<const SMESH_subMesh*> subMeshToClear;
6521 list<const SMESH_subMesh*> subMeshList;
6522 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6524 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6526 aPythonDump << ", ";
6527 aPythonDump << subMesh;
6528 subMeshIds.push_back( subMesh->GetId() );
6529 // detect common parts of submeshes
6530 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6531 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6533 aPythonDump << " ]";
6534 subMeshOrder.push_back( subMeshIds );
6536 // clear collected sub-meshes
6537 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6538 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6539 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6541 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6542 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6543 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6546 aPythonDump << " ])";
6548 mesh.SetMeshOrder( subMeshOrder );
6551 SMESH::SMESH_Mesh_var me = _this();
6552 _gen_i->UpdateIcons( me );
6557 //=============================================================================
6559 * \brief Convert submesh ids into submesh interfaces
6561 //=============================================================================
6563 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6564 SMESH::submesh_array_array& theResOrder,
6565 const bool theIsDump)
6567 int nbSet = theIdsOrder.size();
6568 TPythonDump aPythonDump; // prevent dump of called methods
6570 aPythonDump << "[ ";
6571 theResOrder.length(nbSet);
6572 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6574 for( ; it != theIdsOrder.end(); it++ ) {
6575 // translate submesh identificators into submesh objects
6576 // takeing into account real number of concurrent lists
6577 const TListOfInt& aSubOrder = (*it);
6578 if (!aSubOrder.size())
6581 aPythonDump << "[ ";
6582 // convert shape indices into interfaces
6583 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6584 aResSubSet->length(aSubOrder.size());
6585 TListOfInt::const_iterator subIt = aSubOrder.begin();
6587 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6588 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6590 SMESH::SMESH_subMesh_var subMesh =
6591 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6594 aPythonDump << ", ";
6595 aPythonDump << subMesh;
6597 aResSubSet[ j++ ] = subMesh;
6600 aPythonDump << " ]";
6602 theResOrder[ listIndx++ ] = aResSubSet;
6604 // correct number of lists
6605 theResOrder.length( listIndx );
6608 // finilise python dump
6609 aPythonDump << " ]";
6610 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6614 namespace // utils used by SMESH_MeshPartDS
6617 * \brief Class used to access to protected data of SMDS_MeshInfo
6619 struct TMeshInfo : public SMDS_MeshInfo
6621 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6624 * \brief Element holing its ID only
6626 struct TElemID : public SMDS_LinearEdge
6628 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6632 //================================================================================
6634 // Implementation of SMESH_MeshPartDS
6636 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6637 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6639 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6640 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6643 _meshDS = mesh_i->GetImpl().GetMeshDS();
6645 SetPersistentId( _meshDS->GetPersistentId() );
6647 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6649 // <meshPart> is the whole mesh
6650 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6652 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6653 myGroupSet = _meshDS->GetGroups();
6658 SMESH::long_array_var anIDs = meshPart->GetIDs();
6659 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6660 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6662 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6663 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6664 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6669 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6670 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6671 if ( _elements[ e->GetType() ].insert( e ).second )
6674 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6675 while ( nIt->more() )
6677 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6678 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6685 ShapeToMesh( _meshDS->ShapeToMesh() );
6687 _meshDS = 0; // to enforce iteration on _elements and _nodes
6690 // -------------------------------------------------------------------------------------
6691 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6692 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6695 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6696 for ( ; partIt != meshPart.end(); ++partIt )
6697 if ( const SMDS_MeshElement * e = *partIt )
6698 if ( _elements[ e->GetType() ].insert( e ).second )
6701 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6702 while ( nIt->more() )
6704 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6705 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6711 // -------------------------------------------------------------------------------------
6712 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6714 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6716 TElemID elem( IDelem );
6717 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6718 if ( !_elements[ iType ].empty() )
6720 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6721 if ( it != _elements[ iType ].end() )
6726 // -------------------------------------------------------------------------------------
6727 bool SMESH_MeshPartDS::HasNumerationHoles()
6729 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6731 return ( MinNodeID() != 1 ||
6732 MaxNodeID() != NbNodes() ||
6733 MinElementID() != 1 ||
6734 MaxElementID() != NbElements() );
6736 // -------------------------------------------------------------------------------------
6737 int SMESH_MeshPartDS::MaxNodeID() const
6739 if ( _meshDS ) return _meshDS->MaxNodeID();
6740 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6742 // -------------------------------------------------------------------------------------
6743 int SMESH_MeshPartDS::MinNodeID() const
6745 if ( _meshDS ) return _meshDS->MinNodeID();
6746 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6748 // -------------------------------------------------------------------------------------
6749 int SMESH_MeshPartDS::MaxElementID() const
6751 if ( _meshDS ) return _meshDS->MaxElementID();
6753 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6754 if ( !_elements[ iType ].empty() )
6755 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6758 // -------------------------------------------------------------------------------------
6759 int SMESH_MeshPartDS::MinElementID() const
6761 if ( _meshDS ) return _meshDS->MinElementID();
6763 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6764 if ( !_elements[ iType ].empty() )
6765 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6768 // -------------------------------------------------------------------------------------
6769 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6771 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6773 typedef SMDS_SetIterator
6774 <const SMDS_MeshElement*,
6775 TIDSortedElemSet::const_iterator,
6776 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6777 SMDS_MeshElement::GeomFilter
6780 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6782 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6783 _elements[type].end(),
6784 SMDS_MeshElement::GeomFilter( geomType )));
6786 // -------------------------------------------------------------------------------------
6787 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6789 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6791 typedef SMDS_SetIterator
6792 <const SMDS_MeshElement*,
6793 TIDSortedElemSet::const_iterator,
6794 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6795 SMDS_MeshElement::EntityFilter
6798 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6800 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6801 _elements[type].end(),
6802 SMDS_MeshElement::EntityFilter( entity )));
6804 // -------------------------------------------------------------------------------------
6805 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6807 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6808 if ( type == SMDSAbs_All && !_meshDS )
6810 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6812 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6813 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6815 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6817 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6818 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6820 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6821 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6823 // -------------------------------------------------------------------------------------
6824 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6825 iterType SMESH_MeshPartDS::methName() const \
6827 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6828 return _meshDS ? _meshDS->methName() : iterType \
6829 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6831 // -------------------------------------------------------------------------------------
6832 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6833 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6834 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6835 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6836 #undef _GET_ITER_DEFINE
6838 // END Implementation of SMESH_MeshPartDS
6840 //================================================================================