1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
101 int SMESH_Mesh_i::_idGenerator = 0;
103 //=============================================================================
107 //=============================================================================
109 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
111 : SALOME::GenericObj_i( thePOA )
115 _id = _idGenerator++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
131 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
132 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
133 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
135 aGroup->UnRegister();
136 SMESH::SMESH_GroupBase_var( itGr->second );
141 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
142 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
143 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
145 aSubMesh->UnRegister();
146 SMESH::SMESH_subMesh_var( itSM->second );
148 _mapSubMeshIor.clear();
150 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
151 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
152 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
153 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
154 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
155 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
158 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
162 // clear cached shapes if no more meshes remain; (the cache is blame,
163 // together with publishing, of spent time increasing in issue 22874)
164 if ( _impl->NbMeshes() == 1 )
165 _gen_i->GetShapeReader()->ClearClientBuffer();
167 delete _editor; _editor = NULL;
168 delete _previewEditor; _previewEditor = NULL;
169 delete _impl; _impl = NULL;
170 delete _preMeshInfo; _preMeshInfo = NULL;
173 //=============================================================================
177 * Associates <this> mesh with <theShape> and puts a reference
178 * to <theShape> into the current study;
179 * the previous shape is substituted by the new one.
181 //=============================================================================
183 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
184 throw (SALOME::SALOME_Exception)
186 Unexpect aCatch(SALOME_SalomeException);
188 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
190 catch(SALOME_Exception & S_ex) {
191 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
193 // to track changes of GEOM groups
194 SMESH::SMESH_Mesh_var mesh = _this();
195 addGeomGroupData( theShapeObject, mesh );
196 if ( !CORBA::is_nil( theShapeObject ))
197 _mainShapeTick = theShapeObject->GetTick();
200 //================================================================================
202 * \brief return true if mesh has a shape to build a shape on
204 //================================================================================
206 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
207 throw (SALOME::SALOME_Exception)
209 Unexpect aCatch(SALOME_SalomeException);
212 res = _impl->HasShapeToMesh();
214 catch(SALOME_Exception & S_ex) {
215 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
220 //=======================================================================
221 //function : GetShapeToMesh
223 //=======================================================================
225 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
226 throw (SALOME::SALOME_Exception)
228 Unexpect aCatch(SALOME_SalomeException);
229 GEOM::GEOM_Object_var aShapeObj;
231 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
234 aShapeObj = _gen_i->ShapeToGeomObject( S );
235 if ( aShapeObj->_is_nil() )
237 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
238 // find GEOM_Object by entry (IPAL52735)
239 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
240 for ( ; data != _geomGroupData.end(); ++data )
241 if ( data->_smeshObject->_is_equivalent( _this() ))
243 SALOMEDS::SObject_wrap so = SMESH_Gen_i::getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
244 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
245 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
251 catch(SALOME_Exception & S_ex) {
252 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
254 return aShapeObj._retn();
257 //================================================================================
259 * \brief Return false if the mesh is not yet fully loaded from the study file
261 //================================================================================
263 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
265 Unexpect aCatch(SALOME_SalomeException);
266 return !_preMeshInfo;
269 //================================================================================
271 * \brief Load full mesh data from the study file
273 //================================================================================
275 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
277 Unexpect aCatch(SALOME_SalomeException);
279 _preMeshInfo->FullLoadFromFile();
282 //================================================================================
284 * \brief Remove all nodes and elements
286 //================================================================================
288 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
290 Unexpect aCatch(SALOME_SalomeException);
292 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
296 //CheckGeomGroupModif(); // issue 20145
298 catch(SALOME_Exception & S_ex) {
299 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
302 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
304 SMESH::SMESH_Mesh_var mesh = _this();
305 _gen_i->UpdateIcons( mesh );
308 //================================================================================
310 * \brief Remove all nodes and elements for indicated shape
312 //================================================================================
314 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
315 throw (SALOME::SALOME_Exception)
317 Unexpect aCatch(SALOME_SalomeException);
319 _preMeshInfo->FullLoadFromFile();
322 _impl->ClearSubMesh( ShapeID );
324 catch(SALOME_Exception & S_ex) {
325 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
327 _impl->GetMeshDS()->Modified();
329 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
332 //=============================================================================
334 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
336 //=============================================================================
338 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
340 SMESH::DriverMED_ReadStatus res;
343 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
344 res = SMESH::DRS_OK; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
346 res = SMESH::DRS_EMPTY; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
348 res = SMESH::DRS_WARN_RENUMBER; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
350 res = SMESH::DRS_WARN_SKIP_ELEM; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
352 res = SMESH::DRS_WARN_DESCENDING; break;
353 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
355 res = SMESH::DRS_FAIL; break;
360 //=============================================================================
362 * Convert ::SMESH_ComputeError to SMESH::ComputeError
364 //=============================================================================
366 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
368 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
369 errVar->subShapeID = -1;
370 errVar->hasBadMesh = false;
372 if ( !errorPtr || errorPtr->IsOK() )
374 errVar->code = SMESH::COMPERR_OK;
378 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
379 errVar->comment = errorPtr->myComment.c_str();
381 return errVar._retn();
384 //=============================================================================
388 * Imports mesh data from MED file
390 //=============================================================================
392 SMESH::DriverMED_ReadStatus
393 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
394 throw ( SALOME::SALOME_Exception )
396 Unexpect aCatch(SALOME_SalomeException);
399 status = _impl->MEDToMesh( theFileName, theMeshName );
401 catch( SALOME_Exception& S_ex ) {
402 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
405 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
408 CreateGroupServants();
410 int major, minor, release;
411 major = minor = release = 0;
412 MED::GetMEDVersion(theFileName, major, minor, release);
413 _medFileInfo = new SMESH::MedFileInfo();
414 _medFileInfo->fileName = theFileName;
415 _medFileInfo->fileSize = 0;
416 _medFileInfo->major = major;
417 _medFileInfo->minor = minor;
418 _medFileInfo->release = release;
419 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
421 return ConvertDriverMEDReadStatus(status);
424 //================================================================================
426 * \brief Imports mesh data from the CGNS file
428 //================================================================================
430 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
431 const int theMeshIndex,
432 std::string& theMeshName )
433 throw ( SALOME::SALOME_Exception )
435 Unexpect aCatch(SALOME_SalomeException);
438 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
440 catch( SALOME_Exception& S_ex ) {
441 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
444 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
447 CreateGroupServants();
449 _medFileInfo = new SMESH::MedFileInfo();
450 _medFileInfo->fileName = theFileName;
451 _medFileInfo->major = 0;
452 _medFileInfo->minor = 0;
453 _medFileInfo->release = 0;
454 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
456 return ConvertDriverMEDReadStatus(status);
459 //================================================================================
461 * \brief Return string representation of a MED file version comprising nbDigits
463 //================================================================================
465 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
467 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
469 return CORBA::string_dup( ver.c_str() );
472 //================================================================================
474 * Return the list of med versions compatibles for write/append,
475 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
477 //================================================================================
478 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
480 SMESH::long_array_var aResult = new SMESH::long_array();
481 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
482 long nbver = mvok.size();
483 aResult->length( nbver );
484 for ( int i = 0; i < nbver; i++ )
485 aResult[i] = mvok[i];
486 return aResult._retn();
489 //=============================================================================
493 * Imports mesh data from MED file
495 //=============================================================================
497 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
498 throw ( SALOME::SALOME_Exception )
502 // Read mesh with name = <theMeshName> into SMESH_Mesh
503 _impl->UNVToMesh( theFileName );
505 CreateGroupServants();
507 _medFileInfo = new SMESH::MedFileInfo();
508 _medFileInfo->fileName = theFileName;
509 _medFileInfo->major = 0;
510 _medFileInfo->minor = 0;
511 _medFileInfo->release = 0;
512 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
514 SMESH_CATCH( SMESH::throwCorbaException );
519 //=============================================================================
523 * Imports mesh data from STL file
525 //=============================================================================
526 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
527 throw ( SALOME::SALOME_Exception )
531 // Read mesh with name = <theMeshName> into SMESH_Mesh
532 std::string name = _impl->STLToMesh( theFileName );
535 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
536 _gen_i->SetName( meshSO, name.c_str() );
538 _medFileInfo = new SMESH::MedFileInfo();
539 _medFileInfo->fileName = theFileName;
540 _medFileInfo->major = 0;
541 _medFileInfo->minor = 0;
542 _medFileInfo->release = 0;
543 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
545 SMESH_CATCH( SMESH::throwCorbaException );
550 //================================================================================
552 * \brief Function used in SMESH_CATCH by ImportGMFFile()
554 //================================================================================
558 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
560 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
564 //================================================================================
566 * \brief Imports data from a GMF file and returns an error description
568 //================================================================================
570 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
571 bool theMakeRequiredGroups )
572 throw (SALOME::SALOME_Exception)
574 SMESH_ComputeErrorPtr error;
577 #define SMESH_CAUGHT error =
580 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
582 _medFileInfo = new SMESH::MedFileInfo();
583 _medFileInfo->fileName = theFileName;
584 _medFileInfo->major = 0;
585 _medFileInfo->minor = 0;
586 _medFileInfo->release = 0;
587 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
589 SMESH_CATCH( exceptionToComputeError );
593 CreateGroupServants();
595 return ConvertComputeError( error );
598 //=============================================================================
602 //=============================================================================
604 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
606 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
607 (SMESH_Hypothesis::Hypothesis_Status theStatus)
610 RETURNCASE( HYP_OK );
611 RETURNCASE( HYP_MISSING );
612 RETURNCASE( HYP_CONCURRENT );
613 RETURNCASE( HYP_BAD_PARAMETER );
614 RETURNCASE( HYP_HIDDEN_ALGO );
615 RETURNCASE( HYP_HIDING_ALGO );
616 RETURNCASE( HYP_UNKNOWN_FATAL );
617 RETURNCASE( HYP_INCOMPATIBLE );
618 RETURNCASE( HYP_NOTCONFORM );
619 RETURNCASE( HYP_ALREADY_EXIST );
620 RETURNCASE( HYP_BAD_DIM );
621 RETURNCASE( HYP_BAD_SUBSHAPE );
622 RETURNCASE( HYP_BAD_GEOMETRY );
623 RETURNCASE( HYP_NEED_SHAPE );
624 RETURNCASE( HYP_INCOMPAT_HYPS );
627 return SMESH::HYP_UNKNOWN_FATAL;
630 //=============================================================================
634 * calls internal addHypothesis() and then adds a reference to <anHyp> under
635 * the SObject actually having a reference to <aSubShape>.
636 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
638 //=============================================================================
640 SMESH::Hypothesis_Status
641 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
642 SMESH::SMESH_Hypothesis_ptr anHyp,
643 CORBA::String_out anErrorText)
644 throw(SALOME::SALOME_Exception)
646 Unexpect aCatch(SALOME_SalomeException);
648 _preMeshInfo->ForgetOrLoad();
651 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
652 anErrorText = error.c_str();
654 SMESH::SMESH_Mesh_var mesh( _this() );
655 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
657 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
658 _gen_i->UpdateIcons( mesh );
660 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
662 // Update Python script
663 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
664 << aSubShape << ", " << anHyp << " )";
666 return ConvertHypothesisStatus(status);
669 //=============================================================================
673 //=============================================================================
675 SMESH_Hypothesis::Hypothesis_Status
676 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
677 SMESH::SMESH_Hypothesis_ptr anHyp,
678 std::string* anErrorText)
680 if(MYDEBUG) MESSAGE("addHypothesis");
682 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
683 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
685 if (CORBA::is_nil( anHyp ))
686 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
688 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
691 TopoDS_Shape myLocSubShape;
692 //use PseudoShape in case if mesh has no shape
694 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
696 myLocSubShape = _impl->GetShapeToMesh();
698 const int hypId = anHyp->GetId();
700 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
701 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
703 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
705 // assure there is a corresponding submesh
706 if ( !_impl->IsMainShape( myLocSubShape )) {
707 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
708 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
709 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
712 else if ( anErrorText )
714 *anErrorText = error;
717 catch(SALOME_Exception & S_ex)
719 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
724 //=============================================================================
728 //=============================================================================
730 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
731 SMESH::SMESH_Hypothesis_ptr anHyp)
732 throw(SALOME::SALOME_Exception)
734 Unexpect aCatch(SALOME_SalomeException);
736 _preMeshInfo->ForgetOrLoad();
738 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
739 SMESH::SMESH_Mesh_var mesh = _this();
741 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
743 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
744 _gen_i->UpdateIcons( mesh );
746 // Update Python script
747 if(_impl->HasShapeToMesh())
748 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
749 << aSubShape << ", " << anHyp << " )";
751 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
754 return ConvertHypothesisStatus(status);
757 //=============================================================================
761 //=============================================================================
763 SMESH_Hypothesis::Hypothesis_Status
764 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
765 SMESH::SMESH_Hypothesis_ptr anHyp)
767 if(MYDEBUG) MESSAGE("removeHypothesis()");
769 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
770 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
772 if (CORBA::is_nil( anHyp ))
773 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
775 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
778 TopoDS_Shape myLocSubShape;
779 //use PseudoShape in case if mesh has no shape
780 if( _impl->HasShapeToMesh() )
781 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
783 myLocSubShape = _impl->GetShapeToMesh();
785 const int hypId = anHyp->GetId();
786 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
787 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
789 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
793 catch(SALOME_Exception & S_ex)
795 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
800 //=============================================================================
804 //=============================================================================
806 SMESH::ListOfHypothesis *
807 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
808 throw(SALOME::SALOME_Exception)
810 Unexpect aCatch(SALOME_SalomeException);
811 if (MYDEBUG) MESSAGE("GetHypothesisList");
812 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
813 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
815 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
818 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
819 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
820 myLocSubShape = _impl->GetShapeToMesh();
821 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
822 int i = 0, n = aLocalList.size();
825 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
826 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
827 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
829 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
830 if ( id_hypptr != _mapHypo.end() )
831 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
835 catch(SALOME_Exception & S_ex) {
836 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
839 return aList._retn();
842 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
844 Unexpect aCatch(SALOME_SalomeException);
845 if (MYDEBUG) MESSAGE("GetSubMeshes");
847 SMESH::submesh_array_var aList = new SMESH::submesh_array();
850 TPythonDump aPythonDump;
851 if ( !_mapSubMeshIor.empty() )
855 aList->length( _mapSubMeshIor.size() );
857 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
858 for ( ; it != _mapSubMeshIor.end(); it++ ) {
859 if ( CORBA::is_nil( it->second )) continue;
860 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
862 if (i > 1) aPythonDump << ", ";
863 aPythonDump << it->second;
867 catch(SALOME_Exception & S_ex) {
868 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
871 // Update Python script
872 if ( !_mapSubMeshIor.empty() )
873 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
875 return aList._retn();
878 //=============================================================================
882 //=============================================================================
884 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
885 const char* theName )
886 throw(SALOME::SALOME_Exception)
888 Unexpect aCatch(SALOME_SalomeException);
889 if (CORBA::is_nil(aSubShape))
890 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
892 SMESH::SMESH_subMesh_var subMesh;
893 SMESH::SMESH_Mesh_var aMesh = _this();
895 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
897 //Get or Create the SMESH_subMesh object implementation
899 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
901 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
903 TopoDS_Iterator it( myLocSubShape );
905 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
907 subMesh = getSubMesh( subMeshId );
909 // create a new subMesh object servant if there is none for the shape
910 if ( subMesh->_is_nil() )
911 subMesh = createSubMesh( aSubShape );
912 if ( _gen_i->CanPublishInStudy( subMesh ))
914 SALOMEDS::SObject_wrap aSO =
915 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
916 if ( !aSO->_is_nil()) {
917 // Update Python script
918 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
919 << aSubShape << ", '" << theName << "' )";
923 catch(SALOME_Exception & S_ex) {
924 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
926 return subMesh._retn();
929 //=============================================================================
933 //=============================================================================
935 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
936 throw (SALOME::SALOME_Exception)
940 if ( theSubMesh->_is_nil() )
943 GEOM::GEOM_Object_var aSubShape;
944 // Remove submesh's SObject
945 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
946 if ( !anSO->_is_nil() ) {
947 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
948 SALOMEDS::SObject_wrap anObj, aRef;
949 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
950 anObj->ReferencedObject( aRef.inout() ))
952 CORBA::Object_var obj = aRef->GetObject();
953 aSubShape = GEOM::GEOM_Object::_narrow( obj );
955 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
956 // aSubShape = theSubMesh->GetSubShape();
958 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
959 builder->RemoveObjectWithChildren( anSO );
961 // Update Python script
962 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
965 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
967 _preMeshInfo->ForgetOrLoad();
969 SMESH_CATCH( SMESH::throwCorbaException );
972 //=============================================================================
976 //=============================================================================
978 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
979 const char* theName )
980 throw(SALOME::SALOME_Exception)
982 Unexpect aCatch(SALOME_SalomeException);
984 _preMeshInfo->FullLoadFromFile();
986 SMESH::SMESH_Group_var aNewGroup =
987 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
989 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
991 SMESH::SMESH_Mesh_var mesh = _this();
992 SALOMEDS::SObject_wrap aSO =
993 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
994 if ( !aSO->_is_nil())
995 // Update Python script
996 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
997 << theElemType << ", '" << theName << "' )";
999 return aNewGroup._retn();
1002 //=============================================================================
1006 //=============================================================================
1007 SMESH::SMESH_GroupOnGeom_ptr
1008 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1009 const char* theName,
1010 GEOM::GEOM_Object_ptr theGeomObj)
1011 throw(SALOME::SALOME_Exception)
1013 Unexpect aCatch(SALOME_SalomeException);
1015 _preMeshInfo->FullLoadFromFile();
1017 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1019 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1020 if ( !aShape.IsNull() )
1023 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
1025 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1027 SMESH::SMESH_Mesh_var mesh = _this();
1028 SALOMEDS::SObject_wrap aSO =
1029 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1030 if ( !aSO->_is_nil())
1031 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1032 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1036 return aNewGroup._retn();
1039 //================================================================================
1041 * \brief Creates a group whose contents is defined by filter
1042 * \param theElemType - group type
1043 * \param theName - group name
1044 * \param theFilter - the filter
1045 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1047 //================================================================================
1049 SMESH::SMESH_GroupOnFilter_ptr
1050 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1051 const char* theName,
1052 SMESH::Filter_ptr theFilter )
1053 throw (SALOME::SALOME_Exception)
1055 Unexpect aCatch(SALOME_SalomeException);
1057 _preMeshInfo->FullLoadFromFile();
1059 if ( CORBA::is_nil( theFilter ))
1060 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1062 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1064 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1066 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1067 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1070 if ( !aNewGroup->_is_nil() )
1071 aNewGroup->SetFilter( theFilter );
1073 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1075 SMESH::SMESH_Mesh_var mesh = _this();
1076 SALOMEDS::SObject_wrap aSO =
1077 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1079 if ( !aSO->_is_nil())
1080 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1081 << theElemType << ", '" << theName << "', " << theFilter << " )";
1083 return aNewGroup._retn();
1086 //=============================================================================
1090 //=============================================================================
1092 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1093 throw (SALOME::SALOME_Exception)
1095 if ( theGroup->_is_nil() )
1100 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1104 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1105 if ( !aGroupSO->_is_nil() )
1107 // Update Python script
1108 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1110 // Remove group's SObject
1111 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1112 builder->RemoveObjectWithChildren( aGroupSO );
1114 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1116 // Remove the group from SMESH data structures
1117 removeGroup( aGroup->GetLocalID() );
1119 SMESH_CATCH( SMESH::throwCorbaException );
1122 //=============================================================================
1124 * Remove group with its contents
1126 //=============================================================================
1128 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1129 throw (SALOME::SALOME_Exception)
1133 _preMeshInfo->FullLoadFromFile();
1135 if ( theGroup->_is_nil() )
1138 vector<int> nodeIds; // to remove nodes becoming free
1139 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1140 if ( !isNodal && !theGroup->IsEmpty() )
1142 CORBA::Long elemID = theGroup->GetID( 1 );
1143 int nbElemNodes = GetElemNbNodes( elemID );
1144 if ( nbElemNodes > 0 )
1145 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1148 // Retrieve contents
1149 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1150 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1151 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1152 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1153 elems.assign( elemBeg, elemEnd );
1155 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1158 RemoveGroup( theGroup );
1161 for ( size_t i = 0; i < elems.size(); ++i )
1163 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1167 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1168 nodeIds.push_back( nIt->next()->GetID() );
1170 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1174 _impl->GetMeshDS()->RemoveElement( elems[i] );
1178 // Remove free nodes
1179 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1180 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1181 if ( n->NbInverseElements() == 0 )
1182 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1184 // Update Python script (theGroup must be alive for this)
1185 pyDump << SMESH::SMESH_Mesh_var(_this())
1186 << ".RemoveGroupWithContents( " << theGroup << " )";
1188 SMESH_CATCH( SMESH::throwCorbaException );
1191 //================================================================================
1193 * \brief Get the list of groups existing in the mesh
1194 * \retval SMESH::ListOfGroups * - list of groups
1196 //================================================================================
1198 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1200 Unexpect aCatch(SALOME_SalomeException);
1201 if (MYDEBUG) MESSAGE("GetGroups");
1203 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1206 TPythonDump aPythonDump;
1207 if ( !_mapGroups.empty() )
1209 aPythonDump << "[ ";
1211 aList->length( _mapGroups.size() );
1213 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1214 for ( ; it != _mapGroups.end(); it++ ) {
1215 if ( CORBA::is_nil( it->second )) continue;
1216 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1218 if (i > 1) aPythonDump << ", ";
1219 aPythonDump << it->second;
1223 catch(SALOME_Exception & S_ex) {
1224 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1226 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1228 return aList._retn();
1231 //=============================================================================
1233 * Get number of groups existing in the mesh
1235 //=============================================================================
1237 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1239 Unexpect aCatch(SALOME_SalomeException);
1240 return _mapGroups.size();
1243 //=============================================================================
1245 * New group including all mesh elements present in initial groups is created.
1247 //=============================================================================
1249 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1250 SMESH::SMESH_GroupBase_ptr theGroup2,
1251 const char* theName )
1252 throw (SALOME::SALOME_Exception)
1254 SMESH::SMESH_Group_var aResGrp;
1258 _preMeshInfo->FullLoadFromFile();
1260 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1261 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1263 if ( theGroup1->GetType() != theGroup2->GetType() )
1264 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1269 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1270 if ( aResGrp->_is_nil() )
1271 return SMESH::SMESH_Group::_nil();
1273 aResGrp->AddFrom( theGroup1 );
1274 aResGrp->AddFrom( theGroup2 );
1276 // Update Python script
1277 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1278 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1280 SMESH_CATCH( SMESH::throwCorbaException );
1282 return aResGrp._retn();
1285 //=============================================================================
1287 * \brief New group including all mesh elements present in initial groups is created.
1288 * \param theGroups list of groups
1289 * \param theName name of group to be created
1290 * \return pointer to the new group
1292 //=============================================================================
1294 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1295 const char* theName )
1296 throw (SALOME::SALOME_Exception)
1298 SMESH::SMESH_Group_var aResGrp;
1301 _preMeshInfo->FullLoadFromFile();
1304 return SMESH::SMESH_Group::_nil();
1309 SMESH::ElementType aType = SMESH::ALL;
1310 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1312 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1313 if ( CORBA::is_nil( aGrp ) )
1315 if ( aType == SMESH::ALL )
1316 aType = aGrp->GetType();
1317 else if ( aType != aGrp->GetType() )
1318 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1321 if ( aType == SMESH::ALL )
1322 return SMESH::SMESH_Group::_nil();
1327 aResGrp = CreateGroup( aType, theName );
1328 if ( aResGrp->_is_nil() )
1329 return SMESH::SMESH_Group::_nil();
1331 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1332 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1334 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1335 if ( !CORBA::is_nil( aGrp ) )
1337 aResGrp->AddFrom( aGrp );
1338 if ( g > 0 ) pyDump << ", ";
1342 pyDump << " ], '" << theName << "' )";
1344 SMESH_CATCH( SMESH::throwCorbaException );
1346 return aResGrp._retn();
1349 //=============================================================================
1351 * New group is created. All mesh elements that are
1352 * present in both initial groups are added to the new one.
1354 //=============================================================================
1356 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1357 SMESH::SMESH_GroupBase_ptr theGroup2,
1358 const char* theName )
1359 throw (SALOME::SALOME_Exception)
1361 SMESH::SMESH_Group_var aResGrp;
1366 _preMeshInfo->FullLoadFromFile();
1368 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1369 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1371 if ( theGroup1->GetType() != theGroup2->GetType() )
1372 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1376 // Create Intersection
1377 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1378 if ( aResGrp->_is_nil() )
1379 return aResGrp._retn();
1381 SMESHDS_GroupBase* groupDS1 = 0;
1382 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1383 groupDS1 = grp_i->GetGroupDS();
1385 SMESHDS_GroupBase* groupDS2 = 0;
1386 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1387 groupDS2 = grp_i->GetGroupDS();
1389 SMESHDS_Group* resGroupDS = 0;
1390 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1391 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1393 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1395 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1396 while ( elemIt1->more() )
1398 const SMDS_MeshElement* e = elemIt1->next();
1399 if ( groupDS2->Contains( e ))
1400 resGroupDS->SMDSGroup().Add( e );
1403 // Update Python script
1404 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1405 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1407 SMESH_CATCH( SMESH::throwCorbaException );
1409 return aResGrp._retn();
1412 //=============================================================================
1414 \brief Intersect list of groups. New group is created. All mesh elements that
1415 are present in all initial groups simultaneously are added to the new one.
1416 \param theGroups list of groups
1417 \param theName name of group to be created
1418 \return pointer on the group
1420 //=============================================================================
1421 SMESH::SMESH_Group_ptr
1422 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1423 const char* theName )
1424 throw (SALOME::SALOME_Exception)
1426 SMESH::SMESH_Group_var aResGrp;
1431 _preMeshInfo->FullLoadFromFile();
1434 return SMESH::SMESH_Group::_nil();
1436 // check types and get SMESHDS_GroupBase's
1437 SMESH::ElementType aType = SMESH::ALL;
1438 vector< SMESHDS_GroupBase* > groupVec;
1439 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1441 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1442 if ( CORBA::is_nil( aGrp ) )
1444 if ( aType == SMESH::ALL )
1445 aType = aGrp->GetType();
1446 else if ( aType != aGrp->GetType() )
1447 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1450 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1451 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1453 if ( grpDS->IsEmpty() )
1458 groupVec.push_back( grpDS );
1461 if ( aType == SMESH::ALL ) // all groups are nil
1462 return SMESH::SMESH_Group::_nil();
1467 aResGrp = CreateGroup( aType, theName );
1469 SMESHDS_Group* resGroupDS = 0;
1470 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1471 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1472 if ( !resGroupDS || groupVec.empty() )
1473 return aResGrp._retn();
1476 size_t i, nb = groupVec.size();
1477 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1478 while ( elemIt1->more() )
1480 const SMDS_MeshElement* e = elemIt1->next();
1482 for ( i = 1; ( i < nb && inAll ); ++i )
1483 inAll = groupVec[i]->Contains( e );
1486 resGroupDS->SMDSGroup().Add( e );
1489 // Update Python script
1490 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1491 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1493 SMESH_CATCH( SMESH::throwCorbaException );
1495 return aResGrp._retn();
1498 //=============================================================================
1500 * New group is created. All mesh elements that are present in
1501 * a main group but is not present in a tool group are added to the new one
1503 //=============================================================================
1505 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1506 SMESH::SMESH_GroupBase_ptr theGroup2,
1507 const char* theName )
1508 throw (SALOME::SALOME_Exception)
1510 SMESH::SMESH_Group_var aResGrp;
1515 _preMeshInfo->FullLoadFromFile();
1517 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1518 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1520 if ( theGroup1->GetType() != theGroup2->GetType() )
1521 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1525 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1526 if ( aResGrp->_is_nil() )
1527 return aResGrp._retn();
1529 SMESHDS_GroupBase* groupDS1 = 0;
1530 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1531 groupDS1 = grp_i->GetGroupDS();
1533 SMESHDS_GroupBase* groupDS2 = 0;
1534 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1535 groupDS2 = grp_i->GetGroupDS();
1537 SMESHDS_Group* resGroupDS = 0;
1538 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1539 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1541 if ( groupDS1 && groupDS2 && resGroupDS )
1543 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1544 while ( elemIt1->more() )
1546 const SMDS_MeshElement* e = elemIt1->next();
1547 if ( !groupDS2->Contains( e ))
1548 resGroupDS->SMDSGroup().Add( e );
1551 // Update Python script
1552 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1553 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1555 SMESH_CATCH( SMESH::throwCorbaException );
1557 return aResGrp._retn();
1560 //=============================================================================
1562 \brief Cut lists of groups. New group is created. All mesh elements that are
1563 present in main groups but do not present in tool groups are added to the new one
1564 \param theMainGroups list of main groups
1565 \param theToolGroups list of tool groups
1566 \param theName name of group to be created
1567 \return pointer on the group
1569 //=============================================================================
1570 SMESH::SMESH_Group_ptr
1571 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1572 const SMESH::ListOfGroups& theToolGroups,
1573 const char* theName )
1574 throw (SALOME::SALOME_Exception)
1576 SMESH::SMESH_Group_var aResGrp;
1581 _preMeshInfo->FullLoadFromFile();
1584 return SMESH::SMESH_Group::_nil();
1586 // check types and get SMESHDS_GroupBase's
1587 SMESH::ElementType aType = SMESH::ALL;
1588 vector< SMESHDS_GroupBase* > toolGroupVec;
1589 vector< SMDS_ElemIteratorPtr > mainIterVec;
1591 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1593 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1594 if ( CORBA::is_nil( aGrp ) )
1596 if ( aType == SMESH::ALL )
1597 aType = aGrp->GetType();
1598 else if ( aType != aGrp->GetType() )
1599 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1601 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1602 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1603 if ( !grpDS->IsEmpty() )
1604 mainIterVec.push_back( grpDS->GetElements() );
1606 if ( aType == SMESH::ALL ) // all main groups are nil
1607 return SMESH::SMESH_Group::_nil();
1608 if ( mainIterVec.empty() ) // all main groups are empty
1609 return aResGrp._retn();
1611 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1613 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1614 if ( CORBA::is_nil( aGrp ) )
1616 if ( aType != aGrp->GetType() )
1617 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1619 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1620 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1621 toolGroupVec.push_back( grpDS );
1627 aResGrp = CreateGroup( aType, theName );
1629 SMESHDS_Group* resGroupDS = 0;
1630 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1631 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1633 return aResGrp._retn();
1636 size_t i, nb = toolGroupVec.size();
1637 SMDS_ElemIteratorPtr mainElemIt
1638 ( new SMDS_IteratorOnIterators
1639 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1640 while ( mainElemIt->more() )
1642 const SMDS_MeshElement* e = mainElemIt->next();
1644 for ( i = 0; ( i < nb && !isIn ); ++i )
1645 isIn = toolGroupVec[i]->Contains( e );
1648 resGroupDS->SMDSGroup().Add( e );
1651 // Update Python script
1652 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1653 << ".CutListOfGroups( " << theMainGroups << ", "
1654 << theToolGroups << ", '" << theName << "' )";
1656 SMESH_CATCH( SMESH::throwCorbaException );
1658 return aResGrp._retn();
1661 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1663 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1664 bool & toStopChecking )
1666 toStopChecking = ( nbCommon < nbChecked );
1667 return nbCommon == nbNodes;
1669 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1670 bool & toStopChecking )
1672 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1673 return nbCommon == nbCorners;
1675 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1676 bool & toStopChecking )
1678 return nbCommon > 0;
1680 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1681 bool & toStopChecking )
1683 return nbCommon >= (nbNodes+1) / 2;
1687 //=============================================================================
1689 * Create a group of entities basing on nodes of other groups.
1690 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1691 * \param [in] anElemType - a type of elements to include to the new group.
1692 * \param [in] theName - a name of the new group.
1693 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1694 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1695 * new group provided that it is based on nodes of an element of \a aListOfGroups
1696 * \return SMESH_Group - the created group
1698 // IMP 19939, bug 22010, IMP 22635
1699 //=============================================================================
1701 SMESH::SMESH_Group_ptr
1702 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1703 SMESH::ElementType theElemType,
1704 const char* theName,
1705 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1706 CORBA::Boolean theUnderlyingOnly)
1707 throw (SALOME::SALOME_Exception)
1709 SMESH::SMESH_Group_var aResGrp;
1713 _preMeshInfo->FullLoadFromFile();
1715 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1717 if ( !theName || !aMeshDS )
1718 return SMESH::SMESH_Group::_nil();
1720 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1722 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1723 SMESH_Comment nbCoNoStr( "SMESH.");
1724 switch ( theNbCommonNodes ) {
1725 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1726 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1727 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1728 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1729 default: return aResGrp._retn();
1731 int nbChecked, nbCommon, nbNodes, nbCorners;
1737 aResGrp = CreateGroup( theElemType, theName );
1738 if ( aResGrp->_is_nil() )
1739 return SMESH::SMESH_Group::_nil();
1741 SMESHDS_GroupBase* groupBaseDS =
1742 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1743 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1745 vector<bool> isNodeInGroups;
1747 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1749 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1750 if ( CORBA::is_nil( aGrp ) )
1752 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1753 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1756 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1757 if ( !elIt ) continue;
1759 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1761 while ( elIt->more() ) {
1762 const SMDS_MeshElement* el = elIt->next();
1763 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1764 while ( nIt->more() )
1765 resGroupCore.Add( nIt->next() );
1768 // get elements of theElemType based on nodes of every element of group
1769 else if ( theUnderlyingOnly )
1771 while ( elIt->more() )
1773 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1774 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1775 TIDSortedElemSet checkedElems;
1776 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1777 while ( nIt->more() )
1779 const SMDS_MeshNode* n = nIt->next();
1780 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1781 // check nodes of elements of theElemType around el
1782 while ( elOfTypeIt->more() )
1784 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1785 if ( !checkedElems.insert( elOfType ).second ) continue;
1786 nbNodes = elOfType->NbNodes();
1787 nbCorners = elOfType->NbCornerNodes();
1789 bool toStopChecking = false;
1790 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1791 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1792 if ( elNodes.count( nIt2->next() ) &&
1793 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1795 resGroupCore.Add( elOfType );
1802 // get all nodes of elements of groups
1805 while ( elIt->more() )
1807 const SMDS_MeshElement* el = elIt->next(); // an element of group
1808 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1809 while ( nIt->more() )
1811 const SMDS_MeshNode* n = nIt->next();
1812 if ( n->GetID() >= (int) isNodeInGroups.size() )
1813 isNodeInGroups.resize( n->GetID() + 1, false );
1814 isNodeInGroups[ n->GetID() ] = true;
1820 // Get elements of theElemType based on a certain number of nodes of elements of groups
1821 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1823 const SMDS_MeshNode* n;
1824 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1825 const int isNodeInGroupsSize = isNodeInGroups.size();
1826 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1828 if ( !isNodeInGroups[ iN ] ||
1829 !( n = aMeshDS->FindNode( iN )))
1832 // check nodes of elements of theElemType around n
1833 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1834 while ( elOfTypeIt->more() )
1836 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1837 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1842 nbNodes = elOfType->NbNodes();
1843 nbCorners = elOfType->NbCornerNodes();
1845 bool toStopChecking = false;
1846 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1847 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1849 const int nID = nIt->next()->GetID();
1850 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1851 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1853 resGroupCore.Add( elOfType );
1861 // Update Python script
1862 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1863 << ".CreateDimGroup( "
1864 << theGroups << ", " << theElemType << ", '" << theName << "', "
1865 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1867 SMESH_CATCH( SMESH::throwCorbaException );
1869 return aResGrp._retn();
1872 //================================================================================
1874 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1875 * existing 1D elements as group boundaries.
1876 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1877 * adjacent faces is more than \a sharpAngle in degrees.
1878 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1879 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1880 * \return ListOfGroups - the created groups
1882 //================================================================================
1884 SMESH::ListOfGroups*
1885 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1886 CORBA::Boolean theCreateEdges,
1887 CORBA::Boolean theUseExistingEdges )
1888 throw (SALOME::SALOME_Exception)
1890 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1891 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1894 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1900 _preMeshInfo->FullLoadFromFile();
1902 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1904 std::vector< SMESH_MeshAlgos::Edge > edges =
1905 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1907 if ( theCreateEdges )
1909 std::vector<const SMDS_MeshNode *> nodes(2);
1910 for ( size_t i = 0; i < edges.size(); ++i )
1912 nodes[0] = edges[i]._node1;
1913 nodes[1] = edges[i]._node2;
1914 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1916 if ( edges[i]._medium )
1917 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1919 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1923 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1924 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1926 SMESH::SMESH_MeshEditor_var( GetMeshEditor() ); // create _editor
1928 resultGroups->length( faceGroups.size() );
1929 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1931 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1932 _editor->GenerateGroupName("Group").c_str());
1933 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1935 SMESHDS_GroupBase* groupBaseDS =
1936 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1937 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1939 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1940 for ( size_t i = 0; i < faces.size(); ++i )
1941 groupCore.Add( faces[i] );
1944 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1945 << ".FaceGroupsSeparatedByEdges( "
1946 << TVar( theSharpAngle ) << ", "
1947 << theCreateEdges << ", "
1948 << theUseExistingEdges << " )";
1950 SMESH_CATCH( SMESH::throwCorbaException );
1951 return resultGroups._retn();
1955 //================================================================================
1957 * \brief Remember GEOM group data
1959 //================================================================================
1961 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1962 CORBA::Object_ptr theSmeshObj)
1964 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1967 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1968 if ( groupSO->_is_nil() )
1971 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1972 GEOM::GEOM_IGroupOperations_wrap groupOp =
1973 geomGen->GetIGroupOperations();
1974 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1977 _geomGroupData.push_back( TGeomGroupData() );
1978 TGeomGroupData & groupData = _geomGroupData.back();
1980 CORBA::String_var entry = groupSO->GetID();
1981 groupData._groupEntry = entry.in();
1983 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1984 groupData._indices.insert( ids[i] );
1986 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1987 // shape index in SMESHDS
1988 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1989 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1992 //================================================================================
1994 * Remove GEOM group data relating to removed smesh object
1996 //================================================================================
1998 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2000 list<TGeomGroupData>::iterator
2001 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2002 for ( ; data != dataEnd; ++data ) {
2003 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2004 _geomGroupData.erase( data );
2010 //================================================================================
2012 * \brief Return new group contents if it has been changed and update group data
2014 //================================================================================
2016 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
2018 TopoDS_Shape newShape;
2021 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2022 if ( !groupSO->_is_nil() )
2024 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2025 if ( CORBA::is_nil( groupObj )) return newShape;
2026 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2028 // get indices of group items
2029 set<int> curIndices;
2030 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2031 GEOM::GEOM_IGroupOperations_wrap groupOp =
2032 geomGen->GetIGroupOperations();
2033 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2034 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2035 curIndices.insert( ids[i] );
2037 if ( groupData._indices == curIndices )
2038 return newShape; // group not changed
2041 groupData._indices = curIndices;
2043 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2044 if ( !geomClient ) return newShape;
2045 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2046 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2047 newShape = _gen_i->GeomObjectToShape( geomGroup );
2050 if ( newShape.IsNull() ) {
2051 // geom group becomes empty - return empty compound
2052 TopoDS_Compound compound;
2053 BRep_Builder().MakeCompound(compound);
2054 newShape = compound;
2061 //-----------------------------------------------------------------------------
2063 * \brief Storage of shape and index used in CheckGeomGroupModif()
2065 struct TIndexedShape
2068 TopoDS_Shape _shape;
2069 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2071 //-----------------------------------------------------------------------------
2073 * \brief Data to re-create a group on geometry
2075 struct TGroupOnGeomData
2079 SMDSAbs_ElementType _type;
2081 Quantity_Color _color;
2085 //=============================================================================
2087 * \brief Update data if geometry changes
2091 //=============================================================================
2093 void SMESH_Mesh_i::CheckGeomModif()
2095 if ( !_impl->HasShapeToMesh() ) return;
2097 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
2098 //if ( mainGO->_is_nil() ) return;
2100 // Update after group modification
2102 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
2103 called by other mesh (IPAL52735) */
2104 mainGO->GetType() == GEOM_GROUP ||
2105 mainGO->GetTick() == _mainShapeTick )
2107 CheckGeomGroupModif();
2111 // Update after shape transformation like Translate
2113 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2114 if ( !geomClient ) return;
2115 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2116 if ( geomGen->_is_nil() ) return;
2118 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2119 geomClient->RemoveShapeFromBuffer( ior.in() );
2121 // Update data taking into account that
2122 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2125 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2126 if ( newShape.IsNull() )
2129 _mainShapeTick = mainGO->GetTick();
2131 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2133 // store data of groups on geometry
2134 vector< TGroupOnGeomData > groupsData;
2135 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2136 groupsData.reserve( groups.size() );
2137 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2138 for ( ; g != groups.end(); ++g )
2139 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2141 TGroupOnGeomData data;
2142 data._oldID = group->GetID();
2143 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2144 data._type = group->GetType();
2145 data._name = group->GetStoreName();
2146 data._color = group->GetColor();
2147 groupsData.push_back( data );
2149 // store assigned hypotheses
2150 vector< pair< int, THypList > > ids2Hyps;
2151 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2152 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2154 const TopoDS_Shape& s = s2hyps.Key();
2155 const THypList& hyps = s2hyps.ChangeValue();
2156 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2159 // change shape to mesh
2160 int oldNbSubShapes = meshDS->MaxShapeIndex();
2161 _impl->ShapeToMesh( TopoDS_Shape() );
2162 _impl->ShapeToMesh( newShape );
2164 // re-add shapes of geom groups
2165 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2166 for ( ; data != _geomGroupData.end(); ++data )
2168 TopoDS_Shape newShape = newGroupShape( *data );
2169 if ( !newShape.IsNull() )
2171 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2173 TopoDS_Compound compound;
2174 BRep_Builder().MakeCompound( compound );
2175 BRep_Builder().Add( compound, newShape );
2176 newShape = compound;
2178 _impl->GetSubMesh( newShape );
2181 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2182 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2183 SALOME::INTERNAL_ERROR );
2185 // re-assign hypotheses
2186 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2188 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2189 const THypList& hyps = ids2Hyps[i].second;
2190 THypList::const_iterator h = hyps.begin();
2191 for ( ; h != hyps.end(); ++h )
2192 _impl->AddHypothesis( s, (*h)->GetID() );
2196 for ( size_t i = 0; i < groupsData.size(); ++i )
2198 const TGroupOnGeomData& data = groupsData[i];
2200 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2201 if ( i2g == _mapGroups.end() ) continue;
2203 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2204 if ( !gr_i ) continue;
2207 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2208 meshDS->IndexToShape( data._shapeID ));
2211 _mapGroups.erase( i2g );
2215 g->GetGroupDS()->SetColor( data._color );
2216 gr_i->changeLocalId( id );
2217 _mapGroups[ id ] = i2g->second;
2218 if ( data._oldID != id )
2219 _mapGroups.erase( i2g );
2223 // update _mapSubMesh
2224 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2225 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2226 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2230 //=============================================================================
2232 * \brief Update objects depending on changed geom groups
2234 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2235 * issue 0020210: Update of a smesh group after modification of the associated geom group
2237 //=============================================================================
2239 void SMESH_Mesh_i::CheckGeomGroupModif()
2241 if ( !_impl->HasShapeToMesh() ) return;
2243 CORBA::Long nbEntities = NbNodes() + NbElements();
2245 // Check if group contents changed
2247 typedef map< string, TopoDS_Shape > TEntry2Geom;
2248 TEntry2Geom newGroupContents;
2250 list<TGeomGroupData>::iterator
2251 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2252 for ( ; data != dataEnd; ++data )
2254 pair< TEntry2Geom::iterator, bool > it_new =
2255 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2256 bool processedGroup = !it_new.second;
2257 TopoDS_Shape& newShape = it_new.first->second;
2258 if ( !processedGroup )
2259 newShape = newGroupShape( *data );
2260 if ( newShape.IsNull() )
2261 continue; // no changes
2264 _preMeshInfo->ForgetOrLoad();
2266 if ( processedGroup ) { // update group indices
2267 list<TGeomGroupData>::iterator data2 = data;
2268 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2269 data->_indices = data2->_indices;
2272 // Update SMESH objects according to new GEOM group contents
2274 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2275 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2277 int oldID = submesh->GetId();
2278 if ( !_mapSubMeshIor.count( oldID ))
2280 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2282 // update hypotheses
2283 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2284 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2285 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2287 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2288 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2290 // care of submeshes
2291 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2292 int newID = newSubmesh->GetId();
2293 if ( newID != oldID ) {
2294 _mapSubMesh [ newID ] = newSubmesh;
2295 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2296 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2297 _mapSubMesh. erase(oldID);
2298 _mapSubMesh_i. erase(oldID);
2299 _mapSubMeshIor.erase(oldID);
2300 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2305 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2306 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2307 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2309 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2311 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2312 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2313 ds->SetShape( newShape );
2318 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2319 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2321 // Remove groups and submeshes basing on removed sub-shapes
2323 TopTools_MapOfShape newShapeMap;
2324 TopoDS_Iterator shapeIt( newShape );
2325 for ( ; shapeIt.More(); shapeIt.Next() )
2326 newShapeMap.Add( shapeIt.Value() );
2328 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2329 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2331 if ( newShapeMap.Contains( shapeIt.Value() ))
2333 TopTools_IndexedMapOfShape oldShapeMap;
2334 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2335 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2337 const TopoDS_Shape& oldShape = oldShapeMap(i);
2338 int oldInd = meshDS->ShapeToIndex( oldShape );
2340 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2341 if ( i_smIor != _mapSubMeshIor.end() ) {
2342 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2345 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2346 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2348 // check if a group bases on oldInd shape
2349 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2350 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2351 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2352 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2354 RemoveGroup( i_grp->second ); // several groups can base on same shape
2355 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2360 // Reassign hypotheses and update groups after setting the new shape to mesh
2362 // collect anassigned hypotheses
2363 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2364 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2365 TShapeHypList assignedHyps;
2366 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2368 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2369 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2370 if ( !hyps.empty() ) {
2371 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2372 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2373 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2376 // collect shapes supporting groups
2377 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2378 TShapeTypeList groupData;
2379 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2380 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2381 for ( ; grIt != groups.end(); ++grIt )
2383 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2385 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2387 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2389 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2390 _impl->ShapeToMesh( newShape );
2392 // reassign hypotheses
2393 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2394 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2396 TIndexedShape& geom = indS_hyps->first;
2397 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2398 int oldID = geom._index;
2399 int newID = meshDS->ShapeToIndex( geom._shape );
2400 if ( oldID == 1 ) { // main shape
2402 geom._shape = newShape;
2406 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2407 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2408 // care of sub-meshes
2409 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2410 if ( newID != oldID ) {
2411 _mapSubMesh [ newID ] = newSubmesh;
2412 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2413 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2414 _mapSubMesh. erase(oldID);
2415 _mapSubMesh_i. erase(oldID);
2416 _mapSubMeshIor.erase(oldID);
2417 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2421 TShapeTypeList::iterator geomType = groupData.begin();
2422 for ( ; geomType != groupData.end(); ++geomType )
2424 const TIndexedShape& geom = geomType->first;
2425 int oldID = geom._index;
2426 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2429 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2430 CORBA::String_var name = groupSO->GetName();
2432 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2434 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2435 group_i->changeLocalId( newID );
2438 break; // everything has been updated
2441 } // loop on group data
2445 CORBA::Long newNbEntities = NbNodes() + NbElements();
2446 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2447 if ( newNbEntities != nbEntities )
2449 // Add all SObjects with icons to soToUpdateIcons
2450 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2452 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2453 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2454 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2456 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2457 i_gr != _mapGroups.end(); ++i_gr ) // groups
2458 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2461 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2462 for ( ; so != soToUpdateIcons.end(); ++so )
2463 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2466 //=============================================================================
2468 * \brief Create standalone group from a group on geometry or filter
2470 //=============================================================================
2472 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2473 throw (SALOME::SALOME_Exception)
2475 SMESH::SMESH_Group_var aGroup;
2480 _preMeshInfo->FullLoadFromFile();
2482 if ( theGroup->_is_nil() )
2483 return aGroup._retn();
2485 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2487 return aGroup._retn();
2489 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2491 const int anId = aGroupToRem->GetLocalID();
2492 if ( !_impl->ConvertToStandalone( anId ) )
2493 return aGroup._retn();
2494 removeGeomGroupData( theGroup );
2496 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2498 // remove old instance of group from own map
2499 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2500 _mapGroups.erase( anId );
2502 SALOMEDS::StudyBuilder_var builder;
2503 SALOMEDS::SObject_wrap aGroupSO;
2504 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2505 if ( !aStudy->_is_nil() ) {
2506 builder = aStudy->NewBuilder();
2507 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2508 if ( !aGroupSO->_is_nil() )
2510 // remove reference to geometry
2511 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2512 for ( ; chItr->More(); chItr->Next() )
2513 // Remove group's child SObject
2514 builder->RemoveObject( chItr->Value() );
2516 // Update Python script
2517 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2518 << ".ConvertToStandalone( " << aGroupSO << " )";
2520 // change icon of Group on Filter
2523 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2524 const int isEmpty = ( elemTypes->length() == 0 );
2527 SALOMEDS::GenericAttribute_wrap anAttr =
2528 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2529 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2530 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2536 // remember new group in own map
2537 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2538 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2540 // register CORBA object for persistence
2541 _gen_i->RegisterObject( aGroup );
2543 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2544 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2545 //aGroup->Register();
2546 aGroupToRem->UnRegister();
2548 SMESH_CATCH( SMESH::throwCorbaException );
2550 return aGroup._retn();
2553 //=============================================================================
2557 //=============================================================================
2559 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2561 if(MYDEBUG) MESSAGE( "createSubMesh" );
2562 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2563 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2566 SMESH_subMesh_i * subMeshServant;
2569 subMeshId = mySubMesh->GetId();
2570 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2572 else // "invalid sub-mesh"
2574 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2575 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2576 if ( _mapSubMesh.empty() )
2579 subMeshId = _mapSubMesh.begin()->first - 1;
2580 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2583 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2585 _mapSubMesh [subMeshId] = mySubMesh;
2586 _mapSubMesh_i [subMeshId] = subMeshServant;
2587 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2589 subMeshServant->Register();
2591 // register CORBA object for persistence
2592 int nextId = _gen_i->RegisterObject( subMesh );
2593 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2594 else { nextId = 0; } // avoid "unused variable" warning
2596 // to track changes of GEOM groups
2597 if ( subMeshId > 0 )
2598 addGeomGroupData( theSubShapeObject, subMesh );
2600 return subMesh._retn();
2603 //=======================================================================
2604 //function : getSubMesh
2606 //=======================================================================
2608 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2610 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2611 if ( it == _mapSubMeshIor.end() )
2612 return SMESH::SMESH_subMesh::_nil();
2614 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2617 //=============================================================================
2621 //=============================================================================
2623 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2624 GEOM::GEOM_Object_ptr theSubShapeObject )
2626 bool isHypChanged = false;
2627 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2628 return isHypChanged;
2630 const int subMeshId = theSubMesh->GetId();
2632 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2634 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end() &&
2635 _mapSubMesh[ subMeshId ])
2637 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2640 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2641 isHypChanged = !hyps.empty();
2642 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2643 for ( ; hyp != hyps.end(); ++hyp )
2644 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2651 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2652 isHypChanged = ( aHypList->length() > 0 );
2653 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2654 removeHypothesis( theSubShapeObject, aHypList[i] );
2657 catch( const SALOME::SALOME_Exception& ) {
2658 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2660 removeGeomGroupData( theSubShapeObject );
2664 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2665 if ( id_smi != _mapSubMesh_i.end() )
2666 id_smi->second->UnRegister();
2668 // remove a CORBA object
2669 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2670 if ( id_smptr != _mapSubMeshIor.end() )
2671 SMESH::SMESH_subMesh_var( id_smptr->second );
2673 _mapSubMesh.erase(subMeshId);
2674 _mapSubMesh_i.erase(subMeshId);
2675 _mapSubMeshIor.erase(subMeshId);
2677 return isHypChanged;
2680 //=============================================================================
2684 //=============================================================================
2686 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2687 const char* theName,
2688 const TopoDS_Shape& theShape,
2689 const SMESH_PredicatePtr& thePredicate )
2691 std::string newName;
2692 if ( !theName || !theName[0] )
2694 std::set< std::string > presentNames;
2695 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2696 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2698 CORBA::String_var name = i_gr->second->GetName();
2699 presentNames.insert( name.in() );
2702 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2703 } while ( !presentNames.insert( newName ).second );
2704 theName = newName.c_str();
2707 SMESH::SMESH_GroupBase_var aGroup;
2708 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2710 SMESH_GroupBase_i* aGroupImpl;
2711 if ( !theShape.IsNull() )
2712 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2713 else if ( thePredicate )
2714 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2716 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2718 aGroup = aGroupImpl->_this();
2719 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2720 aGroupImpl->Register();
2722 // register CORBA object for persistence
2723 int nextId = _gen_i->RegisterObject( aGroup );
2724 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2725 else { nextId = 0; } // avoid "unused variable" warning in release mode
2727 // to track changes of GEOM groups
2728 if ( !theShape.IsNull() ) {
2729 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2730 addGeomGroupData( geom, aGroup );
2733 return aGroup._retn();
2736 //=============================================================================
2738 * SMESH_Mesh_i::removeGroup
2740 * Should be called by ~SMESH_Group_i()
2742 //=============================================================================
2744 void SMESH_Mesh_i::removeGroup( const int theId )
2746 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2747 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2748 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2749 _mapGroups.erase( theId );
2750 removeGeomGroupData( group );
2751 if ( !_impl->RemoveGroup( theId ))
2753 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2754 RemoveGroup( group );
2756 group->UnRegister();
2760 //=============================================================================
2764 //=============================================================================
2766 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2767 throw(SALOME::SALOME_Exception)
2769 SMESH::log_array_var aLog;
2773 _preMeshInfo->FullLoadFromFile();
2775 list < SMESHDS_Command * >logDS = _impl->GetLog();
2776 aLog = new SMESH::log_array;
2778 int lg = logDS.size();
2781 list < SMESHDS_Command * >::iterator its = logDS.begin();
2782 while(its != logDS.end()){
2783 SMESHDS_Command *com = *its;
2784 int comType = com->GetType();
2786 int lgcom = com->GetNumber();
2788 const list < int >&intList = com->GetIndexes();
2789 int inum = intList.size();
2791 list < int >::const_iterator ii = intList.begin();
2792 const list < double >&coordList = com->GetCoords();
2793 int rnum = coordList.size();
2795 list < double >::const_iterator ir = coordList.begin();
2796 aLog[indexLog].commandType = comType;
2797 aLog[indexLog].number = lgcom;
2798 aLog[indexLog].coords.length(rnum);
2799 aLog[indexLog].indexes.length(inum);
2800 for(int i = 0; i < rnum; i++){
2801 aLog[indexLog].coords[i] = *ir;
2802 //MESSAGE(" "<<i<<" "<<ir.Value());
2805 for(int i = 0; i < inum; i++){
2806 aLog[indexLog].indexes[i] = *ii;
2807 //MESSAGE(" "<<i<<" "<<ii.Value());
2816 SMESH_CATCH( SMESH::throwCorbaException );
2818 return aLog._retn();
2822 //=============================================================================
2826 //=============================================================================
2828 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2832 SMESH_CATCH( SMESH::throwCorbaException );
2835 //=============================================================================
2839 //=============================================================================
2841 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2846 //=============================================================================
2849 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2850 // issue 0020918: groups removal is caused by hyp modification
2851 // issue 0021208: to forget not loaded mesh data at hyp modification
2852 struct TCallUp_i : public SMESH_Mesh::TCallUp
2854 SMESH_Mesh_i* _mesh;
2855 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2856 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2857 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
2858 virtual void Load () { _mesh->Load(); }
2862 //================================================================================
2864 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2866 //================================================================================
2868 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
2871 _preMeshInfo->ForgetOrLoad();
2873 SMESH::SMESH_Mesh_var mesh = _this();
2874 _gen_i->UpdateIcons( mesh );
2876 // mark a hypothesis as valid after edition
2877 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
2878 SALOMEDS::SObject_wrap hypRoot;
2879 if ( !smeshComp->_is_nil() &&
2880 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
2882 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
2883 for ( ; anIter->More(); anIter->Next() )
2885 SALOMEDS::SObject_wrap hypSO = anIter->Value();
2886 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
2887 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
2888 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
2889 _gen_i->HighLightInvalid( hyp, false );
2894 //=============================================================================
2898 //=============================================================================
2900 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2902 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2905 _impl->SetCallUp( new TCallUp_i(this));
2908 //=============================================================================
2912 //=============================================================================
2914 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2916 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2920 //=============================================================================
2922 * Return mesh editor
2924 //=============================================================================
2926 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2927 throw (SALOME::SALOME_Exception)
2929 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2933 _preMeshInfo->FullLoadFromFile();
2935 // Create MeshEditor
2937 _editor = new SMESH_MeshEditor_i( this, false );
2938 aMeshEdVar = _editor->_this();
2940 // Update Python script
2941 TPythonDump() << _editor << " = "
2942 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2944 SMESH_CATCH( SMESH::throwCorbaException );
2946 return aMeshEdVar._retn();
2949 //=============================================================================
2951 * Return mesh edition previewer
2953 //=============================================================================
2955 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2956 throw (SALOME::SALOME_Exception)
2958 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2962 _preMeshInfo->FullLoadFromFile();
2964 if ( !_previewEditor )
2965 _previewEditor = new SMESH_MeshEditor_i( this, true );
2966 aMeshEdVar = _previewEditor->_this();
2968 SMESH_CATCH( SMESH::throwCorbaException );
2970 return aMeshEdVar._retn();
2973 //================================================================================
2975 * \brief Return true if the mesh has been edited since a last total re-compute
2976 * and those modifications may prevent successful partial re-compute
2978 //================================================================================
2980 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2982 Unexpect aCatch(SALOME_SalomeException);
2983 return _impl->HasModificationsToDiscard();
2986 //================================================================================
2988 * \brief Returns a random unique color
2990 //================================================================================
2992 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2994 const int MAX_ATTEMPTS = 100;
2996 double tolerance = 0.5;
2997 SALOMEDS::Color col;
3001 // generate random color
3002 double red = (double)rand() / RAND_MAX;
3003 double green = (double)rand() / RAND_MAX;
3004 double blue = (double)rand() / RAND_MAX;
3005 // check existence in the list of the existing colors
3006 bool matched = false;
3007 std::list<SALOMEDS::Color>::const_iterator it;
3008 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3009 SALOMEDS::Color color = *it;
3010 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3011 matched = tol < tolerance;
3013 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3014 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3022 //=============================================================================
3024 * Sets auto-color mode. If it is on, groups get unique random colors
3026 //=============================================================================
3028 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3030 Unexpect aCatch(SALOME_SalomeException);
3031 _impl->SetAutoColor(theAutoColor);
3033 TPythonDump pyDump; // not to dump group->SetColor() from below code
3034 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3036 std::list<SALOMEDS::Color> aReservedColors;
3037 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3038 for ( ; it != _mapGroups.end(); it++ ) {
3039 if ( CORBA::is_nil( it->second )) continue;
3040 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3041 it->second->SetColor( aColor );
3042 aReservedColors.push_back( aColor );
3046 //=============================================================================
3048 * Returns true if auto-color mode is on
3050 //=============================================================================
3052 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3054 Unexpect aCatch(SALOME_SalomeException);
3055 return _impl->GetAutoColor();
3058 //=============================================================================
3060 * Checks if there are groups with equal names
3062 //=============================================================================
3064 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3066 return _impl->HasDuplicatedGroupNamesMED();
3069 //================================================================================
3071 * \brief Care of a file before exporting mesh into it
3073 //================================================================================
3075 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3077 SMESH_File aFile( file );
3079 if (aFile.exists()) {
3080 // existing filesystem node
3081 if ( !aFile.isDirectory() ) {
3082 if ( aFile.openForWriting() ) {
3083 if ( overwrite && ! aFile.remove()) {
3084 msg << "Can't replace " << aFile.getName();
3087 msg << "Can't write into " << aFile.getName();
3090 msg << "Location " << aFile.getName() << " is not a file";
3094 // nonexisting file; check if it can be created
3095 if ( !aFile.openForWriting() ) {
3096 msg << "You cannot create the file "
3098 << ". Check the directory existence and access rights";
3106 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3110 //================================================================================
3112 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3113 * \param file - file name
3114 * \param overwrite - to erase the file or not
3115 * \retval string - mesh name
3117 //================================================================================
3119 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3120 CORBA::Boolean overwrite)
3123 PrepareForWriting(file, overwrite);
3124 string aMeshName = "Mesh";
3125 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3126 if ( !aStudy->_is_nil() ) {
3127 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3128 if ( !aMeshSO->_is_nil() ) {
3129 CORBA::String_var name = aMeshSO->GetName();
3131 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3132 if ( !aStudy->GetProperties()->IsLocked() )
3134 SALOMEDS::GenericAttribute_wrap anAttr;
3135 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3136 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3137 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3138 ASSERT(!aFileName->_is_nil());
3139 aFileName->SetValue(file);
3140 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3141 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3142 ASSERT(!aFileType->_is_nil());
3143 aFileType->SetValue("FICHIERMED");
3147 // Update Python script
3148 // set name of mesh before export
3149 TPythonDump() << _gen_i << ".SetName("
3150 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3152 // check names of groups
3158 //================================================================================
3160 * \brief Export to MED file
3162 //================================================================================
3164 void SMESH_Mesh_i::ExportMED(const char* file,
3165 CORBA::Boolean auto_groups,
3166 CORBA::Long version,
3167 CORBA::Boolean overwrite,
3168 CORBA::Boolean autoDimension)
3169 throw(SALOME::SALOME_Exception)
3171 //MESSAGE("MED minor version: "<< minor);
3174 _preMeshInfo->FullLoadFromFile();
3176 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3177 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3179 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3181 << "auto_groups=" <<auto_groups << ", "
3182 << "minor=" << version << ", "
3183 << "overwrite=" << overwrite << ", "
3184 << "meshPart=None, "
3185 << "autoDimension=" << autoDimension << " )";
3187 SMESH_CATCH( SMESH::throwCorbaException );
3190 //================================================================================
3192 * \brief Export a mesh to a SAUV file
3194 //================================================================================
3196 void SMESH_Mesh_i::ExportSAUV (const char* file,
3197 CORBA::Boolean auto_groups)
3198 throw(SALOME::SALOME_Exception)
3200 Unexpect aCatch(SALOME_SalomeException);
3202 _preMeshInfo->FullLoadFromFile();
3204 string aMeshName = prepareMeshNameAndGroups(file, true);
3205 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3206 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3207 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3211 //================================================================================
3213 * \brief Export a mesh to a DAT file
3215 //================================================================================
3217 void SMESH_Mesh_i::ExportDAT (const char *file)
3218 throw(SALOME::SALOME_Exception)
3220 Unexpect aCatch(SALOME_SalomeException);
3222 _preMeshInfo->FullLoadFromFile();
3224 // Update Python script
3225 // check names of groups
3227 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3230 PrepareForWriting(file);
3231 _impl->ExportDAT(file);
3234 //================================================================================
3236 * \brief Export a mesh to an UNV file
3238 //================================================================================
3240 void SMESH_Mesh_i::ExportUNV (const char *file)
3241 throw(SALOME::SALOME_Exception)
3243 Unexpect aCatch(SALOME_SalomeException);
3245 _preMeshInfo->FullLoadFromFile();
3247 // Update Python script
3248 // check names of groups
3250 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3253 PrepareForWriting(file);
3254 _impl->ExportUNV(file);
3257 //================================================================================
3259 * \brief Export a mesh to an STL file
3261 //================================================================================
3263 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3264 throw(SALOME::SALOME_Exception)
3266 Unexpect aCatch(SALOME_SalomeException);
3268 _preMeshInfo->FullLoadFromFile();
3270 // Update Python script
3271 // check names of groups
3273 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3274 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3276 CORBA::String_var name;
3277 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3278 if ( !so->_is_nil() )
3279 name = so->GetName();
3282 PrepareForWriting( file );
3283 _impl->ExportSTL( file, isascii, name.in() );
3286 //================================================================================
3288 * \brief Export a part of mesh to a med file
3290 //================================================================================
3292 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3294 CORBA::Boolean auto_groups,
3295 CORBA::Long version,
3296 CORBA::Boolean overwrite,
3297 CORBA::Boolean autoDimension,
3298 const GEOM::ListOfFields& fields,
3299 const char* geomAssocFields,
3300 CORBA::Double ZTolerance)
3301 throw (SALOME::SALOME_Exception)
3303 MESSAGE("MED version: "<< version);
3306 _preMeshInfo->FullLoadFromFile();
3309 bool have0dField = false;
3310 if ( fields.length() > 0 )
3312 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3313 if ( shapeToMesh->_is_nil() )
3314 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3316 for ( size_t i = 0; i < fields.length(); ++i )
3318 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3319 THROW_SALOME_CORBA_EXCEPTION
3320 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3321 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3322 if ( fieldShape->_is_nil() )
3323 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3324 if ( !fieldShape->IsSame( shapeToMesh ) )
3325 THROW_SALOME_CORBA_EXCEPTION
3326 ( "Field defined not on shape", SALOME::BAD_PARAM);
3327 if ( fields[i]->GetDimension() == 0 )
3330 if ( geomAssocFields )
3331 for ( int i = 0; geomAssocFields[i]; ++i )
3332 switch ( geomAssocFields[i] ) {
3333 case 'v':case 'e':case 'f':case 's': break;
3334 case 'V':case 'E':case 'F':case 'S': break;
3335 default: THROW_SALOME_CORBA_EXCEPTION
3336 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3340 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3344 string aMeshName = "Mesh";
3345 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3346 if ( CORBA::is_nil( meshPart ) ||
3347 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3349 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3350 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3351 0, autoDimension, /*addODOnVertices=*/have0dField,
3353 meshDS = _impl->GetMeshDS();
3358 _preMeshInfo->FullLoadFromFile();
3360 PrepareForWriting(file, overwrite);
3362 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3363 if ( !SO->_is_nil() ) {
3364 CORBA::String_var name = SO->GetName();
3368 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3369 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3370 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3371 meshDS = tmpDSDeleter._obj = partDS;
3376 if ( _impl->HasShapeToMesh() )
3378 DriverMED_W_Field fieldWriter;
3379 fieldWriter.SetFile( file );
3380 fieldWriter.SetMeshName( aMeshName );
3381 fieldWriter.AddODOnVertices( have0dField );
3383 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3387 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3388 goList->length( fields.length() );
3389 for ( size_t i = 0; i < fields.length(); ++i )
3391 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3394 TPythonDump() << _this() << ".ExportPartToMED( "
3395 << meshPart << ", r'"
3397 << auto_groups << ", "
3399 << overwrite << ", "
3400 << autoDimension << ", "
3402 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3403 << TVar( ZTolerance )
3406 SMESH_CATCH( SMESH::throwCorbaException );
3409 //================================================================================
3411 * Write GEOM fields to MED file
3413 //================================================================================
3415 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3416 SMESHDS_Mesh* meshDS,
3417 const GEOM::ListOfFields& fields,
3418 const char* geomAssocFields)
3420 #define METH "SMESH_Mesh_i::exportMEDFields() "
3422 if (( fields.length() < 1 ) &&
3423 ( !geomAssocFields || !geomAssocFields[0] ))
3426 std::vector< std::vector< double > > dblVals;
3427 std::vector< std::vector< int > > intVals;
3428 std::vector< int > subIdsByDim[ 4 ];
3429 const double noneDblValue = 0.;
3430 const double noneIntValue = 0;
3432 for ( size_t iF = 0; iF < fields.length(); ++iF )
3436 int dim = fields[ iF ]->GetDimension();
3437 SMDSAbs_ElementType elemType;
3438 TopAbs_ShapeEnum shapeType;
3440 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3441 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3442 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3443 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3445 continue; // skip fields on whole shape
3447 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3448 if ( dataType == GEOM::FDT_String )
3450 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3451 if ( stepIDs->length() < 1 )
3453 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3454 if ( comps->length() < 1 )
3456 CORBA::String_var name = fields[ iF ]->GetName();
3458 if ( !fieldWriter.Set( meshDS,
3462 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3465 for ( size_t iC = 0; iC < comps->length(); ++iC )
3466 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3468 dblVals.resize( comps->length() );
3469 intVals.resize( comps->length() );
3471 // find sub-shape IDs
3473 std::vector< int >& subIds = subIdsByDim[ dim ];
3474 if ( subIds.empty() )
3475 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3476 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3477 subIds.push_back( id );
3481 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3485 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3487 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3488 if ( step->_is_nil() )
3491 CORBA::Long stamp = step->GetStamp();
3492 CORBA::Long id = step->GetID();
3493 fieldWriter.SetDtIt( int( stamp ), int( id ));
3495 // fill dblVals or intVals
3496 for ( size_t iC = 0; iC < comps->length(); ++iC )
3497 if ( dataType == GEOM::FDT_Double )
3499 dblVals[ iC ].clear();
3500 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3504 intVals[ iC ].clear();
3505 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3509 case GEOM::FDT_Double:
3511 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3512 if ( dblStep->_is_nil() ) continue;
3513 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3514 if ( vv->length() != subIds.size() * comps->length() )
3515 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3516 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3517 for ( size_t iC = 0; iC < comps->length(); ++iC )
3518 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3523 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3524 if ( intStep->_is_nil() ) continue;
3525 GEOM::ListOfLong_var vv = intStep->GetValues();
3526 if ( vv->length() != subIds.size() * comps->length() )
3527 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3528 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3529 for ( size_t iC = 0; iC < comps->length(); ++iC )
3530 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3533 case GEOM::FDT_Bool:
3535 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3536 if ( boolStep->_is_nil() ) continue;
3537 GEOM::short_array_var vv = boolStep->GetValues();
3538 if ( vv->length() != subIds.size() * comps->length() )
3539 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3540 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3541 for ( size_t iC = 0; iC < comps->length(); ++iC )
3542 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3548 // pass values to fieldWriter
3549 elemIt = fieldWriter.GetOrderedElems();
3550 if ( dataType == GEOM::FDT_Double )
3551 while ( elemIt->more() )
3553 const SMDS_MeshElement* e = elemIt->next();
3554 const int shapeID = e->getshapeId();
3555 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3556 for ( size_t iC = 0; iC < comps->length(); ++iC )
3557 fieldWriter.AddValue( noneDblValue );
3559 for ( size_t iC = 0; iC < comps->length(); ++iC )
3560 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3563 while ( elemIt->more() )
3565 const SMDS_MeshElement* e = elemIt->next();
3566 const int shapeID = e->getshapeId();
3567 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3568 for ( size_t iC = 0; iC < comps->length(); ++iC )
3569 fieldWriter.AddValue( (double) noneIntValue );
3571 for ( size_t iC = 0; iC < comps->length(); ++iC )
3572 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3576 fieldWriter.Perform();
3577 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3578 if ( res && res->IsKO() )
3580 if ( res->myComment.empty() )
3581 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3583 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3589 if ( !geomAssocFields || !geomAssocFields[0] )
3592 // write geomAssocFields
3594 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3595 shapeDim[ TopAbs_COMPOUND ] = 3;
3596 shapeDim[ TopAbs_COMPSOLID ] = 3;
3597 shapeDim[ TopAbs_SOLID ] = 3;
3598 shapeDim[ TopAbs_SHELL ] = 2;
3599 shapeDim[ TopAbs_FACE ] = 2;
3600 shapeDim[ TopAbs_WIRE ] = 1;
3601 shapeDim[ TopAbs_EDGE ] = 1;
3602 shapeDim[ TopAbs_VERTEX ] = 0;
3603 shapeDim[ TopAbs_SHAPE ] = 3;
3605 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3607 std::vector< std::string > compNames;
3608 switch ( geomAssocFields[ iF ]) {
3610 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3611 compNames.push_back( "dim" );
3614 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3617 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3620 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3624 compNames.push_back( "id" );
3625 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3626 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3628 fieldWriter.SetDtIt( -1, -1 );
3630 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3634 if ( compNames.size() == 2 ) // _vertices_
3635 while ( elemIt->more() )
3637 const SMDS_MeshElement* e = elemIt->next();
3638 const int shapeID = e->getshapeId();
3641 fieldWriter.AddValue( (double) -1 );
3642 fieldWriter.AddValue( (double) -1 );
3646 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3647 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3648 fieldWriter.AddValue( (double) shapeID );
3652 while ( elemIt->more() )
3654 const SMDS_MeshElement* e = elemIt->next();
3655 const int shapeID = e->getshapeId();
3657 fieldWriter.AddValue( (double) -1 );
3659 fieldWriter.AddValue( (double) shapeID );
3663 fieldWriter.Perform();
3664 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3665 if ( res && res->IsKO() )
3667 if ( res->myComment.empty() )
3668 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3670 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3673 } // loop on geomAssocFields
3678 //================================================================================
3680 * \brief Export a part of mesh to a DAT file
3682 //================================================================================
3684 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3686 throw (SALOME::SALOME_Exception)
3688 Unexpect aCatch(SALOME_SalomeException);
3690 _preMeshInfo->FullLoadFromFile();
3692 PrepareForWriting(file);
3694 SMESH_MeshPartDS partDS( meshPart );
3695 _impl->ExportDAT(file,&partDS);
3697 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3698 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3700 //================================================================================
3702 * \brief Export a part of mesh to an UNV file
3704 //================================================================================
3706 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3708 throw (SALOME::SALOME_Exception)
3710 Unexpect aCatch(SALOME_SalomeException);
3712 _preMeshInfo->FullLoadFromFile();
3714 PrepareForWriting(file);
3716 SMESH_MeshPartDS partDS( meshPart );
3717 _impl->ExportUNV(file, &partDS);
3719 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3720 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3722 //================================================================================
3724 * \brief Export a part of mesh to an STL file
3726 //================================================================================
3728 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3730 ::CORBA::Boolean isascii)
3731 throw (SALOME::SALOME_Exception)
3733 Unexpect aCatch(SALOME_SalomeException);
3735 _preMeshInfo->FullLoadFromFile();
3737 PrepareForWriting(file);
3739 CORBA::String_var name;
3740 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3741 if ( !so->_is_nil() )
3742 name = so->GetName();
3744 SMESH_MeshPartDS partDS( meshPart );
3745 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3747 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3748 << meshPart<< ", r'" << file << "', " << isascii << ")";
3751 //================================================================================
3753 * \brief Export a part of mesh to an STL file
3755 //================================================================================
3757 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3759 CORBA::Boolean overwrite,
3760 CORBA::Boolean groupElemsByType)
3761 throw (SALOME::SALOME_Exception)
3764 Unexpect aCatch(SALOME_SalomeException);
3766 _preMeshInfo->FullLoadFromFile();
3768 PrepareForWriting(file,overwrite);
3770 std::string meshName("");
3771 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3772 if ( !so->_is_nil() )
3774 CORBA::String_var name = so->GetName();
3775 meshName = name.in();
3779 SMESH_MeshPartDS partDS( meshPart );
3780 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3782 SMESH_CATCH( SMESH::throwCorbaException );
3784 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3785 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3787 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3791 //================================================================================
3793 * \brief Export a part of mesh to a GMF file
3795 //================================================================================
3797 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3799 bool withRequiredGroups)
3800 throw (SALOME::SALOME_Exception)
3802 Unexpect aCatch(SALOME_SalomeException);
3804 _preMeshInfo->FullLoadFromFile();
3806 PrepareForWriting(file,/*overwrite=*/true);
3808 SMESH_MeshPartDS partDS( meshPart );
3809 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3811 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3812 << meshPart<< ", r'"
3814 << withRequiredGroups << ")";
3817 //=============================================================================
3819 * Return computation progress [0.,1]
3821 //=============================================================================
3823 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3827 return _impl->GetComputeProgress();
3829 SMESH_CATCH( SMESH::doNothing );
3833 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3835 Unexpect aCatch(SALOME_SalomeException);
3837 return _preMeshInfo->NbNodes();
3839 return _impl->NbNodes();
3842 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3844 Unexpect aCatch(SALOME_SalomeException);
3846 return _preMeshInfo->NbElements();
3848 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3851 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3853 Unexpect aCatch(SALOME_SalomeException);
3855 return _preMeshInfo->Nb0DElements();
3857 return _impl->Nb0DElements();
3860 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3862 Unexpect aCatch(SALOME_SalomeException);
3864 return _preMeshInfo->NbBalls();
3866 return _impl->NbBalls();
3869 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3871 Unexpect aCatch(SALOME_SalomeException);
3873 return _preMeshInfo->NbEdges();
3875 return _impl->NbEdges();
3878 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3879 throw(SALOME::SALOME_Exception)
3881 Unexpect aCatch(SALOME_SalomeException);
3883 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3885 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3888 //=============================================================================
3890 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3892 Unexpect aCatch(SALOME_SalomeException);
3894 return _preMeshInfo->NbFaces();
3896 return _impl->NbFaces();
3899 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3901 Unexpect aCatch(SALOME_SalomeException);
3903 return _preMeshInfo->NbTriangles();
3905 return _impl->NbTriangles();
3908 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3910 Unexpect aCatch(SALOME_SalomeException);
3912 return _preMeshInfo->NbBiQuadTriangles();
3914 return _impl->NbBiQuadTriangles();
3917 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3919 Unexpect aCatch(SALOME_SalomeException);
3921 return _preMeshInfo->NbQuadrangles();
3923 return _impl->NbQuadrangles();
3926 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3928 Unexpect aCatch(SALOME_SalomeException);
3930 return _preMeshInfo->NbBiQuadQuadrangles();
3932 return _impl->NbBiQuadQuadrangles();
3935 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3937 Unexpect aCatch(SALOME_SalomeException);
3939 return _preMeshInfo->NbPolygons();
3941 return _impl->NbPolygons();
3944 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3946 Unexpect aCatch(SALOME_SalomeException);
3948 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3950 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3953 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3954 throw(SALOME::SALOME_Exception)
3956 Unexpect aCatch(SALOME_SalomeException);
3958 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3960 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3963 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3964 throw(SALOME::SALOME_Exception)
3966 Unexpect aCatch(SALOME_SalomeException);
3968 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3970 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3973 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3974 throw(SALOME::SALOME_Exception)
3976 Unexpect aCatch(SALOME_SalomeException);
3978 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3980 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3983 //=============================================================================
3985 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3987 Unexpect aCatch(SALOME_SalomeException);
3989 return _preMeshInfo->NbVolumes();
3991 return _impl->NbVolumes();
3994 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3996 Unexpect aCatch(SALOME_SalomeException);
3998 return _preMeshInfo->NbTetras();
4000 return _impl->NbTetras();
4003 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4005 Unexpect aCatch(SALOME_SalomeException);
4007 return _preMeshInfo->NbHexas();
4009 return _impl->NbHexas();
4012 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4014 Unexpect aCatch(SALOME_SalomeException);
4016 return _preMeshInfo->NbTriQuadHexas();
4018 return _impl->NbTriQuadraticHexas();
4021 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4023 Unexpect aCatch(SALOME_SalomeException);
4025 return _preMeshInfo->NbPyramids();
4027 return _impl->NbPyramids();
4030 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4032 Unexpect aCatch(SALOME_SalomeException);
4034 return _preMeshInfo->NbPrisms();
4036 return _impl->NbPrisms();
4039 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4041 Unexpect aCatch(SALOME_SalomeException);
4043 return _preMeshInfo->NbHexPrisms();
4045 return _impl->NbHexagonalPrisms();
4048 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4050 Unexpect aCatch(SALOME_SalomeException);
4052 return _preMeshInfo->NbPolyhedrons();
4054 return _impl->NbPolyhedrons();
4057 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4058 throw(SALOME::SALOME_Exception)
4060 Unexpect aCatch(SALOME_SalomeException);
4062 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4064 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4067 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4068 throw(SALOME::SALOME_Exception)
4070 Unexpect aCatch(SALOME_SalomeException);
4072 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4074 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4077 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4078 throw(SALOME::SALOME_Exception)
4080 Unexpect aCatch(SALOME_SalomeException);
4082 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4084 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4087 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4088 throw(SALOME::SALOME_Exception)
4090 Unexpect aCatch(SALOME_SalomeException);
4092 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4094 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4097 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4098 throw(SALOME::SALOME_Exception)
4100 Unexpect aCatch(SALOME_SalomeException);
4102 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4104 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4107 //=============================================================================
4109 * Returns nb of published sub-meshes
4111 //=============================================================================
4113 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4115 Unexpect aCatch(SALOME_SalomeException);
4116 return _mapSubMesh_i.size();
4119 //=============================================================================
4121 * Dumps mesh into a string
4123 //=============================================================================
4125 char* SMESH_Mesh_i::Dump()
4129 return CORBA::string_dup( os.str().c_str() );
4132 //=============================================================================
4134 * Method of SMESH_IDSource interface
4136 //=============================================================================
4138 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4140 return GetElementsId();
4143 //=============================================================================
4145 * Returns ids of all elements
4147 //=============================================================================
4149 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4150 throw (SALOME::SALOME_Exception)
4152 Unexpect aCatch(SALOME_SalomeException);
4154 _preMeshInfo->FullLoadFromFile();
4156 SMESH::long_array_var aResult = new SMESH::long_array();
4157 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4159 if ( aSMESHDS_Mesh == NULL )
4160 return aResult._retn();
4162 long nbElements = NbElements();
4163 aResult->length( nbElements );
4164 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4165 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4166 aResult[i] = anIt->next()->GetID();
4168 return aResult._retn();
4172 //=============================================================================
4174 * Returns ids of all elements of given type
4176 //=============================================================================
4178 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4179 throw (SALOME::SALOME_Exception)
4181 Unexpect aCatch(SALOME_SalomeException);
4183 _preMeshInfo->FullLoadFromFile();
4185 SMESH::long_array_var aResult = new SMESH::long_array();
4186 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4188 if ( aSMESHDS_Mesh == NULL )
4189 return aResult._retn();
4191 long nbElements = NbElements();
4193 // No sense in returning ids of elements along with ids of nodes:
4194 // when theElemType == SMESH::ALL, return node ids only if
4195 // there are no elements
4196 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4197 return GetNodesId();
4199 aResult->length( nbElements );
4203 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4204 while ( i < nbElements && anIt->more() )
4205 aResult[i++] = anIt->next()->GetID();
4207 aResult->length( i );
4209 return aResult._retn();
4212 //=============================================================================
4214 * Returns ids of all nodes
4216 //=============================================================================
4218 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4219 throw (SALOME::SALOME_Exception)
4221 Unexpect aCatch(SALOME_SalomeException);
4223 _preMeshInfo->FullLoadFromFile();
4225 SMESH::long_array_var aResult = new SMESH::long_array();
4226 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4228 if ( aMeshDS == NULL )
4229 return aResult._retn();
4231 long nbNodes = NbNodes();
4232 aResult->length( nbNodes );
4233 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4234 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4235 aResult[i] = anIt->next()->GetID();
4237 return aResult._retn();
4240 //=============================================================================
4244 //=============================================================================
4246 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4247 throw (SALOME::SALOME_Exception)
4249 SMESH::ElementType type = SMESH::ALL;
4253 _preMeshInfo->FullLoadFromFile();
4255 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4257 SMESH_CATCH( SMESH::throwCorbaException );
4262 //=============================================================================
4266 //=============================================================================
4268 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4269 throw (SALOME::SALOME_Exception)
4272 _preMeshInfo->FullLoadFromFile();
4274 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4276 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4278 return ( SMESH::EntityType ) e->GetEntityType();
4281 //=============================================================================
4285 //=============================================================================
4287 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4288 throw (SALOME::SALOME_Exception)
4291 _preMeshInfo->FullLoadFromFile();
4293 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4295 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4297 return ( SMESH::GeometryType ) e->GetGeomType();
4300 //=============================================================================
4302 * Returns ID of elements for given submesh
4304 //=============================================================================
4305 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4306 throw (SALOME::SALOME_Exception)
4308 SMESH::long_array_var aResult = new SMESH::long_array();
4312 _preMeshInfo->FullLoadFromFile();
4314 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4315 if(!SM) return aResult._retn();
4317 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4318 if(!SDSM) return aResult._retn();
4320 aResult->length(SDSM->NbElements());
4322 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4324 while ( eIt->more() ) {
4325 aResult[i++] = eIt->next()->GetID();
4328 SMESH_CATCH( SMESH::throwCorbaException );
4330 return aResult._retn();
4333 //=============================================================================
4335 * Returns ID of nodes for given submesh
4336 * If param all==true - returns all nodes, else -
4337 * returns only nodes on shapes.
4339 //=============================================================================
4341 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4343 throw (SALOME::SALOME_Exception)
4345 SMESH::long_array_var aResult = new SMESH::long_array();
4349 _preMeshInfo->FullLoadFromFile();
4351 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4352 if(!SM) return aResult._retn();
4354 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4355 if(!SDSM) return aResult._retn();
4358 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4359 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4360 while ( nIt->more() ) {
4361 const SMDS_MeshNode* elem = nIt->next();
4362 theElems.insert( elem->GetID() );
4365 else { // all nodes of submesh elements
4366 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4367 while ( eIt->more() ) {
4368 const SMDS_MeshElement* anElem = eIt->next();
4369 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4370 while ( nIt->more() ) {
4371 const SMDS_MeshElement* elem = nIt->next();
4372 theElems.insert( elem->GetID() );
4377 aResult->length(theElems.size());
4378 set<int>::iterator itElem;
4380 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4381 aResult[i++] = *itElem;
4383 SMESH_CATCH( SMESH::throwCorbaException );
4385 return aResult._retn();
4388 //=============================================================================
4390 * Returns type of elements for given submesh
4392 //=============================================================================
4394 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4395 throw (SALOME::SALOME_Exception)
4397 SMESH::ElementType type = SMESH::ALL;
4401 _preMeshInfo->FullLoadFromFile();
4403 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4404 if(!SM) return SMESH::ALL;
4406 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4407 if(!SDSM) return SMESH::ALL;
4409 if(SDSM->NbElements()==0)
4410 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4412 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4413 const SMDS_MeshElement* anElem = eIt->next();
4415 type = ( SMESH::ElementType ) anElem->GetType();
4417 SMESH_CATCH( SMESH::throwCorbaException );
4423 //=============================================================================
4425 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4427 //=============================================================================
4429 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4432 _preMeshInfo->FullLoadFromFile();
4434 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4435 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4440 //=============================================================================
4442 * Get XYZ coordinates of node as list of double
4443 * If there is not node for given ID - returns empty list
4445 //=============================================================================
4447 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4450 _preMeshInfo->FullLoadFromFile();
4452 SMESH::double_array_var aResult = new SMESH::double_array();
4453 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4454 if ( aMeshDS == NULL )
4455 return aResult._retn();
4458 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4460 return aResult._retn();
4464 aResult[0] = aNode->X();
4465 aResult[1] = aNode->Y();
4466 aResult[2] = aNode->Z();
4467 return aResult._retn();
4471 //=============================================================================
4473 * For given node returns list of IDs of inverse elements
4474 * If there is not node for given ID - returns empty list
4476 //=============================================================================
4478 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4481 _preMeshInfo->FullLoadFromFile();
4483 SMESH::long_array_var aResult = new SMESH::long_array();
4484 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4485 if ( aMeshDS == NULL )
4486 return aResult._retn();
4489 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4491 return aResult._retn();
4493 // find inverse elements
4494 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4495 aResult->length( aNode->NbInverseElements() );
4496 for( int i = 0; eIt->more(); ++i )
4498 const SMDS_MeshElement* elem = eIt->next();
4499 aResult[ i ] = elem->GetID();
4501 return aResult._retn();
4504 //=============================================================================
4506 * \brief Return position of a node on shape
4508 //=============================================================================
4510 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4513 _preMeshInfo->FullLoadFromFile();
4515 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4516 aNodePosition->shapeID = 0;
4517 aNodePosition->shapeType = GEOM::SHAPE;
4519 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4520 if ( !mesh ) return aNodePosition;
4522 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4524 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4526 aNodePosition->shapeID = aNode->getshapeId();
4527 switch ( pos->GetTypeOfPosition() ) {
4529 aNodePosition->shapeType = GEOM::EDGE;
4530 aNodePosition->params.length(1);
4531 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4533 case SMDS_TOP_FACE: {
4534 SMDS_FacePositionPtr fPos = pos;
4535 aNodePosition->shapeType = GEOM::FACE;
4536 aNodePosition->params.length(2);
4537 aNodePosition->params[0] = fPos->GetUParameter();
4538 aNodePosition->params[1] = fPos->GetVParameter();
4541 case SMDS_TOP_VERTEX:
4542 aNodePosition->shapeType = GEOM::VERTEX;
4544 case SMDS_TOP_3DSPACE:
4545 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4546 aNodePosition->shapeType = GEOM::SOLID;
4547 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4548 aNodePosition->shapeType = GEOM::SHELL;
4554 return aNodePosition;
4557 //=============================================================================
4559 * \brief Return position of an element on shape
4561 //=============================================================================
4563 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4566 _preMeshInfo->FullLoadFromFile();
4568 SMESH::ElementPosition anElementPosition;
4569 anElementPosition.shapeID = 0;
4570 anElementPosition.shapeType = GEOM::SHAPE;
4572 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4573 if ( !mesh ) return anElementPosition;
4575 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4577 anElementPosition.shapeID = anElem->getshapeId();
4578 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4579 if ( !aSp.IsNull() ) {
4580 switch ( aSp.ShapeType() ) {
4582 anElementPosition.shapeType = GEOM::EDGE;
4585 anElementPosition.shapeType = GEOM::FACE;
4588 anElementPosition.shapeType = GEOM::VERTEX;
4591 anElementPosition.shapeType = GEOM::SOLID;
4594 anElementPosition.shapeType = GEOM::SHELL;
4600 return anElementPosition;
4603 //=============================================================================
4605 * If given element is node returns IDs of shape from position
4606 * If there is not node for given ID - returns -1
4608 //=============================================================================
4610 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4613 _preMeshInfo->FullLoadFromFile();
4615 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4616 if ( aMeshDS == NULL )
4620 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4622 return aNode->getshapeId();
4629 //=============================================================================
4631 * For given element returns ID of result shape after
4632 * ::FindShape() from SMESH_MeshEditor
4633 * If there is not element for given ID - returns -1
4635 //=============================================================================
4637 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4640 _preMeshInfo->FullLoadFromFile();
4642 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4643 if ( aMeshDS == NULL )
4646 // try to find element
4647 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4651 ::SMESH_MeshEditor aMeshEditor(_impl);
4652 int index = aMeshEditor.FindShape( elem );
4660 //=============================================================================
4662 * Returns number of nodes for given element
4663 * If there is not element for given ID - returns -1
4665 //=============================================================================
4667 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4670 _preMeshInfo->FullLoadFromFile();
4672 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4673 if ( aMeshDS == NULL ) return -1;
4674 // try to find element
4675 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4676 if(!elem) return -1;
4677 return elem->NbNodes();
4681 //=============================================================================
4683 * Returns ID of node by given index for given element
4684 * If there is not element for given ID - returns -1
4685 * If there is not node for given index - returns -2
4687 //=============================================================================
4689 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4692 _preMeshInfo->FullLoadFromFile();
4694 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4695 if ( aMeshDS == NULL ) return -1;
4696 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4697 if(!elem) return -1;
4698 if( index>=elem->NbNodes() || index<0 ) return -1;
4699 return elem->GetNode(index)->GetID();
4702 //=============================================================================
4704 * Returns IDs of nodes of given element
4706 //=============================================================================
4708 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4711 _preMeshInfo->FullLoadFromFile();
4713 SMESH::long_array_var aResult = new SMESH::long_array();
4714 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4716 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4718 aResult->length( elem->NbNodes() );
4719 for ( int i = 0; i < elem->NbNodes(); ++i )
4720 aResult[ i ] = elem->GetNode( i )->GetID();
4723 return aResult._retn();
4726 //=============================================================================
4728 * Returns true if given node is medium node
4729 * in given quadratic element
4731 //=============================================================================
4733 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4736 _preMeshInfo->FullLoadFromFile();
4738 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4739 if ( aMeshDS == NULL ) return false;
4741 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4742 if(!aNode) return false;
4743 // try to find element
4744 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4745 if(!elem) return false;
4747 return elem->IsMediumNode(aNode);
4751 //=============================================================================
4753 * Returns true if given node is medium node
4754 * in one of quadratic elements
4756 //=============================================================================
4758 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4759 SMESH::ElementType theElemType)
4762 _preMeshInfo->FullLoadFromFile();
4764 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4765 if ( aMeshDS == NULL ) return false;
4768 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4769 if(!aNode) return false;
4771 SMESH_MesherHelper aHelper( *(_impl) );
4773 SMDSAbs_ElementType aType;
4774 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4775 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4776 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4777 else aType = SMDSAbs_All;
4779 return aHelper.IsMedium(aNode,aType);
4783 //=============================================================================
4785 * Returns number of edges for given element
4787 //=============================================================================
4789 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4792 _preMeshInfo->FullLoadFromFile();
4794 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4795 if ( aMeshDS == NULL ) return -1;
4796 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4797 if(!elem) return -1;
4798 return elem->NbEdges();
4802 //=============================================================================
4804 * Returns number of faces for given element
4806 //=============================================================================
4808 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4811 _preMeshInfo->FullLoadFromFile();
4813 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4814 if ( aMeshDS == NULL ) return -1;
4815 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4816 if(!elem) return -1;
4817 return elem->NbFaces();
4820 //=======================================================================
4821 //function : GetElemFaceNodes
4822 //purpose : Returns nodes of given face (counted from zero) for given element.
4823 //=======================================================================
4825 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4826 CORBA::Short faceIndex)
4829 _preMeshInfo->FullLoadFromFile();
4831 SMESH::long_array_var aResult = new SMESH::long_array();
4832 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4834 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4836 SMDS_VolumeTool vtool( elem );
4837 if ( faceIndex < vtool.NbFaces() )
4839 aResult->length( vtool.NbFaceNodes( faceIndex ));
4840 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4841 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4842 aResult[ i ] = nn[ i ]->GetID();
4846 return aResult._retn();
4849 //=======================================================================
4850 //function : GetElemFaceNodes
4851 //purpose : Returns three components of normal of given mesh face.
4852 //=======================================================================
4854 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4855 CORBA::Boolean normalized)
4858 _preMeshInfo->FullLoadFromFile();
4860 SMESH::double_array_var aResult = new SMESH::double_array();
4862 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4865 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4867 aResult->length( 3 );
4868 aResult[ 0 ] = normal.X();
4869 aResult[ 1 ] = normal.Y();
4870 aResult[ 2 ] = normal.Z();
4873 return aResult._retn();
4876 //=======================================================================
4877 //function : FindElementByNodes
4878 //purpose : Returns an element based on all given nodes.
4879 //=======================================================================
4881 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4884 _preMeshInfo->FullLoadFromFile();
4886 CORBA::Long elemID(0);
4887 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4889 vector< const SMDS_MeshNode * > nn( nodes.length() );
4890 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4891 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4894 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4895 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4896 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4897 _impl->NbVolumes( ORDER_QUADRATIC )))
4898 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4900 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4905 //================================================================================
4907 * \brief Return elements including all given nodes.
4909 //================================================================================
4911 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4912 SMESH::ElementType elemType)
4915 _preMeshInfo->FullLoadFromFile();
4917 SMESH::long_array_var result = new SMESH::long_array();
4919 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4921 vector< const SMDS_MeshNode * > nn( nodes.length() );
4922 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4923 nn[i] = mesh->FindNode( nodes[i] );
4925 std::vector<const SMDS_MeshElement *> elems;
4926 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4927 result->length( elems.size() );
4928 for ( size_t i = 0; i < elems.size(); ++i )
4929 result[i] = elems[i]->GetID();
4931 return result._retn();
4934 //=============================================================================
4936 * Returns true if given element is polygon
4938 //=============================================================================
4940 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4943 _preMeshInfo->FullLoadFromFile();
4945 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4946 if ( aMeshDS == NULL ) return false;
4947 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4948 if(!elem) return false;
4949 return elem->IsPoly();
4953 //=============================================================================
4955 * Returns true if given element is quadratic
4957 //=============================================================================
4959 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4962 _preMeshInfo->FullLoadFromFile();
4964 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4965 if ( aMeshDS == NULL ) return false;
4966 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4967 if(!elem) return false;
4968 return elem->IsQuadratic();
4971 //=============================================================================
4973 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4975 //=============================================================================
4977 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4980 _preMeshInfo->FullLoadFromFile();
4982 if ( const SMDS_BallElement* ball =
4983 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4984 return ball->GetDiameter();
4989 //=============================================================================
4991 * Returns bary center for given element
4993 //=============================================================================
4995 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4998 _preMeshInfo->FullLoadFromFile();
5000 SMESH::double_array_var aResult = new SMESH::double_array();
5001 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5002 if ( aMeshDS == NULL )
5003 return aResult._retn();
5005 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5007 return aResult._retn();
5009 if(elem->GetType()==SMDSAbs_Volume) {
5010 SMDS_VolumeTool aTool;
5011 if(aTool.Set(elem)) {
5013 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5018 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5020 double x=0., y=0., z=0.;
5021 for(; anIt->more(); ) {
5023 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5037 return aResult._retn();
5040 //================================================================================
5042 * \brief Create a group of elements preventing computation of a sub-shape
5044 //================================================================================
5046 SMESH::ListOfGroups*
5047 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5048 const char* theGroupName )
5049 throw ( SALOME::SALOME_Exception )
5051 Unexpect aCatch(SALOME_SalomeException);
5053 if ( !theGroupName || strlen( theGroupName) == 0 )
5054 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5056 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5057 ::SMESH_MeshEditor::ElemFeatures elemType;
5059 // submesh by subshape id
5060 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5061 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5064 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5065 if ( error && error->HasBadElems() )
5067 // sort bad elements by type
5068 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5069 const list<const SMDS_MeshElement*>& badElems =
5070 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5071 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5072 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5073 for ( ; elemIt != elemEnd; ++elemIt )
5075 const SMDS_MeshElement* elem = *elemIt;
5076 if ( !elem ) continue;
5078 if ( elem->GetID() < 1 )
5080 // elem is a temporary element, make a real element
5081 vector< const SMDS_MeshNode* > nodes;
5082 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5083 while ( nIt->more() && elem )
5085 nodes.push_back( nIt->next() );
5086 if ( nodes.back()->GetID() < 1 )
5087 elem = 0; // a temporary element on temporary nodes
5091 ::SMESH_MeshEditor editor( _impl );
5092 elem = editor.AddElement( nodes, elemType.Init( elem ));
5096 elemsByType[ elem->GetType() ].push_back( elem );
5099 // how many groups to create?
5101 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5102 nbTypes += int( !elemsByType[ i ].empty() );
5103 groups->length( nbTypes );
5106 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5108 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5109 if ( elems.empty() ) continue;
5111 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5112 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5114 SMESH::SMESH_Mesh_var mesh = _this();
5115 SALOMEDS::SObject_wrap aSO =
5116 _gen_i->PublishGroup( mesh, groups[ iG ],
5117 GEOM::GEOM_Object::_nil(), theGroupName);
5119 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5120 if ( !grp_i ) continue;
5122 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5123 for ( size_t iE = 0; iE < elems.size(); ++iE )
5124 grpDS->SMDSGroup().Add( elems[ iE ]);
5129 return groups._retn();
5132 //=============================================================================
5134 * Create and publish group servants if any groups were imported or created anyhow
5136 //=============================================================================
5138 void SMESH_Mesh_i::CreateGroupServants()
5140 SMESH::SMESH_Mesh_var aMesh = _this();
5143 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5144 while ( groupIt->more() )
5146 ::SMESH_Group* group = groupIt->next();
5147 int anId = group->GetGroupDS()->GetID();
5149 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5150 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5152 addedIDs.insert( anId );
5154 SMESH_GroupBase_i* aGroupImpl;
5156 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5157 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5159 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5160 shape = groupOnGeom->GetShape();
5163 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5166 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5167 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5168 aGroupImpl->Register();
5170 // register CORBA object for persistence
5171 int nextId = _gen_i->RegisterObject( groupVar );
5172 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5173 else { nextId = 0; } // avoid "unused variable" warning in release mode
5175 // publishing the groups in the study
5176 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5177 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5179 if ( !addedIDs.empty() )
5182 set<int>::iterator id = addedIDs.begin();
5183 for ( ; id != addedIDs.end(); ++id )
5185 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5186 int i = std::distance( _mapGroups.begin(), it );
5187 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5192 //=============================================================================
5194 * \brief Return true if all sub-meshes are computed OK - to update an icon
5196 //=============================================================================
5198 bool SMESH_Mesh_i::IsComputedOK()
5200 return _impl->IsComputedOK();
5203 //=============================================================================
5205 * \brief Return groups cantained in _mapGroups by their IDs
5207 //=============================================================================
5209 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5211 int nbGroups = groupIDs.size();
5212 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5213 aList->length( nbGroups );
5215 list<int>::const_iterator ids = groupIDs.begin();
5216 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5218 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5219 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5220 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5222 aList->length( nbGroups );
5223 return aList._retn();
5226 //=============================================================================
5228 * \brief Return information about imported file
5230 //=============================================================================
5232 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5234 SMESH::MedFileInfo_var res( _medFileInfo );
5235 if ( !res.operator->() ) {
5236 res = new SMESH::MedFileInfo;
5238 res->fileSize = res->major = res->minor = res->release = -1;
5243 //=======================================================================
5244 //function : FileInfoToString
5245 //purpose : Persistence of file info
5246 //=======================================================================
5248 std::string SMESH_Mesh_i::FileInfoToString()
5251 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5253 s = SMESH_Comment( _medFileInfo->fileSize )
5254 << " " << _medFileInfo->major
5255 << " " << _medFileInfo->minor
5256 << " " << _medFileInfo->release
5257 << " " << _medFileInfo->fileName;
5262 //=======================================================================
5263 //function : FileInfoFromString
5264 //purpose : Persistence of file info
5265 //=======================================================================
5267 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5269 std::string size, major, minor, release, fileName;
5270 std::istringstream is(info);
5271 is >> size >> major >> minor >> release;
5272 fileName = info.data() + ( size.size() + 1 +
5275 release.size()+ 1 );
5277 _medFileInfo = new SMESH::MedFileInfo();
5278 _medFileInfo->fileName = fileName.c_str();
5279 _medFileInfo->fileSize = atoi( size.c_str() );
5280 _medFileInfo->major = atoi( major.c_str() );
5281 _medFileInfo->minor = atoi( minor.c_str() );
5282 _medFileInfo->release = atoi( release.c_str() );
5285 //=============================================================================
5287 * \brief Pass names of mesh groups from study to mesh DS
5289 //=============================================================================
5291 void SMESH_Mesh_i::checkGroupNames()
5293 int nbGrp = NbGroups();
5297 SMESH::ListOfGroups* grpList = 0;
5298 // avoid dump of "GetGroups"
5300 // store python dump into a local variable inside local scope
5301 SMESH::TPythonDump pDump; // do not delete this line of code
5302 grpList = GetGroups();
5305 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5306 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5309 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5310 if ( aGrpSO->_is_nil() )
5312 // correct name of the mesh group if necessary
5313 const char* guiName = aGrpSO->GetName();
5314 if ( strcmp(guiName, aGrp->GetName()) )
5315 aGrp->SetName( guiName );
5319 //=============================================================================
5321 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5323 //=============================================================================
5324 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5326 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5330 //=============================================================================
5332 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5334 //=============================================================================
5336 char* SMESH_Mesh_i::GetParameters()
5338 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5341 //=============================================================================
5343 * \brief Returns list of notebook variables used for last Mesh operation
5345 //=============================================================================
5346 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5348 SMESH::string_array_var aResult = new SMESH::string_array();
5349 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5351 CORBA::String_var aParameters = GetParameters();
5352 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5353 if ( aSections->length() > 0 ) {
5354 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5355 aResult->length( aVars.length() );
5356 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5357 aResult[i] = CORBA::string_dup( aVars[i] );
5360 return aResult._retn();
5363 //=======================================================================
5364 //function : GetTypes
5365 //purpose : Returns types of elements it contains
5366 //=======================================================================
5368 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5371 return _preMeshInfo->GetTypes();
5373 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5377 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5378 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5379 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5380 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5381 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5382 if (_impl->NbNodes() &&
5383 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5384 types->length( nbTypes );
5386 return types._retn();
5389 //=======================================================================
5390 //function : GetMesh
5391 //purpose : Returns self
5392 //=======================================================================
5394 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5396 return SMESH::SMESH_Mesh::_duplicate( _this() );
5399 //=======================================================================
5400 //function : IsMeshInfoCorrect
5401 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5402 // * happen if mesh data is not yet fully loaded from the file of study.
5403 //=======================================================================
5405 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5407 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5410 //=============================================================================
5412 * \brief Returns number of mesh elements per each \a EntityType
5414 //=============================================================================
5416 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5419 return _preMeshInfo->GetMeshInfo();
5421 SMESH::long_array_var aRes = new SMESH::long_array();
5422 aRes->length(SMESH::Entity_Last);
5423 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5425 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5427 return aRes._retn();
5428 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5429 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5430 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5431 return aRes._retn();
5434 //=============================================================================
5436 * \brief Returns number of mesh elements per each \a ElementType
5438 //=============================================================================
5440 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5442 SMESH::long_array_var aRes = new SMESH::long_array();
5443 aRes->length(SMESH::NB_ELEMENT_TYPES);
5444 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5447 const SMDS_MeshInfo* meshInfo = 0;
5449 meshInfo = _preMeshInfo;
5450 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5451 meshInfo = & meshDS->GetMeshInfo();
5454 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5455 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5457 return aRes._retn();
5460 //=============================================================================
5462 * Collect statistic of mesh elements given by iterator
5464 //=============================================================================
5466 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5467 SMESH::long_array& theInfo)
5469 if (!theItr) return;
5470 while (theItr->more())
5471 theInfo[ theItr->next()->GetEntityType() ]++;
5473 //=============================================================================
5475 * Returns mesh unstructed grid information.
5477 //=============================================================================
5479 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5481 SALOMEDS::TMPFile_var SeqFile;
5482 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5483 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5485 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5486 aWriter->WriteToOutputStringOn();
5487 aWriter->SetInputData(aGrid);
5488 aWriter->SetFileTypeToBinary();
5490 char* str = aWriter->GetOutputString();
5491 int size = aWriter->GetOutputStringLength();
5493 //Allocate octet buffer of required size
5494 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5495 //Copy ostrstream content to the octet buffer
5496 memcpy(OctetBuf, str, size);
5497 //Create and return TMPFile
5498 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5502 return SeqFile._retn();
5505 //=============================================================================
5506 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5507 * SMESH::ElementType type) */
5509 using namespace SMESH::Controls;
5510 //-----------------------------------------------------------------------------
5511 struct PredicateIterator : public SMDS_ElemIterator
5513 SMDS_ElemIteratorPtr _elemIter;
5514 PredicatePtr _predicate;
5515 const SMDS_MeshElement* _elem;
5517 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5518 PredicatePtr predicate):
5519 _elemIter(iterator), _predicate(predicate)
5527 virtual const SMDS_MeshElement* next()
5529 const SMDS_MeshElement* res = _elem;
5531 while ( _elemIter->more() && !_elem )
5533 _elem = _elemIter->next();
5534 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5541 //-----------------------------------------------------------------------------
5542 struct IDSourceIterator : public SMDS_ElemIterator
5544 const CORBA::Long* _idPtr;
5545 const CORBA::Long* _idEndPtr;
5546 SMESH::long_array_var _idArray;
5547 const SMDS_Mesh* _mesh;
5548 const SMDSAbs_ElementType _type;
5549 const SMDS_MeshElement* _elem;
5551 IDSourceIterator( const SMDS_Mesh* mesh,
5552 const CORBA::Long* ids,
5554 SMDSAbs_ElementType type):
5555 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5557 if ( _idPtr && nbIds && _mesh )
5560 IDSourceIterator( const SMDS_Mesh* mesh,
5561 SMESH::long_array* idArray,
5562 SMDSAbs_ElementType type):
5563 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5565 if ( idArray && _mesh )
5567 _idPtr = &_idArray[0];
5568 _idEndPtr = _idPtr + _idArray->length();
5576 virtual const SMDS_MeshElement* next()
5578 const SMDS_MeshElement* res = _elem;
5580 while ( _idPtr < _idEndPtr && !_elem )
5582 if ( _type == SMDSAbs_Node )
5584 _elem = _mesh->FindNode( *_idPtr++ );
5586 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5587 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5595 //-----------------------------------------------------------------------------
5597 struct NodeOfElemIterator : public SMDS_ElemIterator
5599 TColStd_MapOfInteger _checkedNodeIDs;
5600 SMDS_ElemIteratorPtr _elemIter;
5601 SMDS_ElemIteratorPtr _nodeIter;
5602 const SMDS_MeshElement* _node;
5604 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5606 if ( _elemIter && _elemIter->more() )
5608 _nodeIter = _elemIter->next()->nodesIterator();
5616 virtual const SMDS_MeshElement* next()
5618 const SMDS_MeshElement* res = _node;
5620 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5622 if ( _nodeIter->more() )
5624 _node = _nodeIter->next();
5625 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5630 _nodeIter = _elemIter->next()->nodesIterator();
5638 //=============================================================================
5640 * Return iterator on elements of given type in given object
5642 //=============================================================================
5644 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5645 SMESH::ElementType theType)
5647 SMDS_ElemIteratorPtr elemIt;
5648 bool typeOK = ( theType == SMESH::ALL );
5649 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5651 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5652 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5653 if ( !mesh_i ) return elemIt;
5654 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5656 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5658 elemIt = meshDS->elementsIterator( elemType );
5661 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5663 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5666 elemIt = sm->GetElements();
5667 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5669 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5670 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5674 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5676 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5677 if ( groupDS && ( elemType == groupDS->GetType() ||
5678 elemType == SMDSAbs_Node ||
5679 elemType == SMDSAbs_All ))
5681 elemIt = groupDS->GetElements();
5682 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5685 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5687 if ( filter_i->GetElementType() == theType ||
5688 elemType == SMDSAbs_Node ||
5689 elemType == SMDSAbs_All)
5691 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5692 if ( pred_i && pred_i->GetPredicate() )
5694 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5695 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5696 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5697 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5703 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5704 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5705 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5707 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5710 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5711 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5715 SMESH::long_array_var ids = theObject->GetIDs();
5716 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5718 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5721 if ( elemIt && elemIt->more() && !typeOK )
5723 if ( elemType == SMDSAbs_Node )
5725 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5729 elemIt = SMDS_ElemIteratorPtr();
5735 //=============================================================================
5736 namespace // Finding concurrent hypotheses
5737 //=============================================================================
5741 * \brief mapping of mesh dimension into shape type
5743 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5745 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5747 case 0: aType = TopAbs_VERTEX; break;
5748 case 1: aType = TopAbs_EDGE; break;
5749 case 2: aType = TopAbs_FACE; break;
5751 default:aType = TopAbs_SOLID; break;
5756 //-----------------------------------------------------------------------------
5758 * \brief Internal structure used to find concurrent submeshes
5760 * It represents a pair < submesh, concurrent dimension >, where
5761 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5762 * with another submesh. In other words, it is dimension of a hypothesis assigned
5769 int _dim; //!< a dimension the algo can build (concurrent dimension)
5770 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5771 TopTools_MapOfShape _shapeMap;
5772 SMESH_subMesh* _subMesh;
5773 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5775 //-----------------------------------------------------------------------------
5776 // Return the algorithm
5777 const SMESH_Algo* GetAlgo() const
5778 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5780 //-----------------------------------------------------------------------------
5782 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5784 const TopoDS_Shape& theShape)
5786 _subMesh = (SMESH_subMesh*)theSubMesh;
5787 SetShape( theDim, theShape );
5790 //-----------------------------------------------------------------------------
5792 void SetShape(const int theDim,
5793 const TopoDS_Shape& theShape)
5796 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5797 if (_dim >= _ownDim)
5798 _shapeMap.Add( theShape );
5800 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5801 for( ; anExp.More(); anExp.Next() )
5802 _shapeMap.Add( anExp.Current() );
5806 //-----------------------------------------------------------------------------
5807 //! Check sharing of sub-shapes
5808 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5809 const TopTools_MapOfShape& theToFind,
5810 const TopAbs_ShapeEnum theType)
5812 bool isShared = false;
5813 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5814 for (; !isShared && anItr.More(); anItr.Next() )
5816 const TopoDS_Shape aSubSh = anItr.Key();
5817 // check for case when concurrent dimensions are same
5818 isShared = theToFind.Contains( aSubSh );
5819 // check for sub-shape with concurrent dimension
5820 TopExp_Explorer anExp( aSubSh, theType );
5821 for ( ; !isShared && anExp.More(); anExp.Next() )
5822 isShared = theToFind.Contains( anExp.Current() );
5827 //-----------------------------------------------------------------------------
5828 //! check algorithms
5829 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5830 const SMESHDS_Hypothesis* theA2)
5832 if ( !theA1 || !theA2 ||
5833 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5834 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5835 return false; // one of the hypothesis is not algorithm
5836 // check algorithm names (should be equal)
5837 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5841 //-----------------------------------------------------------------------------
5842 //! Check if sub-shape hypotheses are concurrent
5843 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5845 if ( _subMesh == theOther->_subMesh )
5846 return false; // same sub-shape - should not be
5848 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5849 // any of the two submeshes is not on COMPOUND shape )
5850 // -> no concurrency
5851 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5852 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5853 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5854 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5855 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5858 // bool checkSubShape = ( _dim >= theOther->_dim )
5859 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5860 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5861 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5862 if ( !checkSubShape )
5865 // check algorithms to be same
5866 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5867 return true; // different algorithms -> concurrency !
5869 // check hypothesises for concurrence (skip first as algorithm)
5871 // pointers should be same, because it is referened from mesh hypothesis partition
5872 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5873 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5874 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5875 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5877 // the submeshes are concurrent if their algorithms has different parameters
5878 return nbSame != (int)theOther->_hypotheses.size() - 1;
5881 // Return true if algorithm of this SMESH_DimHyp is used if no
5882 // sub-mesh order is imposed by the user
5883 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5885 // NeedDiscreteBoundary() algo has a higher priority
5886 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5887 theOther->GetAlgo()->NeedDiscreteBoundary() )
5888 return !this->GetAlgo()->NeedDiscreteBoundary();
5890 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5893 }; // end of SMESH_DimHyp
5894 //-----------------------------------------------------------------------------
5896 typedef list<const SMESH_DimHyp*> TDimHypList;
5898 //-----------------------------------------------------------------------------
5900 void addDimHypInstance(const int theDim,
5901 const TopoDS_Shape& theShape,
5902 const SMESH_Algo* theAlgo,
5903 const SMESH_subMesh* theSubMesh,
5904 const list <const SMESHDS_Hypothesis*>& theHypList,
5905 TDimHypList* theDimHypListArr )
5907 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5908 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5909 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5910 dimHyp->_hypotheses.push_front(theAlgo);
5911 listOfdimHyp.push_back( dimHyp );
5914 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5915 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5916 theHypList.begin(), theHypList.end() );
5919 //-----------------------------------------------------------------------------
5920 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5921 TDimHypList& theListOfConcurr)
5923 if ( theListOfConcurr.empty() )
5925 theListOfConcurr.push_back( theDimHyp );
5929 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5930 while ( hypIt != theListOfConcurr.end() &&
5931 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5933 theListOfConcurr.insert( hypIt, theDimHyp );
5937 //-----------------------------------------------------------------------------
5938 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5939 const TDimHypList& theListOfDimHyp,
5940 TDimHypList& theListOfConcurrHyp,
5941 set<int>& theSetOfConcurrId )
5943 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5944 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5946 const SMESH_DimHyp* curDimHyp = *rIt;
5947 if ( curDimHyp == theDimHyp )
5948 break; // meet own dimHyp pointer in same dimension
5950 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5951 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5953 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5958 //-----------------------------------------------------------------------------
5959 void unionLists(TListOfInt& theListOfId,
5960 TListOfListOfInt& theListOfListOfId,
5963 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5964 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5966 continue; //skip already treated lists
5967 // check if other list has any same submesh object
5968 TListOfInt& otherListOfId = *it;
5969 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5970 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5973 // union two lists (from source into target)
5974 TListOfInt::iterator it2 = otherListOfId.begin();
5975 for ( ; it2 != otherListOfId.end(); it2++ ) {
5976 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5977 theListOfId.push_back(*it2);
5979 // clear source list
5980 otherListOfId.clear();
5983 //-----------------------------------------------------------------------------
5985 //! free memory allocated for dimension-hypothesis objects
5986 void removeDimHyps( TDimHypList* theArrOfList )
5988 for (int i = 0; i < 4; i++ ) {
5989 TDimHypList& listOfdimHyp = theArrOfList[i];
5990 TDimHypList::const_iterator it = listOfdimHyp.begin();
5991 for ( ; it != listOfdimHyp.end(); it++ )
5996 //-----------------------------------------------------------------------------
5998 * \brief find common submeshes with given submesh
5999 * \param theSubMeshList list of already collected submesh to check
6000 * \param theSubMesh given submesh to intersect with other
6001 * \param theCommonSubMeshes collected common submeshes
6003 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6004 const SMESH_subMesh* theSubMesh,
6005 set<const SMESH_subMesh*>& theCommon )
6009 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6010 for ( ; it != theSubMeshList.end(); it++ )
6011 theSubMesh->FindIntersection( *it, theCommon );
6012 theSubMeshList.push_back( theSubMesh );
6013 //theCommon.insert( theSubMesh );
6016 //-----------------------------------------------------------------------------
6017 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6019 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6020 for ( ; listsIt != smLists.end(); ++listsIt )
6022 const TListOfInt& smIDs = *listsIt;
6023 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6031 //=============================================================================
6033 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6035 //=============================================================================
6037 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6039 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6040 if ( isSubMeshInList( submeshID, anOrder ))
6043 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6044 return isSubMeshInList( submeshID, allConurrent );
6047 //=============================================================================
6049 * \brief Return submesh objects list in meshing order
6051 //=============================================================================
6053 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6055 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6057 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6059 return aResult._retn();
6061 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6062 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6063 anOrder.splice( anOrder.end(), allConurrent );
6066 TListOfListOfInt::iterator listIt = anOrder.begin();
6067 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6068 unionLists( *listIt, anOrder, listIndx + 1 );
6070 // convert submesh ids into interface instances
6071 // and dump command into python
6072 convertMeshOrder( anOrder, aResult, false );
6074 return aResult._retn();
6077 //=============================================================================
6079 * \brief Finds concurrent sub-meshes
6081 //=============================================================================
6083 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6085 TListOfListOfInt anOrder;
6086 ::SMESH_Mesh& mesh = GetImpl();
6088 // collect submeshes and detect concurrent algorithms and hypothesises
6089 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6091 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6092 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6093 ::SMESH_subMesh* sm = (*i_sm).second;
6095 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6097 // list of assigned hypothesises
6098 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6099 // Find out dimensions where the submesh can be concurrent.
6100 // We define the dimensions by algo of each of hypotheses in hypList
6101 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6102 for( ; hypIt != hypList.end(); hypIt++ ) {
6103 SMESH_Algo* anAlgo = 0;
6104 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6105 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6106 // hyp it-self is algo
6107 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6109 // try to find algorithm with help of sub-shapes
6110 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6111 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6112 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6115 continue; // no algorithm assigned to a current submesh
6117 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6118 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6120 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6121 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6122 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6124 } // end iterations on submesh
6126 // iterate on created dimension-hypotheses and check for concurrents
6127 for ( int i = 0; i < 4; i++ ) {
6128 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6129 // check for concurrents in own and other dimensions (step-by-step)
6130 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6131 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6132 const SMESH_DimHyp* dimHyp = *dhIt;
6133 TDimHypList listOfConcurr;
6134 set<int> setOfConcurrIds;
6135 // looking for concurrents and collect into own list
6136 for ( int j = i; j < 4; j++ )
6137 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6138 // check if any concurrents found
6139 if ( listOfConcurr.size() > 0 ) {
6140 // add own submesh to list of concurrent
6141 addInOrderOfPriority( dimHyp, listOfConcurr );
6142 list<int> listOfConcurrIds;
6143 TDimHypList::iterator hypIt = listOfConcurr.begin();
6144 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6145 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6146 anOrder.push_back( listOfConcurrIds );
6151 removeDimHyps(dimHypListArr);
6153 // now, minimize the number of concurrent groups
6154 // Here we assume that lists of submeshes can have same submesh
6155 // in case of multi-dimension algorithms, as result
6156 // list with common submesh has to be united into one list
6158 TListOfListOfInt::iterator listIt = anOrder.begin();
6159 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6160 unionLists( *listIt, anOrder, listIndx + 1 );
6166 //=============================================================================
6168 * \brief Set submesh object order
6169 * \param theSubMeshArray submesh array order
6171 //=============================================================================
6173 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6176 _preMeshInfo->ForgetOrLoad();
6179 ::SMESH_Mesh& mesh = GetImpl();
6181 TPythonDump aPythonDump; // prevent dump of called methods
6182 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6184 TListOfListOfInt subMeshOrder;
6185 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6187 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6188 TListOfInt subMeshIds;
6190 aPythonDump << ", ";
6191 aPythonDump << "[ ";
6192 // Collect subMeshes which should be clear
6193 // do it list-by-list, because modification of submesh order
6194 // take effect between concurrent submeshes only
6195 set<const SMESH_subMesh*> subMeshToClear;
6196 list<const SMESH_subMesh*> subMeshList;
6197 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6199 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6201 aPythonDump << ", ";
6202 aPythonDump << subMesh;
6203 subMeshIds.push_back( subMesh->GetId() );
6204 // detect common parts of submeshes
6205 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6206 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6208 aPythonDump << " ]";
6209 subMeshOrder.push_back( subMeshIds );
6211 // clear collected submeshes
6212 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6213 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6214 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6215 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6217 aPythonDump << " ])";
6219 mesh.SetMeshOrder( subMeshOrder );
6222 SMESH::SMESH_Mesh_var me = _this();
6223 _gen_i->UpdateIcons( me );
6228 //=============================================================================
6230 * \brief Convert submesh ids into submesh interfaces
6232 //=============================================================================
6234 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6235 SMESH::submesh_array_array& theResOrder,
6236 const bool theIsDump)
6238 int nbSet = theIdsOrder.size();
6239 TPythonDump aPythonDump; // prevent dump of called methods
6241 aPythonDump << "[ ";
6242 theResOrder.length(nbSet);
6243 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6245 for( ; it != theIdsOrder.end(); it++ ) {
6246 // translate submesh identificators into submesh objects
6247 // takeing into account real number of concurrent lists
6248 const TListOfInt& aSubOrder = (*it);
6249 if (!aSubOrder.size())
6252 aPythonDump << "[ ";
6253 // convert shape indices into interfaces
6254 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6255 aResSubSet->length(aSubOrder.size());
6256 TListOfInt::const_iterator subIt = aSubOrder.begin();
6258 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6259 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6261 SMESH::SMESH_subMesh_var subMesh =
6262 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6265 aPythonDump << ", ";
6266 aPythonDump << subMesh;
6268 aResSubSet[ j++ ] = subMesh;
6271 aPythonDump << " ]";
6273 theResOrder[ listIndx++ ] = aResSubSet;
6275 // correct number of lists
6276 theResOrder.length( listIndx );
6279 // finilise python dump
6280 aPythonDump << " ]";
6281 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6285 namespace // utils used by SMESH_MeshPartDS
6288 * \brief Class used to access to protected data of SMDS_MeshInfo
6290 struct TMeshInfo : public SMDS_MeshInfo
6292 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6295 * \brief Element holing its ID only
6297 struct TElemID : public SMDS_LinearEdge
6299 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6303 //================================================================================
6305 // Implementation of SMESH_MeshPartDS
6307 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6308 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6310 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6311 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6314 _meshDS = mesh_i->GetImpl().GetMeshDS();
6316 SetPersistentId( _meshDS->GetPersistentId() );
6318 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6320 // <meshPart> is the whole mesh
6321 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6323 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6324 myGroupSet = _meshDS->GetGroups();
6329 SMESH::long_array_var anIDs = meshPart->GetIDs();
6330 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6331 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6333 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6334 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6335 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6340 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6341 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6342 if ( _elements[ e->GetType() ].insert( e ).second )
6345 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6346 while ( nIt->more() )
6348 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6349 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6356 ShapeToMesh( _meshDS->ShapeToMesh() );
6358 _meshDS = 0; // to enforce iteration on _elements and _nodes
6361 // -------------------------------------------------------------------------------------
6362 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6363 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6366 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6367 for ( ; partIt != meshPart.end(); ++partIt )
6368 if ( const SMDS_MeshElement * e = *partIt )
6369 if ( _elements[ e->GetType() ].insert( e ).second )
6372 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6373 while ( nIt->more() )
6375 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6376 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6382 // -------------------------------------------------------------------------------------
6383 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6385 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6387 TElemID elem( IDelem );
6388 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6389 if ( !_elements[ iType ].empty() )
6391 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6392 if ( it != _elements[ iType ].end() )
6397 // -------------------------------------------------------------------------------------
6398 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6400 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6402 typedef SMDS_SetIterator
6403 <const SMDS_MeshElement*,
6404 TIDSortedElemSet::const_iterator,
6405 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6406 SMDS_MeshElement::GeomFilter
6409 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6411 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6412 _elements[type].end(),
6413 SMDS_MeshElement::GeomFilter( geomType )));
6415 // -------------------------------------------------------------------------------------
6416 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6418 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6420 typedef SMDS_SetIterator
6421 <const SMDS_MeshElement*,
6422 TIDSortedElemSet::const_iterator,
6423 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6424 SMDS_MeshElement::EntityFilter
6427 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6429 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6430 _elements[type].end(),
6431 SMDS_MeshElement::EntityFilter( entity )));
6433 // -------------------------------------------------------------------------------------
6434 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6436 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6437 if ( type == SMDSAbs_All && !_meshDS )
6439 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6441 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6442 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6444 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6446 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6447 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6449 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6450 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6452 // -------------------------------------------------------------------------------------
6453 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6454 iterType SMESH_MeshPartDS::methName() const \
6456 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6457 return _meshDS ? _meshDS->methName() : iterType \
6458 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6460 // -------------------------------------------------------------------------------------
6461 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6462 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6463 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6464 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6465 #undef _GET_ITER_DEFINE
6467 // END Implementation of SMESH_MeshPartDS
6469 //================================================================================