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
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 //================================================================================
2049 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
2051 TopoDS_Shape newShape;
2054 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2055 if ( !groupSO->_is_nil() )
2057 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2058 if ( CORBA::is_nil( groupObj )) return newShape;
2059 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2061 // get indices of group items
2062 set<int> curIndices;
2063 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2064 GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
2065 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2066 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2067 curIndices.insert( ids[i] );
2069 if ( groupData._indices == curIndices )
2070 return newShape; // group not changed
2073 groupData._indices = curIndices;
2075 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2076 if ( !geomClient ) return newShape;
2077 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2078 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2079 newShape = _gen_i->GeomObjectToShape( geomGroup );
2082 if ( newShape.IsNull() ) {
2083 // geom group becomes empty - return empty compound
2084 TopoDS_Compound compound;
2085 BRep_Builder().MakeCompound(compound);
2086 newShape = compound;
2093 //-----------------------------------------------------------------------------
2095 * \brief Storage of shape and index used in CheckGeomGroupModif()
2097 struct TIndexedShape
2100 TopoDS_Shape _shape;
2101 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2103 //-----------------------------------------------------------------------------
2105 * \brief Data to re-create a group on geometry
2107 struct TGroupOnGeomData
2110 TopoDS_Shape _shape;
2111 SMDSAbs_ElementType _type;
2113 Quantity_Color _color;
2115 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2117 _oldID = group->GetID();
2118 _type = group->GetType();
2119 _name = group->GetStoreName();
2120 _color = group->GetColor();
2124 //-----------------------------------------------------------------------------
2126 * \brief Check if a filter is still valid after geometry removal
2128 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2130 if ( theFilter->_is_nil() )
2132 SMESH::Filter::Criteria_var criteria;
2133 theFilter->GetCriteria( criteria.out() );
2135 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2137 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2139 switch ( criteria[ iCr ].Type )
2141 case SMESH::FT_BelongToGeom:
2142 case SMESH::FT_BelongToPlane:
2143 case SMESH::FT_BelongToCylinder:
2144 case SMESH::FT_BelongToGenSurface:
2145 case SMESH::FT_LyingOnGeom:
2146 entry = thresholdID;
2148 case SMESH::FT_ConnectedElements:
2151 entry = thresholdID;
2157 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2158 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2159 if ( so->_is_nil() )
2161 CORBA::Object_var obj = so->GetObject();
2162 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2163 if ( gen->GeomObjectToShape( geom ).IsNull() )
2166 } // loop on criteria
2172 //=============================================================================
2174 * \brief Update data if geometry changes
2178 //=============================================================================
2180 void SMESH_Mesh_i::CheckGeomModif()
2182 SMESH::SMESH_Mesh_var me = _this();
2183 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2185 TPythonDump dumpNothing; // prevent any dump
2187 //bool removedFromClient = false;
2189 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2191 //removedFromClient = _impl->HasShapeToMesh();
2193 // try to find geometry by study reference
2194 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2195 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2196 if ( !meshSO->_is_nil() &&
2197 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2198 geomRefSO->ReferencedObject( geomSO.inout() ))
2200 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2201 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2204 if ( mainGO->_is_nil() && // geometry removed ==>
2205 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2207 // convert geom dependent groups into standalone ones
2208 CheckGeomGroupModif();
2210 _impl->ShapeToMesh( TopoDS_Shape() );
2212 // remove sub-meshes
2213 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2214 while ( i_sm != _mapSubMeshIor.end() )
2216 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2218 RemoveSubMesh( sm );
2220 // remove all children except groups in the study
2221 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2222 SALOMEDS::SObject_wrap so;
2223 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2224 if ( meshSO->FindSubObject( tag, so.inout() ))
2225 builder->RemoveObjectWithChildren( so );
2227 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2233 if ( !_impl->HasShapeToMesh() ) return;
2236 // Update after group modification
2238 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2239 mainGO->GetTick() == _mainShapeTick )
2241 int nb = NbNodes() + NbElements();
2242 CheckGeomGroupModif();
2243 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2244 _gen_i->UpdateIcons( me );
2248 // Update after shape modification
2250 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2251 if ( !geomClient ) return;
2252 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2253 if ( geomGen->_is_nil() ) return;
2255 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2256 geomClient->RemoveShapeFromBuffer( ior.in() );
2258 // Update data taking into account that if topology doesn't change
2259 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2262 _preMeshInfo->ForgetAllData();
2265 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2266 if ( newShape.IsNull() )
2269 _mainShapeTick = mainGO->GetTick();
2271 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2273 // store data of groups on geometry
2274 std::vector< TGroupOnGeomData > groupsData;
2275 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2276 groupsData.reserve( groups.size() );
2277 TopTools_DataMapOfShapeShape old2newShapeMap;
2278 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2279 for ( ; g != groups.end(); ++g )
2281 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2283 groupsData.push_back( TGroupOnGeomData( group ));
2286 SMESH::SMESH_GroupOnGeom_var gog;
2287 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2288 if ( i_grp != _mapGroups.end() )
2289 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2291 GEOM::GEOM_Object_var geom;
2292 if ( !gog->_is_nil() )
2293 geom = gog->GetShape();
2294 if ( !geom->_is_nil() )
2296 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2297 geomClient->RemoveShapeFromBuffer( ior.in() );
2298 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2299 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2301 else if ( old2newShapeMap.IsBound( group->GetShape() ))
2303 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2307 // store assigned hypotheses
2308 std::vector< pair< int, THypList > > ids2Hyps;
2309 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2310 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2312 const TopoDS_Shape& s = s2hyps.Key();
2313 const THypList& hyps = s2hyps.ChangeValue();
2314 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2317 // count shapes excluding compounds corresponding to geom groups
2318 int oldNbSubShapes = meshDS->MaxShapeIndex();
2319 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2321 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2322 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2326 // check if shape topology changes - save shape type per shape ID
2327 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2328 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2329 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2331 // change shape to mesh
2332 _impl->ShapeToMesh( TopoDS_Shape() );
2333 _impl->ShapeToMesh( newShape );
2335 // check if shape topology changes - check new shape types
2336 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2337 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2339 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2340 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2343 // re-add shapes (compounds) of geom groups
2344 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2345 for ( ; data != _geomGroupData.end(); ++data )
2347 TopoDS_Shape newShape = newGroupShape( *data );
2348 if ( !newShape.IsNull() )
2350 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2352 TopoDS_Compound compound;
2353 BRep_Builder().MakeCompound( compound );
2354 BRep_Builder().Add( compound, newShape );
2355 newShape = compound;
2357 _impl->GetSubMesh( newShape );
2361 // re-assign hypotheses
2362 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2364 if ( !sameTopology && ids2Hyps[i].first != 1 )
2365 continue; // assign only global hypos
2366 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2367 const THypList& hyps = ids2Hyps[i].second;
2368 THypList::const_iterator h = hyps.begin();
2369 for ( ; h != hyps.end(); ++h )
2370 _impl->AddHypothesis( s, (*h)->GetID() );
2373 if ( !sameTopology )
2375 // remove invalid study sub-objects
2376 CheckGeomGroupModif();
2380 // restore groups on geometry
2381 for ( size_t i = 0; i < groupsData.size(); ++i )
2383 const TGroupOnGeomData& data = groupsData[i];
2384 if ( data._shape.IsNull() )
2387 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2388 if ( i2g == _mapGroups.end() ) continue;
2390 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2391 if ( !gr_i ) continue;
2393 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2395 _mapGroups.erase( i2g );
2397 g->GetGroupDS()->SetColor( data._color );
2400 // update _mapSubMesh
2401 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2402 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2403 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2406 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
2409 //=============================================================================
2411 * \brief Update objects depending on changed geom groups
2413 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2414 * issue 0020210: Update of a smesh group after modification of the associated geom group
2416 //=============================================================================
2418 void SMESH_Mesh_i::CheckGeomGroupModif()
2420 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2421 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2422 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2423 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2424 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2426 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2427 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2428 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2430 int nbValid = 0, nbRemoved = 0;
2431 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2432 for ( ; chItr->More(); chItr->Next() )
2434 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2435 if ( !smSO->_is_nil() &&
2436 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2437 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2439 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2440 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2441 if ( !geom->_non_existent() )
2444 continue; // keep the sub-mesh
2447 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2448 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2449 if ( !sm->_is_nil() && !sm->_non_existent() )
2451 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2452 if ( smGeom->_is_nil() )
2454 RemoveSubMesh( sm );
2461 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2462 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2466 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2467 builder->RemoveObjectWithChildren( rootSO );
2471 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2472 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2473 while ( i_gr != _mapGroups.end())
2475 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2477 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2478 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2479 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2480 bool isValidGeom = false;
2481 if ( !onGeom->_is_nil() )
2483 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2485 else if ( !onFilt->_is_nil() )
2487 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2491 isValidGeom = ( !groupSO->_is_nil() &&
2492 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2496 if ( !IsLoaded() || group->IsEmpty() )
2498 RemoveGroup( group );
2500 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2502 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2504 else // is it possible?
2506 builder->RemoveObjectWithChildren( refSO );
2512 if ( !_impl->HasShapeToMesh() ) return;
2514 CORBA::Long nbEntities = NbNodes() + NbElements();
2516 // Check if group contents changed
2518 typedef map< string, TopoDS_Shape > TEntry2Geom;
2519 TEntry2Geom newGroupContents;
2521 list<TGeomGroupData>::iterator
2522 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2523 for ( ; data != dataEnd; ++data )
2525 pair< TEntry2Geom::iterator, bool > it_new =
2526 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2527 bool processedGroup = !it_new.second;
2528 TopoDS_Shape& newShape = it_new.first->second;
2529 if ( !processedGroup )
2530 newShape = newGroupShape( *data );
2531 if ( newShape.IsNull() )
2532 continue; // no changes
2535 _preMeshInfo->ForgetOrLoad();
2537 if ( processedGroup ) { // update group indices
2538 list<TGeomGroupData>::iterator data2 = data;
2539 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2540 data->_indices = data2->_indices;
2543 // Update SMESH objects according to new GEOM group contents
2545 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2546 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2548 int oldID = submesh->GetId();
2549 if ( !_mapSubMeshIor.count( oldID ))
2551 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2553 // update hypotheses
2554 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2555 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2556 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2558 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2559 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2561 // care of submeshes
2562 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2563 int newID = newSubmesh->GetId();
2564 if ( newID != oldID ) {
2565 _mapSubMesh [ newID ] = newSubmesh;
2566 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2567 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2568 _mapSubMesh. erase(oldID);
2569 _mapSubMesh_i. erase(oldID);
2570 _mapSubMeshIor.erase(oldID);
2571 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2576 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2577 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2578 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2580 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2582 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2583 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2584 ds->SetShape( newShape );
2589 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2590 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2592 // Remove groups and submeshes basing on removed sub-shapes
2594 TopTools_MapOfShape newShapeMap;
2595 TopoDS_Iterator shapeIt( newShape );
2596 for ( ; shapeIt.More(); shapeIt.Next() )
2597 newShapeMap.Add( shapeIt.Value() );
2599 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2600 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2602 if ( newShapeMap.Contains( shapeIt.Value() ))
2604 TopTools_IndexedMapOfShape oldShapeMap;
2605 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2606 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2608 const TopoDS_Shape& oldShape = oldShapeMap(i);
2609 int oldInd = meshDS->ShapeToIndex( oldShape );
2611 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2612 if ( i_smIor != _mapSubMeshIor.end() ) {
2613 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2616 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2617 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2619 // check if a group bases on oldInd shape
2620 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2621 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2622 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2623 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2625 RemoveGroup( i_grp->second ); // several groups can base on same shape
2626 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2631 // Reassign hypotheses and update groups after setting the new shape to mesh
2633 // collect anassigned hypotheses
2634 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2635 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2636 TShapeHypList assignedHyps;
2637 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2639 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2640 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2641 if ( !hyps.empty() ) {
2642 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2643 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2644 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2647 // collect shapes supporting groups
2648 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2649 TShapeTypeList groupData;
2650 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2651 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2652 for ( ; grIt != groups.end(); ++grIt )
2654 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2656 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2658 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2660 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2661 _impl->ShapeToMesh( newShape );
2663 // reassign hypotheses
2664 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2665 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2667 TIndexedShape& geom = indS_hyps->first;
2668 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2669 int oldID = geom._index;
2670 int newID = meshDS->ShapeToIndex( geom._shape );
2671 if ( oldID == 1 ) { // main shape
2673 geom._shape = newShape;
2677 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2678 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2679 // care of sub-meshes
2680 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2681 if ( newID != oldID ) {
2682 _mapSubMesh [ newID ] = newSubmesh;
2683 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2684 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2685 _mapSubMesh. erase(oldID);
2686 _mapSubMesh_i. erase(oldID);
2687 _mapSubMeshIor.erase(oldID);
2688 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2692 TShapeTypeList::iterator geomType = groupData.begin();
2693 for ( ; geomType != groupData.end(); ++geomType )
2695 const TIndexedShape& geom = geomType->first;
2696 int oldID = geom._index;
2697 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2700 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2701 CORBA::String_var name = groupSO->GetName();
2703 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2704 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2705 /*id=*/-1, geom._shape ))
2706 group_i->changeLocalId( group->GetID() );
2709 break; // everything has been updated
2712 } // loop on group data
2716 CORBA::Long newNbEntities = NbNodes() + NbElements();
2717 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2718 if ( newNbEntities != nbEntities )
2720 // Add all SObjects with icons to soToUpdateIcons
2721 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2723 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2724 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2725 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2727 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2728 i_gr != _mapGroups.end(); ++i_gr ) // groups
2729 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2732 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2733 for ( ; so != soToUpdateIcons.end(); ++so )
2734 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2737 //=============================================================================
2739 * \brief Create standalone group from a group on geometry or filter
2741 //=============================================================================
2743 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2744 throw (SALOME::SALOME_Exception)
2746 SMESH::SMESH_Group_var aGroup;
2751 _preMeshInfo->FullLoadFromFile();
2753 if ( theGroup->_is_nil() )
2754 return aGroup._retn();
2756 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2758 return aGroup._retn();
2760 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2762 const int anId = aGroupToRem->GetLocalID();
2763 if ( !_impl->ConvertToStandalone( anId ) )
2764 return aGroup._retn();
2765 removeGeomGroupData( theGroup );
2767 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2769 // remove old instance of group from own map
2770 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2771 _mapGroups.erase( anId );
2773 SALOMEDS::StudyBuilder_var builder;
2774 SALOMEDS::SObject_wrap aGroupSO;
2775 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2776 if ( !aStudy->_is_nil() ) {
2777 builder = aStudy->NewBuilder();
2778 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2779 if ( !aGroupSO->_is_nil() )
2781 // remove reference to geometry
2782 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2783 for ( ; chItr->More(); chItr->Next() )
2785 // Remove group's child SObject
2786 SALOMEDS::SObject_wrap so = chItr->Value();
2787 builder->RemoveObject( so );
2789 // Update Python script
2790 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2791 << ".ConvertToStandalone( " << aGroupSO << " )";
2793 // change icon of Group on Filter
2796 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2797 // const int isEmpty = ( elemTypes->length() == 0 );
2800 SALOMEDS::GenericAttribute_wrap anAttr =
2801 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2802 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2803 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2809 // remember new group in own map
2810 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2811 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2813 // register CORBA object for persistence
2814 _gen_i->RegisterObject( aGroup );
2816 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2817 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2818 //aGroup->Register();
2819 aGroupToRem->UnRegister();
2821 SMESH_CATCH( SMESH::throwCorbaException );
2823 return aGroup._retn();
2826 //=============================================================================
2830 //=============================================================================
2832 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2834 if(MYDEBUG) MESSAGE( "createSubMesh" );
2835 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2836 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2839 SMESH_subMesh_i * subMeshServant;
2842 subMeshId = mySubMesh->GetId();
2843 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2845 else // "invalid sub-mesh"
2847 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2848 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2849 if ( _mapSubMesh.empty() )
2852 subMeshId = _mapSubMesh.begin()->first - 1;
2853 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2856 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2858 _mapSubMesh [subMeshId] = mySubMesh;
2859 _mapSubMesh_i [subMeshId] = subMeshServant;
2860 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2862 subMeshServant->Register();
2864 // register CORBA object for persistence
2865 int nextId = _gen_i->RegisterObject( subMesh );
2866 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2867 else { nextId = 0; } // avoid "unused variable" warning
2869 // to track changes of GEOM groups
2870 if ( subMeshId > 0 )
2871 addGeomGroupData( theSubShapeObject, subMesh );
2873 return subMesh._retn();
2876 //=======================================================================
2877 //function : getSubMesh
2879 //=======================================================================
2881 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2883 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2884 if ( it == _mapSubMeshIor.end() )
2885 return SMESH::SMESH_subMesh::_nil();
2887 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2890 //=============================================================================
2894 //=============================================================================
2896 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2897 GEOM::GEOM_Object_ptr theSubShapeObject )
2899 bool isHypChanged = false;
2900 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2901 return isHypChanged;
2903 const int subMeshId = theSubMesh->GetId();
2905 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2908 if (( _mapSubMesh.count( subMeshId )) &&
2909 ( sm = _impl->GetSubMeshContaining( subMeshId )))
2911 TopoDS_Shape S = sm->GetSubShape();
2914 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2915 isHypChanged = !hyps.empty();
2916 if ( isHypChanged && _preMeshInfo )
2917 _preMeshInfo->ForgetOrLoad();
2918 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2919 for ( ; hyp != hyps.end(); ++hyp )
2920 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2927 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2928 isHypChanged = ( aHypList->length() > 0 );
2929 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2930 removeHypothesis( theSubShapeObject, aHypList[i] );
2933 catch( const SALOME::SALOME_Exception& ) {
2934 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2936 removeGeomGroupData( theSubShapeObject );
2940 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2941 if ( id_smi != _mapSubMesh_i.end() )
2942 id_smi->second->UnRegister();
2944 // remove a CORBA object
2945 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2946 if ( id_smptr != _mapSubMeshIor.end() )
2947 SMESH::SMESH_subMesh_var( id_smptr->second );
2949 _mapSubMesh.erase(subMeshId);
2950 _mapSubMesh_i.erase(subMeshId);
2951 _mapSubMeshIor.erase(subMeshId);
2953 return isHypChanged;
2956 //=============================================================================
2960 //=============================================================================
2962 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2963 const char* theName,
2965 const TopoDS_Shape& theShape,
2966 const SMESH_PredicatePtr& thePredicate )
2968 std::string newName;
2969 if ( !theName || !theName[0] )
2971 std::set< std::string > presentNames;
2972 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2973 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2975 CORBA::String_var name = i_gr->second->GetName();
2976 presentNames.insert( name.in() );
2979 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2980 } while ( !presentNames.insert( newName ).second );
2981 theName = newName.c_str();
2983 SMESH::SMESH_GroupBase_var aGroup;
2984 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
2985 theID, theShape, thePredicate ))
2987 int anId = g->GetID();
2988 SMESH_GroupBase_i* aGroupImpl;
2989 if ( !theShape.IsNull() )
2990 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2991 else if ( thePredicate )
2992 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2994 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2996 aGroup = aGroupImpl->_this();
2997 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2998 aGroupImpl->Register();
3000 // register CORBA object for persistence
3001 int nextId = _gen_i->RegisterObject( aGroup );
3002 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3003 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3005 // to track changes of GEOM groups
3006 if ( !theShape.IsNull() ) {
3007 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3008 addGeomGroupData( geom, aGroup );
3011 return aGroup._retn();
3014 //=============================================================================
3016 * SMESH_Mesh_i::removeGroup
3018 * Should be called by ~SMESH_Group_i()
3020 //=============================================================================
3022 void SMESH_Mesh_i::removeGroup( const int theId )
3024 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3025 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3026 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3027 _mapGroups.erase( theId );
3028 removeGeomGroupData( group );
3029 if ( !_impl->RemoveGroup( theId ))
3031 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3032 RemoveGroup( group );
3034 group->UnRegister();
3038 //=============================================================================
3042 //=============================================================================
3044 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3045 throw(SALOME::SALOME_Exception)
3047 SMESH::log_array_var aLog;
3051 _preMeshInfo->FullLoadFromFile();
3053 list < SMESHDS_Command * >logDS = _impl->GetLog();
3054 aLog = new SMESH::log_array;
3056 int lg = logDS.size();
3059 list < SMESHDS_Command * >::iterator its = logDS.begin();
3060 while(its != logDS.end()){
3061 SMESHDS_Command *com = *its;
3062 int comType = com->GetType();
3064 int lgcom = com->GetNumber();
3066 const list < int >&intList = com->GetIndexes();
3067 int inum = intList.size();
3069 list < int >::const_iterator ii = intList.begin();
3070 const list < double >&coordList = com->GetCoords();
3071 int rnum = coordList.size();
3073 list < double >::const_iterator ir = coordList.begin();
3074 aLog[indexLog].commandType = comType;
3075 aLog[indexLog].number = lgcom;
3076 aLog[indexLog].coords.length(rnum);
3077 aLog[indexLog].indexes.length(inum);
3078 for(int i = 0; i < rnum; i++){
3079 aLog[indexLog].coords[i] = *ir;
3080 //MESSAGE(" "<<i<<" "<<ir.Value());
3083 for(int i = 0; i < inum; i++){
3084 aLog[indexLog].indexes[i] = *ii;
3085 //MESSAGE(" "<<i<<" "<<ii.Value());
3094 SMESH_CATCH( SMESH::throwCorbaException );
3096 return aLog._retn();
3100 //=============================================================================
3104 //=============================================================================
3106 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3110 SMESH_CATCH( SMESH::throwCorbaException );
3113 //=============================================================================
3117 //=============================================================================
3119 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3124 //=============================================================================
3127 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3128 // issue 0020918: groups removal is caused by hyp modification
3129 // issue 0021208: to forget not loaded mesh data at hyp modification
3130 struct TCallUp_i : public SMESH_Mesh::TCallUp
3132 SMESH_Mesh_i* _mesh;
3133 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3134 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3135 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3136 virtual void Load () { _mesh->Load(); }
3140 //================================================================================
3142 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3144 //================================================================================
3146 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3149 _preMeshInfo->ForgetOrLoad();
3151 SMESH::SMESH_Mesh_var mesh = _this();
3152 _gen_i->UpdateIcons( mesh );
3154 // mark a hypothesis as valid after edition
3155 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3156 SALOMEDS::SObject_wrap hypRoot;
3157 if ( !smeshComp->_is_nil() &&
3158 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3160 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3161 for ( ; anIter->More(); anIter->Next() )
3163 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3164 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3165 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3166 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3167 _gen_i->HighLightInvalid( hyp, false );
3172 //=============================================================================
3176 //=============================================================================
3178 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3180 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3183 _impl->SetCallUp( new TCallUp_i(this));
3186 //=============================================================================
3190 //=============================================================================
3192 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3194 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3198 //=============================================================================
3200 * Return mesh editor
3202 //=============================================================================
3204 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3205 throw (SALOME::SALOME_Exception)
3207 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3211 _preMeshInfo->FullLoadFromFile();
3213 // Create MeshEditor
3215 _editor = new SMESH_MeshEditor_i( this, false );
3216 aMeshEdVar = _editor->_this();
3218 // Update Python script
3219 TPythonDump() << _editor << " = "
3220 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3222 SMESH_CATCH( SMESH::throwCorbaException );
3224 return aMeshEdVar._retn();
3227 //=============================================================================
3229 * Return mesh edition previewer
3231 //=============================================================================
3233 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3234 throw (SALOME::SALOME_Exception)
3236 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3240 _preMeshInfo->FullLoadFromFile();
3242 if ( !_previewEditor )
3243 _previewEditor = new SMESH_MeshEditor_i( this, true );
3244 aMeshEdVar = _previewEditor->_this();
3246 SMESH_CATCH( SMESH::throwCorbaException );
3248 return aMeshEdVar._retn();
3251 //================================================================================
3253 * \brief Return true if the mesh has been edited since a last total re-compute
3254 * and those modifications may prevent successful partial re-compute
3256 //================================================================================
3258 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3260 Unexpect aCatch(SALOME_SalomeException);
3261 return _impl->HasModificationsToDiscard();
3264 //================================================================================
3266 * \brief Returns a random unique color
3268 //================================================================================
3270 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3272 const int MAX_ATTEMPTS = 100;
3274 double tolerance = 0.5;
3275 SALOMEDS::Color col;
3279 // generate random color
3280 double red = (double)rand() / RAND_MAX;
3281 double green = (double)rand() / RAND_MAX;
3282 double blue = (double)rand() / RAND_MAX;
3283 // check existence in the list of the existing colors
3284 bool matched = false;
3285 std::list<SALOMEDS::Color>::const_iterator it;
3286 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3287 SALOMEDS::Color color = *it;
3288 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3289 matched = tol < tolerance;
3291 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3292 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3300 //=============================================================================
3302 * Sets auto-color mode. If it is on, groups get unique random colors
3304 //=============================================================================
3306 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3308 Unexpect aCatch(SALOME_SalomeException);
3309 _impl->SetAutoColor(theAutoColor);
3311 TPythonDump pyDump; // not to dump group->SetColor() from below code
3312 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3314 std::list<SALOMEDS::Color> aReservedColors;
3315 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3316 for ( ; it != _mapGroups.end(); it++ ) {
3317 if ( CORBA::is_nil( it->second )) continue;
3318 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3319 it->second->SetColor( aColor );
3320 aReservedColors.push_back( aColor );
3324 //=============================================================================
3326 * Returns true if auto-color mode is on
3328 //=============================================================================
3330 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3332 Unexpect aCatch(SALOME_SalomeException);
3333 return _impl->GetAutoColor();
3336 //=============================================================================
3338 * Checks if there are groups with equal names
3340 //=============================================================================
3342 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3344 return _impl->HasDuplicatedGroupNamesMED();
3347 //================================================================================
3349 * \brief Care of a file before exporting mesh into it
3351 //================================================================================
3353 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3355 SMESH_File aFile( file, false );
3357 if ( aFile.exists() ) {
3358 // existing filesystem node
3359 if ( !aFile.isDirectory() ) {
3360 if ( aFile.openForWriting() ) {
3361 if ( overwrite && ! aFile.remove()) {
3362 msg << "Can't replace " << aFile.getName();
3365 msg << "Can't write into " << aFile.getName();
3368 msg << "Location " << aFile.getName() << " is not a file";
3372 // nonexisting file; check if it can be created
3373 if ( !aFile.openForWriting() ) {
3374 msg << "You cannot create the file "
3376 << ". Check the directory existence and access rights";
3384 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3388 //================================================================================
3390 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3391 * \param file - file name
3392 * \param overwrite - to erase the file or not
3393 * \retval string - mesh name
3395 //================================================================================
3397 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3398 CORBA::Boolean overwrite)
3401 PrepareForWriting(file, overwrite);
3402 string aMeshName = "Mesh";
3403 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3404 if ( !aStudy->_is_nil() ) {
3405 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3406 if ( !aMeshSO->_is_nil() ) {
3407 CORBA::String_var name = aMeshSO->GetName();
3409 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3410 if ( !aStudy->GetProperties()->IsLocked() )
3412 SALOMEDS::GenericAttribute_wrap anAttr;
3413 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3414 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3415 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3416 ASSERT(!aFileName->_is_nil());
3417 aFileName->SetValue(file);
3418 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3419 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3420 ASSERT(!aFileType->_is_nil());
3421 aFileType->SetValue("FICHIERMED");
3425 // Update Python script
3426 // set name of mesh before export
3427 TPythonDump() << _gen_i << ".SetName("
3428 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3430 // check names of groups
3436 //================================================================================
3438 * \brief Export to MED file
3440 //================================================================================
3442 void SMESH_Mesh_i::ExportMED(const char* file,
3443 CORBA::Boolean auto_groups,
3444 CORBA::Long version,
3445 CORBA::Boolean overwrite,
3446 CORBA::Boolean autoDimension)
3447 throw(SALOME::SALOME_Exception)
3449 //MESSAGE("MED minor version: "<< minor);
3452 _preMeshInfo->FullLoadFromFile();
3454 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3455 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3457 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3459 << "auto_groups=" <<auto_groups << ", "
3460 << "minor=" << version << ", "
3461 << "overwrite=" << overwrite << ", "
3462 << "meshPart=None, "
3463 << "autoDimension=" << autoDimension << " )";
3465 SMESH_CATCH( SMESH::throwCorbaException );
3468 //================================================================================
3470 * \brief Export a mesh to a SAUV file
3472 //================================================================================
3474 void SMESH_Mesh_i::ExportSAUV (const char* file,
3475 CORBA::Boolean auto_groups)
3476 throw(SALOME::SALOME_Exception)
3478 Unexpect aCatch(SALOME_SalomeException);
3480 _preMeshInfo->FullLoadFromFile();
3482 string aMeshName = prepareMeshNameAndGroups(file, true);
3483 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3484 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3485 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3489 //================================================================================
3491 * \brief Export a mesh to a DAT file
3493 //================================================================================
3495 void SMESH_Mesh_i::ExportDAT (const char *file)
3496 throw(SALOME::SALOME_Exception)
3498 Unexpect aCatch(SALOME_SalomeException);
3500 _preMeshInfo->FullLoadFromFile();
3502 // Update Python script
3503 // check names of groups
3505 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3508 PrepareForWriting(file);
3509 _impl->ExportDAT(file);
3512 //================================================================================
3514 * \brief Export a mesh to an UNV file
3516 //================================================================================
3518 void SMESH_Mesh_i::ExportUNV (const char *file)
3519 throw(SALOME::SALOME_Exception)
3521 Unexpect aCatch(SALOME_SalomeException);
3523 _preMeshInfo->FullLoadFromFile();
3525 // Update Python script
3526 // check names of groups
3528 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3531 PrepareForWriting(file);
3532 _impl->ExportUNV(file);
3535 //================================================================================
3537 * \brief Export a mesh to an STL file
3539 //================================================================================
3541 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3542 throw(SALOME::SALOME_Exception)
3544 Unexpect aCatch(SALOME_SalomeException);
3546 _preMeshInfo->FullLoadFromFile();
3548 // Update Python script
3549 // check names of groups
3551 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3552 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3554 CORBA::String_var name;
3555 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3556 if ( !so->_is_nil() )
3557 name = so->GetName();
3560 PrepareForWriting( file );
3561 _impl->ExportSTL( file, isascii, name.in() );
3564 //================================================================================
3566 * \brief Export a part of mesh to a med file
3568 //================================================================================
3570 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3572 CORBA::Boolean auto_groups,
3573 CORBA::Long version,
3574 CORBA::Boolean overwrite,
3575 CORBA::Boolean autoDimension,
3576 const GEOM::ListOfFields& fields,
3577 const char* geomAssocFields,
3578 CORBA::Double ZTolerance)
3579 throw (SALOME::SALOME_Exception)
3581 MESSAGE("MED version: "<< version);
3584 _preMeshInfo->FullLoadFromFile();
3587 bool have0dField = false;
3588 if ( fields.length() > 0 )
3590 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3591 if ( shapeToMesh->_is_nil() )
3592 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3594 for ( size_t i = 0; i < fields.length(); ++i )
3596 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3597 THROW_SALOME_CORBA_EXCEPTION
3598 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3599 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3600 if ( fieldShape->_is_nil() )
3601 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3602 if ( !fieldShape->IsSame( shapeToMesh ) )
3603 THROW_SALOME_CORBA_EXCEPTION
3604 ( "Field defined not on shape", SALOME::BAD_PARAM);
3605 if ( fields[i]->GetDimension() == 0 )
3608 if ( geomAssocFields )
3609 for ( int i = 0; geomAssocFields[i]; ++i )
3610 switch ( geomAssocFields[i] ) {
3611 case 'v':case 'e':case 'f':case 's': break;
3612 case 'V':case 'E':case 'F':case 'S': break;
3613 default: THROW_SALOME_CORBA_EXCEPTION
3614 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3618 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3622 string aMeshName = "Mesh";
3623 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3624 if ( CORBA::is_nil( meshPart ) ||
3625 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3627 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3628 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3629 0, autoDimension, /*addODOnVertices=*/have0dField,
3631 meshDS = _impl->GetMeshDS();
3636 _preMeshInfo->FullLoadFromFile();
3638 PrepareForWriting(file, overwrite);
3640 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3641 if ( !SO->_is_nil() ) {
3642 CORBA::String_var name = SO->GetName();
3646 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3647 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3648 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3649 meshDS = tmpDSDeleter._obj = partDS;
3654 if ( _impl->HasShapeToMesh() )
3656 DriverMED_W_Field fieldWriter;
3657 fieldWriter.SetFile( file );
3658 fieldWriter.SetMeshName( aMeshName );
3659 fieldWriter.AddODOnVertices( have0dField );
3661 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3665 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3666 goList->length( fields.length() );
3667 for ( size_t i = 0; i < fields.length(); ++i )
3669 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3672 TPythonDump() << _this() << ".ExportPartToMED( "
3673 << meshPart << ", r'"
3675 << auto_groups << ", "
3677 << overwrite << ", "
3678 << autoDimension << ", "
3680 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3681 << TVar( ZTolerance )
3684 SMESH_CATCH( SMESH::throwCorbaException );
3687 //================================================================================
3689 * Write GEOM fields to MED file
3691 //================================================================================
3693 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3694 SMESHDS_Mesh* meshDS,
3695 const GEOM::ListOfFields& fields,
3696 const char* geomAssocFields)
3698 #define METH "SMESH_Mesh_i::exportMEDFields() "
3700 if (( fields.length() < 1 ) &&
3701 ( !geomAssocFields || !geomAssocFields[0] ))
3704 std::vector< std::vector< double > > dblVals;
3705 std::vector< std::vector< int > > intVals;
3706 std::vector< int > subIdsByDim[ 4 ];
3707 const double noneDblValue = 0.;
3708 const double noneIntValue = 0;
3710 for ( size_t iF = 0; iF < fields.length(); ++iF )
3714 int dim = fields[ iF ]->GetDimension();
3715 SMDSAbs_ElementType elemType;
3716 TopAbs_ShapeEnum shapeType;
3718 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3719 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3720 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3721 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3723 continue; // skip fields on whole shape
3725 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3726 if ( dataType == GEOM::FDT_String )
3728 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3729 if ( stepIDs->length() < 1 )
3731 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3732 if ( comps->length() < 1 )
3734 CORBA::String_var name = fields[ iF ]->GetName();
3736 if ( !fieldWriter.Set( meshDS,
3740 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3743 for ( size_t iC = 0; iC < comps->length(); ++iC )
3744 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3746 dblVals.resize( comps->length() );
3747 intVals.resize( comps->length() );
3749 // find sub-shape IDs
3751 std::vector< int >& subIds = subIdsByDim[ dim ];
3752 if ( subIds.empty() )
3753 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3754 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3755 subIds.push_back( id );
3759 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3763 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3765 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3766 if ( step->_is_nil() )
3769 CORBA::Long stamp = step->GetStamp();
3770 CORBA::Long id = step->GetID();
3771 fieldWriter.SetDtIt( int( stamp ), int( id ));
3773 // fill dblVals or intVals
3774 for ( size_t iC = 0; iC < comps->length(); ++iC )
3775 if ( dataType == GEOM::FDT_Double )
3777 dblVals[ iC ].clear();
3778 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3782 intVals[ iC ].clear();
3783 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3787 case GEOM::FDT_Double:
3789 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3790 if ( dblStep->_is_nil() ) continue;
3791 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3792 if ( vv->length() != subIds.size() * comps->length() )
3793 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3794 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3795 for ( size_t iC = 0; iC < comps->length(); ++iC )
3796 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3801 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3802 if ( intStep->_is_nil() ) continue;
3803 GEOM::ListOfLong_var vv = intStep->GetValues();
3804 if ( vv->length() != subIds.size() * comps->length() )
3805 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3806 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3807 for ( size_t iC = 0; iC < comps->length(); ++iC )
3808 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3811 case GEOM::FDT_Bool:
3813 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3814 if ( boolStep->_is_nil() ) continue;
3815 GEOM::short_array_var vv = boolStep->GetValues();
3816 if ( vv->length() != subIds.size() * comps->length() )
3817 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3818 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3819 for ( size_t iC = 0; iC < comps->length(); ++iC )
3820 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3826 // pass values to fieldWriter
3827 elemIt = fieldWriter.GetOrderedElems();
3828 if ( dataType == GEOM::FDT_Double )
3829 while ( elemIt->more() )
3831 const SMDS_MeshElement* e = elemIt->next();
3832 const int shapeID = e->getshapeId();
3833 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3834 for ( size_t iC = 0; iC < comps->length(); ++iC )
3835 fieldWriter.AddValue( noneDblValue );
3837 for ( size_t iC = 0; iC < comps->length(); ++iC )
3838 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3841 while ( elemIt->more() )
3843 const SMDS_MeshElement* e = elemIt->next();
3844 const int shapeID = e->getshapeId();
3845 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3846 for ( size_t iC = 0; iC < comps->length(); ++iC )
3847 fieldWriter.AddValue( (double) noneIntValue );
3849 for ( size_t iC = 0; iC < comps->length(); ++iC )
3850 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3854 fieldWriter.Perform();
3855 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3856 if ( res && res->IsKO() )
3858 if ( res->myComment.empty() )
3859 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3861 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3867 if ( !geomAssocFields || !geomAssocFields[0] )
3870 // write geomAssocFields
3872 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3873 shapeDim[ TopAbs_COMPOUND ] = 3;
3874 shapeDim[ TopAbs_COMPSOLID ] = 3;
3875 shapeDim[ TopAbs_SOLID ] = 3;
3876 shapeDim[ TopAbs_SHELL ] = 2;
3877 shapeDim[ TopAbs_FACE ] = 2;
3878 shapeDim[ TopAbs_WIRE ] = 1;
3879 shapeDim[ TopAbs_EDGE ] = 1;
3880 shapeDim[ TopAbs_VERTEX ] = 0;
3881 shapeDim[ TopAbs_SHAPE ] = 3;
3883 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3885 std::vector< std::string > compNames;
3886 switch ( geomAssocFields[ iF ]) {
3888 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3889 compNames.push_back( "dim" );
3892 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3895 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3898 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3902 compNames.push_back( "id" );
3903 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3904 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3906 fieldWriter.SetDtIt( -1, -1 );
3908 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3912 if ( compNames.size() == 2 ) // _vertices_
3913 while ( elemIt->more() )
3915 const SMDS_MeshElement* e = elemIt->next();
3916 const int shapeID = e->getshapeId();
3919 fieldWriter.AddValue( (double) -1 );
3920 fieldWriter.AddValue( (double) -1 );
3924 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3925 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3926 fieldWriter.AddValue( (double) shapeID );
3930 while ( elemIt->more() )
3932 const SMDS_MeshElement* e = elemIt->next();
3933 const int shapeID = e->getshapeId();
3935 fieldWriter.AddValue( (double) -1 );
3937 fieldWriter.AddValue( (double) shapeID );
3941 fieldWriter.Perform();
3942 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3943 if ( res && res->IsKO() )
3945 if ( res->myComment.empty() )
3946 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3948 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3951 } // loop on geomAssocFields
3956 //================================================================================
3958 * \brief Export a part of mesh to a DAT file
3960 //================================================================================
3962 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3964 throw (SALOME::SALOME_Exception)
3966 Unexpect aCatch(SALOME_SalomeException);
3968 _preMeshInfo->FullLoadFromFile();
3970 PrepareForWriting(file);
3972 SMESH_MeshPartDS partDS( meshPart );
3973 _impl->ExportDAT(file,&partDS);
3975 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3976 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3978 //================================================================================
3980 * \brief Export a part of mesh to an UNV file
3982 //================================================================================
3984 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3986 throw (SALOME::SALOME_Exception)
3988 Unexpect aCatch(SALOME_SalomeException);
3990 _preMeshInfo->FullLoadFromFile();
3992 PrepareForWriting(file);
3994 SMESH_MeshPartDS partDS( meshPart );
3995 _impl->ExportUNV(file, &partDS);
3997 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3998 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4000 //================================================================================
4002 * \brief Export a part of mesh to an STL file
4004 //================================================================================
4006 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4008 ::CORBA::Boolean isascii)
4009 throw (SALOME::SALOME_Exception)
4011 Unexpect aCatch(SALOME_SalomeException);
4013 _preMeshInfo->FullLoadFromFile();
4015 PrepareForWriting(file);
4017 CORBA::String_var name;
4018 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4019 if ( !so->_is_nil() )
4020 name = so->GetName();
4022 SMESH_MeshPartDS partDS( meshPart );
4023 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4025 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4026 << meshPart<< ", r'" << file << "', " << isascii << ")";
4029 //================================================================================
4031 * \brief Export a part of mesh to an STL file
4033 //================================================================================
4035 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4037 CORBA::Boolean overwrite,
4038 CORBA::Boolean groupElemsByType)
4039 throw (SALOME::SALOME_Exception)
4042 Unexpect aCatch(SALOME_SalomeException);
4044 _preMeshInfo->FullLoadFromFile();
4046 PrepareForWriting(file,overwrite);
4048 std::string meshName("");
4049 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4050 if ( !so->_is_nil() )
4052 CORBA::String_var name = so->GetName();
4053 meshName = name.in();
4057 SMESH_MeshPartDS partDS( meshPart );
4058 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4060 SMESH_CATCH( SMESH::throwCorbaException );
4062 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4063 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4065 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4069 //================================================================================
4071 * \brief Export a part of mesh to a GMF file
4073 //================================================================================
4075 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4077 bool withRequiredGroups)
4078 throw (SALOME::SALOME_Exception)
4080 Unexpect aCatch(SALOME_SalomeException);
4082 _preMeshInfo->FullLoadFromFile();
4084 PrepareForWriting(file,/*overwrite=*/true);
4086 SMESH_MeshPartDS partDS( meshPart );
4087 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4089 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4090 << meshPart<< ", r'"
4092 << withRequiredGroups << ")";
4095 //=============================================================================
4097 * Return computation progress [0.,1]
4099 //=============================================================================
4101 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4105 return _impl->GetComputeProgress();
4107 SMESH_CATCH( SMESH::doNothing );
4111 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4113 Unexpect aCatch(SALOME_SalomeException);
4115 return _preMeshInfo->NbNodes();
4117 return _impl->NbNodes();
4120 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4122 Unexpect aCatch(SALOME_SalomeException);
4124 return _preMeshInfo->NbElements();
4126 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4129 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4131 Unexpect aCatch(SALOME_SalomeException);
4133 return _preMeshInfo->Nb0DElements();
4135 return _impl->Nb0DElements();
4138 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4140 Unexpect aCatch(SALOME_SalomeException);
4142 return _preMeshInfo->NbBalls();
4144 return _impl->NbBalls();
4147 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4149 Unexpect aCatch(SALOME_SalomeException);
4151 return _preMeshInfo->NbEdges();
4153 return _impl->NbEdges();
4156 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4157 throw(SALOME::SALOME_Exception)
4159 Unexpect aCatch(SALOME_SalomeException);
4161 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4163 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4166 //=============================================================================
4168 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4170 Unexpect aCatch(SALOME_SalomeException);
4172 return _preMeshInfo->NbFaces();
4174 return _impl->NbFaces();
4177 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4179 Unexpect aCatch(SALOME_SalomeException);
4181 return _preMeshInfo->NbTriangles();
4183 return _impl->NbTriangles();
4186 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4188 Unexpect aCatch(SALOME_SalomeException);
4190 return _preMeshInfo->NbBiQuadTriangles();
4192 return _impl->NbBiQuadTriangles();
4195 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4197 Unexpect aCatch(SALOME_SalomeException);
4199 return _preMeshInfo->NbQuadrangles();
4201 return _impl->NbQuadrangles();
4204 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4206 Unexpect aCatch(SALOME_SalomeException);
4208 return _preMeshInfo->NbBiQuadQuadrangles();
4210 return _impl->NbBiQuadQuadrangles();
4213 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4215 Unexpect aCatch(SALOME_SalomeException);
4217 return _preMeshInfo->NbPolygons();
4219 return _impl->NbPolygons();
4222 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4224 Unexpect aCatch(SALOME_SalomeException);
4226 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4228 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4231 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4232 throw(SALOME::SALOME_Exception)
4234 Unexpect aCatch(SALOME_SalomeException);
4236 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4238 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4241 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4242 throw(SALOME::SALOME_Exception)
4244 Unexpect aCatch(SALOME_SalomeException);
4246 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4248 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4251 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4252 throw(SALOME::SALOME_Exception)
4254 Unexpect aCatch(SALOME_SalomeException);
4256 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4258 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4261 //=============================================================================
4263 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4265 Unexpect aCatch(SALOME_SalomeException);
4267 return _preMeshInfo->NbVolumes();
4269 return _impl->NbVolumes();
4272 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4274 Unexpect aCatch(SALOME_SalomeException);
4276 return _preMeshInfo->NbTetras();
4278 return _impl->NbTetras();
4281 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4283 Unexpect aCatch(SALOME_SalomeException);
4285 return _preMeshInfo->NbHexas();
4287 return _impl->NbHexas();
4290 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4292 Unexpect aCatch(SALOME_SalomeException);
4294 return _preMeshInfo->NbTriQuadHexas();
4296 return _impl->NbTriQuadraticHexas();
4299 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4301 Unexpect aCatch(SALOME_SalomeException);
4303 return _preMeshInfo->NbPyramids();
4305 return _impl->NbPyramids();
4308 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4310 Unexpect aCatch(SALOME_SalomeException);
4312 return _preMeshInfo->NbPrisms();
4314 return _impl->NbPrisms();
4317 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4319 Unexpect aCatch(SALOME_SalomeException);
4321 return _preMeshInfo->NbHexPrisms();
4323 return _impl->NbHexagonalPrisms();
4326 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4328 Unexpect aCatch(SALOME_SalomeException);
4330 return _preMeshInfo->NbPolyhedrons();
4332 return _impl->NbPolyhedrons();
4335 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4336 throw(SALOME::SALOME_Exception)
4338 Unexpect aCatch(SALOME_SalomeException);
4340 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4342 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4345 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4346 throw(SALOME::SALOME_Exception)
4348 Unexpect aCatch(SALOME_SalomeException);
4350 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4352 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4355 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4356 throw(SALOME::SALOME_Exception)
4358 Unexpect aCatch(SALOME_SalomeException);
4360 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4362 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4365 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4366 throw(SALOME::SALOME_Exception)
4368 Unexpect aCatch(SALOME_SalomeException);
4370 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4372 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4375 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4376 throw(SALOME::SALOME_Exception)
4378 Unexpect aCatch(SALOME_SalomeException);
4380 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4382 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4385 //=============================================================================
4387 * Returns nb of published sub-meshes
4389 //=============================================================================
4391 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4393 Unexpect aCatch(SALOME_SalomeException);
4394 return _mapSubMesh_i.size();
4397 //=============================================================================
4399 * Dumps mesh into a string
4401 //=============================================================================
4403 char* SMESH_Mesh_i::Dump()
4407 return CORBA::string_dup( os.str().c_str() );
4410 //=============================================================================
4412 * Method of SMESH_IDSource interface
4414 //=============================================================================
4416 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4418 return GetElementsId();
4421 //=============================================================================
4423 * Returns ids of all elements
4425 //=============================================================================
4427 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4428 throw (SALOME::SALOME_Exception)
4430 Unexpect aCatch(SALOME_SalomeException);
4432 _preMeshInfo->FullLoadFromFile();
4434 SMESH::long_array_var aResult = new SMESH::long_array();
4435 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4437 if ( aSMESHDS_Mesh == NULL )
4438 return aResult._retn();
4440 long nbElements = NbElements();
4441 aResult->length( nbElements );
4442 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4443 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4444 aResult[i] = anIt->next()->GetID();
4446 return aResult._retn();
4450 //=============================================================================
4452 * Returns ids of all elements of given type
4454 //=============================================================================
4456 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4457 throw (SALOME::SALOME_Exception)
4459 Unexpect aCatch(SALOME_SalomeException);
4461 _preMeshInfo->FullLoadFromFile();
4463 SMESH::long_array_var aResult = new SMESH::long_array();
4464 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4466 if ( aSMESHDS_Mesh == NULL )
4467 return aResult._retn();
4469 long nbElements = NbElements();
4471 // No sense in returning ids of elements along with ids of nodes:
4472 // when theElemType == SMESH::ALL, return node ids only if
4473 // there are no elements
4474 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4475 return GetNodesId();
4477 aResult->length( nbElements );
4481 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4482 while ( i < nbElements && anIt->more() )
4483 aResult[i++] = anIt->next()->GetID();
4485 aResult->length( i );
4487 return aResult._retn();
4490 //=============================================================================
4492 * Returns ids of all nodes
4494 //=============================================================================
4496 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4497 throw (SALOME::SALOME_Exception)
4499 Unexpect aCatch(SALOME_SalomeException);
4501 _preMeshInfo->FullLoadFromFile();
4503 SMESH::long_array_var aResult = new SMESH::long_array();
4504 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4506 if ( aMeshDS == NULL )
4507 return aResult._retn();
4509 long nbNodes = NbNodes();
4510 aResult->length( nbNodes );
4511 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4512 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4513 aResult[i] = anIt->next()->GetID();
4515 return aResult._retn();
4518 //=============================================================================
4522 //=============================================================================
4524 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4525 throw (SALOME::SALOME_Exception)
4527 SMESH::ElementType type = SMESH::ALL;
4531 _preMeshInfo->FullLoadFromFile();
4533 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4535 SMESH_CATCH( SMESH::throwCorbaException );
4540 //=============================================================================
4544 //=============================================================================
4546 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4547 throw (SALOME::SALOME_Exception)
4550 _preMeshInfo->FullLoadFromFile();
4552 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4554 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4556 return ( SMESH::EntityType ) e->GetEntityType();
4559 //=============================================================================
4563 //=============================================================================
4565 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4566 throw (SALOME::SALOME_Exception)
4569 _preMeshInfo->FullLoadFromFile();
4571 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4573 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4575 return ( SMESH::GeometryType ) e->GetGeomType();
4578 //=============================================================================
4580 * Returns ID of elements for given submesh
4582 //=============================================================================
4583 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4584 throw (SALOME::SALOME_Exception)
4586 SMESH::long_array_var aResult = new SMESH::long_array();
4590 _preMeshInfo->FullLoadFromFile();
4592 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4593 if(!SM) return aResult._retn();
4595 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4596 if(!SDSM) return aResult._retn();
4598 aResult->length(SDSM->NbElements());
4600 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4602 while ( eIt->more() ) {
4603 aResult[i++] = eIt->next()->GetID();
4606 SMESH_CATCH( SMESH::throwCorbaException );
4608 return aResult._retn();
4611 //=============================================================================
4613 * Returns ID of nodes for given submesh
4614 * If param all==true - returns all nodes, else -
4615 * returns only nodes on shapes.
4617 //=============================================================================
4619 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4621 throw (SALOME::SALOME_Exception)
4623 SMESH::long_array_var aResult = new SMESH::long_array();
4627 _preMeshInfo->FullLoadFromFile();
4629 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4630 if(!SM) return aResult._retn();
4632 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4633 if(!SDSM) return aResult._retn();
4636 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4637 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4638 while ( nIt->more() ) {
4639 const SMDS_MeshNode* elem = nIt->next();
4640 theElems.insert( elem->GetID() );
4643 else { // all nodes of submesh elements
4644 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4645 while ( eIt->more() ) {
4646 const SMDS_MeshElement* anElem = eIt->next();
4647 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4648 while ( nIt->more() ) {
4649 const SMDS_MeshElement* elem = nIt->next();
4650 theElems.insert( elem->GetID() );
4655 aResult->length(theElems.size());
4656 set<int>::iterator itElem;
4658 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4659 aResult[i++] = *itElem;
4661 SMESH_CATCH( SMESH::throwCorbaException );
4663 return aResult._retn();
4666 //=============================================================================
4668 * Returns type of elements for given submesh
4670 //=============================================================================
4672 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4673 throw (SALOME::SALOME_Exception)
4675 SMESH::ElementType type = SMESH::ALL;
4679 _preMeshInfo->FullLoadFromFile();
4681 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4682 if(!SM) return SMESH::ALL;
4684 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4685 if(!SDSM) return SMESH::ALL;
4687 if(SDSM->NbElements()==0)
4688 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4690 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4691 const SMDS_MeshElement* anElem = eIt->next();
4693 type = ( SMESH::ElementType ) anElem->GetType();
4695 SMESH_CATCH( SMESH::throwCorbaException );
4701 //=============================================================================
4703 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4705 //=============================================================================
4707 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4710 _preMeshInfo->FullLoadFromFile();
4712 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4713 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4718 //=============================================================================
4720 * Get XYZ coordinates of node as list of double
4721 * If there is not node for given ID - returns empty list
4723 //=============================================================================
4725 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4728 _preMeshInfo->FullLoadFromFile();
4730 SMESH::double_array_var aResult = new SMESH::double_array();
4731 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4732 if ( aMeshDS == NULL )
4733 return aResult._retn();
4736 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4738 return aResult._retn();
4742 aResult[0] = aNode->X();
4743 aResult[1] = aNode->Y();
4744 aResult[2] = aNode->Z();
4745 return aResult._retn();
4749 //=============================================================================
4751 * For given node returns list of IDs of inverse elements
4752 * If there is not node for given ID - returns empty list
4754 //=============================================================================
4756 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4757 SMESH::ElementType elemType)
4760 _preMeshInfo->FullLoadFromFile();
4762 SMESH::long_array_var aResult = new SMESH::long_array();
4763 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4764 if ( aMeshDS == NULL )
4765 return aResult._retn();
4768 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4770 return aResult._retn();
4772 // find inverse elements
4773 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4774 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4775 aResult->length( aNode->NbInverseElements( type ));
4776 for( int i = 0; eIt->more(); ++i )
4778 const SMDS_MeshElement* elem = eIt->next();
4779 aResult[ i ] = elem->GetID();
4781 return aResult._retn();
4784 //=============================================================================
4786 * \brief Return position of a node on shape
4788 //=============================================================================
4790 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4793 _preMeshInfo->FullLoadFromFile();
4795 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4796 aNodePosition->shapeID = 0;
4797 aNodePosition->shapeType = GEOM::SHAPE;
4799 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4800 if ( !mesh ) return aNodePosition;
4802 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4804 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4806 aNodePosition->shapeID = aNode->getshapeId();
4807 switch ( pos->GetTypeOfPosition() ) {
4809 aNodePosition->shapeType = GEOM::EDGE;
4810 aNodePosition->params.length(1);
4811 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4813 case SMDS_TOP_FACE: {
4814 SMDS_FacePositionPtr fPos = pos;
4815 aNodePosition->shapeType = GEOM::FACE;
4816 aNodePosition->params.length(2);
4817 aNodePosition->params[0] = fPos->GetUParameter();
4818 aNodePosition->params[1] = fPos->GetVParameter();
4821 case SMDS_TOP_VERTEX:
4822 aNodePosition->shapeType = GEOM::VERTEX;
4824 case SMDS_TOP_3DSPACE:
4825 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4826 aNodePosition->shapeType = GEOM::SOLID;
4827 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4828 aNodePosition->shapeType = GEOM::SHELL;
4834 return aNodePosition;
4837 //=============================================================================
4839 * \brief Return position of an element on shape
4841 //=============================================================================
4843 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4846 _preMeshInfo->FullLoadFromFile();
4848 SMESH::ElementPosition anElementPosition;
4849 anElementPosition.shapeID = 0;
4850 anElementPosition.shapeType = GEOM::SHAPE;
4852 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4853 if ( !mesh ) return anElementPosition;
4855 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4857 anElementPosition.shapeID = anElem->getshapeId();
4858 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4859 if ( !aSp.IsNull() ) {
4860 switch ( aSp.ShapeType() ) {
4862 anElementPosition.shapeType = GEOM::EDGE;
4865 anElementPosition.shapeType = GEOM::FACE;
4868 anElementPosition.shapeType = GEOM::VERTEX;
4871 anElementPosition.shapeType = GEOM::SOLID;
4874 anElementPosition.shapeType = GEOM::SHELL;
4880 return anElementPosition;
4883 //=============================================================================
4885 * If given element is node returns IDs of shape from position
4886 * If there is not node for given ID - returns -1
4888 //=============================================================================
4890 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4893 _preMeshInfo->FullLoadFromFile();
4895 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4896 if ( aMeshDS == NULL )
4900 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4902 return aNode->getshapeId();
4909 //=============================================================================
4911 * For given element returns ID of result shape after
4912 * ::FindShape() from SMESH_MeshEditor
4913 * If there is not element for given ID - returns -1
4915 //=============================================================================
4917 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4920 _preMeshInfo->FullLoadFromFile();
4922 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4923 if ( aMeshDS == NULL )
4926 // try to find element
4927 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4931 ::SMESH_MeshEditor aMeshEditor(_impl);
4932 int index = aMeshEditor.FindShape( elem );
4940 //=============================================================================
4942 * Returns number of nodes for given element
4943 * If there is not element for given ID - returns -1
4945 //=============================================================================
4947 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4950 _preMeshInfo->FullLoadFromFile();
4952 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4953 if ( aMeshDS == NULL ) return -1;
4954 // try to find element
4955 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4956 if(!elem) return -1;
4957 return elem->NbNodes();
4961 //=============================================================================
4963 * Returns ID of node by given index for given element
4964 * If there is not element for given ID - returns -1
4965 * If there is not node for given index - returns -2
4967 //=============================================================================
4969 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4972 _preMeshInfo->FullLoadFromFile();
4974 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4975 if ( aMeshDS == NULL ) return -1;
4976 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4977 if(!elem) return -1;
4978 if( index>=elem->NbNodes() || index<0 ) return -1;
4979 return elem->GetNode(index)->GetID();
4982 //=============================================================================
4984 * Returns IDs of nodes of given element
4986 //=============================================================================
4988 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4991 _preMeshInfo->FullLoadFromFile();
4993 SMESH::long_array_var aResult = new SMESH::long_array();
4994 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4996 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4998 aResult->length( elem->NbNodes() );
4999 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5000 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5001 aResult[ i ] = n->GetID();
5004 return aResult._retn();
5007 //=============================================================================
5009 * Returns true if given node is medium node
5010 * in given quadratic element
5012 //=============================================================================
5014 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5017 _preMeshInfo->FullLoadFromFile();
5019 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5020 if ( aMeshDS == NULL ) return false;
5022 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5023 if(!aNode) return false;
5024 // try to find element
5025 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5026 if(!elem) return false;
5028 return elem->IsMediumNode(aNode);
5032 //=============================================================================
5034 * Returns true if given node is medium node
5035 * in one of quadratic elements
5037 //=============================================================================
5039 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5040 SMESH::ElementType theElemType)
5043 _preMeshInfo->FullLoadFromFile();
5045 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5046 if ( aMeshDS == NULL ) return false;
5049 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5050 if(!aNode) return false;
5052 SMESH_MesherHelper aHelper( *(_impl) );
5054 SMDSAbs_ElementType aType;
5055 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5056 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5057 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5058 else aType = SMDSAbs_All;
5060 return aHelper.IsMedium(aNode,aType);
5064 //=============================================================================
5066 * Returns number of edges for given element
5068 //=============================================================================
5070 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5073 _preMeshInfo->FullLoadFromFile();
5075 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5076 if ( aMeshDS == NULL ) return -1;
5077 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5078 if(!elem) return -1;
5079 return elem->NbEdges();
5083 //=============================================================================
5085 * Returns number of faces for given element
5087 //=============================================================================
5089 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5092 _preMeshInfo->FullLoadFromFile();
5094 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5095 if ( aMeshDS == NULL ) return -1;
5096 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5097 if(!elem) return -1;
5098 return elem->NbFaces();
5101 //=======================================================================
5102 //function : GetElemFaceNodes
5103 //purpose : Returns nodes of given face (counted from zero) for given element.
5104 //=======================================================================
5106 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5107 CORBA::Short faceIndex)
5110 _preMeshInfo->FullLoadFromFile();
5112 SMESH::long_array_var aResult = new SMESH::long_array();
5113 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5115 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5117 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5118 if ( faceIndex < vtool.NbFaces() )
5120 aResult->length( vtool.NbFaceNodes( faceIndex ));
5121 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5122 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5123 aResult[ i ] = nn[ i ]->GetID();
5127 return aResult._retn();
5130 //=======================================================================
5131 //function : GetFaceNormal
5132 //purpose : Returns three components of normal of given mesh face.
5133 //=======================================================================
5135 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5136 CORBA::Boolean normalized)
5139 _preMeshInfo->FullLoadFromFile();
5141 SMESH::double_array_var aResult = new SMESH::double_array();
5143 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5146 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5148 aResult->length( 3 );
5149 aResult[ 0 ] = normal.X();
5150 aResult[ 1 ] = normal.Y();
5151 aResult[ 2 ] = normal.Z();
5154 return aResult._retn();
5157 //=======================================================================
5158 //function : FindElementByNodes
5159 //purpose : Returns an element based on all given nodes.
5160 //=======================================================================
5162 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5165 _preMeshInfo->FullLoadFromFile();
5167 CORBA::Long elemID(0);
5168 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5170 vector< const SMDS_MeshNode * > nn( nodes.length() );
5171 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5172 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5175 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5176 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5177 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5178 _impl->NbVolumes( ORDER_QUADRATIC )))
5179 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5181 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5186 //================================================================================
5188 * \brief Return elements including all given nodes.
5190 //================================================================================
5192 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5193 SMESH::ElementType elemType)
5196 _preMeshInfo->FullLoadFromFile();
5198 SMESH::long_array_var result = new SMESH::long_array();
5200 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5202 vector< const SMDS_MeshNode * > nn( nodes.length() );
5203 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5204 nn[i] = mesh->FindNode( nodes[i] );
5206 std::vector<const SMDS_MeshElement *> elems;
5207 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5208 result->length( elems.size() );
5209 for ( size_t i = 0; i < elems.size(); ++i )
5210 result[i] = elems[i]->GetID();
5212 return result._retn();
5215 //=============================================================================
5217 * Returns true if given element is polygon
5219 //=============================================================================
5221 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5224 _preMeshInfo->FullLoadFromFile();
5226 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5227 if ( aMeshDS == NULL ) return false;
5228 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5229 if(!elem) return false;
5230 return elem->IsPoly();
5234 //=============================================================================
5236 * Returns true if given element is quadratic
5238 //=============================================================================
5240 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5243 _preMeshInfo->FullLoadFromFile();
5245 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5246 if ( aMeshDS == NULL ) return false;
5247 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5248 if(!elem) return false;
5249 return elem->IsQuadratic();
5252 //=============================================================================
5254 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5256 //=============================================================================
5258 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5261 _preMeshInfo->FullLoadFromFile();
5263 if ( const SMDS_BallElement* ball =
5264 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5265 return ball->GetDiameter();
5270 //=============================================================================
5272 * Returns bary center for given element
5274 //=============================================================================
5276 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5279 _preMeshInfo->FullLoadFromFile();
5281 SMESH::double_array_var aResult = new SMESH::double_array();
5282 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5283 if ( aMeshDS == NULL )
5284 return aResult._retn();
5286 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5288 return aResult._retn();
5290 if(elem->GetType()==SMDSAbs_Volume) {
5291 SMDS_VolumeTool aTool;
5292 if(aTool.Set(elem)) {
5294 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5299 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5301 double x=0., y=0., z=0.;
5302 for(; anIt->more(); ) {
5304 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5318 return aResult._retn();
5321 //================================================================================
5323 * \brief Create a group of elements preventing computation of a sub-shape
5325 //================================================================================
5327 SMESH::ListOfGroups*
5328 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5329 const char* theGroupName )
5330 throw ( SALOME::SALOME_Exception )
5332 Unexpect aCatch(SALOME_SalomeException);
5334 if ( !theGroupName || strlen( theGroupName) == 0 )
5335 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5337 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5338 ::SMESH_MeshEditor::ElemFeatures elemType;
5340 // submesh by subshape id
5341 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5342 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5345 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5346 if ( error && error->HasBadElems() )
5348 // sort bad elements by type
5349 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5350 const list<const SMDS_MeshElement*>& badElems =
5351 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5352 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5353 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5354 for ( ; elemIt != elemEnd; ++elemIt )
5356 const SMDS_MeshElement* elem = *elemIt;
5357 if ( !elem ) continue;
5359 if ( elem->GetID() < 1 )
5361 // elem is a temporary element, make a real element
5362 vector< const SMDS_MeshNode* > nodes;
5363 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5364 while ( nIt->more() && elem )
5366 nodes.push_back( nIt->next() );
5367 if ( nodes.back()->GetID() < 1 )
5368 elem = 0; // a temporary element on temporary nodes
5372 ::SMESH_MeshEditor editor( _impl );
5373 elem = editor.AddElement( nodes, elemType.Init( elem ));
5377 elemsByType[ elem->GetType() ].push_back( elem );
5380 // how many groups to create?
5382 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5383 nbTypes += int( !elemsByType[ i ].empty() );
5384 groups->length( nbTypes );
5387 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5389 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5390 if ( elems.empty() ) continue;
5392 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5393 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5395 SMESH::SMESH_Mesh_var mesh = _this();
5396 SALOMEDS::SObject_wrap aSO =
5397 _gen_i->PublishGroup( mesh, groups[ iG ],
5398 GEOM::GEOM_Object::_nil(), theGroupName);
5400 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5401 if ( !grp_i ) continue;
5403 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5404 for ( size_t iE = 0; iE < elems.size(); ++iE )
5405 grpDS->SMDSGroup().Add( elems[ iE ]);
5410 return groups._retn();
5413 //=============================================================================
5415 * Create and publish group servants if any groups were imported or created anyhow
5417 //=============================================================================
5419 void SMESH_Mesh_i::CreateGroupServants()
5421 SMESH::SMESH_Mesh_var aMesh = _this();
5424 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5425 while ( groupIt->more() )
5427 ::SMESH_Group* group = groupIt->next();
5428 int anId = group->GetID();
5430 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5431 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5433 addedIDs.insert( anId );
5435 SMESH_GroupBase_i* aGroupImpl;
5437 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5438 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5440 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5441 shape = groupOnGeom->GetShape();
5444 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5447 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5448 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5449 aGroupImpl->Register();
5451 // register CORBA object for persistence
5452 int nextId = _gen_i->RegisterObject( groupVar );
5453 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5454 else { nextId = 0; } // avoid "unused variable" warning in release mode
5456 // publishing the groups in the study
5457 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5458 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5460 if ( !addedIDs.empty() )
5463 set<int>::iterator id = addedIDs.begin();
5464 for ( ; id != addedIDs.end(); ++id )
5466 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5467 int i = std::distance( _mapGroups.begin(), it );
5468 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5473 //=============================================================================
5475 * \brief Return true if all sub-meshes are computed OK - to update an icon
5477 //=============================================================================
5479 bool SMESH_Mesh_i::IsComputedOK()
5481 return _impl->IsComputedOK();
5484 //=============================================================================
5486 * \brief Return groups cantained in _mapGroups by their IDs
5488 //=============================================================================
5490 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5492 int nbGroups = groupIDs.size();
5493 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5494 aList->length( nbGroups );
5496 list<int>::const_iterator ids = groupIDs.begin();
5497 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5499 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5500 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5501 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5503 aList->length( nbGroups );
5504 return aList._retn();
5507 //=============================================================================
5509 * \brief Return information about imported file
5511 //=============================================================================
5513 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5515 SMESH::MedFileInfo_var res( _medFileInfo );
5516 if ( !res.operator->() ) {
5517 res = new SMESH::MedFileInfo;
5519 res->fileSize = res->major = res->minor = res->release = -1;
5524 //=======================================================================
5525 //function : FileInfoToString
5526 //purpose : Persistence of file info
5527 //=======================================================================
5529 std::string SMESH_Mesh_i::FileInfoToString()
5532 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5534 s = SMESH_Comment( _medFileInfo->fileSize )
5535 << " " << _medFileInfo->major
5536 << " " << _medFileInfo->minor
5537 << " " << _medFileInfo->release
5538 << " " << _medFileInfo->fileName;
5543 //=======================================================================
5544 //function : FileInfoFromString
5545 //purpose : Persistence of file info
5546 //=======================================================================
5548 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5550 std::string size, major, minor, release, fileName;
5551 std::istringstream is(info);
5552 is >> size >> major >> minor >> release;
5553 fileName = info.data() + ( size.size() + 1 +
5556 release.size()+ 1 );
5558 _medFileInfo = new SMESH::MedFileInfo();
5559 _medFileInfo->fileName = fileName.c_str();
5560 _medFileInfo->fileSize = atoi( size.c_str() );
5561 _medFileInfo->major = atoi( major.c_str() );
5562 _medFileInfo->minor = atoi( minor.c_str() );
5563 _medFileInfo->release = atoi( release.c_str() );
5566 //=============================================================================
5568 * \brief Pass names of mesh groups from study to mesh DS
5570 //=============================================================================
5572 void SMESH_Mesh_i::checkGroupNames()
5574 int nbGrp = NbGroups();
5578 SMESH::ListOfGroups* grpList = 0;
5579 // avoid dump of "GetGroups"
5581 // store python dump into a local variable inside local scope
5582 SMESH::TPythonDump pDump; // do not delete this line of code
5583 grpList = GetGroups();
5586 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5587 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5590 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5591 if ( aGrpSO->_is_nil() )
5593 // correct name of the mesh group if necessary
5594 const char* guiName = aGrpSO->GetName();
5595 if ( strcmp(guiName, aGrp->GetName()) )
5596 aGrp->SetName( guiName );
5600 //=============================================================================
5602 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5604 //=============================================================================
5605 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5607 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5611 //=============================================================================
5613 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5615 //=============================================================================
5617 char* SMESH_Mesh_i::GetParameters()
5619 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5622 //=============================================================================
5624 * \brief Returns list of notebook variables used for last Mesh operation
5626 //=============================================================================
5627 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5629 SMESH::string_array_var aResult = new SMESH::string_array();
5630 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5632 CORBA::String_var aParameters = GetParameters();
5633 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5634 if ( aSections->length() > 0 ) {
5635 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5636 aResult->length( aVars.length() );
5637 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5638 aResult[i] = CORBA::string_dup( aVars[i] );
5641 return aResult._retn();
5644 //=======================================================================
5645 //function : GetTypes
5646 //purpose : Returns types of elements it contains
5647 //=======================================================================
5649 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5652 return _preMeshInfo->GetTypes();
5654 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5658 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5659 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5660 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5661 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5662 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5663 if (_impl->NbNodes() &&
5664 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5665 types->length( nbTypes );
5667 return types._retn();
5670 //=======================================================================
5671 //function : GetMesh
5672 //purpose : Returns self
5673 //=======================================================================
5675 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5677 return SMESH::SMESH_Mesh::_duplicate( _this() );
5680 //=======================================================================
5681 //function : IsMeshInfoCorrect
5682 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5683 // * happen if mesh data is not yet fully loaded from the file of study.
5684 //=======================================================================
5686 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5688 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5691 //=============================================================================
5693 * \brief Returns number of mesh elements per each \a EntityType
5695 //=============================================================================
5697 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5700 return _preMeshInfo->GetMeshInfo();
5702 SMESH::long_array_var aRes = new SMESH::long_array();
5703 aRes->length(SMESH::Entity_Last);
5704 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5706 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5708 return aRes._retn();
5709 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5710 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5711 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5712 return aRes._retn();
5715 //=============================================================================
5717 * \brief Returns number of mesh elements per each \a ElementType
5719 //=============================================================================
5721 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5723 SMESH::long_array_var aRes = new SMESH::long_array();
5724 aRes->length(SMESH::NB_ELEMENT_TYPES);
5725 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5728 const SMDS_MeshInfo* meshInfo = 0;
5730 meshInfo = _preMeshInfo;
5731 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5732 meshInfo = & meshDS->GetMeshInfo();
5735 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5736 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5738 return aRes._retn();
5741 //=============================================================================
5743 * Collect statistic of mesh elements given by iterator
5745 //=============================================================================
5747 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5748 SMESH::long_array& theInfo)
5750 if (!theItr) return;
5751 while (theItr->more())
5752 theInfo[ theItr->next()->GetEntityType() ]++;
5754 //=============================================================================
5756 * Returns mesh unstructed grid information.
5758 //=============================================================================
5760 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5762 SALOMEDS::TMPFile_var SeqFile;
5763 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5764 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5766 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5767 aWriter->WriteToOutputStringOn();
5768 aWriter->SetInputData(aGrid);
5769 aWriter->SetFileTypeToBinary();
5771 char* str = aWriter->GetOutputString();
5772 int size = aWriter->GetOutputStringLength();
5774 //Allocate octet buffer of required size
5775 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5776 //Copy ostrstream content to the octet buffer
5777 memcpy(OctetBuf, str, size);
5778 //Create and return TMPFile
5779 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5783 return SeqFile._retn();
5786 //=============================================================================
5787 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5788 * SMESH::ElementType type) */
5790 using namespace SMESH::Controls;
5791 //-----------------------------------------------------------------------------
5792 struct PredicateIterator : public SMDS_ElemIterator
5794 SMDS_ElemIteratorPtr _elemIter;
5795 PredicatePtr _predicate;
5796 const SMDS_MeshElement* _elem;
5797 SMDSAbs_ElementType _type;
5799 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5800 PredicatePtr predicate,
5801 SMDSAbs_ElementType type):
5802 _elemIter(iterator), _predicate(predicate), _type(type)
5810 virtual const SMDS_MeshElement* next()
5812 const SMDS_MeshElement* res = _elem;
5814 while ( _elemIter->more() && !_elem )
5816 if ((_elem = _elemIter->next()) &&
5817 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5818 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5825 //-----------------------------------------------------------------------------
5826 struct IDSourceIterator : public SMDS_ElemIterator
5828 const CORBA::Long* _idPtr;
5829 const CORBA::Long* _idEndPtr;
5830 SMESH::long_array_var _idArray;
5831 const SMDS_Mesh* _mesh;
5832 const SMDSAbs_ElementType _type;
5833 const SMDS_MeshElement* _elem;
5835 IDSourceIterator( const SMDS_Mesh* mesh,
5836 const CORBA::Long* ids,
5838 SMDSAbs_ElementType type):
5839 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5841 if ( _idPtr && nbIds && _mesh )
5844 IDSourceIterator( const SMDS_Mesh* mesh,
5845 SMESH::long_array* idArray,
5846 SMDSAbs_ElementType type):
5847 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5849 if ( idArray && _mesh )
5851 _idPtr = &_idArray[0];
5852 _idEndPtr = _idPtr + _idArray->length();
5860 virtual const SMDS_MeshElement* next()
5862 const SMDS_MeshElement* res = _elem;
5864 while ( _idPtr < _idEndPtr && !_elem )
5866 if ( _type == SMDSAbs_Node )
5868 _elem = _mesh->FindNode( *_idPtr++ );
5870 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5871 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5879 //-----------------------------------------------------------------------------
5881 struct NodeOfElemIterator : public SMDS_ElemIterator
5883 TColStd_MapOfInteger _checkedNodeIDs;
5884 SMDS_ElemIteratorPtr _elemIter;
5885 SMDS_ElemIteratorPtr _nodeIter;
5886 const SMDS_MeshElement* _node;
5888 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5890 if ( _elemIter && _elemIter->more() )
5892 _nodeIter = _elemIter->next()->nodesIterator();
5900 virtual const SMDS_MeshElement* next()
5902 const SMDS_MeshElement* res = _node;
5904 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5906 if ( _nodeIter->more() )
5908 _node = _nodeIter->next();
5909 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5914 _nodeIter = _elemIter->next()->nodesIterator();
5922 //=============================================================================
5924 * Return iterator on elements of given type in given object
5926 //=============================================================================
5928 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5929 SMESH::ElementType theType)
5931 SMDS_ElemIteratorPtr elemIt;
5932 bool typeOK = ( theType == SMESH::ALL );
5933 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5935 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5936 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5937 if ( !mesh_i ) return elemIt;
5938 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5940 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5942 elemIt = meshDS->elementsIterator( elemType );
5945 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5947 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5950 elemIt = sm->GetElements();
5951 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5953 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5954 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5958 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5960 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5961 if ( groupDS && ( elemType == groupDS->GetType() ||
5962 elemType == SMDSAbs_Node ||
5963 elemType == SMDSAbs_All ))
5965 elemIt = groupDS->GetElements();
5966 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5969 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5971 if ( filter_i->GetElementType() == theType ||
5972 filter_i->GetElementType() == SMESH::ALL ||
5973 elemType == SMDSAbs_Node ||
5974 elemType == SMDSAbs_All)
5976 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5977 if ( pred_i && pred_i->GetPredicate() )
5979 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5980 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5981 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
5982 elemIt = SMDS_ElemIteratorPtr
5983 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
5984 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
5990 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5991 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5992 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5994 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
5995 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5998 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5999 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6003 SMESH::long_array_var ids = theObject->GetIDs();
6004 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6006 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6009 if ( elemIt && elemIt->more() && !typeOK )
6011 if ( elemType == SMDSAbs_Node )
6013 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6017 elemIt = SMDS_ElemIteratorPtr();
6023 //=============================================================================
6024 namespace // Finding concurrent hypotheses
6025 //=============================================================================
6029 * \brief mapping of mesh dimension into shape type
6031 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6033 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6035 case 0: aType = TopAbs_VERTEX; break;
6036 case 1: aType = TopAbs_EDGE; break;
6037 case 2: aType = TopAbs_FACE; break;
6039 default:aType = TopAbs_SOLID; break;
6044 //-----------------------------------------------------------------------------
6046 * \brief Internal structure used to find concurrent submeshes
6048 * It represents a pair < submesh, concurrent dimension >, where
6049 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6050 * with another submesh. In other words, it is dimension of a hypothesis assigned
6057 int _dim; //!< a dimension the algo can build (concurrent dimension)
6058 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6059 TopTools_MapOfShape _shapeMap;
6060 SMESH_subMesh* _subMesh;
6061 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6063 //-----------------------------------------------------------------------------
6064 // Return the algorithm
6065 const SMESH_Algo* GetAlgo() const
6066 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6068 //-----------------------------------------------------------------------------
6070 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6072 const TopoDS_Shape& theShape)
6074 _subMesh = (SMESH_subMesh*)theSubMesh;
6075 SetShape( theDim, theShape );
6078 //-----------------------------------------------------------------------------
6080 void SetShape(const int theDim,
6081 const TopoDS_Shape& theShape)
6084 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6085 if (_dim >= _ownDim)
6086 _shapeMap.Add( theShape );
6088 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6089 for( ; anExp.More(); anExp.Next() )
6090 _shapeMap.Add( anExp.Current() );
6094 //-----------------------------------------------------------------------------
6095 //! Check sharing of sub-shapes
6096 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6097 const TopTools_MapOfShape& theToFind,
6098 const TopAbs_ShapeEnum theType)
6100 bool isShared = false;
6101 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6102 for (; !isShared && anItr.More(); anItr.Next() )
6104 const TopoDS_Shape aSubSh = anItr.Key();
6105 // check for case when concurrent dimensions are same
6106 isShared = theToFind.Contains( aSubSh );
6107 // check for sub-shape with concurrent dimension
6108 TopExp_Explorer anExp( aSubSh, theType );
6109 for ( ; !isShared && anExp.More(); anExp.Next() )
6110 isShared = theToFind.Contains( anExp.Current() );
6115 //-----------------------------------------------------------------------------
6116 //! check algorithms
6117 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6118 const SMESHDS_Hypothesis* theA2)
6120 if ( !theA1 || !theA2 ||
6121 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6122 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6123 return false; // one of the hypothesis is not algorithm
6124 // check algorithm names (should be equal)
6125 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6129 //-----------------------------------------------------------------------------
6130 //! Check if sub-shape hypotheses are concurrent
6131 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6133 if ( _subMesh == theOther->_subMesh )
6134 return false; // same sub-shape - should not be
6136 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6137 // any of the two submeshes is not on COMPOUND shape )
6138 // -> no concurrency
6139 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6140 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6141 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6142 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6143 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6146 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6147 if ( !checkSubShape )
6150 // check algorithms to be same
6151 const SMESH_Algo* a1 = this->GetAlgo();
6152 const SMESH_Algo* a2 = theOther->GetAlgo();
6153 bool isSame = checkAlgo( a1, a2 );
6157 return false; // pb?
6158 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6161 // check hypothesises for concurrence (skip first as algorithm)
6163 // pointers should be same, because it is referened from mesh hypothesis partition
6164 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6165 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6166 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6167 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6169 // the submeshes are concurrent if their algorithms has different parameters
6170 return nbSame != theOther->_hypotheses.size() - 1;
6173 // Return true if algorithm of this SMESH_DimHyp is used if no
6174 // sub-mesh order is imposed by the user
6175 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6177 // NeedDiscreteBoundary() algo has a higher priority
6178 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6179 theOther->GetAlgo()->NeedDiscreteBoundary() )
6180 return !this->GetAlgo()->NeedDiscreteBoundary();
6182 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6185 }; // end of SMESH_DimHyp
6186 //-----------------------------------------------------------------------------
6188 typedef list<const SMESH_DimHyp*> TDimHypList;
6190 //-----------------------------------------------------------------------------
6192 void addDimHypInstance(const int theDim,
6193 const TopoDS_Shape& theShape,
6194 const SMESH_Algo* theAlgo,
6195 const SMESH_subMesh* theSubMesh,
6196 const list <const SMESHDS_Hypothesis*>& theHypList,
6197 TDimHypList* theDimHypListArr )
6199 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6200 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6201 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6202 dimHyp->_hypotheses.push_front(theAlgo);
6203 listOfdimHyp.push_back( dimHyp );
6206 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6207 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6208 theHypList.begin(), theHypList.end() );
6211 //-----------------------------------------------------------------------------
6212 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6213 TDimHypList& theListOfConcurr)
6215 if ( theListOfConcurr.empty() )
6217 theListOfConcurr.push_back( theDimHyp );
6221 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6222 while ( hypIt != theListOfConcurr.end() &&
6223 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6225 theListOfConcurr.insert( hypIt, theDimHyp );
6229 //-----------------------------------------------------------------------------
6230 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6231 const TDimHypList& theListOfDimHyp,
6232 TDimHypList& theListOfConcurrHyp,
6233 set<int>& theSetOfConcurrId )
6235 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6236 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6238 const SMESH_DimHyp* curDimHyp = *rIt;
6239 if ( curDimHyp == theDimHyp )
6240 break; // meet own dimHyp pointer in same dimension
6242 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6243 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6245 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6250 //-----------------------------------------------------------------------------
6251 void unionLists(TListOfInt& theListOfId,
6252 TListOfListOfInt& theListOfListOfId,
6255 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6256 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6258 continue; //skip already treated lists
6259 // check if other list has any same submesh object
6260 TListOfInt& otherListOfId = *it;
6261 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6262 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6265 // union two lists (from source into target)
6266 TListOfInt::iterator it2 = otherListOfId.begin();
6267 for ( ; it2 != otherListOfId.end(); it2++ ) {
6268 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6269 theListOfId.push_back(*it2);
6271 // clear source list
6272 otherListOfId.clear();
6275 //-----------------------------------------------------------------------------
6277 //! free memory allocated for dimension-hypothesis objects
6278 void removeDimHyps( TDimHypList* theArrOfList )
6280 for (int i = 0; i < 4; i++ ) {
6281 TDimHypList& listOfdimHyp = theArrOfList[i];
6282 TDimHypList::const_iterator it = listOfdimHyp.begin();
6283 for ( ; it != listOfdimHyp.end(); it++ )
6288 //-----------------------------------------------------------------------------
6290 * \brief find common submeshes with given submesh
6291 * \param theSubMeshList list of already collected submesh to check
6292 * \param theSubMesh given submesh to intersect with other
6293 * \param theCommonSubMeshes collected common submeshes
6295 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6296 const SMESH_subMesh* theSubMesh,
6297 set<const SMESH_subMesh*>& theCommon )
6301 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6302 for ( ; it != theSubMeshList.end(); it++ )
6303 theSubMesh->FindIntersection( *it, theCommon );
6304 theSubMeshList.push_back( theSubMesh );
6305 //theCommon.insert( theSubMesh );
6308 //-----------------------------------------------------------------------------
6309 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6311 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6312 for ( ; listsIt != smLists.end(); ++listsIt )
6314 const TListOfInt& smIDs = *listsIt;
6315 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6323 //=============================================================================
6325 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6327 //=============================================================================
6329 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6331 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6332 if ( isSubMeshInList( submeshID, anOrder ))
6335 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6336 return isSubMeshInList( submeshID, allConurrent );
6339 //=============================================================================
6341 * \brief Return submesh objects list in meshing order
6343 //=============================================================================
6345 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6347 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6349 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6351 return aResult._retn();
6353 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6354 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6355 anOrder.splice( anOrder.end(), allConurrent );
6358 TListOfListOfInt::iterator listIt = anOrder.begin();
6359 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6360 unionLists( *listIt, anOrder, listIndx + 1 );
6362 // convert submesh ids into interface instances
6363 // and dump command into python
6364 convertMeshOrder( anOrder, aResult, false );
6366 return aResult._retn();
6369 //=============================================================================
6371 * \brief Finds concurrent sub-meshes
6373 //=============================================================================
6375 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6377 TListOfListOfInt anOrder;
6378 ::SMESH_Mesh& mesh = GetImpl();
6380 // collect submeshes and detect concurrent algorithms and hypothesises
6381 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6383 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6384 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6385 ::SMESH_subMesh* sm = (*i_sm).second;
6387 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6389 // list of assigned hypothesises
6390 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6391 // Find out dimensions where the submesh can be concurrent.
6392 // We define the dimensions by algo of each of hypotheses in hypList
6393 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6394 for( ; hypIt != hypList.end(); hypIt++ ) {
6395 SMESH_Algo* anAlgo = 0;
6396 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6397 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6398 // hyp it-self is algo
6399 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6401 // try to find algorithm with help of sub-shapes
6402 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6403 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6404 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6407 continue; // no algorithm assigned to a current submesh
6409 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6410 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6412 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6413 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6414 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6416 } // end iterations on submesh
6418 // iterate on created dimension-hypotheses and check for concurrents
6419 for ( int i = 0; i < 4; i++ ) {
6420 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6421 // check for concurrents in own and other dimensions (step-by-step)
6422 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6423 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6424 const SMESH_DimHyp* dimHyp = *dhIt;
6425 TDimHypList listOfConcurr;
6426 set<int> setOfConcurrIds;
6427 // looking for concurrents and collect into own list
6428 for ( int j = i; j < 4; j++ )
6429 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6430 // check if any concurrents found
6431 if ( listOfConcurr.size() > 0 ) {
6432 // add own submesh to list of concurrent
6433 addInOrderOfPriority( dimHyp, listOfConcurr );
6434 list<int> listOfConcurrIds;
6435 TDimHypList::iterator hypIt = listOfConcurr.begin();
6436 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6437 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6438 anOrder.push_back( listOfConcurrIds );
6443 removeDimHyps(dimHypListArr);
6445 // now, minimize the number of concurrent groups
6446 // Here we assume that lists of submeshes can have same submesh
6447 // in case of multi-dimension algorithms, as result
6448 // list with common submesh has to be united into one list
6450 TListOfListOfInt::iterator listIt = anOrder.begin();
6451 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6452 unionLists( *listIt, anOrder, listIndx + 1 );
6458 //=============================================================================
6460 * \brief Set submesh object order
6461 * \param theSubMeshArray submesh array order
6463 //=============================================================================
6465 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6468 _preMeshInfo->ForgetOrLoad();
6471 ::SMESH_Mesh& mesh = GetImpl();
6473 TPythonDump aPythonDump; // prevent dump of called methods
6474 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6476 TListOfListOfInt subMeshOrder;
6477 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6479 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6480 TListOfInt subMeshIds;
6482 aPythonDump << ", ";
6483 aPythonDump << "[ ";
6484 // Collect subMeshes which should be clear
6485 // do it list-by-list, because modification of submesh order
6486 // take effect between concurrent submeshes only
6487 set<const SMESH_subMesh*> subMeshToClear;
6488 list<const SMESH_subMesh*> subMeshList;
6489 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6491 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6493 aPythonDump << ", ";
6494 aPythonDump << subMesh;
6495 subMeshIds.push_back( subMesh->GetId() );
6496 // detect common parts of submeshes
6497 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6498 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6500 aPythonDump << " ]";
6501 subMeshOrder.push_back( subMeshIds );
6503 // clear collected sub-meshes
6504 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6505 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6506 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6508 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6509 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6510 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6513 aPythonDump << " ])";
6515 mesh.SetMeshOrder( subMeshOrder );
6518 SMESH::SMESH_Mesh_var me = _this();
6519 _gen_i->UpdateIcons( me );
6524 //=============================================================================
6526 * \brief Convert submesh ids into submesh interfaces
6528 //=============================================================================
6530 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6531 SMESH::submesh_array_array& theResOrder,
6532 const bool theIsDump)
6534 int nbSet = theIdsOrder.size();
6535 TPythonDump aPythonDump; // prevent dump of called methods
6537 aPythonDump << "[ ";
6538 theResOrder.length(nbSet);
6539 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6541 for( ; it != theIdsOrder.end(); it++ ) {
6542 // translate submesh identificators into submesh objects
6543 // takeing into account real number of concurrent lists
6544 const TListOfInt& aSubOrder = (*it);
6545 if (!aSubOrder.size())
6548 aPythonDump << "[ ";
6549 // convert shape indices into interfaces
6550 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6551 aResSubSet->length(aSubOrder.size());
6552 TListOfInt::const_iterator subIt = aSubOrder.begin();
6554 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6555 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6557 SMESH::SMESH_subMesh_var subMesh =
6558 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6561 aPythonDump << ", ";
6562 aPythonDump << subMesh;
6564 aResSubSet[ j++ ] = subMesh;
6567 aPythonDump << " ]";
6569 theResOrder[ listIndx++ ] = aResSubSet;
6571 // correct number of lists
6572 theResOrder.length( listIndx );
6575 // finilise python dump
6576 aPythonDump << " ]";
6577 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6581 namespace // utils used by SMESH_MeshPartDS
6584 * \brief Class used to access to protected data of SMDS_MeshInfo
6586 struct TMeshInfo : public SMDS_MeshInfo
6588 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6591 * \brief Element holing its ID only
6593 struct TElemID : public SMDS_LinearEdge
6595 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6599 //================================================================================
6601 // Implementation of SMESH_MeshPartDS
6603 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6604 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6606 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6607 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6610 _meshDS = mesh_i->GetImpl().GetMeshDS();
6612 SetPersistentId( _meshDS->GetPersistentId() );
6614 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6616 // <meshPart> is the whole mesh
6617 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6619 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6620 myGroupSet = _meshDS->GetGroups();
6625 SMESH::long_array_var anIDs = meshPart->GetIDs();
6626 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6627 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6629 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6630 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6631 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6636 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6637 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6638 if ( _elements[ e->GetType() ].insert( e ).second )
6641 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6642 while ( nIt->more() )
6644 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6645 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6652 ShapeToMesh( _meshDS->ShapeToMesh() );
6654 _meshDS = 0; // to enforce iteration on _elements and _nodes
6657 // -------------------------------------------------------------------------------------
6658 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6659 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6662 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6663 for ( ; partIt != meshPart.end(); ++partIt )
6664 if ( const SMDS_MeshElement * e = *partIt )
6665 if ( _elements[ e->GetType() ].insert( e ).second )
6668 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6669 while ( nIt->more() )
6671 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6672 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6678 // -------------------------------------------------------------------------------------
6679 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6681 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6683 TElemID elem( IDelem );
6684 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6685 if ( !_elements[ iType ].empty() )
6687 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6688 if ( it != _elements[ iType ].end() )
6693 // -------------------------------------------------------------------------------------
6694 bool SMESH_MeshPartDS::HasNumerationHoles()
6696 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6698 return ( MinNodeID() != 1 ||
6699 MaxNodeID() != NbNodes() ||
6700 MinElementID() != 1 ||
6701 MaxElementID() != NbElements() );
6703 // -------------------------------------------------------------------------------------
6704 int SMESH_MeshPartDS::MaxNodeID() const
6706 if ( _meshDS ) return _meshDS->MaxNodeID();
6707 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6709 // -------------------------------------------------------------------------------------
6710 int SMESH_MeshPartDS::MinNodeID() const
6712 if ( _meshDS ) return _meshDS->MinNodeID();
6713 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6715 // -------------------------------------------------------------------------------------
6716 int SMESH_MeshPartDS::MaxElementID() const
6718 if ( _meshDS ) return _meshDS->MaxElementID();
6720 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6721 if ( !_elements[ iType ].empty() )
6722 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6725 // -------------------------------------------------------------------------------------
6726 int SMESH_MeshPartDS::MinElementID() const
6728 if ( _meshDS ) return _meshDS->MinElementID();
6730 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6731 if ( !_elements[ iType ].empty() )
6732 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6735 // -------------------------------------------------------------------------------------
6736 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6738 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6740 typedef SMDS_SetIterator
6741 <const SMDS_MeshElement*,
6742 TIDSortedElemSet::const_iterator,
6743 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6744 SMDS_MeshElement::GeomFilter
6747 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6749 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6750 _elements[type].end(),
6751 SMDS_MeshElement::GeomFilter( geomType )));
6753 // -------------------------------------------------------------------------------------
6754 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6756 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6758 typedef SMDS_SetIterator
6759 <const SMDS_MeshElement*,
6760 TIDSortedElemSet::const_iterator,
6761 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6762 SMDS_MeshElement::EntityFilter
6765 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6767 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6768 _elements[type].end(),
6769 SMDS_MeshElement::EntityFilter( entity )));
6771 // -------------------------------------------------------------------------------------
6772 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6774 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6775 if ( type == SMDSAbs_All && !_meshDS )
6777 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6779 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6780 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6782 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6784 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6785 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6787 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6788 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6790 // -------------------------------------------------------------------------------------
6791 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6792 iterType SMESH_MeshPartDS::methName() const \
6794 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6795 return _meshDS ? _meshDS->methName() : iterType \
6796 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6798 // -------------------------------------------------------------------------------------
6799 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6800 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6801 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6802 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6803 #undef _GET_ITER_DEFINE
6805 // END Implementation of SMESH_MeshPartDS
6807 //================================================================================