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 ( int i = 0; i < elem->NbNodes(); ++i )
4724 aResult[ i ] = elem->GetNode( i )->GetID();
4727 return aResult._retn();
4730 //=============================================================================
4732 * Returns true if given node is medium node
4733 * in given quadratic element
4735 //=============================================================================
4737 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4740 _preMeshInfo->FullLoadFromFile();
4742 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4743 if ( aMeshDS == NULL ) return false;
4745 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4746 if(!aNode) return false;
4747 // try to find element
4748 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4749 if(!elem) return false;
4751 return elem->IsMediumNode(aNode);
4755 //=============================================================================
4757 * Returns true if given node is medium node
4758 * in one of quadratic elements
4760 //=============================================================================
4762 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4763 SMESH::ElementType theElemType)
4766 _preMeshInfo->FullLoadFromFile();
4768 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4769 if ( aMeshDS == NULL ) return false;
4772 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4773 if(!aNode) return false;
4775 SMESH_MesherHelper aHelper( *(_impl) );
4777 SMDSAbs_ElementType aType;
4778 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4779 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4780 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4781 else aType = SMDSAbs_All;
4783 return aHelper.IsMedium(aNode,aType);
4787 //=============================================================================
4789 * Returns number of edges for given element
4791 //=============================================================================
4793 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4796 _preMeshInfo->FullLoadFromFile();
4798 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4799 if ( aMeshDS == NULL ) return -1;
4800 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4801 if(!elem) return -1;
4802 return elem->NbEdges();
4806 //=============================================================================
4808 * Returns number of faces for given element
4810 //=============================================================================
4812 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4815 _preMeshInfo->FullLoadFromFile();
4817 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4818 if ( aMeshDS == NULL ) return -1;
4819 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4820 if(!elem) return -1;
4821 return elem->NbFaces();
4824 //=======================================================================
4825 //function : GetElemFaceNodes
4826 //purpose : Returns nodes of given face (counted from zero) for given element.
4827 //=======================================================================
4829 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4830 CORBA::Short faceIndex)
4833 _preMeshInfo->FullLoadFromFile();
4835 SMESH::long_array_var aResult = new SMESH::long_array();
4836 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4838 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4840 SMDS_VolumeTool vtool( elem );
4841 if ( faceIndex < vtool.NbFaces() )
4843 aResult->length( vtool.NbFaceNodes( faceIndex ));
4844 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4845 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4846 aResult[ i ] = nn[ i ]->GetID();
4850 return aResult._retn();
4853 //=======================================================================
4854 //function : GetElemFaceNodes
4855 //purpose : Returns three components of normal of given mesh face.
4856 //=======================================================================
4858 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4859 CORBA::Boolean normalized)
4862 _preMeshInfo->FullLoadFromFile();
4864 SMESH::double_array_var aResult = new SMESH::double_array();
4866 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4869 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4871 aResult->length( 3 );
4872 aResult[ 0 ] = normal.X();
4873 aResult[ 1 ] = normal.Y();
4874 aResult[ 2 ] = normal.Z();
4877 return aResult._retn();
4880 //=======================================================================
4881 //function : FindElementByNodes
4882 //purpose : Returns an element based on all given nodes.
4883 //=======================================================================
4885 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4888 _preMeshInfo->FullLoadFromFile();
4890 CORBA::Long elemID(0);
4891 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4893 vector< const SMDS_MeshNode * > nn( nodes.length() );
4894 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4895 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4898 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4899 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4900 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4901 _impl->NbVolumes( ORDER_QUADRATIC )))
4902 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4904 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4909 //================================================================================
4911 * \brief Return elements including all given nodes.
4913 //================================================================================
4915 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4916 SMESH::ElementType elemType)
4919 _preMeshInfo->FullLoadFromFile();
4921 SMESH::long_array_var result = new SMESH::long_array();
4923 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4925 vector< const SMDS_MeshNode * > nn( nodes.length() );
4926 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4927 nn[i] = mesh->FindNode( nodes[i] );
4929 std::vector<const SMDS_MeshElement *> elems;
4930 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4931 result->length( elems.size() );
4932 for ( size_t i = 0; i < elems.size(); ++i )
4933 result[i] = elems[i]->GetID();
4935 return result._retn();
4938 //=============================================================================
4940 * Returns true if given element is polygon
4942 //=============================================================================
4944 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4947 _preMeshInfo->FullLoadFromFile();
4949 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4950 if ( aMeshDS == NULL ) return false;
4951 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4952 if(!elem) return false;
4953 return elem->IsPoly();
4957 //=============================================================================
4959 * Returns true if given element is quadratic
4961 //=============================================================================
4963 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4966 _preMeshInfo->FullLoadFromFile();
4968 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4969 if ( aMeshDS == NULL ) return false;
4970 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4971 if(!elem) return false;
4972 return elem->IsQuadratic();
4975 //=============================================================================
4977 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4979 //=============================================================================
4981 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4984 _preMeshInfo->FullLoadFromFile();
4986 if ( const SMDS_BallElement* ball =
4987 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4988 return ball->GetDiameter();
4993 //=============================================================================
4995 * Returns bary center for given element
4997 //=============================================================================
4999 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5002 _preMeshInfo->FullLoadFromFile();
5004 SMESH::double_array_var aResult = new SMESH::double_array();
5005 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5006 if ( aMeshDS == NULL )
5007 return aResult._retn();
5009 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5011 return aResult._retn();
5013 if(elem->GetType()==SMDSAbs_Volume) {
5014 SMDS_VolumeTool aTool;
5015 if(aTool.Set(elem)) {
5017 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5022 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5024 double x=0., y=0., z=0.;
5025 for(; anIt->more(); ) {
5027 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5041 return aResult._retn();
5044 //================================================================================
5046 * \brief Create a group of elements preventing computation of a sub-shape
5048 //================================================================================
5050 SMESH::ListOfGroups*
5051 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5052 const char* theGroupName )
5053 throw ( SALOME::SALOME_Exception )
5055 Unexpect aCatch(SALOME_SalomeException);
5057 if ( !theGroupName || strlen( theGroupName) == 0 )
5058 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5060 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5061 ::SMESH_MeshEditor::ElemFeatures elemType;
5063 // submesh by subshape id
5064 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5065 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5068 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5069 if ( error && error->HasBadElems() )
5071 // sort bad elements by type
5072 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5073 const list<const SMDS_MeshElement*>& badElems =
5074 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5075 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5076 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5077 for ( ; elemIt != elemEnd; ++elemIt )
5079 const SMDS_MeshElement* elem = *elemIt;
5080 if ( !elem ) continue;
5082 if ( elem->GetID() < 1 )
5084 // elem is a temporary element, make a real element
5085 vector< const SMDS_MeshNode* > nodes;
5086 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5087 while ( nIt->more() && elem )
5089 nodes.push_back( nIt->next() );
5090 if ( nodes.back()->GetID() < 1 )
5091 elem = 0; // a temporary element on temporary nodes
5095 ::SMESH_MeshEditor editor( _impl );
5096 elem = editor.AddElement( nodes, elemType.Init( elem ));
5100 elemsByType[ elem->GetType() ].push_back( elem );
5103 // how many groups to create?
5105 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5106 nbTypes += int( !elemsByType[ i ].empty() );
5107 groups->length( nbTypes );
5110 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5112 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5113 if ( elems.empty() ) continue;
5115 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5116 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5118 SMESH::SMESH_Mesh_var mesh = _this();
5119 SALOMEDS::SObject_wrap aSO =
5120 _gen_i->PublishGroup( mesh, groups[ iG ],
5121 GEOM::GEOM_Object::_nil(), theGroupName);
5123 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5124 if ( !grp_i ) continue;
5126 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5127 for ( size_t iE = 0; iE < elems.size(); ++iE )
5128 grpDS->SMDSGroup().Add( elems[ iE ]);
5133 return groups._retn();
5136 //=============================================================================
5138 * Create and publish group servants if any groups were imported or created anyhow
5140 //=============================================================================
5142 void SMESH_Mesh_i::CreateGroupServants()
5144 SMESH::SMESH_Mesh_var aMesh = _this();
5147 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5148 while ( groupIt->more() )
5150 ::SMESH_Group* group = groupIt->next();
5151 int anId = group->GetGroupDS()->GetID();
5153 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5154 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5156 addedIDs.insert( anId );
5158 SMESH_GroupBase_i* aGroupImpl;
5160 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5161 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5163 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5164 shape = groupOnGeom->GetShape();
5167 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5170 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5171 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5172 aGroupImpl->Register();
5174 // register CORBA object for persistence
5175 int nextId = _gen_i->RegisterObject( groupVar );
5176 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5177 else { nextId = 0; } // avoid "unused variable" warning in release mode
5179 // publishing the groups in the study
5180 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5181 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5183 if ( !addedIDs.empty() )
5186 set<int>::iterator id = addedIDs.begin();
5187 for ( ; id != addedIDs.end(); ++id )
5189 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5190 int i = std::distance( _mapGroups.begin(), it );
5191 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5196 //=============================================================================
5198 * \brief Return true if all sub-meshes are computed OK - to update an icon
5200 //=============================================================================
5202 bool SMESH_Mesh_i::IsComputedOK()
5204 return _impl->IsComputedOK();
5207 //=============================================================================
5209 * \brief Return groups cantained in _mapGroups by their IDs
5211 //=============================================================================
5213 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5215 int nbGroups = groupIDs.size();
5216 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5217 aList->length( nbGroups );
5219 list<int>::const_iterator ids = groupIDs.begin();
5220 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5222 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5223 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5224 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5226 aList->length( nbGroups );
5227 return aList._retn();
5230 //=============================================================================
5232 * \brief Return information about imported file
5234 //=============================================================================
5236 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5238 SMESH::MedFileInfo_var res( _medFileInfo );
5239 if ( !res.operator->() ) {
5240 res = new SMESH::MedFileInfo;
5242 res->fileSize = res->major = res->minor = res->release = -1;
5247 //=======================================================================
5248 //function : FileInfoToString
5249 //purpose : Persistence of file info
5250 //=======================================================================
5252 std::string SMESH_Mesh_i::FileInfoToString()
5255 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5257 s = SMESH_Comment( _medFileInfo->fileSize )
5258 << " " << _medFileInfo->major
5259 << " " << _medFileInfo->minor
5260 << " " << _medFileInfo->release
5261 << " " << _medFileInfo->fileName;
5266 //=======================================================================
5267 //function : FileInfoFromString
5268 //purpose : Persistence of file info
5269 //=======================================================================
5271 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5273 std::string size, major, minor, release, fileName;
5274 std::istringstream is(info);
5275 is >> size >> major >> minor >> release;
5276 fileName = info.data() + ( size.size() + 1 +
5279 release.size()+ 1 );
5281 _medFileInfo = new SMESH::MedFileInfo();
5282 _medFileInfo->fileName = fileName.c_str();
5283 _medFileInfo->fileSize = atoi( size.c_str() );
5284 _medFileInfo->major = atoi( major.c_str() );
5285 _medFileInfo->minor = atoi( minor.c_str() );
5286 _medFileInfo->release = atoi( release.c_str() );
5289 //=============================================================================
5291 * \brief Pass names of mesh groups from study to mesh DS
5293 //=============================================================================
5295 void SMESH_Mesh_i::checkGroupNames()
5297 int nbGrp = NbGroups();
5301 SMESH::ListOfGroups* grpList = 0;
5302 // avoid dump of "GetGroups"
5304 // store python dump into a local variable inside local scope
5305 SMESH::TPythonDump pDump; // do not delete this line of code
5306 grpList = GetGroups();
5309 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5310 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5313 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5314 if ( aGrpSO->_is_nil() )
5316 // correct name of the mesh group if necessary
5317 const char* guiName = aGrpSO->GetName();
5318 if ( strcmp(guiName, aGrp->GetName()) )
5319 aGrp->SetName( guiName );
5323 //=============================================================================
5325 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5327 //=============================================================================
5328 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5330 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5334 //=============================================================================
5336 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5338 //=============================================================================
5340 char* SMESH_Mesh_i::GetParameters()
5342 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5345 //=============================================================================
5347 * \brief Returns list of notebook variables used for last Mesh operation
5349 //=============================================================================
5350 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5352 SMESH::string_array_var aResult = new SMESH::string_array();
5353 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5355 CORBA::String_var aParameters = GetParameters();
5356 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5357 if ( aSections->length() > 0 ) {
5358 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5359 aResult->length( aVars.length() );
5360 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5361 aResult[i] = CORBA::string_dup( aVars[i] );
5364 return aResult._retn();
5367 //=======================================================================
5368 //function : GetTypes
5369 //purpose : Returns types of elements it contains
5370 //=======================================================================
5372 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5375 return _preMeshInfo->GetTypes();
5377 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5381 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5382 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5383 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5384 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5385 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5386 if (_impl->NbNodes() &&
5387 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5388 types->length( nbTypes );
5390 return types._retn();
5393 //=======================================================================
5394 //function : GetMesh
5395 //purpose : Returns self
5396 //=======================================================================
5398 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5400 return SMESH::SMESH_Mesh::_duplicate( _this() );
5403 //=======================================================================
5404 //function : IsMeshInfoCorrect
5405 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5406 // * happen if mesh data is not yet fully loaded from the file of study.
5407 //=======================================================================
5409 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5411 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5414 //=============================================================================
5416 * \brief Returns number of mesh elements per each \a EntityType
5418 //=============================================================================
5420 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5423 return _preMeshInfo->GetMeshInfo();
5425 SMESH::long_array_var aRes = new SMESH::long_array();
5426 aRes->length(SMESH::Entity_Last);
5427 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5429 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5431 return aRes._retn();
5432 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5433 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5434 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5435 return aRes._retn();
5438 //=============================================================================
5440 * \brief Returns number of mesh elements per each \a ElementType
5442 //=============================================================================
5444 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5446 SMESH::long_array_var aRes = new SMESH::long_array();
5447 aRes->length(SMESH::NB_ELEMENT_TYPES);
5448 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5451 const SMDS_MeshInfo* meshInfo = 0;
5453 meshInfo = _preMeshInfo;
5454 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5455 meshInfo = & meshDS->GetMeshInfo();
5458 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5459 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5461 return aRes._retn();
5464 //=============================================================================
5466 * Collect statistic of mesh elements given by iterator
5468 //=============================================================================
5470 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5471 SMESH::long_array& theInfo)
5473 if (!theItr) return;
5474 while (theItr->more())
5475 theInfo[ theItr->next()->GetEntityType() ]++;
5477 //=============================================================================
5479 * Returns mesh unstructed grid information.
5481 //=============================================================================
5483 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5485 SALOMEDS::TMPFile_var SeqFile;
5486 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5487 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5489 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5490 aWriter->WriteToOutputStringOn();
5491 aWriter->SetInputData(aGrid);
5492 aWriter->SetFileTypeToBinary();
5494 char* str = aWriter->GetOutputString();
5495 int size = aWriter->GetOutputStringLength();
5497 //Allocate octet buffer of required size
5498 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5499 //Copy ostrstream content to the octet buffer
5500 memcpy(OctetBuf, str, size);
5501 //Create and return TMPFile
5502 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5506 return SeqFile._retn();
5509 //=============================================================================
5510 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5511 * SMESH::ElementType type) */
5513 using namespace SMESH::Controls;
5514 //-----------------------------------------------------------------------------
5515 struct PredicateIterator : public SMDS_ElemIterator
5517 SMDS_ElemIteratorPtr _elemIter;
5518 PredicatePtr _predicate;
5519 const SMDS_MeshElement* _elem;
5520 SMDSAbs_ElementType _type;
5522 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5523 PredicatePtr predicate,
5524 SMDSAbs_ElementType type):
5525 _elemIter(iterator), _predicate(predicate), _type(type)
5533 virtual const SMDS_MeshElement* next()
5535 const SMDS_MeshElement* res = _elem;
5537 while ( _elemIter->more() && !_elem )
5539 if ((_elem = _elemIter->next()) &&
5540 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5541 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5548 //-----------------------------------------------------------------------------
5549 struct IDSourceIterator : public SMDS_ElemIterator
5551 const CORBA::Long* _idPtr;
5552 const CORBA::Long* _idEndPtr;
5553 SMESH::long_array_var _idArray;
5554 const SMDS_Mesh* _mesh;
5555 const SMDSAbs_ElementType _type;
5556 const SMDS_MeshElement* _elem;
5558 IDSourceIterator( const SMDS_Mesh* mesh,
5559 const CORBA::Long* ids,
5561 SMDSAbs_ElementType type):
5562 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5564 if ( _idPtr && nbIds && _mesh )
5567 IDSourceIterator( const SMDS_Mesh* mesh,
5568 SMESH::long_array* idArray,
5569 SMDSAbs_ElementType type):
5570 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5572 if ( idArray && _mesh )
5574 _idPtr = &_idArray[0];
5575 _idEndPtr = _idPtr + _idArray->length();
5583 virtual const SMDS_MeshElement* next()
5585 const SMDS_MeshElement* res = _elem;
5587 while ( _idPtr < _idEndPtr && !_elem )
5589 if ( _type == SMDSAbs_Node )
5591 _elem = _mesh->FindNode( *_idPtr++ );
5593 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5594 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5602 //-----------------------------------------------------------------------------
5604 struct NodeOfElemIterator : public SMDS_ElemIterator
5606 TColStd_MapOfInteger _checkedNodeIDs;
5607 SMDS_ElemIteratorPtr _elemIter;
5608 SMDS_ElemIteratorPtr _nodeIter;
5609 const SMDS_MeshElement* _node;
5611 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5613 if ( _elemIter && _elemIter->more() )
5615 _nodeIter = _elemIter->next()->nodesIterator();
5623 virtual const SMDS_MeshElement* next()
5625 const SMDS_MeshElement* res = _node;
5627 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5629 if ( _nodeIter->more() )
5631 _node = _nodeIter->next();
5632 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5637 _nodeIter = _elemIter->next()->nodesIterator();
5645 //=============================================================================
5647 * Return iterator on elements of given type in given object
5649 //=============================================================================
5651 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5652 SMESH::ElementType theType)
5654 SMDS_ElemIteratorPtr elemIt;
5655 bool typeOK = ( theType == SMESH::ALL );
5656 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5658 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5659 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5660 if ( !mesh_i ) return elemIt;
5661 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5663 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5665 elemIt = meshDS->elementsIterator( elemType );
5668 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5670 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5673 elemIt = sm->GetElements();
5674 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5676 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5677 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5681 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5683 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5684 if ( groupDS && ( elemType == groupDS->GetType() ||
5685 elemType == SMDSAbs_Node ||
5686 elemType == SMDSAbs_All ))
5688 elemIt = groupDS->GetElements();
5689 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5692 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5694 if ( filter_i->GetElementType() == theType ||
5695 filter_i->GetElementType() == SMESH::ALL ||
5696 elemType == SMDSAbs_Node ||
5697 elemType == SMDSAbs_All)
5699 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5700 if ( pred_i && pred_i->GetPredicate() )
5702 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5703 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5704 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
5705 elemIt = SMDS_ElemIteratorPtr
5706 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
5707 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
5713 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5714 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5715 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5717 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
5718 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5721 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5722 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
5726 SMESH::long_array_var ids = theObject->GetIDs();
5727 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
5729 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5732 if ( elemIt && elemIt->more() && !typeOK )
5734 if ( elemType == SMDSAbs_Node )
5736 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5740 elemIt = SMDS_ElemIteratorPtr();
5746 //=============================================================================
5747 namespace // Finding concurrent hypotheses
5748 //=============================================================================
5752 * \brief mapping of mesh dimension into shape type
5754 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5756 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5758 case 0: aType = TopAbs_VERTEX; break;
5759 case 1: aType = TopAbs_EDGE; break;
5760 case 2: aType = TopAbs_FACE; break;
5762 default:aType = TopAbs_SOLID; break;
5767 //-----------------------------------------------------------------------------
5769 * \brief Internal structure used to find concurrent submeshes
5771 * It represents a pair < submesh, concurrent dimension >, where
5772 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5773 * with another submesh. In other words, it is dimension of a hypothesis assigned
5780 int _dim; //!< a dimension the algo can build (concurrent dimension)
5781 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5782 TopTools_MapOfShape _shapeMap;
5783 SMESH_subMesh* _subMesh;
5784 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5786 //-----------------------------------------------------------------------------
5787 // Return the algorithm
5788 const SMESH_Algo* GetAlgo() const
5789 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5791 //-----------------------------------------------------------------------------
5793 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5795 const TopoDS_Shape& theShape)
5797 _subMesh = (SMESH_subMesh*)theSubMesh;
5798 SetShape( theDim, theShape );
5801 //-----------------------------------------------------------------------------
5803 void SetShape(const int theDim,
5804 const TopoDS_Shape& theShape)
5807 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5808 if (_dim >= _ownDim)
5809 _shapeMap.Add( theShape );
5811 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5812 for( ; anExp.More(); anExp.Next() )
5813 _shapeMap.Add( anExp.Current() );
5817 //-----------------------------------------------------------------------------
5818 //! Check sharing of sub-shapes
5819 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5820 const TopTools_MapOfShape& theToFind,
5821 const TopAbs_ShapeEnum theType)
5823 bool isShared = false;
5824 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5825 for (; !isShared && anItr.More(); anItr.Next() )
5827 const TopoDS_Shape aSubSh = anItr.Key();
5828 // check for case when concurrent dimensions are same
5829 isShared = theToFind.Contains( aSubSh );
5830 // check for sub-shape with concurrent dimension
5831 TopExp_Explorer anExp( aSubSh, theType );
5832 for ( ; !isShared && anExp.More(); anExp.Next() )
5833 isShared = theToFind.Contains( anExp.Current() );
5838 //-----------------------------------------------------------------------------
5839 //! check algorithms
5840 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5841 const SMESHDS_Hypothesis* theA2)
5843 if ( !theA1 || !theA2 ||
5844 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5845 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5846 return false; // one of the hypothesis is not algorithm
5847 // check algorithm names (should be equal)
5848 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5852 //-----------------------------------------------------------------------------
5853 //! Check if sub-shape hypotheses are concurrent
5854 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5856 if ( _subMesh == theOther->_subMesh )
5857 return false; // same sub-shape - should not be
5859 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5860 // any of the two submeshes is not on COMPOUND shape )
5861 // -> no concurrency
5862 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5863 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5864 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5865 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5866 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5869 // bool checkSubShape = ( _dim >= theOther->_dim )
5870 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5871 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5872 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5873 if ( !checkSubShape )
5876 // check algorithms to be same
5877 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5878 return true; // different algorithms -> concurrency !
5880 // check hypothesises for concurrence (skip first as algorithm)
5882 // pointers should be same, because it is referened from mesh hypothesis partition
5883 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5884 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5885 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5886 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5888 // the submeshes are concurrent if their algorithms has different parameters
5889 return nbSame != (int)theOther->_hypotheses.size() - 1;
5892 // Return true if algorithm of this SMESH_DimHyp is used if no
5893 // sub-mesh order is imposed by the user
5894 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5896 // NeedDiscreteBoundary() algo has a higher priority
5897 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5898 theOther->GetAlgo()->NeedDiscreteBoundary() )
5899 return !this->GetAlgo()->NeedDiscreteBoundary();
5901 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5904 }; // end of SMESH_DimHyp
5905 //-----------------------------------------------------------------------------
5907 typedef list<const SMESH_DimHyp*> TDimHypList;
5909 //-----------------------------------------------------------------------------
5911 void addDimHypInstance(const int theDim,
5912 const TopoDS_Shape& theShape,
5913 const SMESH_Algo* theAlgo,
5914 const SMESH_subMesh* theSubMesh,
5915 const list <const SMESHDS_Hypothesis*>& theHypList,
5916 TDimHypList* theDimHypListArr )
5918 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5919 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5920 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5921 dimHyp->_hypotheses.push_front(theAlgo);
5922 listOfdimHyp.push_back( dimHyp );
5925 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5926 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5927 theHypList.begin(), theHypList.end() );
5930 //-----------------------------------------------------------------------------
5931 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5932 TDimHypList& theListOfConcurr)
5934 if ( theListOfConcurr.empty() )
5936 theListOfConcurr.push_back( theDimHyp );
5940 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5941 while ( hypIt != theListOfConcurr.end() &&
5942 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5944 theListOfConcurr.insert( hypIt, theDimHyp );
5948 //-----------------------------------------------------------------------------
5949 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5950 const TDimHypList& theListOfDimHyp,
5951 TDimHypList& theListOfConcurrHyp,
5952 set<int>& theSetOfConcurrId )
5954 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5955 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5957 const SMESH_DimHyp* curDimHyp = *rIt;
5958 if ( curDimHyp == theDimHyp )
5959 break; // meet own dimHyp pointer in same dimension
5961 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5962 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5964 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5969 //-----------------------------------------------------------------------------
5970 void unionLists(TListOfInt& theListOfId,
5971 TListOfListOfInt& theListOfListOfId,
5974 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5975 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5977 continue; //skip already treated lists
5978 // check if other list has any same submesh object
5979 TListOfInt& otherListOfId = *it;
5980 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5981 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5984 // union two lists (from source into target)
5985 TListOfInt::iterator it2 = otherListOfId.begin();
5986 for ( ; it2 != otherListOfId.end(); it2++ ) {
5987 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5988 theListOfId.push_back(*it2);
5990 // clear source list
5991 otherListOfId.clear();
5994 //-----------------------------------------------------------------------------
5996 //! free memory allocated for dimension-hypothesis objects
5997 void removeDimHyps( TDimHypList* theArrOfList )
5999 for (int i = 0; i < 4; i++ ) {
6000 TDimHypList& listOfdimHyp = theArrOfList[i];
6001 TDimHypList::const_iterator it = listOfdimHyp.begin();
6002 for ( ; it != listOfdimHyp.end(); it++ )
6007 //-----------------------------------------------------------------------------
6009 * \brief find common submeshes with given submesh
6010 * \param theSubMeshList list of already collected submesh to check
6011 * \param theSubMesh given submesh to intersect with other
6012 * \param theCommonSubMeshes collected common submeshes
6014 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6015 const SMESH_subMesh* theSubMesh,
6016 set<const SMESH_subMesh*>& theCommon )
6020 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6021 for ( ; it != theSubMeshList.end(); it++ )
6022 theSubMesh->FindIntersection( *it, theCommon );
6023 theSubMeshList.push_back( theSubMesh );
6024 //theCommon.insert( theSubMesh );
6027 //-----------------------------------------------------------------------------
6028 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6030 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6031 for ( ; listsIt != smLists.end(); ++listsIt )
6033 const TListOfInt& smIDs = *listsIt;
6034 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6042 //=============================================================================
6044 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6046 //=============================================================================
6048 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6050 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6051 if ( isSubMeshInList( submeshID, anOrder ))
6054 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6055 return isSubMeshInList( submeshID, allConurrent );
6058 //=============================================================================
6060 * \brief Return submesh objects list in meshing order
6062 //=============================================================================
6064 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6066 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6068 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6070 return aResult._retn();
6072 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6073 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6074 anOrder.splice( anOrder.end(), allConurrent );
6077 TListOfListOfInt::iterator listIt = anOrder.begin();
6078 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6079 unionLists( *listIt, anOrder, listIndx + 1 );
6081 // convert submesh ids into interface instances
6082 // and dump command into python
6083 convertMeshOrder( anOrder, aResult, false );
6085 return aResult._retn();
6088 //=============================================================================
6090 * \brief Finds concurrent sub-meshes
6092 //=============================================================================
6094 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6096 TListOfListOfInt anOrder;
6097 ::SMESH_Mesh& mesh = GetImpl();
6099 // collect submeshes and detect concurrent algorithms and hypothesises
6100 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6102 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6103 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6104 ::SMESH_subMesh* sm = (*i_sm).second;
6106 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6108 // list of assigned hypothesises
6109 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6110 // Find out dimensions where the submesh can be concurrent.
6111 // We define the dimensions by algo of each of hypotheses in hypList
6112 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6113 for( ; hypIt != hypList.end(); hypIt++ ) {
6114 SMESH_Algo* anAlgo = 0;
6115 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6116 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6117 // hyp it-self is algo
6118 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6120 // try to find algorithm with help of sub-shapes
6121 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6122 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6123 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6126 continue; // no algorithm assigned to a current submesh
6128 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6129 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6131 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6132 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6133 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6135 } // end iterations on submesh
6137 // iterate on created dimension-hypotheses and check for concurrents
6138 for ( int i = 0; i < 4; i++ ) {
6139 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6140 // check for concurrents in own and other dimensions (step-by-step)
6141 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6142 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6143 const SMESH_DimHyp* dimHyp = *dhIt;
6144 TDimHypList listOfConcurr;
6145 set<int> setOfConcurrIds;
6146 // looking for concurrents and collect into own list
6147 for ( int j = i; j < 4; j++ )
6148 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6149 // check if any concurrents found
6150 if ( listOfConcurr.size() > 0 ) {
6151 // add own submesh to list of concurrent
6152 addInOrderOfPriority( dimHyp, listOfConcurr );
6153 list<int> listOfConcurrIds;
6154 TDimHypList::iterator hypIt = listOfConcurr.begin();
6155 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6156 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6157 anOrder.push_back( listOfConcurrIds );
6162 removeDimHyps(dimHypListArr);
6164 // now, minimize the number of concurrent groups
6165 // Here we assume that lists of submeshes can have same submesh
6166 // in case of multi-dimension algorithms, as result
6167 // list with common submesh has to be united into one list
6169 TListOfListOfInt::iterator listIt = anOrder.begin();
6170 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6171 unionLists( *listIt, anOrder, listIndx + 1 );
6177 //=============================================================================
6179 * \brief Set submesh object order
6180 * \param theSubMeshArray submesh array order
6182 //=============================================================================
6184 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6187 _preMeshInfo->ForgetOrLoad();
6190 ::SMESH_Mesh& mesh = GetImpl();
6192 TPythonDump aPythonDump; // prevent dump of called methods
6193 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6195 TListOfListOfInt subMeshOrder;
6196 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6198 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6199 TListOfInt subMeshIds;
6201 aPythonDump << ", ";
6202 aPythonDump << "[ ";
6203 // Collect subMeshes which should be clear
6204 // do it list-by-list, because modification of submesh order
6205 // take effect between concurrent submeshes only
6206 set<const SMESH_subMesh*> subMeshToClear;
6207 list<const SMESH_subMesh*> subMeshList;
6208 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6210 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6212 aPythonDump << ", ";
6213 aPythonDump << subMesh;
6214 subMeshIds.push_back( subMesh->GetId() );
6215 // detect common parts of submeshes
6216 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6217 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6219 aPythonDump << " ]";
6220 subMeshOrder.push_back( subMeshIds );
6222 // clear collected submeshes
6223 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6224 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6225 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6226 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6228 aPythonDump << " ])";
6230 mesh.SetMeshOrder( subMeshOrder );
6233 SMESH::SMESH_Mesh_var me = _this();
6234 _gen_i->UpdateIcons( me );
6239 //=============================================================================
6241 * \brief Convert submesh ids into submesh interfaces
6243 //=============================================================================
6245 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6246 SMESH::submesh_array_array& theResOrder,
6247 const bool theIsDump)
6249 int nbSet = theIdsOrder.size();
6250 TPythonDump aPythonDump; // prevent dump of called methods
6252 aPythonDump << "[ ";
6253 theResOrder.length(nbSet);
6254 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6256 for( ; it != theIdsOrder.end(); it++ ) {
6257 // translate submesh identificators into submesh objects
6258 // takeing into account real number of concurrent lists
6259 const TListOfInt& aSubOrder = (*it);
6260 if (!aSubOrder.size())
6263 aPythonDump << "[ ";
6264 // convert shape indices into interfaces
6265 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6266 aResSubSet->length(aSubOrder.size());
6267 TListOfInt::const_iterator subIt = aSubOrder.begin();
6269 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6270 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6272 SMESH::SMESH_subMesh_var subMesh =
6273 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6276 aPythonDump << ", ";
6277 aPythonDump << subMesh;
6279 aResSubSet[ j++ ] = subMesh;
6282 aPythonDump << " ]";
6284 theResOrder[ listIndx++ ] = aResSubSet;
6286 // correct number of lists
6287 theResOrder.length( listIndx );
6290 // finilise python dump
6291 aPythonDump << " ]";
6292 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6296 namespace // utils used by SMESH_MeshPartDS
6299 * \brief Class used to access to protected data of SMDS_MeshInfo
6301 struct TMeshInfo : public SMDS_MeshInfo
6303 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6306 * \brief Element holing its ID only
6308 struct TElemID : public SMDS_LinearEdge
6310 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6314 //================================================================================
6316 // Implementation of SMESH_MeshPartDS
6318 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6319 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6321 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6322 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6325 _meshDS = mesh_i->GetImpl().GetMeshDS();
6327 SetPersistentId( _meshDS->GetPersistentId() );
6329 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6331 // <meshPart> is the whole mesh
6332 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6334 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6335 myGroupSet = _meshDS->GetGroups();
6340 SMESH::long_array_var anIDs = meshPart->GetIDs();
6341 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6342 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6344 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6345 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6346 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6351 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6352 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6353 if ( _elements[ e->GetType() ].insert( e ).second )
6356 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6357 while ( nIt->more() )
6359 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6360 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6367 ShapeToMesh( _meshDS->ShapeToMesh() );
6369 _meshDS = 0; // to enforce iteration on _elements and _nodes
6372 // -------------------------------------------------------------------------------------
6373 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6374 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6377 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6378 for ( ; partIt != meshPart.end(); ++partIt )
6379 if ( const SMDS_MeshElement * e = *partIt )
6380 if ( _elements[ e->GetType() ].insert( e ).second )
6383 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6384 while ( nIt->more() )
6386 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6387 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6393 // -------------------------------------------------------------------------------------
6394 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6396 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6398 TElemID elem( IDelem );
6399 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6400 if ( !_elements[ iType ].empty() )
6402 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6403 if ( it != _elements[ iType ].end() )
6408 // -------------------------------------------------------------------------------------
6409 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6411 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6413 typedef SMDS_SetIterator
6414 <const SMDS_MeshElement*,
6415 TIDSortedElemSet::const_iterator,
6416 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6417 SMDS_MeshElement::GeomFilter
6420 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6422 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6423 _elements[type].end(),
6424 SMDS_MeshElement::GeomFilter( geomType )));
6426 // -------------------------------------------------------------------------------------
6427 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6429 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6431 typedef SMDS_SetIterator
6432 <const SMDS_MeshElement*,
6433 TIDSortedElemSet::const_iterator,
6434 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6435 SMDS_MeshElement::EntityFilter
6438 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6440 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6441 _elements[type].end(),
6442 SMDS_MeshElement::EntityFilter( entity )));
6444 // -------------------------------------------------------------------------------------
6445 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6447 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6448 if ( type == SMDSAbs_All && !_meshDS )
6450 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6452 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6453 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6455 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6457 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6458 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6460 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6461 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6463 // -------------------------------------------------------------------------------------
6464 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6465 iterType SMESH_MeshPartDS::methName() const \
6467 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6468 return _meshDS ? _meshDS->methName() : iterType \
6469 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6471 // -------------------------------------------------------------------------------------
6472 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6473 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6474 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6475 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6476 #undef _GET_ITER_DEFINE
6478 // END Implementation of SMESH_MeshPartDS
6480 //================================================================================