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, /*id=*/-1, 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, /*id=*/-1, 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 editor = 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 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2433 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2434 /*id=*/-1, geom._shape ))
2435 group_i->changeLocalId( group->GetID() );
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,
2689 const TopoDS_Shape& theShape,
2690 const SMESH_PredicatePtr& thePredicate )
2692 std::string newName;
2693 if ( !theName || !theName[0] )
2695 std::set< std::string > presentNames;
2696 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2697 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2699 CORBA::String_var name = i_gr->second->GetName();
2700 presentNames.insert( name.in() );
2703 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2704 } while ( !presentNames.insert( newName ).second );
2705 theName = newName.c_str();
2707 SMESH::SMESH_GroupBase_var aGroup;
2708 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
2709 theID, theShape, thePredicate ))
2711 int anId = g->GetID();
2712 SMESH_GroupBase_i* aGroupImpl;
2713 if ( !theShape.IsNull() )
2714 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2715 else if ( thePredicate )
2716 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2718 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2720 aGroup = aGroupImpl->_this();
2721 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2722 aGroupImpl->Register();
2724 // register CORBA object for persistence
2725 int nextId = _gen_i->RegisterObject( aGroup );
2726 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2727 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
2729 // to track changes of GEOM groups
2730 if ( !theShape.IsNull() ) {
2731 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2732 addGeomGroupData( geom, aGroup );
2735 return aGroup._retn();
2738 //=============================================================================
2740 * SMESH_Mesh_i::removeGroup
2742 * Should be called by ~SMESH_Group_i()
2744 //=============================================================================
2746 void SMESH_Mesh_i::removeGroup( const int theId )
2748 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2749 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2750 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2751 _mapGroups.erase( theId );
2752 removeGeomGroupData( group );
2753 if ( !_impl->RemoveGroup( theId ))
2755 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2756 RemoveGroup( group );
2758 group->UnRegister();
2762 //=============================================================================
2766 //=============================================================================
2768 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2769 throw(SALOME::SALOME_Exception)
2771 SMESH::log_array_var aLog;
2775 _preMeshInfo->FullLoadFromFile();
2777 list < SMESHDS_Command * >logDS = _impl->GetLog();
2778 aLog = new SMESH::log_array;
2780 int lg = logDS.size();
2783 list < SMESHDS_Command * >::iterator its = logDS.begin();
2784 while(its != logDS.end()){
2785 SMESHDS_Command *com = *its;
2786 int comType = com->GetType();
2788 int lgcom = com->GetNumber();
2790 const list < int >&intList = com->GetIndexes();
2791 int inum = intList.size();
2793 list < int >::const_iterator ii = intList.begin();
2794 const list < double >&coordList = com->GetCoords();
2795 int rnum = coordList.size();
2797 list < double >::const_iterator ir = coordList.begin();
2798 aLog[indexLog].commandType = comType;
2799 aLog[indexLog].number = lgcom;
2800 aLog[indexLog].coords.length(rnum);
2801 aLog[indexLog].indexes.length(inum);
2802 for(int i = 0; i < rnum; i++){
2803 aLog[indexLog].coords[i] = *ir;
2804 //MESSAGE(" "<<i<<" "<<ir.Value());
2807 for(int i = 0; i < inum; i++){
2808 aLog[indexLog].indexes[i] = *ii;
2809 //MESSAGE(" "<<i<<" "<<ii.Value());
2818 SMESH_CATCH( SMESH::throwCorbaException );
2820 return aLog._retn();
2824 //=============================================================================
2828 //=============================================================================
2830 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2834 SMESH_CATCH( SMESH::throwCorbaException );
2837 //=============================================================================
2841 //=============================================================================
2843 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2848 //=============================================================================
2851 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2852 // issue 0020918: groups removal is caused by hyp modification
2853 // issue 0021208: to forget not loaded mesh data at hyp modification
2854 struct TCallUp_i : public SMESH_Mesh::TCallUp
2856 SMESH_Mesh_i* _mesh;
2857 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2858 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2859 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
2860 virtual void Load () { _mesh->Load(); }
2864 //================================================================================
2866 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2868 //================================================================================
2870 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
2873 _preMeshInfo->ForgetOrLoad();
2875 SMESH::SMESH_Mesh_var mesh = _this();
2876 _gen_i->UpdateIcons( mesh );
2878 // mark a hypothesis as valid after edition
2879 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
2880 SALOMEDS::SObject_wrap hypRoot;
2881 if ( !smeshComp->_is_nil() &&
2882 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
2884 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
2885 for ( ; anIter->More(); anIter->Next() )
2887 SALOMEDS::SObject_wrap hypSO = anIter->Value();
2888 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
2889 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
2890 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
2891 _gen_i->HighLightInvalid( hyp, false );
2896 //=============================================================================
2900 //=============================================================================
2902 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2904 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2907 _impl->SetCallUp( new TCallUp_i(this));
2910 //=============================================================================
2914 //=============================================================================
2916 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2918 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2922 //=============================================================================
2924 * Return mesh editor
2926 //=============================================================================
2928 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2929 throw (SALOME::SALOME_Exception)
2931 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2935 _preMeshInfo->FullLoadFromFile();
2937 // Create MeshEditor
2939 _editor = new SMESH_MeshEditor_i( this, false );
2940 aMeshEdVar = _editor->_this();
2942 // Update Python script
2943 TPythonDump() << _editor << " = "
2944 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2946 SMESH_CATCH( SMESH::throwCorbaException );
2948 return aMeshEdVar._retn();
2951 //=============================================================================
2953 * Return mesh edition previewer
2955 //=============================================================================
2957 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2958 throw (SALOME::SALOME_Exception)
2960 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2964 _preMeshInfo->FullLoadFromFile();
2966 if ( !_previewEditor )
2967 _previewEditor = new SMESH_MeshEditor_i( this, true );
2968 aMeshEdVar = _previewEditor->_this();
2970 SMESH_CATCH( SMESH::throwCorbaException );
2972 return aMeshEdVar._retn();
2975 //================================================================================
2977 * \brief Return true if the mesh has been edited since a last total re-compute
2978 * and those modifications may prevent successful partial re-compute
2980 //================================================================================
2982 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2984 Unexpect aCatch(SALOME_SalomeException);
2985 return _impl->HasModificationsToDiscard();
2988 //================================================================================
2990 * \brief Returns a random unique color
2992 //================================================================================
2994 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2996 const int MAX_ATTEMPTS = 100;
2998 double tolerance = 0.5;
2999 SALOMEDS::Color col;
3003 // generate random color
3004 double red = (double)rand() / RAND_MAX;
3005 double green = (double)rand() / RAND_MAX;
3006 double blue = (double)rand() / RAND_MAX;
3007 // check existence in the list of the existing colors
3008 bool matched = false;
3009 std::list<SALOMEDS::Color>::const_iterator it;
3010 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3011 SALOMEDS::Color color = *it;
3012 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3013 matched = tol < tolerance;
3015 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3016 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3024 //=============================================================================
3026 * Sets auto-color mode. If it is on, groups get unique random colors
3028 //=============================================================================
3030 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3032 Unexpect aCatch(SALOME_SalomeException);
3033 _impl->SetAutoColor(theAutoColor);
3035 TPythonDump pyDump; // not to dump group->SetColor() from below code
3036 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3038 std::list<SALOMEDS::Color> aReservedColors;
3039 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3040 for ( ; it != _mapGroups.end(); it++ ) {
3041 if ( CORBA::is_nil( it->second )) continue;
3042 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3043 it->second->SetColor( aColor );
3044 aReservedColors.push_back( aColor );
3048 //=============================================================================
3050 * Returns true if auto-color mode is on
3052 //=============================================================================
3054 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3056 Unexpect aCatch(SALOME_SalomeException);
3057 return _impl->GetAutoColor();
3060 //=============================================================================
3062 * Checks if there are groups with equal names
3064 //=============================================================================
3066 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3068 return _impl->HasDuplicatedGroupNamesMED();
3071 //================================================================================
3073 * \brief Care of a file before exporting mesh into it
3075 //================================================================================
3077 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3079 SMESH_File aFile( file );
3081 if (aFile.exists()) {
3082 // existing filesystem node
3083 if ( !aFile.isDirectory() ) {
3084 if ( aFile.openForWriting() ) {
3085 if ( overwrite && ! aFile.remove()) {
3086 msg << "Can't replace " << aFile.getName();
3089 msg << "Can't write into " << aFile.getName();
3092 msg << "Location " << aFile.getName() << " is not a file";
3096 // nonexisting file; check if it can be created
3097 if ( !aFile.openForWriting() ) {
3098 msg << "You cannot create the file "
3100 << ". Check the directory existence and access rights";
3108 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3112 //================================================================================
3114 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3115 * \param file - file name
3116 * \param overwrite - to erase the file or not
3117 * \retval string - mesh name
3119 //================================================================================
3121 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3122 CORBA::Boolean overwrite)
3125 PrepareForWriting(file, overwrite);
3126 string aMeshName = "Mesh";
3127 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3128 if ( !aStudy->_is_nil() ) {
3129 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3130 if ( !aMeshSO->_is_nil() ) {
3131 CORBA::String_var name = aMeshSO->GetName();
3133 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3134 if ( !aStudy->GetProperties()->IsLocked() )
3136 SALOMEDS::GenericAttribute_wrap anAttr;
3137 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3138 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3139 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3140 ASSERT(!aFileName->_is_nil());
3141 aFileName->SetValue(file);
3142 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3143 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3144 ASSERT(!aFileType->_is_nil());
3145 aFileType->SetValue("FICHIERMED");
3149 // Update Python script
3150 // set name of mesh before export
3151 TPythonDump() << _gen_i << ".SetName("
3152 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3154 // check names of groups
3160 //================================================================================
3162 * \brief Export to MED file
3164 //================================================================================
3166 void SMESH_Mesh_i::ExportMED(const char* file,
3167 CORBA::Boolean auto_groups,
3168 CORBA::Long version,
3169 CORBA::Boolean overwrite,
3170 CORBA::Boolean autoDimension)
3171 throw(SALOME::SALOME_Exception)
3173 //MESSAGE("MED minor version: "<< minor);
3176 _preMeshInfo->FullLoadFromFile();
3178 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3179 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3181 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3183 << "auto_groups=" <<auto_groups << ", "
3184 << "minor=" << version << ", "
3185 << "overwrite=" << overwrite << ", "
3186 << "meshPart=None, "
3187 << "autoDimension=" << autoDimension << " )";
3189 SMESH_CATCH( SMESH::throwCorbaException );
3192 //================================================================================
3194 * \brief Export a mesh to a SAUV file
3196 //================================================================================
3198 void SMESH_Mesh_i::ExportSAUV (const char* file,
3199 CORBA::Boolean auto_groups)
3200 throw(SALOME::SALOME_Exception)
3202 Unexpect aCatch(SALOME_SalomeException);
3204 _preMeshInfo->FullLoadFromFile();
3206 string aMeshName = prepareMeshNameAndGroups(file, true);
3207 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3208 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3209 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3213 //================================================================================
3215 * \brief Export a mesh to a DAT file
3217 //================================================================================
3219 void SMESH_Mesh_i::ExportDAT (const char *file)
3220 throw(SALOME::SALOME_Exception)
3222 Unexpect aCatch(SALOME_SalomeException);
3224 _preMeshInfo->FullLoadFromFile();
3226 // Update Python script
3227 // check names of groups
3229 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3232 PrepareForWriting(file);
3233 _impl->ExportDAT(file);
3236 //================================================================================
3238 * \brief Export a mesh to an UNV file
3240 //================================================================================
3242 void SMESH_Mesh_i::ExportUNV (const char *file)
3243 throw(SALOME::SALOME_Exception)
3245 Unexpect aCatch(SALOME_SalomeException);
3247 _preMeshInfo->FullLoadFromFile();
3249 // Update Python script
3250 // check names of groups
3252 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3255 PrepareForWriting(file);
3256 _impl->ExportUNV(file);
3259 //================================================================================
3261 * \brief Export a mesh to an STL file
3263 //================================================================================
3265 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3266 throw(SALOME::SALOME_Exception)
3268 Unexpect aCatch(SALOME_SalomeException);
3270 _preMeshInfo->FullLoadFromFile();
3272 // Update Python script
3273 // check names of groups
3275 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3276 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3278 CORBA::String_var name;
3279 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3280 if ( !so->_is_nil() )
3281 name = so->GetName();
3284 PrepareForWriting( file );
3285 _impl->ExportSTL( file, isascii, name.in() );
3288 //================================================================================
3290 * \brief Export a part of mesh to a med file
3292 //================================================================================
3294 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3296 CORBA::Boolean auto_groups,
3297 CORBA::Long version,
3298 CORBA::Boolean overwrite,
3299 CORBA::Boolean autoDimension,
3300 const GEOM::ListOfFields& fields,
3301 const char* geomAssocFields,
3302 CORBA::Double ZTolerance)
3303 throw (SALOME::SALOME_Exception)
3305 MESSAGE("MED version: "<< version);
3308 _preMeshInfo->FullLoadFromFile();
3311 bool have0dField = false;
3312 if ( fields.length() > 0 )
3314 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3315 if ( shapeToMesh->_is_nil() )
3316 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3318 for ( size_t i = 0; i < fields.length(); ++i )
3320 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3321 THROW_SALOME_CORBA_EXCEPTION
3322 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3323 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3324 if ( fieldShape->_is_nil() )
3325 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3326 if ( !fieldShape->IsSame( shapeToMesh ) )
3327 THROW_SALOME_CORBA_EXCEPTION
3328 ( "Field defined not on shape", SALOME::BAD_PARAM);
3329 if ( fields[i]->GetDimension() == 0 )
3332 if ( geomAssocFields )
3333 for ( int i = 0; geomAssocFields[i]; ++i )
3334 switch ( geomAssocFields[i] ) {
3335 case 'v':case 'e':case 'f':case 's': break;
3336 case 'V':case 'E':case 'F':case 'S': break;
3337 default: THROW_SALOME_CORBA_EXCEPTION
3338 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3342 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3346 string aMeshName = "Mesh";
3347 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3348 if ( CORBA::is_nil( meshPart ) ||
3349 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3351 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3352 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3353 0, autoDimension, /*addODOnVertices=*/have0dField,
3355 meshDS = _impl->GetMeshDS();
3360 _preMeshInfo->FullLoadFromFile();
3362 PrepareForWriting(file, overwrite);
3364 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3365 if ( !SO->_is_nil() ) {
3366 CORBA::String_var name = SO->GetName();
3370 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3371 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3372 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3373 meshDS = tmpDSDeleter._obj = partDS;
3378 if ( _impl->HasShapeToMesh() )
3380 DriverMED_W_Field fieldWriter;
3381 fieldWriter.SetFile( file );
3382 fieldWriter.SetMeshName( aMeshName );
3383 fieldWriter.AddODOnVertices( have0dField );
3385 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3389 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3390 goList->length( fields.length() );
3391 for ( size_t i = 0; i < fields.length(); ++i )
3393 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3396 TPythonDump() << _this() << ".ExportPartToMED( "
3397 << meshPart << ", r'"
3399 << auto_groups << ", "
3401 << overwrite << ", "
3402 << autoDimension << ", "
3404 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3405 << TVar( ZTolerance )
3408 SMESH_CATCH( SMESH::throwCorbaException );
3411 //================================================================================
3413 * Write GEOM fields to MED file
3415 //================================================================================
3417 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3418 SMESHDS_Mesh* meshDS,
3419 const GEOM::ListOfFields& fields,
3420 const char* geomAssocFields)
3422 #define METH "SMESH_Mesh_i::exportMEDFields() "
3424 if (( fields.length() < 1 ) &&
3425 ( !geomAssocFields || !geomAssocFields[0] ))
3428 std::vector< std::vector< double > > dblVals;
3429 std::vector< std::vector< int > > intVals;
3430 std::vector< int > subIdsByDim[ 4 ];
3431 const double noneDblValue = 0.;
3432 const double noneIntValue = 0;
3434 for ( size_t iF = 0; iF < fields.length(); ++iF )
3438 int dim = fields[ iF ]->GetDimension();
3439 SMDSAbs_ElementType elemType;
3440 TopAbs_ShapeEnum shapeType;
3442 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3443 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3444 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3445 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3447 continue; // skip fields on whole shape
3449 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3450 if ( dataType == GEOM::FDT_String )
3452 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3453 if ( stepIDs->length() < 1 )
3455 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3456 if ( comps->length() < 1 )
3458 CORBA::String_var name = fields[ iF ]->GetName();
3460 if ( !fieldWriter.Set( meshDS,
3464 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3467 for ( size_t iC = 0; iC < comps->length(); ++iC )
3468 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3470 dblVals.resize( comps->length() );
3471 intVals.resize( comps->length() );
3473 // find sub-shape IDs
3475 std::vector< int >& subIds = subIdsByDim[ dim ];
3476 if ( subIds.empty() )
3477 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3478 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3479 subIds.push_back( id );
3483 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3487 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3489 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3490 if ( step->_is_nil() )
3493 CORBA::Long stamp = step->GetStamp();
3494 CORBA::Long id = step->GetID();
3495 fieldWriter.SetDtIt( int( stamp ), int( id ));
3497 // fill dblVals or intVals
3498 for ( size_t iC = 0; iC < comps->length(); ++iC )
3499 if ( dataType == GEOM::FDT_Double )
3501 dblVals[ iC ].clear();
3502 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3506 intVals[ iC ].clear();
3507 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3511 case GEOM::FDT_Double:
3513 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3514 if ( dblStep->_is_nil() ) continue;
3515 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3516 if ( vv->length() != subIds.size() * comps->length() )
3517 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3518 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3519 for ( size_t iC = 0; iC < comps->length(); ++iC )
3520 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3525 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3526 if ( intStep->_is_nil() ) continue;
3527 GEOM::ListOfLong_var vv = intStep->GetValues();
3528 if ( vv->length() != subIds.size() * comps->length() )
3529 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3530 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3531 for ( size_t iC = 0; iC < comps->length(); ++iC )
3532 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3535 case GEOM::FDT_Bool:
3537 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3538 if ( boolStep->_is_nil() ) continue;
3539 GEOM::short_array_var vv = boolStep->GetValues();
3540 if ( vv->length() != subIds.size() * comps->length() )
3541 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3542 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3543 for ( size_t iC = 0; iC < comps->length(); ++iC )
3544 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3550 // pass values to fieldWriter
3551 elemIt = fieldWriter.GetOrderedElems();
3552 if ( dataType == GEOM::FDT_Double )
3553 while ( elemIt->more() )
3555 const SMDS_MeshElement* e = elemIt->next();
3556 const int shapeID = e->getshapeId();
3557 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3558 for ( size_t iC = 0; iC < comps->length(); ++iC )
3559 fieldWriter.AddValue( noneDblValue );
3561 for ( size_t iC = 0; iC < comps->length(); ++iC )
3562 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3565 while ( elemIt->more() )
3567 const SMDS_MeshElement* e = elemIt->next();
3568 const int shapeID = e->getshapeId();
3569 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3570 for ( size_t iC = 0; iC < comps->length(); ++iC )
3571 fieldWriter.AddValue( (double) noneIntValue );
3573 for ( size_t iC = 0; iC < comps->length(); ++iC )
3574 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3578 fieldWriter.Perform();
3579 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3580 if ( res && res->IsKO() )
3582 if ( res->myComment.empty() )
3583 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3585 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3591 if ( !geomAssocFields || !geomAssocFields[0] )
3594 // write geomAssocFields
3596 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3597 shapeDim[ TopAbs_COMPOUND ] = 3;
3598 shapeDim[ TopAbs_COMPSOLID ] = 3;
3599 shapeDim[ TopAbs_SOLID ] = 3;
3600 shapeDim[ TopAbs_SHELL ] = 2;
3601 shapeDim[ TopAbs_FACE ] = 2;
3602 shapeDim[ TopAbs_WIRE ] = 1;
3603 shapeDim[ TopAbs_EDGE ] = 1;
3604 shapeDim[ TopAbs_VERTEX ] = 0;
3605 shapeDim[ TopAbs_SHAPE ] = 3;
3607 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3609 std::vector< std::string > compNames;
3610 switch ( geomAssocFields[ iF ]) {
3612 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3613 compNames.push_back( "dim" );
3616 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3619 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3622 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3626 compNames.push_back( "id" );
3627 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3628 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3630 fieldWriter.SetDtIt( -1, -1 );
3632 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3636 if ( compNames.size() == 2 ) // _vertices_
3637 while ( elemIt->more() )
3639 const SMDS_MeshElement* e = elemIt->next();
3640 const int shapeID = e->getshapeId();
3643 fieldWriter.AddValue( (double) -1 );
3644 fieldWriter.AddValue( (double) -1 );
3648 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3649 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3650 fieldWriter.AddValue( (double) shapeID );
3654 while ( elemIt->more() )
3656 const SMDS_MeshElement* e = elemIt->next();
3657 const int shapeID = e->getshapeId();
3659 fieldWriter.AddValue( (double) -1 );
3661 fieldWriter.AddValue( (double) shapeID );
3665 fieldWriter.Perform();
3666 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3667 if ( res && res->IsKO() )
3669 if ( res->myComment.empty() )
3670 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3672 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3675 } // loop on geomAssocFields
3680 //================================================================================
3682 * \brief Export a part of mesh to a DAT file
3684 //================================================================================
3686 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3688 throw (SALOME::SALOME_Exception)
3690 Unexpect aCatch(SALOME_SalomeException);
3692 _preMeshInfo->FullLoadFromFile();
3694 PrepareForWriting(file);
3696 SMESH_MeshPartDS partDS( meshPart );
3697 _impl->ExportDAT(file,&partDS);
3699 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3700 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3702 //================================================================================
3704 * \brief Export a part of mesh to an UNV file
3706 //================================================================================
3708 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3710 throw (SALOME::SALOME_Exception)
3712 Unexpect aCatch(SALOME_SalomeException);
3714 _preMeshInfo->FullLoadFromFile();
3716 PrepareForWriting(file);
3718 SMESH_MeshPartDS partDS( meshPart );
3719 _impl->ExportUNV(file, &partDS);
3721 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3722 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3724 //================================================================================
3726 * \brief Export a part of mesh to an STL file
3728 //================================================================================
3730 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3732 ::CORBA::Boolean isascii)
3733 throw (SALOME::SALOME_Exception)
3735 Unexpect aCatch(SALOME_SalomeException);
3737 _preMeshInfo->FullLoadFromFile();
3739 PrepareForWriting(file);
3741 CORBA::String_var name;
3742 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3743 if ( !so->_is_nil() )
3744 name = so->GetName();
3746 SMESH_MeshPartDS partDS( meshPart );
3747 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3749 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3750 << meshPart<< ", r'" << file << "', " << isascii << ")";
3753 //================================================================================
3755 * \brief Export a part of mesh to an STL file
3757 //================================================================================
3759 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3761 CORBA::Boolean overwrite,
3762 CORBA::Boolean groupElemsByType)
3763 throw (SALOME::SALOME_Exception)
3766 Unexpect aCatch(SALOME_SalomeException);
3768 _preMeshInfo->FullLoadFromFile();
3770 PrepareForWriting(file,overwrite);
3772 std::string meshName("");
3773 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3774 if ( !so->_is_nil() )
3776 CORBA::String_var name = so->GetName();
3777 meshName = name.in();
3781 SMESH_MeshPartDS partDS( meshPart );
3782 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3784 SMESH_CATCH( SMESH::throwCorbaException );
3786 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3787 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3789 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3793 //================================================================================
3795 * \brief Export a part of mesh to a GMF file
3797 //================================================================================
3799 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3801 bool withRequiredGroups)
3802 throw (SALOME::SALOME_Exception)
3804 Unexpect aCatch(SALOME_SalomeException);
3806 _preMeshInfo->FullLoadFromFile();
3808 PrepareForWriting(file,/*overwrite=*/true);
3810 SMESH_MeshPartDS partDS( meshPart );
3811 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3813 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3814 << meshPart<< ", r'"
3816 << withRequiredGroups << ")";
3819 //=============================================================================
3821 * Return computation progress [0.,1]
3823 //=============================================================================
3825 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3829 return _impl->GetComputeProgress();
3831 SMESH_CATCH( SMESH::doNothing );
3835 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3837 Unexpect aCatch(SALOME_SalomeException);
3839 return _preMeshInfo->NbNodes();
3841 return _impl->NbNodes();
3844 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3846 Unexpect aCatch(SALOME_SalomeException);
3848 return _preMeshInfo->NbElements();
3850 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3853 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3855 Unexpect aCatch(SALOME_SalomeException);
3857 return _preMeshInfo->Nb0DElements();
3859 return _impl->Nb0DElements();
3862 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3864 Unexpect aCatch(SALOME_SalomeException);
3866 return _preMeshInfo->NbBalls();
3868 return _impl->NbBalls();
3871 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3873 Unexpect aCatch(SALOME_SalomeException);
3875 return _preMeshInfo->NbEdges();
3877 return _impl->NbEdges();
3880 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3881 throw(SALOME::SALOME_Exception)
3883 Unexpect aCatch(SALOME_SalomeException);
3885 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3887 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3890 //=============================================================================
3892 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3894 Unexpect aCatch(SALOME_SalomeException);
3896 return _preMeshInfo->NbFaces();
3898 return _impl->NbFaces();
3901 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3903 Unexpect aCatch(SALOME_SalomeException);
3905 return _preMeshInfo->NbTriangles();
3907 return _impl->NbTriangles();
3910 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3912 Unexpect aCatch(SALOME_SalomeException);
3914 return _preMeshInfo->NbBiQuadTriangles();
3916 return _impl->NbBiQuadTriangles();
3919 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3921 Unexpect aCatch(SALOME_SalomeException);
3923 return _preMeshInfo->NbQuadrangles();
3925 return _impl->NbQuadrangles();
3928 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3930 Unexpect aCatch(SALOME_SalomeException);
3932 return _preMeshInfo->NbBiQuadQuadrangles();
3934 return _impl->NbBiQuadQuadrangles();
3937 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3939 Unexpect aCatch(SALOME_SalomeException);
3941 return _preMeshInfo->NbPolygons();
3943 return _impl->NbPolygons();
3946 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3948 Unexpect aCatch(SALOME_SalomeException);
3950 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3952 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3955 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3956 throw(SALOME::SALOME_Exception)
3958 Unexpect aCatch(SALOME_SalomeException);
3960 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3962 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3965 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3966 throw(SALOME::SALOME_Exception)
3968 Unexpect aCatch(SALOME_SalomeException);
3970 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3972 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3975 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3976 throw(SALOME::SALOME_Exception)
3978 Unexpect aCatch(SALOME_SalomeException);
3980 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3982 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3985 //=============================================================================
3987 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3989 Unexpect aCatch(SALOME_SalomeException);
3991 return _preMeshInfo->NbVolumes();
3993 return _impl->NbVolumes();
3996 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3998 Unexpect aCatch(SALOME_SalomeException);
4000 return _preMeshInfo->NbTetras();
4002 return _impl->NbTetras();
4005 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4007 Unexpect aCatch(SALOME_SalomeException);
4009 return _preMeshInfo->NbHexas();
4011 return _impl->NbHexas();
4014 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4016 Unexpect aCatch(SALOME_SalomeException);
4018 return _preMeshInfo->NbTriQuadHexas();
4020 return _impl->NbTriQuadraticHexas();
4023 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4025 Unexpect aCatch(SALOME_SalomeException);
4027 return _preMeshInfo->NbPyramids();
4029 return _impl->NbPyramids();
4032 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4034 Unexpect aCatch(SALOME_SalomeException);
4036 return _preMeshInfo->NbPrisms();
4038 return _impl->NbPrisms();
4041 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4043 Unexpect aCatch(SALOME_SalomeException);
4045 return _preMeshInfo->NbHexPrisms();
4047 return _impl->NbHexagonalPrisms();
4050 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4052 Unexpect aCatch(SALOME_SalomeException);
4054 return _preMeshInfo->NbPolyhedrons();
4056 return _impl->NbPolyhedrons();
4059 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4060 throw(SALOME::SALOME_Exception)
4062 Unexpect aCatch(SALOME_SalomeException);
4064 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4066 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4069 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4070 throw(SALOME::SALOME_Exception)
4072 Unexpect aCatch(SALOME_SalomeException);
4074 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4076 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4079 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4080 throw(SALOME::SALOME_Exception)
4082 Unexpect aCatch(SALOME_SalomeException);
4084 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4086 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4089 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4090 throw(SALOME::SALOME_Exception)
4092 Unexpect aCatch(SALOME_SalomeException);
4094 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4096 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4099 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4100 throw(SALOME::SALOME_Exception)
4102 Unexpect aCatch(SALOME_SalomeException);
4104 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4106 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4109 //=============================================================================
4111 * Returns nb of published sub-meshes
4113 //=============================================================================
4115 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4117 Unexpect aCatch(SALOME_SalomeException);
4118 return _mapSubMesh_i.size();
4121 //=============================================================================
4123 * Dumps mesh into a string
4125 //=============================================================================
4127 char* SMESH_Mesh_i::Dump()
4131 return CORBA::string_dup( os.str().c_str() );
4134 //=============================================================================
4136 * Method of SMESH_IDSource interface
4138 //=============================================================================
4140 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4142 return GetElementsId();
4145 //=============================================================================
4147 * Returns ids of all elements
4149 //=============================================================================
4151 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4152 throw (SALOME::SALOME_Exception)
4154 Unexpect aCatch(SALOME_SalomeException);
4156 _preMeshInfo->FullLoadFromFile();
4158 SMESH::long_array_var aResult = new SMESH::long_array();
4159 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4161 if ( aSMESHDS_Mesh == NULL )
4162 return aResult._retn();
4164 long nbElements = NbElements();
4165 aResult->length( nbElements );
4166 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4167 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4168 aResult[i] = anIt->next()->GetID();
4170 return aResult._retn();
4174 //=============================================================================
4176 * Returns ids of all elements of given type
4178 //=============================================================================
4180 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4181 throw (SALOME::SALOME_Exception)
4183 Unexpect aCatch(SALOME_SalomeException);
4185 _preMeshInfo->FullLoadFromFile();
4187 SMESH::long_array_var aResult = new SMESH::long_array();
4188 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4190 if ( aSMESHDS_Mesh == NULL )
4191 return aResult._retn();
4193 long nbElements = NbElements();
4195 // No sense in returning ids of elements along with ids of nodes:
4196 // when theElemType == SMESH::ALL, return node ids only if
4197 // there are no elements
4198 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4199 return GetNodesId();
4201 aResult->length( nbElements );
4205 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4206 while ( i < nbElements && anIt->more() )
4207 aResult[i++] = anIt->next()->GetID();
4209 aResult->length( i );
4211 return aResult._retn();
4214 //=============================================================================
4216 * Returns ids of all nodes
4218 //=============================================================================
4220 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4221 throw (SALOME::SALOME_Exception)
4223 Unexpect aCatch(SALOME_SalomeException);
4225 _preMeshInfo->FullLoadFromFile();
4227 SMESH::long_array_var aResult = new SMESH::long_array();
4228 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4230 if ( aMeshDS == NULL )
4231 return aResult._retn();
4233 long nbNodes = NbNodes();
4234 aResult->length( nbNodes );
4235 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4236 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4237 aResult[i] = anIt->next()->GetID();
4239 return aResult._retn();
4242 //=============================================================================
4246 //=============================================================================
4248 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4249 throw (SALOME::SALOME_Exception)
4251 SMESH::ElementType type = SMESH::ALL;
4255 _preMeshInfo->FullLoadFromFile();
4257 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4259 SMESH_CATCH( SMESH::throwCorbaException );
4264 //=============================================================================
4268 //=============================================================================
4270 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4271 throw (SALOME::SALOME_Exception)
4274 _preMeshInfo->FullLoadFromFile();
4276 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4278 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4280 return ( SMESH::EntityType ) e->GetEntityType();
4283 //=============================================================================
4287 //=============================================================================
4289 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4290 throw (SALOME::SALOME_Exception)
4293 _preMeshInfo->FullLoadFromFile();
4295 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4297 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4299 return ( SMESH::GeometryType ) e->GetGeomType();
4302 //=============================================================================
4304 * Returns ID of elements for given submesh
4306 //=============================================================================
4307 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4308 throw (SALOME::SALOME_Exception)
4310 SMESH::long_array_var aResult = new SMESH::long_array();
4314 _preMeshInfo->FullLoadFromFile();
4316 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4317 if(!SM) return aResult._retn();
4319 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4320 if(!SDSM) return aResult._retn();
4322 aResult->length(SDSM->NbElements());
4324 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4326 while ( eIt->more() ) {
4327 aResult[i++] = eIt->next()->GetID();
4330 SMESH_CATCH( SMESH::throwCorbaException );
4332 return aResult._retn();
4335 //=============================================================================
4337 * Returns ID of nodes for given submesh
4338 * If param all==true - returns all nodes, else -
4339 * returns only nodes on shapes.
4341 //=============================================================================
4343 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4345 throw (SALOME::SALOME_Exception)
4347 SMESH::long_array_var aResult = new SMESH::long_array();
4351 _preMeshInfo->FullLoadFromFile();
4353 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4354 if(!SM) return aResult._retn();
4356 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4357 if(!SDSM) return aResult._retn();
4360 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4361 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4362 while ( nIt->more() ) {
4363 const SMDS_MeshNode* elem = nIt->next();
4364 theElems.insert( elem->GetID() );
4367 else { // all nodes of submesh elements
4368 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4369 while ( eIt->more() ) {
4370 const SMDS_MeshElement* anElem = eIt->next();
4371 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4372 while ( nIt->more() ) {
4373 const SMDS_MeshElement* elem = nIt->next();
4374 theElems.insert( elem->GetID() );
4379 aResult->length(theElems.size());
4380 set<int>::iterator itElem;
4382 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4383 aResult[i++] = *itElem;
4385 SMESH_CATCH( SMESH::throwCorbaException );
4387 return aResult._retn();
4390 //=============================================================================
4392 * Returns type of elements for given submesh
4394 //=============================================================================
4396 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4397 throw (SALOME::SALOME_Exception)
4399 SMESH::ElementType type = SMESH::ALL;
4403 _preMeshInfo->FullLoadFromFile();
4405 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4406 if(!SM) return SMESH::ALL;
4408 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4409 if(!SDSM) return SMESH::ALL;
4411 if(SDSM->NbElements()==0)
4412 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4414 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4415 const SMDS_MeshElement* anElem = eIt->next();
4417 type = ( SMESH::ElementType ) anElem->GetType();
4419 SMESH_CATCH( SMESH::throwCorbaException );
4425 //=============================================================================
4427 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4429 //=============================================================================
4431 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4434 _preMeshInfo->FullLoadFromFile();
4436 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4437 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4442 //=============================================================================
4444 * Get XYZ coordinates of node as list of double
4445 * If there is not node for given ID - returns empty list
4447 //=============================================================================
4449 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4452 _preMeshInfo->FullLoadFromFile();
4454 SMESH::double_array_var aResult = new SMESH::double_array();
4455 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4456 if ( aMeshDS == NULL )
4457 return aResult._retn();
4460 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4462 return aResult._retn();
4466 aResult[0] = aNode->X();
4467 aResult[1] = aNode->Y();
4468 aResult[2] = aNode->Z();
4469 return aResult._retn();
4473 //=============================================================================
4475 * For given node returns list of IDs of inverse elements
4476 * If there is not node for given ID - returns empty list
4478 //=============================================================================
4480 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4481 SMESH::ElementType elemType)
4484 _preMeshInfo->FullLoadFromFile();
4486 SMESH::long_array_var aResult = new SMESH::long_array();
4487 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4488 if ( aMeshDS == NULL )
4489 return aResult._retn();
4492 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4494 return aResult._retn();
4496 // find inverse elements
4497 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4498 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4499 aResult->length( aNode->NbInverseElements( type ));
4500 for( int i = 0; eIt->more(); ++i )
4502 const SMDS_MeshElement* elem = eIt->next();
4503 aResult[ i ] = elem->GetID();
4505 return aResult._retn();
4508 //=============================================================================
4510 * \brief Return position of a node on shape
4512 //=============================================================================
4514 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4517 _preMeshInfo->FullLoadFromFile();
4519 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4520 aNodePosition->shapeID = 0;
4521 aNodePosition->shapeType = GEOM::SHAPE;
4523 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4524 if ( !mesh ) return aNodePosition;
4526 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4528 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4530 aNodePosition->shapeID = aNode->getshapeId();
4531 switch ( pos->GetTypeOfPosition() ) {
4533 aNodePosition->shapeType = GEOM::EDGE;
4534 aNodePosition->params.length(1);
4535 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4537 case SMDS_TOP_FACE: {
4538 SMDS_FacePositionPtr fPos = pos;
4539 aNodePosition->shapeType = GEOM::FACE;
4540 aNodePosition->params.length(2);
4541 aNodePosition->params[0] = fPos->GetUParameter();
4542 aNodePosition->params[1] = fPos->GetVParameter();
4545 case SMDS_TOP_VERTEX:
4546 aNodePosition->shapeType = GEOM::VERTEX;
4548 case SMDS_TOP_3DSPACE:
4549 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4550 aNodePosition->shapeType = GEOM::SOLID;
4551 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4552 aNodePosition->shapeType = GEOM::SHELL;
4558 return aNodePosition;
4561 //=============================================================================
4563 * \brief Return position of an element on shape
4565 //=============================================================================
4567 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4570 _preMeshInfo->FullLoadFromFile();
4572 SMESH::ElementPosition anElementPosition;
4573 anElementPosition.shapeID = 0;
4574 anElementPosition.shapeType = GEOM::SHAPE;
4576 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4577 if ( !mesh ) return anElementPosition;
4579 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4581 anElementPosition.shapeID = anElem->getshapeId();
4582 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4583 if ( !aSp.IsNull() ) {
4584 switch ( aSp.ShapeType() ) {
4586 anElementPosition.shapeType = GEOM::EDGE;
4589 anElementPosition.shapeType = GEOM::FACE;
4592 anElementPosition.shapeType = GEOM::VERTEX;
4595 anElementPosition.shapeType = GEOM::SOLID;
4598 anElementPosition.shapeType = GEOM::SHELL;
4604 return anElementPosition;
4607 //=============================================================================
4609 * If given element is node returns IDs of shape from position
4610 * If there is not node for given ID - returns -1
4612 //=============================================================================
4614 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4617 _preMeshInfo->FullLoadFromFile();
4619 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4620 if ( aMeshDS == NULL )
4624 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4626 return aNode->getshapeId();
4633 //=============================================================================
4635 * For given element returns ID of result shape after
4636 * ::FindShape() from SMESH_MeshEditor
4637 * If there is not element for given ID - returns -1
4639 //=============================================================================
4641 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4644 _preMeshInfo->FullLoadFromFile();
4646 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4647 if ( aMeshDS == NULL )
4650 // try to find element
4651 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4655 ::SMESH_MeshEditor aMeshEditor(_impl);
4656 int index = aMeshEditor.FindShape( elem );
4664 //=============================================================================
4666 * Returns number of nodes for given element
4667 * If there is not element for given ID - returns -1
4669 //=============================================================================
4671 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4674 _preMeshInfo->FullLoadFromFile();
4676 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4677 if ( aMeshDS == NULL ) return -1;
4678 // try to find element
4679 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4680 if(!elem) return -1;
4681 return elem->NbNodes();
4685 //=============================================================================
4687 * Returns ID of node by given index for given element
4688 * If there is not element for given ID - returns -1
4689 * If there is not node for given index - returns -2
4691 //=============================================================================
4693 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4696 _preMeshInfo->FullLoadFromFile();
4698 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4699 if ( aMeshDS == NULL ) return -1;
4700 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4701 if(!elem) return -1;
4702 if( index>=elem->NbNodes() || index<0 ) return -1;
4703 return elem->GetNode(index)->GetID();
4706 //=============================================================================
4708 * Returns IDs of nodes of given element
4710 //=============================================================================
4712 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4715 _preMeshInfo->FullLoadFromFile();
4717 SMESH::long_array_var aResult = new SMESH::long_array();
4718 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4720 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4722 aResult->length( elem->NbNodes() );
4723 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4724 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
4725 aResult[ i ] = n->GetID();
4728 return aResult._retn();
4731 //=============================================================================
4733 * Returns true if given node is medium node
4734 * in given quadratic element
4736 //=============================================================================
4738 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4741 _preMeshInfo->FullLoadFromFile();
4743 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4744 if ( aMeshDS == NULL ) return false;
4746 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4747 if(!aNode) return false;
4748 // try to find element
4749 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4750 if(!elem) return false;
4752 return elem->IsMediumNode(aNode);
4756 //=============================================================================
4758 * Returns true if given node is medium node
4759 * in one of quadratic elements
4761 //=============================================================================
4763 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4764 SMESH::ElementType theElemType)
4767 _preMeshInfo->FullLoadFromFile();
4769 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4770 if ( aMeshDS == NULL ) return false;
4773 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4774 if(!aNode) return false;
4776 SMESH_MesherHelper aHelper( *(_impl) );
4778 SMDSAbs_ElementType aType;
4779 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4780 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4781 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4782 else aType = SMDSAbs_All;
4784 return aHelper.IsMedium(aNode,aType);
4788 //=============================================================================
4790 * Returns number of edges for given element
4792 //=============================================================================
4794 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4797 _preMeshInfo->FullLoadFromFile();
4799 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4800 if ( aMeshDS == NULL ) return -1;
4801 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4802 if(!elem) return -1;
4803 return elem->NbEdges();
4807 //=============================================================================
4809 * Returns number of faces for given element
4811 //=============================================================================
4813 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4816 _preMeshInfo->FullLoadFromFile();
4818 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4819 if ( aMeshDS == NULL ) return -1;
4820 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4821 if(!elem) return -1;
4822 return elem->NbFaces();
4825 //=======================================================================
4826 //function : GetElemFaceNodes
4827 //purpose : Returns nodes of given face (counted from zero) for given element.
4828 //=======================================================================
4830 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4831 CORBA::Short faceIndex)
4834 _preMeshInfo->FullLoadFromFile();
4836 SMESH::long_array_var aResult = new SMESH::long_array();
4837 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4839 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4841 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
4842 if ( faceIndex < vtool.NbFaces() )
4844 aResult->length( vtool.NbFaceNodes( faceIndex ));
4845 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4846 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4847 aResult[ i ] = nn[ i ]->GetID();
4851 return aResult._retn();
4854 //=======================================================================
4855 //function : GetElemFaceNodes
4856 //purpose : Returns three components of normal of given mesh face.
4857 //=======================================================================
4859 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4860 CORBA::Boolean normalized)
4863 _preMeshInfo->FullLoadFromFile();
4865 SMESH::double_array_var aResult = new SMESH::double_array();
4867 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4870 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4872 aResult->length( 3 );
4873 aResult[ 0 ] = normal.X();
4874 aResult[ 1 ] = normal.Y();
4875 aResult[ 2 ] = normal.Z();
4878 return aResult._retn();
4881 //=======================================================================
4882 //function : FindElementByNodes
4883 //purpose : Returns an element based on all given nodes.
4884 //=======================================================================
4886 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4889 _preMeshInfo->FullLoadFromFile();
4891 CORBA::Long elemID(0);
4892 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4894 vector< const SMDS_MeshNode * > nn( nodes.length() );
4895 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4896 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4899 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4900 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4901 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4902 _impl->NbVolumes( ORDER_QUADRATIC )))
4903 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4905 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4910 //================================================================================
4912 * \brief Return elements including all given nodes.
4914 //================================================================================
4916 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4917 SMESH::ElementType elemType)
4920 _preMeshInfo->FullLoadFromFile();
4922 SMESH::long_array_var result = new SMESH::long_array();
4924 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4926 vector< const SMDS_MeshNode * > nn( nodes.length() );
4927 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4928 nn[i] = mesh->FindNode( nodes[i] );
4930 std::vector<const SMDS_MeshElement *> elems;
4931 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4932 result->length( elems.size() );
4933 for ( size_t i = 0; i < elems.size(); ++i )
4934 result[i] = elems[i]->GetID();
4936 return result._retn();
4939 //=============================================================================
4941 * Returns true if given element is polygon
4943 //=============================================================================
4945 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4948 _preMeshInfo->FullLoadFromFile();
4950 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4951 if ( aMeshDS == NULL ) return false;
4952 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4953 if(!elem) return false;
4954 return elem->IsPoly();
4958 //=============================================================================
4960 * Returns true if given element is quadratic
4962 //=============================================================================
4964 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4967 _preMeshInfo->FullLoadFromFile();
4969 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4970 if ( aMeshDS == NULL ) return false;
4971 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4972 if(!elem) return false;
4973 return elem->IsQuadratic();
4976 //=============================================================================
4978 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4980 //=============================================================================
4982 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4985 _preMeshInfo->FullLoadFromFile();
4987 if ( const SMDS_BallElement* ball =
4988 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4989 return ball->GetDiameter();
4994 //=============================================================================
4996 * Returns bary center for given element
4998 //=============================================================================
5000 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5003 _preMeshInfo->FullLoadFromFile();
5005 SMESH::double_array_var aResult = new SMESH::double_array();
5006 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5007 if ( aMeshDS == NULL )
5008 return aResult._retn();
5010 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5012 return aResult._retn();
5014 if(elem->GetType()==SMDSAbs_Volume) {
5015 SMDS_VolumeTool aTool;
5016 if(aTool.Set(elem)) {
5018 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5023 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5025 double x=0., y=0., z=0.;
5026 for(; anIt->more(); ) {
5028 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5042 return aResult._retn();
5045 //================================================================================
5047 * \brief Create a group of elements preventing computation of a sub-shape
5049 //================================================================================
5051 SMESH::ListOfGroups*
5052 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5053 const char* theGroupName )
5054 throw ( SALOME::SALOME_Exception )
5056 Unexpect aCatch(SALOME_SalomeException);
5058 if ( !theGroupName || strlen( theGroupName) == 0 )
5059 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5061 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5062 ::SMESH_MeshEditor::ElemFeatures elemType;
5064 // submesh by subshape id
5065 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5066 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5069 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5070 if ( error && error->HasBadElems() )
5072 // sort bad elements by type
5073 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5074 const list<const SMDS_MeshElement*>& badElems =
5075 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5076 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5077 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5078 for ( ; elemIt != elemEnd; ++elemIt )
5080 const SMDS_MeshElement* elem = *elemIt;
5081 if ( !elem ) continue;
5083 if ( elem->GetID() < 1 )
5085 // elem is a temporary element, make a real element
5086 vector< const SMDS_MeshNode* > nodes;
5087 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5088 while ( nIt->more() && elem )
5090 nodes.push_back( nIt->next() );
5091 if ( nodes.back()->GetID() < 1 )
5092 elem = 0; // a temporary element on temporary nodes
5096 ::SMESH_MeshEditor editor( _impl );
5097 elem = editor.AddElement( nodes, elemType.Init( elem ));
5101 elemsByType[ elem->GetType() ].push_back( elem );
5104 // how many groups to create?
5106 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5107 nbTypes += int( !elemsByType[ i ].empty() );
5108 groups->length( nbTypes );
5111 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5113 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5114 if ( elems.empty() ) continue;
5116 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5117 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5119 SMESH::SMESH_Mesh_var mesh = _this();
5120 SALOMEDS::SObject_wrap aSO =
5121 _gen_i->PublishGroup( mesh, groups[ iG ],
5122 GEOM::GEOM_Object::_nil(), theGroupName);
5124 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5125 if ( !grp_i ) continue;
5127 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5128 for ( size_t iE = 0; iE < elems.size(); ++iE )
5129 grpDS->SMDSGroup().Add( elems[ iE ]);
5134 return groups._retn();
5137 //=============================================================================
5139 * Create and publish group servants if any groups were imported or created anyhow
5141 //=============================================================================
5143 void SMESH_Mesh_i::CreateGroupServants()
5145 SMESH::SMESH_Mesh_var aMesh = _this();
5148 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5149 while ( groupIt->more() )
5151 ::SMESH_Group* group = groupIt->next();
5152 int anId = group->GetGroupDS()->GetID();
5154 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5155 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5157 addedIDs.insert( anId );
5159 SMESH_GroupBase_i* aGroupImpl;
5161 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5162 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5164 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5165 shape = groupOnGeom->GetShape();
5168 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5171 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5172 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5173 aGroupImpl->Register();
5175 // register CORBA object for persistence
5176 int nextId = _gen_i->RegisterObject( groupVar );
5177 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5178 else { nextId = 0; } // avoid "unused variable" warning in release mode
5180 // publishing the groups in the study
5181 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5182 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5184 if ( !addedIDs.empty() )
5187 set<int>::iterator id = addedIDs.begin();
5188 for ( ; id != addedIDs.end(); ++id )
5190 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5191 int i = std::distance( _mapGroups.begin(), it );
5192 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5197 //=============================================================================
5199 * \brief Return true if all sub-meshes are computed OK - to update an icon
5201 //=============================================================================
5203 bool SMESH_Mesh_i::IsComputedOK()
5205 return _impl->IsComputedOK();
5208 //=============================================================================
5210 * \brief Return groups cantained in _mapGroups by their IDs
5212 //=============================================================================
5214 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5216 int nbGroups = groupIDs.size();
5217 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5218 aList->length( nbGroups );
5220 list<int>::const_iterator ids = groupIDs.begin();
5221 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5223 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5224 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5225 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5227 aList->length( nbGroups );
5228 return aList._retn();
5231 //=============================================================================
5233 * \brief Return information about imported file
5235 //=============================================================================
5237 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5239 SMESH::MedFileInfo_var res( _medFileInfo );
5240 if ( !res.operator->() ) {
5241 res = new SMESH::MedFileInfo;
5243 res->fileSize = res->major = res->minor = res->release = -1;
5248 //=======================================================================
5249 //function : FileInfoToString
5250 //purpose : Persistence of file info
5251 //=======================================================================
5253 std::string SMESH_Mesh_i::FileInfoToString()
5256 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5258 s = SMESH_Comment( _medFileInfo->fileSize )
5259 << " " << _medFileInfo->major
5260 << " " << _medFileInfo->minor
5261 << " " << _medFileInfo->release
5262 << " " << _medFileInfo->fileName;
5267 //=======================================================================
5268 //function : FileInfoFromString
5269 //purpose : Persistence of file info
5270 //=======================================================================
5272 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5274 std::string size, major, minor, release, fileName;
5275 std::istringstream is(info);
5276 is >> size >> major >> minor >> release;
5277 fileName = info.data() + ( size.size() + 1 +
5280 release.size()+ 1 );
5282 _medFileInfo = new SMESH::MedFileInfo();
5283 _medFileInfo->fileName = fileName.c_str();
5284 _medFileInfo->fileSize = atoi( size.c_str() );
5285 _medFileInfo->major = atoi( major.c_str() );
5286 _medFileInfo->minor = atoi( minor.c_str() );
5287 _medFileInfo->release = atoi( release.c_str() );
5290 //=============================================================================
5292 * \brief Pass names of mesh groups from study to mesh DS
5294 //=============================================================================
5296 void SMESH_Mesh_i::checkGroupNames()
5298 int nbGrp = NbGroups();
5302 SMESH::ListOfGroups* grpList = 0;
5303 // avoid dump of "GetGroups"
5305 // store python dump into a local variable inside local scope
5306 SMESH::TPythonDump pDump; // do not delete this line of code
5307 grpList = GetGroups();
5310 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5311 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5314 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5315 if ( aGrpSO->_is_nil() )
5317 // correct name of the mesh group if necessary
5318 const char* guiName = aGrpSO->GetName();
5319 if ( strcmp(guiName, aGrp->GetName()) )
5320 aGrp->SetName( guiName );
5324 //=============================================================================
5326 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5328 //=============================================================================
5329 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5331 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5335 //=============================================================================
5337 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5339 //=============================================================================
5341 char* SMESH_Mesh_i::GetParameters()
5343 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5346 //=============================================================================
5348 * \brief Returns list of notebook variables used for last Mesh operation
5350 //=============================================================================
5351 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5353 SMESH::string_array_var aResult = new SMESH::string_array();
5354 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5356 CORBA::String_var aParameters = GetParameters();
5357 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5358 if ( aSections->length() > 0 ) {
5359 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5360 aResult->length( aVars.length() );
5361 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5362 aResult[i] = CORBA::string_dup( aVars[i] );
5365 return aResult._retn();
5368 //=======================================================================
5369 //function : GetTypes
5370 //purpose : Returns types of elements it contains
5371 //=======================================================================
5373 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5376 return _preMeshInfo->GetTypes();
5378 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5382 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5383 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5384 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5385 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5386 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5387 if (_impl->NbNodes() &&
5388 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5389 types->length( nbTypes );
5391 return types._retn();
5394 //=======================================================================
5395 //function : GetMesh
5396 //purpose : Returns self
5397 //=======================================================================
5399 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5401 return SMESH::SMESH_Mesh::_duplicate( _this() );
5404 //=======================================================================
5405 //function : IsMeshInfoCorrect
5406 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5407 // * happen if mesh data is not yet fully loaded from the file of study.
5408 //=======================================================================
5410 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5412 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5415 //=============================================================================
5417 * \brief Returns number of mesh elements per each \a EntityType
5419 //=============================================================================
5421 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5424 return _preMeshInfo->GetMeshInfo();
5426 SMESH::long_array_var aRes = new SMESH::long_array();
5427 aRes->length(SMESH::Entity_Last);
5428 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5430 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5432 return aRes._retn();
5433 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5434 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5435 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5436 return aRes._retn();
5439 //=============================================================================
5441 * \brief Returns number of mesh elements per each \a ElementType
5443 //=============================================================================
5445 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5447 SMESH::long_array_var aRes = new SMESH::long_array();
5448 aRes->length(SMESH::NB_ELEMENT_TYPES);
5449 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5452 const SMDS_MeshInfo* meshInfo = 0;
5454 meshInfo = _preMeshInfo;
5455 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5456 meshInfo = & meshDS->GetMeshInfo();
5459 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5460 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5462 return aRes._retn();
5465 //=============================================================================
5467 * Collect statistic of mesh elements given by iterator
5469 //=============================================================================
5471 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5472 SMESH::long_array& theInfo)
5474 if (!theItr) return;
5475 while (theItr->more())
5476 theInfo[ theItr->next()->GetEntityType() ]++;
5478 //=============================================================================
5480 * Returns mesh unstructed grid information.
5482 //=============================================================================
5484 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5486 SALOMEDS::TMPFile_var SeqFile;
5487 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5488 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5490 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5491 aWriter->WriteToOutputStringOn();
5492 aWriter->SetInputData(aGrid);
5493 aWriter->SetFileTypeToBinary();
5495 char* str = aWriter->GetOutputString();
5496 int size = aWriter->GetOutputStringLength();
5498 //Allocate octet buffer of required size
5499 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5500 //Copy ostrstream content to the octet buffer
5501 memcpy(OctetBuf, str, size);
5502 //Create and return TMPFile
5503 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5507 return SeqFile._retn();
5510 //=============================================================================
5511 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5512 * SMESH::ElementType type) */
5514 using namespace SMESH::Controls;
5515 //-----------------------------------------------------------------------------
5516 struct PredicateIterator : public SMDS_ElemIterator
5518 SMDS_ElemIteratorPtr _elemIter;
5519 PredicatePtr _predicate;
5520 const SMDS_MeshElement* _elem;
5521 SMDSAbs_ElementType _type;
5523 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5524 PredicatePtr predicate,
5525 SMDSAbs_ElementType type):
5526 _elemIter(iterator), _predicate(predicate), _type(type)
5534 virtual const SMDS_MeshElement* next()
5536 const SMDS_MeshElement* res = _elem;
5538 while ( _elemIter->more() && !_elem )
5540 if ((_elem = _elemIter->next()) &&
5541 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5542 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5549 //-----------------------------------------------------------------------------
5550 struct IDSourceIterator : public SMDS_ElemIterator
5552 const CORBA::Long* _idPtr;
5553 const CORBA::Long* _idEndPtr;
5554 SMESH::long_array_var _idArray;
5555 const SMDS_Mesh* _mesh;
5556 const SMDSAbs_ElementType _type;
5557 const SMDS_MeshElement* _elem;
5559 IDSourceIterator( const SMDS_Mesh* mesh,
5560 const CORBA::Long* ids,
5562 SMDSAbs_ElementType type):
5563 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5565 if ( _idPtr && nbIds && _mesh )
5568 IDSourceIterator( const SMDS_Mesh* mesh,
5569 SMESH::long_array* idArray,
5570 SMDSAbs_ElementType type):
5571 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5573 if ( idArray && _mesh )
5575 _idPtr = &_idArray[0];
5576 _idEndPtr = _idPtr + _idArray->length();
5584 virtual const SMDS_MeshElement* next()
5586 const SMDS_MeshElement* res = _elem;
5588 while ( _idPtr < _idEndPtr && !_elem )
5590 if ( _type == SMDSAbs_Node )
5592 _elem = _mesh->FindNode( *_idPtr++ );
5594 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5595 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5603 //-----------------------------------------------------------------------------
5605 struct NodeOfElemIterator : public SMDS_ElemIterator
5607 TColStd_MapOfInteger _checkedNodeIDs;
5608 SMDS_ElemIteratorPtr _elemIter;
5609 SMDS_ElemIteratorPtr _nodeIter;
5610 const SMDS_MeshElement* _node;
5612 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5614 if ( _elemIter && _elemIter->more() )
5616 _nodeIter = _elemIter->next()->nodesIterator();
5624 virtual const SMDS_MeshElement* next()
5626 const SMDS_MeshElement* res = _node;
5628 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5630 if ( _nodeIter->more() )
5632 _node = _nodeIter->next();
5633 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5638 _nodeIter = _elemIter->next()->nodesIterator();
5646 //=============================================================================
5648 * Return iterator on elements of given type in given object
5650 //=============================================================================
5652 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5653 SMESH::ElementType theType)
5655 SMDS_ElemIteratorPtr elemIt;
5656 bool typeOK = ( theType == SMESH::ALL );
5657 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5659 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5660 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5661 if ( !mesh_i ) return elemIt;
5662 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5664 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5666 elemIt = meshDS->elementsIterator( elemType );
5669 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5671 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5674 elemIt = sm->GetElements();
5675 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5677 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5678 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5682 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5684 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5685 if ( groupDS && ( elemType == groupDS->GetType() ||
5686 elemType == SMDSAbs_Node ||
5687 elemType == SMDSAbs_All ))
5689 elemIt = groupDS->GetElements();
5690 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5693 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5695 if ( filter_i->GetElementType() == theType ||
5696 filter_i->GetElementType() == SMESH::ALL ||
5697 elemType == SMDSAbs_Node ||
5698 elemType == SMDSAbs_All)
5700 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5701 if ( pred_i && pred_i->GetPredicate() )
5703 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5704 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5705 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
5706 elemIt = SMDS_ElemIteratorPtr
5707 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
5708 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
5714 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5715 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5716 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5718 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
5719 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5722 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5723 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
5727 SMESH::long_array_var ids = theObject->GetIDs();
5728 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
5730 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5733 if ( elemIt && elemIt->more() && !typeOK )
5735 if ( elemType == SMDSAbs_Node )
5737 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5741 elemIt = SMDS_ElemIteratorPtr();
5747 //=============================================================================
5748 namespace // Finding concurrent hypotheses
5749 //=============================================================================
5753 * \brief mapping of mesh dimension into shape type
5755 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5757 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5759 case 0: aType = TopAbs_VERTEX; break;
5760 case 1: aType = TopAbs_EDGE; break;
5761 case 2: aType = TopAbs_FACE; break;
5763 default:aType = TopAbs_SOLID; break;
5768 //-----------------------------------------------------------------------------
5770 * \brief Internal structure used to find concurrent submeshes
5772 * It represents a pair < submesh, concurrent dimension >, where
5773 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5774 * with another submesh. In other words, it is dimension of a hypothesis assigned
5781 int _dim; //!< a dimension the algo can build (concurrent dimension)
5782 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5783 TopTools_MapOfShape _shapeMap;
5784 SMESH_subMesh* _subMesh;
5785 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5787 //-----------------------------------------------------------------------------
5788 // Return the algorithm
5789 const SMESH_Algo* GetAlgo() const
5790 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5792 //-----------------------------------------------------------------------------
5794 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5796 const TopoDS_Shape& theShape)
5798 _subMesh = (SMESH_subMesh*)theSubMesh;
5799 SetShape( theDim, theShape );
5802 //-----------------------------------------------------------------------------
5804 void SetShape(const int theDim,
5805 const TopoDS_Shape& theShape)
5808 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5809 if (_dim >= _ownDim)
5810 _shapeMap.Add( theShape );
5812 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5813 for( ; anExp.More(); anExp.Next() )
5814 _shapeMap.Add( anExp.Current() );
5818 //-----------------------------------------------------------------------------
5819 //! Check sharing of sub-shapes
5820 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5821 const TopTools_MapOfShape& theToFind,
5822 const TopAbs_ShapeEnum theType)
5824 bool isShared = false;
5825 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5826 for (; !isShared && anItr.More(); anItr.Next() )
5828 const TopoDS_Shape aSubSh = anItr.Key();
5829 // check for case when concurrent dimensions are same
5830 isShared = theToFind.Contains( aSubSh );
5831 // check for sub-shape with concurrent dimension
5832 TopExp_Explorer anExp( aSubSh, theType );
5833 for ( ; !isShared && anExp.More(); anExp.Next() )
5834 isShared = theToFind.Contains( anExp.Current() );
5839 //-----------------------------------------------------------------------------
5840 //! check algorithms
5841 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5842 const SMESHDS_Hypothesis* theA2)
5844 if ( !theA1 || !theA2 ||
5845 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5846 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5847 return false; // one of the hypothesis is not algorithm
5848 // check algorithm names (should be equal)
5849 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5853 //-----------------------------------------------------------------------------
5854 //! Check if sub-shape hypotheses are concurrent
5855 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5857 if ( _subMesh == theOther->_subMesh )
5858 return false; // same sub-shape - should not be
5860 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5861 // any of the two submeshes is not on COMPOUND shape )
5862 // -> no concurrency
5863 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5864 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5865 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5866 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5867 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5870 // bool checkSubShape = ( _dim >= theOther->_dim )
5871 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5872 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5873 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5874 if ( !checkSubShape )
5877 // check algorithms to be same
5878 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5879 return true; // different algorithms -> concurrency !
5881 // check hypothesises for concurrence (skip first as algorithm)
5883 // pointers should be same, because it is referened from mesh hypothesis partition
5884 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5885 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5886 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5887 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5889 // the submeshes are concurrent if their algorithms has different parameters
5890 return nbSame != (int)theOther->_hypotheses.size() - 1;
5893 // Return true if algorithm of this SMESH_DimHyp is used if no
5894 // sub-mesh order is imposed by the user
5895 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5897 // NeedDiscreteBoundary() algo has a higher priority
5898 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5899 theOther->GetAlgo()->NeedDiscreteBoundary() )
5900 return !this->GetAlgo()->NeedDiscreteBoundary();
5902 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5905 }; // end of SMESH_DimHyp
5906 //-----------------------------------------------------------------------------
5908 typedef list<const SMESH_DimHyp*> TDimHypList;
5910 //-----------------------------------------------------------------------------
5912 void addDimHypInstance(const int theDim,
5913 const TopoDS_Shape& theShape,
5914 const SMESH_Algo* theAlgo,
5915 const SMESH_subMesh* theSubMesh,
5916 const list <const SMESHDS_Hypothesis*>& theHypList,
5917 TDimHypList* theDimHypListArr )
5919 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5920 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5921 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5922 dimHyp->_hypotheses.push_front(theAlgo);
5923 listOfdimHyp.push_back( dimHyp );
5926 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5927 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5928 theHypList.begin(), theHypList.end() );
5931 //-----------------------------------------------------------------------------
5932 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5933 TDimHypList& theListOfConcurr)
5935 if ( theListOfConcurr.empty() )
5937 theListOfConcurr.push_back( theDimHyp );
5941 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5942 while ( hypIt != theListOfConcurr.end() &&
5943 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5945 theListOfConcurr.insert( hypIt, theDimHyp );
5949 //-----------------------------------------------------------------------------
5950 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5951 const TDimHypList& theListOfDimHyp,
5952 TDimHypList& theListOfConcurrHyp,
5953 set<int>& theSetOfConcurrId )
5955 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5956 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5958 const SMESH_DimHyp* curDimHyp = *rIt;
5959 if ( curDimHyp == theDimHyp )
5960 break; // meet own dimHyp pointer in same dimension
5962 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5963 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5965 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5970 //-----------------------------------------------------------------------------
5971 void unionLists(TListOfInt& theListOfId,
5972 TListOfListOfInt& theListOfListOfId,
5975 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5976 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5978 continue; //skip already treated lists
5979 // check if other list has any same submesh object
5980 TListOfInt& otherListOfId = *it;
5981 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5982 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5985 // union two lists (from source into target)
5986 TListOfInt::iterator it2 = otherListOfId.begin();
5987 for ( ; it2 != otherListOfId.end(); it2++ ) {
5988 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5989 theListOfId.push_back(*it2);
5991 // clear source list
5992 otherListOfId.clear();
5995 //-----------------------------------------------------------------------------
5997 //! free memory allocated for dimension-hypothesis objects
5998 void removeDimHyps( TDimHypList* theArrOfList )
6000 for (int i = 0; i < 4; i++ ) {
6001 TDimHypList& listOfdimHyp = theArrOfList[i];
6002 TDimHypList::const_iterator it = listOfdimHyp.begin();
6003 for ( ; it != listOfdimHyp.end(); it++ )
6008 //-----------------------------------------------------------------------------
6010 * \brief find common submeshes with given submesh
6011 * \param theSubMeshList list of already collected submesh to check
6012 * \param theSubMesh given submesh to intersect with other
6013 * \param theCommonSubMeshes collected common submeshes
6015 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6016 const SMESH_subMesh* theSubMesh,
6017 set<const SMESH_subMesh*>& theCommon )
6021 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6022 for ( ; it != theSubMeshList.end(); it++ )
6023 theSubMesh->FindIntersection( *it, theCommon );
6024 theSubMeshList.push_back( theSubMesh );
6025 //theCommon.insert( theSubMesh );
6028 //-----------------------------------------------------------------------------
6029 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6031 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6032 for ( ; listsIt != smLists.end(); ++listsIt )
6034 const TListOfInt& smIDs = *listsIt;
6035 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6043 //=============================================================================
6045 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6047 //=============================================================================
6049 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6051 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6052 if ( isSubMeshInList( submeshID, anOrder ))
6055 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6056 return isSubMeshInList( submeshID, allConurrent );
6059 //=============================================================================
6061 * \brief Return submesh objects list in meshing order
6063 //=============================================================================
6065 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6067 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6069 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6071 return aResult._retn();
6073 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6074 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6075 anOrder.splice( anOrder.end(), allConurrent );
6078 TListOfListOfInt::iterator listIt = anOrder.begin();
6079 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6080 unionLists( *listIt, anOrder, listIndx + 1 );
6082 // convert submesh ids into interface instances
6083 // and dump command into python
6084 convertMeshOrder( anOrder, aResult, false );
6086 return aResult._retn();
6089 //=============================================================================
6091 * \brief Finds concurrent sub-meshes
6093 //=============================================================================
6095 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6097 TListOfListOfInt anOrder;
6098 ::SMESH_Mesh& mesh = GetImpl();
6100 // collect submeshes and detect concurrent algorithms and hypothesises
6101 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6103 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6104 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6105 ::SMESH_subMesh* sm = (*i_sm).second;
6107 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6109 // list of assigned hypothesises
6110 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6111 // Find out dimensions where the submesh can be concurrent.
6112 // We define the dimensions by algo of each of hypotheses in hypList
6113 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6114 for( ; hypIt != hypList.end(); hypIt++ ) {
6115 SMESH_Algo* anAlgo = 0;
6116 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6117 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6118 // hyp it-self is algo
6119 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6121 // try to find algorithm with help of sub-shapes
6122 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6123 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6124 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6127 continue; // no algorithm assigned to a current submesh
6129 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6130 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6132 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6133 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6134 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6136 } // end iterations on submesh
6138 // iterate on created dimension-hypotheses and check for concurrents
6139 for ( int i = 0; i < 4; i++ ) {
6140 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6141 // check for concurrents in own and other dimensions (step-by-step)
6142 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6143 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6144 const SMESH_DimHyp* dimHyp = *dhIt;
6145 TDimHypList listOfConcurr;
6146 set<int> setOfConcurrIds;
6147 // looking for concurrents and collect into own list
6148 for ( int j = i; j < 4; j++ )
6149 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6150 // check if any concurrents found
6151 if ( listOfConcurr.size() > 0 ) {
6152 // add own submesh to list of concurrent
6153 addInOrderOfPriority( dimHyp, listOfConcurr );
6154 list<int> listOfConcurrIds;
6155 TDimHypList::iterator hypIt = listOfConcurr.begin();
6156 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6157 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6158 anOrder.push_back( listOfConcurrIds );
6163 removeDimHyps(dimHypListArr);
6165 // now, minimize the number of concurrent groups
6166 // Here we assume that lists of submeshes can have same submesh
6167 // in case of multi-dimension algorithms, as result
6168 // list with common submesh has to be united into one list
6170 TListOfListOfInt::iterator listIt = anOrder.begin();
6171 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6172 unionLists( *listIt, anOrder, listIndx + 1 );
6178 //=============================================================================
6180 * \brief Set submesh object order
6181 * \param theSubMeshArray submesh array order
6183 //=============================================================================
6185 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6188 _preMeshInfo->ForgetOrLoad();
6191 ::SMESH_Mesh& mesh = GetImpl();
6193 TPythonDump aPythonDump; // prevent dump of called methods
6194 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6196 TListOfListOfInt subMeshOrder;
6197 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6199 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6200 TListOfInt subMeshIds;
6202 aPythonDump << ", ";
6203 aPythonDump << "[ ";
6204 // Collect subMeshes which should be clear
6205 // do it list-by-list, because modification of submesh order
6206 // take effect between concurrent submeshes only
6207 set<const SMESH_subMesh*> subMeshToClear;
6208 list<const SMESH_subMesh*> subMeshList;
6209 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6211 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6213 aPythonDump << ", ";
6214 aPythonDump << subMesh;
6215 subMeshIds.push_back( subMesh->GetId() );
6216 // detect common parts of submeshes
6217 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6218 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6220 aPythonDump << " ]";
6221 subMeshOrder.push_back( subMeshIds );
6223 // clear collected submeshes
6224 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6225 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6226 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6227 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6229 aPythonDump << " ])";
6231 mesh.SetMeshOrder( subMeshOrder );
6234 SMESH::SMESH_Mesh_var me = _this();
6235 _gen_i->UpdateIcons( me );
6240 //=============================================================================
6242 * \brief Convert submesh ids into submesh interfaces
6244 //=============================================================================
6246 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6247 SMESH::submesh_array_array& theResOrder,
6248 const bool theIsDump)
6250 int nbSet = theIdsOrder.size();
6251 TPythonDump aPythonDump; // prevent dump of called methods
6253 aPythonDump << "[ ";
6254 theResOrder.length(nbSet);
6255 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6257 for( ; it != theIdsOrder.end(); it++ ) {
6258 // translate submesh identificators into submesh objects
6259 // takeing into account real number of concurrent lists
6260 const TListOfInt& aSubOrder = (*it);
6261 if (!aSubOrder.size())
6264 aPythonDump << "[ ";
6265 // convert shape indices into interfaces
6266 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6267 aResSubSet->length(aSubOrder.size());
6268 TListOfInt::const_iterator subIt = aSubOrder.begin();
6270 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6271 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6273 SMESH::SMESH_subMesh_var subMesh =
6274 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6277 aPythonDump << ", ";
6278 aPythonDump << subMesh;
6280 aResSubSet[ j++ ] = subMesh;
6283 aPythonDump << " ]";
6285 theResOrder[ listIndx++ ] = aResSubSet;
6287 // correct number of lists
6288 theResOrder.length( listIndx );
6291 // finilise python dump
6292 aPythonDump << " ]";
6293 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6297 namespace // utils used by SMESH_MeshPartDS
6300 * \brief Class used to access to protected data of SMDS_MeshInfo
6302 struct TMeshInfo : public SMDS_MeshInfo
6304 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6307 * \brief Element holing its ID only
6309 struct TElemID : public SMDS_LinearEdge
6311 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6315 //================================================================================
6317 // Implementation of SMESH_MeshPartDS
6319 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6320 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6322 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6323 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6326 _meshDS = mesh_i->GetImpl().GetMeshDS();
6328 SetPersistentId( _meshDS->GetPersistentId() );
6330 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6332 // <meshPart> is the whole mesh
6333 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6335 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6336 myGroupSet = _meshDS->GetGroups();
6341 SMESH::long_array_var anIDs = meshPart->GetIDs();
6342 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6343 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6345 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6346 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6347 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6352 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6353 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6354 if ( _elements[ e->GetType() ].insert( e ).second )
6357 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6358 while ( nIt->more() )
6360 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6361 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6368 ShapeToMesh( _meshDS->ShapeToMesh() );
6370 _meshDS = 0; // to enforce iteration on _elements and _nodes
6373 // -------------------------------------------------------------------------------------
6374 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6375 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6378 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6379 for ( ; partIt != meshPart.end(); ++partIt )
6380 if ( const SMDS_MeshElement * e = *partIt )
6381 if ( _elements[ e->GetType() ].insert( e ).second )
6384 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6385 while ( nIt->more() )
6387 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6388 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6394 // -------------------------------------------------------------------------------------
6395 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6397 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6399 TElemID elem( IDelem );
6400 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6401 if ( !_elements[ iType ].empty() )
6403 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6404 if ( it != _elements[ iType ].end() )
6409 // -------------------------------------------------------------------------------------
6410 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6412 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6414 typedef SMDS_SetIterator
6415 <const SMDS_MeshElement*,
6416 TIDSortedElemSet::const_iterator,
6417 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6418 SMDS_MeshElement::GeomFilter
6421 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6423 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6424 _elements[type].end(),
6425 SMDS_MeshElement::GeomFilter( geomType )));
6427 // -------------------------------------------------------------------------------------
6428 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6430 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6432 typedef SMDS_SetIterator
6433 <const SMDS_MeshElement*,
6434 TIDSortedElemSet::const_iterator,
6435 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6436 SMDS_MeshElement::EntityFilter
6439 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6441 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6442 _elements[type].end(),
6443 SMDS_MeshElement::EntityFilter( entity )));
6445 // -------------------------------------------------------------------------------------
6446 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6448 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6449 if ( type == SMDSAbs_All && !_meshDS )
6451 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6453 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6454 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6456 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6458 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6459 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6461 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6462 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6464 // -------------------------------------------------------------------------------------
6465 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6466 iterType SMESH_MeshPartDS::methName() const \
6468 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6469 return _meshDS ? _meshDS->methName() : iterType \
6470 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6472 // -------------------------------------------------------------------------------------
6473 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6474 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6475 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6476 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6477 #undef _GET_ITER_DEFINE
6479 // END Implementation of SMESH_MeshPartDS
6481 //================================================================================