1 // Copyright (C) 2007-2014 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_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 #include <vtkUnstructuredGridWriter.h>
84 // to pass CORBA exception through SMESH_TRY
85 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
87 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
90 static int MYDEBUG = 0;
92 static int MYDEBUG = 0;
96 using SMESH::TPythonDump;
98 int SMESH_Mesh_i::_idGenerator = 0;
100 //=============================================================================
104 //=============================================================================
106 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
108 CORBA::Long studyId )
109 : SALOME::GenericObj_i( thePOA )
111 MESSAGE("SMESH_Mesh_i");
114 _id = _idGenerator++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
130 MESSAGE("~SMESH_Mesh_i");
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 aGroup->UnRegister();
138 SMESH::SMESH_GroupBase_var( itGr->second );
143 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
144 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
145 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
147 aSubMesh->UnRegister();
148 SMESH::SMESH_subMesh_var( itSM->second );
150 _mapSubMeshIor.clear();
152 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
156 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
157 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
160 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
164 delete _editor; _editor = NULL;
165 delete _previewEditor; _previewEditor = NULL;
166 delete _impl; _impl = NULL;
167 delete _preMeshInfo; _preMeshInfo = NULL;
170 //=============================================================================
174 * Associates <this> mesh with <theShape> and puts a reference
175 * to <theShape> into the current study;
176 * the previous shape is substituted by the new one.
178 //=============================================================================
180 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
181 throw (SALOME::SALOME_Exception)
183 Unexpect aCatch(SALOME_SalomeException);
185 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
187 catch(SALOME_Exception & S_ex) {
188 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
190 // to track changes of GEOM groups
191 SMESH::SMESH_Mesh_var mesh = _this();
192 addGeomGroupData( theShapeObject, mesh );
193 if ( !CORBA::is_nil( theShapeObject ))
194 _mainShapeTick = theShapeObject->GetTick();
197 //================================================================================
199 * \brief return true if mesh has a shape to build a shape on
201 //================================================================================
203 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
204 throw (SALOME::SALOME_Exception)
206 Unexpect aCatch(SALOME_SalomeException);
209 res = _impl->HasShapeToMesh();
211 catch(SALOME_Exception & S_ex) {
212 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
217 //=======================================================================
218 //function : GetShapeToMesh
220 //=======================================================================
222 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
223 throw (SALOME::SALOME_Exception)
225 Unexpect aCatch(SALOME_SalomeException);
226 GEOM::GEOM_Object_var aShapeObj;
228 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
230 aShapeObj = _gen_i->ShapeToGeomObject( S );
232 catch(SALOME_Exception & S_ex) {
233 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
235 return aShapeObj._retn();
238 //================================================================================
240 * \brief Return false if the mesh is not yet fully loaded from the study file
242 //================================================================================
244 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
246 Unexpect aCatch(SALOME_SalomeException);
247 return !_preMeshInfo;
250 //================================================================================
252 * \brief Load full mesh data from the study file
254 //================================================================================
256 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
258 Unexpect aCatch(SALOME_SalomeException);
260 _preMeshInfo->FullLoadFromFile();
263 //================================================================================
265 * \brief Remove all nodes and elements
267 //================================================================================
269 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
271 Unexpect aCatch(SALOME_SalomeException);
273 _preMeshInfo->ForgetAllData();
277 //CheckGeomGroupModif(); // issue 20145
279 catch(SALOME_Exception & S_ex) {
280 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
282 _impl->GetMeshDS()->Modified();
284 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
287 //================================================================================
289 * \brief Remove all nodes and elements for indicated shape
291 //================================================================================
293 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
294 throw (SALOME::SALOME_Exception)
296 Unexpect aCatch(SALOME_SalomeException);
298 _preMeshInfo->FullLoadFromFile();
301 _impl->ClearSubMesh( ShapeID );
303 catch(SALOME_Exception & S_ex) {
304 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
306 _impl->GetMeshDS()->Modified();
308 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
311 //=============================================================================
313 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
315 //=============================================================================
317 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
319 SMESH::DriverMED_ReadStatus res;
322 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
323 res = SMESH::DRS_OK; break;
324 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
325 res = SMESH::DRS_EMPTY; break;
326 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
327 res = SMESH::DRS_WARN_RENUMBER; break;
328 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
329 res = SMESH::DRS_WARN_SKIP_ELEM; break;
330 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
331 res = SMESH::DRS_WARN_DESCENDING; break;
332 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
334 res = SMESH::DRS_FAIL; break;
339 //=============================================================================
341 * Convert ::SMESH_ComputeError to SMESH::ComputeError
343 //=============================================================================
345 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
347 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
348 errVar->subShapeID = -1;
349 errVar->hasBadMesh = false;
351 if ( !errorPtr || errorPtr->IsOK() )
353 errVar->code = SMESH::COMPERR_OK;
357 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
358 errVar->comment = errorPtr->myComment.c_str();
360 return errVar._retn();
363 //=============================================================================
367 * Imports mesh data from MED file
369 //=============================================================================
371 SMESH::DriverMED_ReadStatus
372 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
373 throw ( SALOME::SALOME_Exception )
375 Unexpect aCatch(SALOME_SalomeException);
378 status = _impl->MEDToMesh( theFileName, theMeshName );
380 catch( SALOME_Exception& S_ex ) {
381 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
384 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
387 CreateGroupServants();
389 int major, minor, release;
390 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
391 major = minor = release = -1;
392 _medFileInfo = new SMESH::MedFileInfo();
393 _medFileInfo->fileName = theFileName;
394 _medFileInfo->fileSize = 0;
395 _medFileInfo->major = major;
396 _medFileInfo->minor = minor;
397 _medFileInfo->release = release;
398 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
400 return ConvertDriverMEDReadStatus(status);
403 //================================================================================
405 * \brief Imports mesh data from the CGNS file
407 //================================================================================
409 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
410 const int theMeshIndex,
411 std::string& theMeshName )
412 throw ( SALOME::SALOME_Exception )
414 Unexpect aCatch(SALOME_SalomeException);
417 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
419 catch( SALOME_Exception& S_ex ) {
420 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
423 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
426 CreateGroupServants();
428 return ConvertDriverMEDReadStatus(status);
431 //================================================================================
433 * \brief Return string representation of a MED file version comprising nbDigits
435 //================================================================================
437 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
439 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
441 return CORBA::string_dup( ver.c_str() );
444 //=============================================================================
448 * Imports mesh data from MED file
450 //=============================================================================
452 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
453 throw ( SALOME::SALOME_Exception )
457 // Read mesh with name = <theMeshName> into SMESH_Mesh
458 _impl->UNVToMesh( theFileName );
460 CreateGroupServants();
462 SMESH_CATCH( SMESH::throwCorbaException );
467 //=============================================================================
471 * Imports mesh data from STL file
473 //=============================================================================
474 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
475 throw ( SALOME::SALOME_Exception )
479 // Read mesh with name = <theMeshName> into SMESH_Mesh
480 _impl->STLToMesh( theFileName );
482 SMESH_CATCH( SMESH::throwCorbaException );
487 //================================================================================
489 * \brief Function used in SMESH_CATCH by ImportGMFFile()
491 //================================================================================
495 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
497 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
501 //================================================================================
503 * \brief Imports data from a GMF file and returns an error description
505 //================================================================================
507 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
508 bool theMakeRequiredGroups )
509 throw (SALOME::SALOME_Exception)
511 SMESH_ComputeErrorPtr error;
514 #define SMESH_CAUGHT error =
517 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
519 SMESH_CATCH( exceptionToComputeError );
523 CreateGroupServants();
525 return ConvertComputeError( error );
528 //=============================================================================
532 //=============================================================================
534 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
536 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
537 (SMESH_Hypothesis::Hypothesis_Status theStatus)
540 RETURNCASE( HYP_OK );
541 RETURNCASE( HYP_MISSING );
542 RETURNCASE( HYP_CONCURENT );
543 RETURNCASE( HYP_BAD_PARAMETER );
544 RETURNCASE( HYP_HIDDEN_ALGO );
545 RETURNCASE( HYP_HIDING_ALGO );
546 RETURNCASE( HYP_UNKNOWN_FATAL );
547 RETURNCASE( HYP_INCOMPATIBLE );
548 RETURNCASE( HYP_NOTCONFORM );
549 RETURNCASE( HYP_ALREADY_EXIST );
550 RETURNCASE( HYP_BAD_DIM );
551 RETURNCASE( HYP_BAD_SUBSHAPE );
552 RETURNCASE( HYP_BAD_GEOMETRY );
553 RETURNCASE( HYP_NEED_SHAPE );
554 RETURNCASE( HYP_INCOMPAT_HYPS );
557 return SMESH::HYP_UNKNOWN_FATAL;
560 //=============================================================================
564 * calls internal addHypothesis() and then adds a reference to <anHyp> under
565 * the SObject actually having a reference to <aSubShape>.
566 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
568 //=============================================================================
570 SMESH::Hypothesis_Status
571 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
572 SMESH::SMESH_Hypothesis_ptr anHyp,
573 CORBA::String_out anErrorText)
574 throw(SALOME::SALOME_Exception)
576 Unexpect aCatch(SALOME_SalomeException);
578 _preMeshInfo->ForgetOrLoad();
581 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
582 anErrorText = error.c_str();
584 SMESH::SMESH_Mesh_var mesh( _this() );
585 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
587 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
588 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
590 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
592 // Update Python script
593 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
594 << aSubShape << ", " << anHyp << " )";
596 return ConvertHypothesisStatus(status);
599 //=============================================================================
603 //=============================================================================
605 SMESH_Hypothesis::Hypothesis_Status
606 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
607 SMESH::SMESH_Hypothesis_ptr anHyp,
608 std::string* anErrorText)
610 if(MYDEBUG) MESSAGE("addHypothesis");
612 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
613 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
615 if (CORBA::is_nil( anHyp ))
616 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
618 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
621 TopoDS_Shape myLocSubShape;
622 //use PseudoShape in case if mesh has no shape
624 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
626 myLocSubShape = _impl->GetShapeToMesh();
628 const int hypId = anHyp->GetId();
630 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
631 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
633 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
635 // assure there is a corresponding submesh
636 if ( !_impl->IsMainShape( myLocSubShape )) {
637 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
638 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
639 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
642 else if ( anErrorText )
644 *anErrorText = error;
647 catch(SALOME_Exception & S_ex)
649 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
654 //=============================================================================
658 //=============================================================================
660 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
661 SMESH::SMESH_Hypothesis_ptr anHyp)
662 throw(SALOME::SALOME_Exception)
664 Unexpect aCatch(SALOME_SalomeException);
666 _preMeshInfo->ForgetOrLoad();
668 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
669 SMESH::SMESH_Mesh_var mesh = _this();
671 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
673 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
674 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
676 // Update Python script
677 if(_impl->HasShapeToMesh())
678 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
679 << aSubShape << ", " << anHyp << " )";
681 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
684 return ConvertHypothesisStatus(status);
687 //=============================================================================
691 //=============================================================================
693 SMESH_Hypothesis::Hypothesis_Status
694 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
695 SMESH::SMESH_Hypothesis_ptr anHyp)
697 if(MYDEBUG) MESSAGE("removeHypothesis()");
699 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
700 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
702 if (CORBA::is_nil( anHyp ))
703 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
705 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
708 TopoDS_Shape myLocSubShape;
709 //use PseudoShape in case if mesh has no shape
710 if( _impl->HasShapeToMesh() )
711 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
713 myLocSubShape = _impl->GetShapeToMesh();
715 const int hypId = anHyp->GetId();
716 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
717 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
719 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
723 catch(SALOME_Exception & S_ex)
725 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
730 //=============================================================================
734 //=============================================================================
736 SMESH::ListOfHypothesis *
737 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
738 throw(SALOME::SALOME_Exception)
740 Unexpect aCatch(SALOME_SalomeException);
741 if (MYDEBUG) MESSAGE("GetHypothesisList");
742 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
743 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
745 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
748 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
749 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
750 myLocSubShape = _impl->GetShapeToMesh();
751 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
752 int i = 0, n = aLocalList.size();
755 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
756 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
757 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
759 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
760 if ( id_hypptr != _mapHypo.end() )
761 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
765 catch(SALOME_Exception & S_ex) {
766 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
769 return aList._retn();
772 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
774 Unexpect aCatch(SALOME_SalomeException);
775 if (MYDEBUG) MESSAGE("GetSubMeshes");
777 SMESH::submesh_array_var aList = new SMESH::submesh_array();
780 TPythonDump aPythonDump;
781 if ( !_mapSubMeshIor.empty() )
785 aList->length( _mapSubMeshIor.size() );
787 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
788 for ( ; it != _mapSubMeshIor.end(); it++ ) {
789 if ( CORBA::is_nil( it->second )) continue;
790 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
792 if (i > 1) aPythonDump << ", ";
793 aPythonDump << it->second;
797 catch(SALOME_Exception & S_ex) {
798 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
801 // Update Python script
802 if ( !_mapSubMeshIor.empty() )
803 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
805 return aList._retn();
808 //=============================================================================
812 //=============================================================================
814 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
815 const char* theName )
816 throw(SALOME::SALOME_Exception)
818 Unexpect aCatch(SALOME_SalomeException);
819 if (CORBA::is_nil(aSubShape))
820 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
822 SMESH::SMESH_subMesh_var subMesh;
823 SMESH::SMESH_Mesh_var aMesh = _this();
825 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
827 //Get or Create the SMESH_subMesh object implementation
829 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
831 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
833 TopoDS_Iterator it( myLocSubShape );
835 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
837 subMesh = getSubMesh( subMeshId );
839 // create a new subMesh object servant if there is none for the shape
840 if ( subMesh->_is_nil() )
841 subMesh = createSubMesh( aSubShape );
842 if ( _gen_i->CanPublishInStudy( subMesh ))
844 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
845 SALOMEDS::SObject_wrap aSO =
846 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
847 if ( !aSO->_is_nil()) {
848 // Update Python script
849 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
850 << aSubShape << ", '" << theName << "' )";
854 catch(SALOME_Exception & S_ex) {
855 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
857 return subMesh._retn();
860 //=============================================================================
864 //=============================================================================
866 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
867 throw (SALOME::SALOME_Exception)
871 if ( theSubMesh->_is_nil() )
874 GEOM::GEOM_Object_var aSubShape;
875 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
876 if ( !aStudy->_is_nil() ) {
877 // Remove submesh's SObject
878 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
879 if ( !anSO->_is_nil() ) {
880 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
881 SALOMEDS::SObject_wrap anObj, aRef;
882 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
883 anObj->ReferencedObject( aRef.inout() ))
885 CORBA::Object_var obj = aRef->GetObject();
886 aSubShape = GEOM::GEOM_Object::_narrow( obj );
888 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
889 // aSubShape = theSubMesh->GetSubShape();
891 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
892 builder->RemoveObjectWithChildren( anSO );
894 // Update Python script
895 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
899 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
901 _preMeshInfo->ForgetOrLoad();
903 SMESH_CATCH( SMESH::throwCorbaException );
906 //=============================================================================
910 //=============================================================================
912 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
913 const char* theName )
914 throw(SALOME::SALOME_Exception)
916 Unexpect aCatch(SALOME_SalomeException);
918 _preMeshInfo->FullLoadFromFile();
920 SMESH::SMESH_Group_var aNewGroup =
921 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
923 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
925 SMESH::SMESH_Mesh_var mesh = _this();
926 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
927 SALOMEDS::SObject_wrap aSO =
928 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
929 if ( !aSO->_is_nil())
930 // Update Python script
931 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
932 << theElemType << ", '" << theName << "' )";
934 return aNewGroup._retn();
937 //=============================================================================
941 //=============================================================================
942 SMESH::SMESH_GroupOnGeom_ptr
943 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
945 GEOM::GEOM_Object_ptr theGeomObj)
946 throw(SALOME::SALOME_Exception)
948 Unexpect aCatch(SALOME_SalomeException);
950 _preMeshInfo->FullLoadFromFile();
952 SMESH::SMESH_GroupOnGeom_var aNewGroup;
954 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
955 if ( !aShape.IsNull() )
958 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
960 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
962 SMESH::SMESH_Mesh_var mesh = _this();
963 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
964 SALOMEDS::SObject_wrap aSO =
965 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
966 if ( !aSO->_is_nil())
967 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
968 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
972 return aNewGroup._retn();
975 //================================================================================
977 * \brief Creates a group whose contents is defined by filter
978 * \param theElemType - group type
979 * \param theName - group name
980 * \param theFilter - the filter
981 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
983 //================================================================================
985 SMESH::SMESH_GroupOnFilter_ptr
986 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
988 SMESH::Filter_ptr theFilter )
989 throw (SALOME::SALOME_Exception)
991 Unexpect aCatch(SALOME_SalomeException);
993 _preMeshInfo->FullLoadFromFile();
995 if ( CORBA::is_nil( theFilter ))
996 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
998 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1000 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1002 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1003 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1006 if ( !aNewGroup->_is_nil() )
1007 aNewGroup->SetFilter( theFilter );
1009 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1011 SMESH::SMESH_Mesh_var mesh = _this();
1012 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1013 SALOMEDS::SObject_wrap aSO =
1014 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1016 if ( !aSO->_is_nil())
1017 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1018 << theElemType << ", '" << theName << "', " << theFilter << " )";
1020 return aNewGroup._retn();
1023 //=============================================================================
1027 //=============================================================================
1029 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1030 throw (SALOME::SALOME_Exception)
1032 if ( theGroup->_is_nil() )
1037 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1041 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1042 if ( !aStudy->_is_nil() )
1044 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1045 if ( !aGroupSO->_is_nil() )
1047 // Update Python script
1048 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1050 // Remove group's SObject
1051 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1052 builder->RemoveObjectWithChildren( aGroupSO );
1056 // Remove the group from SMESH data structures
1057 removeGroup( aGroup->GetLocalID() );
1059 SMESH_CATCH( SMESH::throwCorbaException );
1062 //=============================================================================
1064 * Remove group with its contents
1066 //=============================================================================
1068 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1069 throw (SALOME::SALOME_Exception)
1073 _preMeshInfo->FullLoadFromFile();
1075 if ( theGroup->_is_nil() )
1079 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1080 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1081 while ( elemIt->more() )
1082 _impl->GetMeshDS()->RemoveElement( elemIt->next() );
1084 TPythonDump pyDump; // Supress dump from RemoveGroup()
1086 // Update Python script (theGroup must be alive for this)
1087 pyDump << SMESH::SMESH_Mesh_var(_this())
1088 << ".RemoveGroupWithContents( " << theGroup << " )";
1091 RemoveGroup( theGroup );
1093 SMESH_CATCH( SMESH::throwCorbaException );
1096 //================================================================================
1098 * \brief Get the list of groups existing in the mesh
1099 * \retval SMESH::ListOfGroups * - list of groups
1101 //================================================================================
1103 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1105 Unexpect aCatch(SALOME_SalomeException);
1106 if (MYDEBUG) MESSAGE("GetGroups");
1108 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1111 TPythonDump aPythonDump;
1112 if ( !_mapGroups.empty() )
1114 aPythonDump << "[ ";
1116 aList->length( _mapGroups.size() );
1118 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1119 for ( ; it != _mapGroups.end(); it++ ) {
1120 if ( CORBA::is_nil( it->second )) continue;
1121 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1123 if (i > 1) aPythonDump << ", ";
1124 aPythonDump << it->second;
1128 catch(SALOME_Exception & S_ex) {
1129 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1131 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1133 return aList._retn();
1136 //=============================================================================
1138 * Get number of groups existing in the mesh
1140 //=============================================================================
1142 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1144 Unexpect aCatch(SALOME_SalomeException);
1145 return _mapGroups.size();
1148 //=============================================================================
1150 * New group including all mesh elements present in initial groups is created.
1152 //=============================================================================
1154 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1155 SMESH::SMESH_GroupBase_ptr theGroup2,
1156 const char* theName )
1157 throw (SALOME::SALOME_Exception)
1159 SMESH::SMESH_Group_var aResGrp;
1163 _preMeshInfo->FullLoadFromFile();
1165 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1166 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1168 if ( theGroup1->GetType() != theGroup2->GetType() )
1169 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1174 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1175 if ( aResGrp->_is_nil() )
1176 return SMESH::SMESH_Group::_nil();
1178 aResGrp->AddFrom( theGroup1 );
1179 aResGrp->AddFrom( theGroup2 );
1181 // Update Python script
1182 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1183 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1185 SMESH_CATCH( SMESH::throwCorbaException );
1187 return aResGrp._retn();
1190 //=============================================================================
1192 * \brief New group including all mesh elements present in initial groups is created.
1193 * \param theGroups list of groups
1194 * \param theName name of group to be created
1195 * \return pointer to the new group
1197 //=============================================================================
1199 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1200 const char* theName )
1201 throw (SALOME::SALOME_Exception)
1203 SMESH::SMESH_Group_var aResGrp;
1206 _preMeshInfo->FullLoadFromFile();
1209 return SMESH::SMESH_Group::_nil();
1214 SMESH::ElementType aType = SMESH::ALL;
1215 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1217 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1218 if ( CORBA::is_nil( aGrp ) )
1220 if ( aType == SMESH::ALL )
1221 aType = aGrp->GetType();
1222 else if ( aType != aGrp->GetType() )
1223 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1226 if ( aType == SMESH::ALL )
1227 return SMESH::SMESH_Group::_nil();
1232 aResGrp = CreateGroup( aType, theName );
1233 if ( aResGrp->_is_nil() )
1234 return SMESH::SMESH_Group::_nil();
1236 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1237 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1239 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1240 if ( !CORBA::is_nil( aGrp ) )
1242 aResGrp->AddFrom( aGrp );
1243 if ( g > 0 ) pyDump << ", ";
1247 pyDump << " ], '" << theName << "' )";
1249 SMESH_CATCH( SMESH::throwCorbaException );
1251 return aResGrp._retn();
1254 //=============================================================================
1256 * New group is created. All mesh elements that are
1257 * present in both initial groups are added to the new one.
1259 //=============================================================================
1261 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1262 SMESH::SMESH_GroupBase_ptr theGroup2,
1263 const char* theName )
1264 throw (SALOME::SALOME_Exception)
1266 SMESH::SMESH_Group_var aResGrp;
1271 _preMeshInfo->FullLoadFromFile();
1273 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1274 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1276 if ( theGroup1->GetType() != theGroup2->GetType() )
1277 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1281 // Create Intersection
1282 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1283 if ( aResGrp->_is_nil() )
1284 return aResGrp._retn();
1286 SMESHDS_GroupBase* groupDS1 = 0;
1287 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1288 groupDS1 = grp_i->GetGroupDS();
1290 SMESHDS_GroupBase* groupDS2 = 0;
1291 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1292 groupDS2 = grp_i->GetGroupDS();
1294 SMESHDS_Group* resGroupDS = 0;
1295 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1296 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1298 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1300 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1301 while ( elemIt1->more() )
1303 const SMDS_MeshElement* e = elemIt1->next();
1304 if ( groupDS2->Contains( e ))
1305 resGroupDS->SMDSGroup().Add( e );
1308 // Update Python script
1309 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1310 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1312 SMESH_CATCH( SMESH::throwCorbaException );
1314 return aResGrp._retn();
1317 //=============================================================================
1319 \brief Intersect list of groups. New group is created. All mesh elements that
1320 are present in all initial groups simultaneously are added to the new one.
1321 \param theGroups list of groups
1322 \param theName name of group to be created
1323 \return pointer on the group
1325 //=============================================================================
1326 SMESH::SMESH_Group_ptr
1327 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1328 const char* theName )
1329 throw (SALOME::SALOME_Exception)
1331 SMESH::SMESH_Group_var aResGrp;
1336 _preMeshInfo->FullLoadFromFile();
1339 return SMESH::SMESH_Group::_nil();
1341 // check types and get SMESHDS_GroupBase's
1342 SMESH::ElementType aType = SMESH::ALL;
1343 vector< SMESHDS_GroupBase* > groupVec;
1344 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1346 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1347 if ( CORBA::is_nil( aGrp ) )
1349 if ( aType == SMESH::ALL )
1350 aType = aGrp->GetType();
1351 else if ( aType != aGrp->GetType() )
1352 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1355 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1356 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1358 if ( grpDS->IsEmpty() )
1363 groupVec.push_back( grpDS );
1366 if ( aType == SMESH::ALL ) // all groups are nil
1367 return SMESH::SMESH_Group::_nil();
1372 aResGrp = CreateGroup( aType, theName );
1374 SMESHDS_Group* resGroupDS = 0;
1375 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1376 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1377 if ( !resGroupDS || groupVec.empty() )
1378 return aResGrp._retn();
1381 size_t i, nb = groupVec.size();
1382 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1383 while ( elemIt1->more() )
1385 const SMDS_MeshElement* e = elemIt1->next();
1387 for ( i = 1; ( i < nb && inAll ); ++i )
1388 inAll = groupVec[i]->Contains( e );
1391 resGroupDS->SMDSGroup().Add( e );
1394 // Update Python script
1395 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1396 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1398 SMESH_CATCH( SMESH::throwCorbaException );
1400 return aResGrp._retn();
1403 //=============================================================================
1405 * New group is created. All mesh elements that are present in
1406 * a main group but is not present in a tool group are added to the new one
1408 //=============================================================================
1410 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1411 SMESH::SMESH_GroupBase_ptr theGroup2,
1412 const char* theName )
1413 throw (SALOME::SALOME_Exception)
1415 SMESH::SMESH_Group_var aResGrp;
1420 _preMeshInfo->FullLoadFromFile();
1422 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1423 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1425 if ( theGroup1->GetType() != theGroup2->GetType() )
1426 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1430 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1431 if ( aResGrp->_is_nil() )
1432 return aResGrp._retn();
1434 SMESHDS_GroupBase* groupDS1 = 0;
1435 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1436 groupDS1 = grp_i->GetGroupDS();
1438 SMESHDS_GroupBase* groupDS2 = 0;
1439 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1440 groupDS2 = grp_i->GetGroupDS();
1442 SMESHDS_Group* resGroupDS = 0;
1443 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1444 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1446 if ( groupDS1 && groupDS2 && resGroupDS )
1448 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1449 while ( elemIt1->more() )
1451 const SMDS_MeshElement* e = elemIt1->next();
1452 if ( !groupDS2->Contains( e ))
1453 resGroupDS->SMDSGroup().Add( e );
1456 // Update Python script
1457 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1458 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1460 SMESH_CATCH( SMESH::throwCorbaException );
1462 return aResGrp._retn();
1465 //=============================================================================
1467 \brief Cut lists of groups. New group is created. All mesh elements that are
1468 present in main groups but do not present in tool groups are added to the new one
1469 \param theMainGroups list of main groups
1470 \param theToolGroups list of tool groups
1471 \param theName name of group to be created
1472 \return pointer on the group
1474 //=============================================================================
1475 SMESH::SMESH_Group_ptr
1476 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1477 const SMESH::ListOfGroups& theToolGroups,
1478 const char* theName )
1479 throw (SALOME::SALOME_Exception)
1481 SMESH::SMESH_Group_var aResGrp;
1486 _preMeshInfo->FullLoadFromFile();
1489 return SMESH::SMESH_Group::_nil();
1491 // check types and get SMESHDS_GroupBase's
1492 SMESH::ElementType aType = SMESH::ALL;
1493 vector< SMESHDS_GroupBase* > toolGroupVec;
1494 vector< SMDS_ElemIteratorPtr > mainIterVec;
1496 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1498 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1499 if ( CORBA::is_nil( aGrp ) )
1501 if ( aType == SMESH::ALL )
1502 aType = aGrp->GetType();
1503 else if ( aType != aGrp->GetType() )
1504 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1506 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1507 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1508 if ( !grpDS->IsEmpty() )
1509 mainIterVec.push_back( grpDS->GetElements() );
1511 if ( aType == SMESH::ALL ) // all main groups are nil
1512 return SMESH::SMESH_Group::_nil();
1513 if ( mainIterVec.empty() ) // all main groups are empty
1514 return aResGrp._retn();
1516 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1518 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1519 if ( CORBA::is_nil( aGrp ) )
1521 if ( aType != aGrp->GetType() )
1522 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1524 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1525 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1526 toolGroupVec.push_back( grpDS );
1532 aResGrp = CreateGroup( aType, theName );
1534 SMESHDS_Group* resGroupDS = 0;
1535 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1536 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1538 return aResGrp._retn();
1541 size_t i, nb = toolGroupVec.size();
1542 SMDS_ElemIteratorPtr mainElemIt
1543 ( new SMDS_IteratorOnIterators
1544 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1545 while ( mainElemIt->more() )
1547 const SMDS_MeshElement* e = mainElemIt->next();
1549 for ( i = 0; ( i < nb && !isIn ); ++i )
1550 isIn = toolGroupVec[i]->Contains( e );
1553 resGroupDS->SMDSGroup().Add( e );
1556 // Update Python script
1557 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1558 << ".CutListOfGroups( " << theMainGroups << ", "
1559 << theToolGroups << ", '" << theName << "' )";
1561 SMESH_CATCH( SMESH::throwCorbaException );
1563 return aResGrp._retn();
1566 //=============================================================================
1568 \brief Create groups of entities from existing groups of superior dimensions
1570 1) extract all nodes from each group,
1571 2) combine all elements of specified dimension laying on these nodes.
1572 \param theGroups list of source groups
1573 \param theElemType dimension of elements
1574 \param theName name of new group
1575 \return pointer on new group
1579 //=============================================================================
1581 SMESH::SMESH_Group_ptr
1582 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1583 SMESH::ElementType theElemType,
1584 const char* theName )
1585 throw (SALOME::SALOME_Exception)
1587 SMESH::SMESH_Group_var aResGrp;
1591 _preMeshInfo->FullLoadFromFile();
1593 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1595 if ( !theName || !aMeshDS )
1596 return SMESH::SMESH_Group::_nil();
1598 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1604 aResGrp = CreateGroup( theElemType, theName );
1605 if ( aResGrp->_is_nil() )
1606 return SMESH::SMESH_Group::_nil();
1608 SMESHDS_GroupBase* groupBaseDS =
1609 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1610 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1612 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1614 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1615 if ( CORBA::is_nil( aGrp ) )
1618 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1619 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1621 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1623 while ( elIt->more() ) {
1624 const SMDS_MeshElement* el = elIt->next();
1625 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1626 while ( nIt->more() )
1627 resGroupCore.Add( nIt->next() );
1630 else // get elements of theElemType based on nodes of every element of group
1632 while ( elIt->more() )
1634 const SMDS_MeshElement* el = elIt->next(); // an element of group
1635 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1636 TIDSortedElemSet checkedElems;
1637 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1638 while ( nIt->more() )
1640 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1641 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1642 // check nodes of elements of theElemType around el
1643 while ( elOfTypeIt->more() )
1645 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1646 if ( !checkedElems.insert( elOfType ).second ) continue;
1648 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1649 bool allNodesOK = true;
1650 while ( nIt2->more() && allNodesOK )
1651 allNodesOK = elNodes.count( nIt2->next() );
1653 resGroupCore.Add( elOfType );
1660 // Update Python script
1661 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1662 << ".CreateDimGroup( "
1663 << theGroups << ", " << theElemType << ", '" << theName << "' )";
1665 SMESH_CATCH( SMESH::throwCorbaException );
1667 return aResGrp._retn();
1670 //================================================================================
1672 * \brief Remember GEOM group data
1674 //================================================================================
1676 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1677 CORBA::Object_ptr theSmeshObj)
1679 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1682 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1683 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1684 if ( groupSO->_is_nil() )
1687 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1688 GEOM::GEOM_IGroupOperations_wrap groupOp =
1689 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1690 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1693 _geomGroupData.push_back( TGeomGroupData() );
1694 TGeomGroupData & groupData = _geomGroupData.back();
1696 CORBA::String_var entry = groupSO->GetID();
1697 groupData._groupEntry = entry.in();
1699 for ( int i = 0; i < ids->length(); ++i )
1700 groupData._indices.insert( ids[i] );
1702 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1703 // shape index in SMESHDS
1704 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1705 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1708 //================================================================================
1710 * Remove GEOM group data relating to removed smesh object
1712 //================================================================================
1714 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1716 list<TGeomGroupData>::iterator
1717 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1718 for ( ; data != dataEnd; ++data ) {
1719 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1720 _geomGroupData.erase( data );
1726 //================================================================================
1728 * \brief Return new group contents if it has been changed and update group data
1730 //================================================================================
1732 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1734 TopoDS_Shape newShape;
1737 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1738 if ( study->_is_nil() ) return newShape; // means "not changed"
1739 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1740 if ( !groupSO->_is_nil() )
1742 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1743 if ( CORBA::is_nil( groupObj )) return newShape;
1744 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1746 // get indices of group items
1747 set<int> curIndices;
1748 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1749 GEOM::GEOM_IGroupOperations_wrap groupOp =
1750 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1751 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1752 for ( int i = 0; i < ids->length(); ++i )
1753 curIndices.insert( ids[i] );
1755 if ( groupData._indices == curIndices )
1756 return newShape; // group not changed
1759 groupData._indices = curIndices;
1761 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1762 if ( !geomClient ) return newShape;
1763 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1764 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1765 newShape = _gen_i->GeomObjectToShape( geomGroup );
1768 if ( newShape.IsNull() ) {
1769 // geom group becomes empty - return empty compound
1770 TopoDS_Compound compound;
1771 BRep_Builder().MakeCompound(compound);
1772 newShape = compound;
1779 //-----------------------------------------------------------------------------
1781 * \brief Storage of shape and index used in CheckGeomGroupModif()
1783 struct TIndexedShape
1786 TopoDS_Shape _shape;
1787 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1789 //-----------------------------------------------------------------------------
1791 * \brief Data to re-create a group on geometry
1793 struct TGroupOnGeomData
1797 SMDSAbs_ElementType _type;
1799 Quantity_Color _color;
1803 //=============================================================================
1805 * \brief Update data if geometry changes
1809 //=============================================================================
1811 void SMESH_Mesh_i::CheckGeomModif()
1813 if ( !_impl->HasShapeToMesh() ) return;
1815 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1816 if ( study->_is_nil() ) return;
1818 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1819 if ( mainGO->_is_nil() ) return;
1821 if ( mainGO->GetType() == GEOM_GROUP ||
1822 mainGO->GetTick() == _mainShapeTick )
1824 CheckGeomGroupModif();
1828 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1829 if ( !geomClient ) return;
1830 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1831 if ( geomGen->_is_nil() ) return;
1833 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1834 geomClient->RemoveShapeFromBuffer( ior.in() );
1836 // Update data taking into account that
1837 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1840 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1841 if ( newShape.IsNull() )
1844 _mainShapeTick = mainGO->GetTick();
1846 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1848 // store data of groups on geometry
1849 vector< TGroupOnGeomData > groupsData;
1850 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1851 groupsData.reserve( groups.size() );
1852 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1853 for ( ; g != groups.end(); ++g )
1854 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1856 TGroupOnGeomData data;
1857 data._oldID = group->GetID();
1858 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1859 data._type = group->GetType();
1860 data._name = group->GetStoreName();
1861 data._color = group->GetColor();
1862 groupsData.push_back( data );
1864 // store assigned hypotheses
1865 vector< pair< int, THypList > > ids2Hyps;
1866 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
1867 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
1869 const TopoDS_Shape& s = s2hyps.Key();
1870 const THypList& hyps = s2hyps.ChangeValue();
1871 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
1874 // change shape to mesh
1875 int oldNbSubShapes = meshDS->MaxShapeIndex();
1876 _impl->ShapeToMesh( TopoDS_Shape() );
1877 _impl->ShapeToMesh( newShape );
1879 // re-add shapes of geom groups
1880 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
1881 for ( ; data != _geomGroupData.end(); ++data )
1883 TopoDS_Shape newShape = newGroupShape( *data );
1884 if ( !newShape.IsNull() )
1886 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
1888 TopoDS_Compound compound;
1889 BRep_Builder().MakeCompound( compound );
1890 BRep_Builder().Add( compound, newShape );
1891 newShape = compound;
1893 _impl->GetSubMesh( newShape );
1896 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
1897 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
1898 SALOME::INTERNAL_ERROR );
1900 // re-assign hypotheses
1901 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
1903 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
1904 const THypList& hyps = ids2Hyps[i].second;
1905 THypList::const_iterator h = hyps.begin();
1906 for ( ; h != hyps.end(); ++h )
1907 _impl->AddHypothesis( s, (*h)->GetID() );
1911 for ( size_t i = 0; i < groupsData.size(); ++i )
1913 const TGroupOnGeomData& data = groupsData[i];
1915 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
1916 if ( i2g == _mapGroups.end() ) continue;
1918 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
1919 if ( !gr_i ) continue;
1922 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
1923 meshDS->IndexToShape( data._shapeID ));
1926 _mapGroups.erase( i2g );
1930 g->GetGroupDS()->SetColor( data._color );
1931 gr_i->changeLocalId( id );
1932 _mapGroups[ id ] = i2g->second;
1933 if ( data._oldID != id )
1934 _mapGroups.erase( i2g );
1938 // update _mapSubMesh
1939 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
1940 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
1941 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
1945 //=============================================================================
1947 * \brief Update objects depending on changed geom groups
1949 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1950 * issue 0020210: Update of a smesh group after modification of the associated geom group
1952 //=============================================================================
1954 void SMESH_Mesh_i::CheckGeomGroupModif()
1956 if ( !_impl->HasShapeToMesh() ) return;
1958 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1959 if ( study->_is_nil() ) return;
1961 CORBA::Long nbEntities = NbNodes() + NbElements();
1963 // Check if group contents changed
1965 typedef map< string, TopoDS_Shape > TEntry2Geom;
1966 TEntry2Geom newGroupContents;
1968 list<TGeomGroupData>::iterator
1969 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1970 for ( ; data != dataEnd; ++data )
1972 pair< TEntry2Geom::iterator, bool > it_new =
1973 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1974 bool processedGroup = !it_new.second;
1975 TopoDS_Shape& newShape = it_new.first->second;
1976 if ( !processedGroup )
1977 newShape = newGroupShape( *data );
1978 if ( newShape.IsNull() )
1979 continue; // no changes
1982 _preMeshInfo->ForgetOrLoad();
1984 if ( processedGroup ) { // update group indices
1985 list<TGeomGroupData>::iterator data2 = data;
1986 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1987 data->_indices = data2->_indices;
1990 // Update SMESH objects according to new GEOM group contents
1992 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1993 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1995 int oldID = submesh->GetId();
1996 if ( !_mapSubMeshIor.count( oldID ))
1998 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2000 // update hypotheses
2001 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2002 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2003 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2005 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2006 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2008 // care of submeshes
2009 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2010 int newID = newSubmesh->GetId();
2011 if ( newID != oldID ) {
2012 _mapSubMesh [ newID ] = newSubmesh;
2013 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2014 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2015 _mapSubMesh. erase(oldID);
2016 _mapSubMesh_i. erase(oldID);
2017 _mapSubMeshIor.erase(oldID);
2018 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2023 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2024 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2025 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2027 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2029 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2030 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2031 ds->SetShape( newShape );
2036 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2037 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2039 // Remove groups and submeshes basing on removed sub-shapes
2041 TopTools_MapOfShape newShapeMap;
2042 TopoDS_Iterator shapeIt( newShape );
2043 for ( ; shapeIt.More(); shapeIt.Next() )
2044 newShapeMap.Add( shapeIt.Value() );
2046 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2047 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2049 if ( newShapeMap.Contains( shapeIt.Value() ))
2051 TopTools_IndexedMapOfShape oldShapeMap;
2052 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2053 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2055 const TopoDS_Shape& oldShape = oldShapeMap(i);
2056 int oldInd = meshDS->ShapeToIndex( oldShape );
2058 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2059 if ( i_smIor != _mapSubMeshIor.end() ) {
2060 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2063 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2064 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2066 // check if a group bases on oldInd shape
2067 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2068 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2069 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2070 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2072 RemoveGroup( i_grp->second ); // several groups can base on same shape
2073 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2078 // Reassign hypotheses and update groups after setting the new shape to mesh
2080 // collect anassigned hypotheses
2081 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2082 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2083 TShapeHypList assignedHyps;
2084 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2086 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2087 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2088 if ( !hyps.empty() ) {
2089 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2090 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2091 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2094 // collect shapes supporting groups
2095 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2096 TShapeTypeList groupData;
2097 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2098 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2099 for ( ; grIt != groups.end(); ++grIt )
2101 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2103 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2105 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2106 _impl->ShapeToMesh( newShape );
2108 // reassign hypotheses
2109 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2110 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2112 TIndexedShape& geom = indS_hyps->first;
2113 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2114 int oldID = geom._index;
2115 int newID = meshDS->ShapeToIndex( geom._shape );
2116 if ( oldID == 1 ) { // main shape
2118 geom._shape = newShape;
2122 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2123 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2124 // care of submeshes
2125 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2126 if ( newID != oldID ) {
2127 _mapSubMesh [ newID ] = newSubmesh;
2128 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2129 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2130 _mapSubMesh. erase(oldID);
2131 _mapSubMesh_i. erase(oldID);
2132 _mapSubMeshIor.erase(oldID);
2133 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2137 TShapeTypeList::iterator geomType = groupData.begin();
2138 for ( ; geomType != groupData.end(); ++geomType )
2140 const TIndexedShape& geom = geomType->first;
2141 int oldID = geom._index;
2142 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2145 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2146 CORBA::String_var name = groupSO->GetName();
2148 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2150 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2151 group_i->changeLocalId( newID );
2154 break; // everything has been updated
2157 } // loop on group data
2161 CORBA::Long newNbEntities = NbNodes() + NbElements();
2162 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2163 if ( newNbEntities != nbEntities )
2165 // Add all SObjects with icons to soToUpdateIcons
2166 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2168 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2169 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2170 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2172 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2173 i_gr != _mapGroups.end(); ++i_gr ) // groups
2174 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2177 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2178 for ( ; so != soToUpdateIcons.end(); ++so )
2179 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2182 //=============================================================================
2184 * \brief Create standalone group from a group on geometry or filter
2186 //=============================================================================
2188 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2189 throw (SALOME::SALOME_Exception)
2191 SMESH::SMESH_Group_var aGroup;
2196 _preMeshInfo->FullLoadFromFile();
2198 if ( theGroup->_is_nil() )
2199 return aGroup._retn();
2201 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2203 return aGroup._retn();
2205 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2207 const int anId = aGroupToRem->GetLocalID();
2208 if ( !_impl->ConvertToStandalone( anId ) )
2209 return aGroup._retn();
2210 removeGeomGroupData( theGroup );
2212 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2214 // remove old instance of group from own map
2215 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2216 _mapGroups.erase( anId );
2218 SALOMEDS::StudyBuilder_var builder;
2219 SALOMEDS::SObject_wrap aGroupSO;
2220 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2221 if ( !aStudy->_is_nil() ) {
2222 builder = aStudy->NewBuilder();
2223 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2224 if ( !aGroupSO->_is_nil() )
2226 // remove reference to geometry
2227 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2228 for ( ; chItr->More(); chItr->Next() )
2229 // Remove group's child SObject
2230 builder->RemoveObject( chItr->Value() );
2232 // Update Python script
2233 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2234 << ".ConvertToStandalone( " << aGroupSO << " )";
2236 // change icon of Group on Filter
2239 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2240 const int isEmpty = ( elemTypes->length() == 0 );
2243 SALOMEDS::GenericAttribute_wrap anAttr =
2244 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2245 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2246 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2252 // remember new group in own map
2253 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2254 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2256 // register CORBA object for persistence
2257 _gen_i->RegisterObject( aGroup );
2259 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2260 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2261 //aGroup->Register();
2262 aGroupToRem->UnRegister();
2264 SMESH_CATCH( SMESH::throwCorbaException );
2266 return aGroup._retn();
2269 //=============================================================================
2273 //=============================================================================
2275 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2277 if(MYDEBUG) MESSAGE( "createSubMesh" );
2278 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2279 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2280 const int subMeshId = mySubMesh->GetId();
2282 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2283 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2285 _mapSubMesh [subMeshId] = mySubMesh;
2286 _mapSubMesh_i [subMeshId] = subMeshServant;
2287 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2289 subMeshServant->Register();
2291 // register CORBA object for persistence
2292 int nextId = _gen_i->RegisterObject( subMesh );
2293 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2294 else { nextId = 0; } // avoid "unused variable" warning
2296 // to track changes of GEOM groups
2297 addGeomGroupData( theSubShapeObject, subMesh );
2299 return subMesh._retn();
2302 //=======================================================================
2303 //function : getSubMesh
2305 //=======================================================================
2307 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2309 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2310 if ( it == _mapSubMeshIor.end() )
2311 return SMESH::SMESH_subMesh::_nil();
2313 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2316 //=============================================================================
2320 //=============================================================================
2322 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2323 GEOM::GEOM_Object_ptr theSubShapeObject )
2325 bool isHypChanged = false;
2326 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2327 return isHypChanged;
2329 const int subMeshId = theSubMesh->GetId();
2331 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2333 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2335 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2338 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2339 isHypChanged = !hyps.empty();
2340 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2341 for ( ; hyp != hyps.end(); ++hyp )
2342 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2349 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2350 isHypChanged = ( aHypList->length() > 0 );
2351 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2352 removeHypothesis( theSubShapeObject, aHypList[i] );
2355 catch( const SALOME::SALOME_Exception& ) {
2356 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2358 removeGeomGroupData( theSubShapeObject );
2362 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2363 if ( id_smi != _mapSubMesh_i.end() )
2364 id_smi->second->UnRegister();
2366 // remove a CORBA object
2367 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2368 if ( id_smptr != _mapSubMeshIor.end() )
2369 SMESH::SMESH_subMesh_var( id_smptr->second );
2371 _mapSubMesh.erase(subMeshId);
2372 _mapSubMesh_i.erase(subMeshId);
2373 _mapSubMeshIor.erase(subMeshId);
2375 return isHypChanged;
2378 //=============================================================================
2382 //=============================================================================
2384 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2385 const char* theName,
2386 const TopoDS_Shape& theShape,
2387 const SMESH_PredicatePtr& thePredicate )
2389 std::string newName;
2390 if ( !theName || strlen( theName ) == 0 )
2392 std::set< std::string > presentNames;
2393 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2394 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2396 CORBA::String_var name = i_gr->second->GetName();
2397 presentNames.insert( name.in() );
2400 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2401 } while ( !presentNames.insert( newName ).second );
2402 theName = newName.c_str();
2405 SMESH::SMESH_GroupBase_var aGroup;
2406 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2408 SMESH_GroupBase_i* aGroupImpl;
2409 if ( !theShape.IsNull() )
2410 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2411 else if ( thePredicate )
2412 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2414 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2416 aGroup = aGroupImpl->_this();
2417 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2418 aGroupImpl->Register();
2420 // register CORBA object for persistence
2421 int nextId = _gen_i->RegisterObject( aGroup );
2422 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2423 else { nextId = 0; } // avoid "unused variable" warning in release mode
2425 // to track changes of GEOM groups
2426 if ( !theShape.IsNull() ) {
2427 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2428 addGeomGroupData( geom, aGroup );
2431 return aGroup._retn();
2434 //=============================================================================
2436 * SMESH_Mesh_i::removeGroup
2438 * Should be called by ~SMESH_Group_i()
2440 //=============================================================================
2442 void SMESH_Mesh_i::removeGroup( const int theId )
2444 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2445 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2446 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2447 _mapGroups.erase( theId );
2448 removeGeomGroupData( group );
2449 if ( !_impl->RemoveGroup( theId ))
2451 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2452 RemoveGroup( group );
2454 group->UnRegister();
2458 //=============================================================================
2462 //=============================================================================
2464 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2465 throw(SALOME::SALOME_Exception)
2467 SMESH::log_array_var aLog;
2471 _preMeshInfo->FullLoadFromFile();
2473 list < SMESHDS_Command * >logDS = _impl->GetLog();
2474 aLog = new SMESH::log_array;
2476 int lg = logDS.size();
2479 list < SMESHDS_Command * >::iterator its = logDS.begin();
2480 while(its != logDS.end()){
2481 SMESHDS_Command *com = *its;
2482 int comType = com->GetType();
2484 int lgcom = com->GetNumber();
2486 const list < int >&intList = com->GetIndexes();
2487 int inum = intList.size();
2489 list < int >::const_iterator ii = intList.begin();
2490 const list < double >&coordList = com->GetCoords();
2491 int rnum = coordList.size();
2493 list < double >::const_iterator ir = coordList.begin();
2494 aLog[indexLog].commandType = comType;
2495 aLog[indexLog].number = lgcom;
2496 aLog[indexLog].coords.length(rnum);
2497 aLog[indexLog].indexes.length(inum);
2498 for(int i = 0; i < rnum; i++){
2499 aLog[indexLog].coords[i] = *ir;
2500 //MESSAGE(" "<<i<<" "<<ir.Value());
2503 for(int i = 0; i < inum; i++){
2504 aLog[indexLog].indexes[i] = *ii;
2505 //MESSAGE(" "<<i<<" "<<ii.Value());
2514 SMESH_CATCH( SMESH::throwCorbaException );
2516 return aLog._retn();
2520 //=============================================================================
2524 //=============================================================================
2526 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2530 SMESH_CATCH( SMESH::throwCorbaException );
2533 //=============================================================================
2537 //=============================================================================
2539 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2544 //=============================================================================
2548 //=============================================================================
2550 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2555 //=============================================================================
2558 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2559 // issue 0020918: groups removal is caused by hyp modification
2560 // issue 0021208: to forget not loaded mesh data at hyp modification
2561 struct TCallUp_i : public SMESH_Mesh::TCallUp
2563 SMESH_Mesh_i* _mesh;
2564 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2565 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2566 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2567 virtual void Load () { _mesh->Load(); }
2571 //================================================================================
2573 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2575 //================================================================================
2577 void SMESH_Mesh_i::onHypothesisModified()
2580 _preMeshInfo->ForgetOrLoad();
2583 //=============================================================================
2587 //=============================================================================
2589 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2591 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2594 _impl->SetCallUp( new TCallUp_i(this));
2597 //=============================================================================
2601 //=============================================================================
2603 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2605 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2609 //=============================================================================
2611 * Return mesh editor
2613 //=============================================================================
2615 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2616 throw (SALOME::SALOME_Exception)
2618 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2622 _preMeshInfo->FullLoadFromFile();
2624 // Create MeshEditor
2626 _editor = new SMESH_MeshEditor_i( this, false );
2627 aMeshEdVar = _editor->_this();
2629 // Update Python script
2630 TPythonDump() << _editor << " = "
2631 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2633 SMESH_CATCH( SMESH::throwCorbaException );
2635 return aMeshEdVar._retn();
2638 //=============================================================================
2640 * Return mesh edition previewer
2642 //=============================================================================
2644 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2645 throw (SALOME::SALOME_Exception)
2647 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2651 _preMeshInfo->FullLoadFromFile();
2653 if ( !_previewEditor )
2654 _previewEditor = new SMESH_MeshEditor_i( this, true );
2655 aMeshEdVar = _previewEditor->_this();
2657 SMESH_CATCH( SMESH::throwCorbaException );
2659 return aMeshEdVar._retn();
2662 //================================================================================
2664 * \brief Return true if the mesh has been edited since a last total re-compute
2665 * and those modifications may prevent successful partial re-compute
2667 //================================================================================
2669 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2671 Unexpect aCatch(SALOME_SalomeException);
2672 return _impl->HasModificationsToDiscard();
2675 //================================================================================
2677 * \brief Returns a random unique color
2679 //================================================================================
2681 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2683 const int MAX_ATTEMPTS = 100;
2685 double tolerance = 0.5;
2686 SALOMEDS::Color col;
2690 // generate random color
2691 double red = (double)rand() / RAND_MAX;
2692 double green = (double)rand() / RAND_MAX;
2693 double blue = (double)rand() / RAND_MAX;
2694 // check existence in the list of the existing colors
2695 bool matched = false;
2696 std::list<SALOMEDS::Color>::const_iterator it;
2697 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2698 SALOMEDS::Color color = *it;
2699 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2700 matched = tol < tolerance;
2702 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2703 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2711 //=============================================================================
2713 * Sets auto-color mode. If it is on, groups get unique random colors
2715 //=============================================================================
2717 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2719 Unexpect aCatch(SALOME_SalomeException);
2720 _impl->SetAutoColor(theAutoColor);
2722 TPythonDump pyDump; // not to dump group->SetColor() from below code
2723 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2725 std::list<SALOMEDS::Color> aReservedColors;
2726 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2727 for ( ; it != _mapGroups.end(); it++ ) {
2728 if ( CORBA::is_nil( it->second )) continue;
2729 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2730 it->second->SetColor( aColor );
2731 aReservedColors.push_back( aColor );
2735 //=============================================================================
2737 * Returns true if auto-color mode is on
2739 //=============================================================================
2741 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2743 Unexpect aCatch(SALOME_SalomeException);
2744 return _impl->GetAutoColor();
2747 //=============================================================================
2749 * Checks if there are groups with equal names
2751 //=============================================================================
2753 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2755 return _impl->HasDuplicatedGroupNamesMED();
2758 //================================================================================
2760 * \brief Care of a file before exporting mesh into it
2762 //================================================================================
2764 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2766 SMESH_File aFile( file );
2768 if (aFile.exists()) {
2769 // existing filesystem node
2770 if ( !aFile.isDirectory() ) {
2771 if ( aFile.openForWriting() ) {
2772 if ( overwrite && ! aFile.remove()) {
2773 msg << "Can't replace " << aFile.getName();
2776 msg << "Can't write into " << aFile.getName();
2779 msg << "Location " << aFile.getName() << " is not a file";
2783 // nonexisting file; check if it can be created
2784 if ( !aFile.openForWriting() ) {
2785 msg << "You cannot create the file "
2787 << ". Check the directory existance and access rights";
2795 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2799 //================================================================================
2801 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2802 * \param file - file name
2803 * \param overwrite - to erase the file or not
2804 * \retval string - mesh name
2806 //================================================================================
2808 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2809 CORBA::Boolean overwrite)
2812 PrepareForWriting(file, overwrite);
2813 string aMeshName = "Mesh";
2814 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2815 if ( !aStudy->_is_nil() ) {
2816 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2817 if ( !aMeshSO->_is_nil() ) {
2818 CORBA::String_var name = aMeshSO->GetName();
2820 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2821 if ( !aStudy->GetProperties()->IsLocked() )
2823 SALOMEDS::GenericAttribute_wrap anAttr;
2824 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2825 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2826 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2827 ASSERT(!aFileName->_is_nil());
2828 aFileName->SetValue(file);
2829 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2830 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2831 ASSERT(!aFileType->_is_nil());
2832 aFileType->SetValue("FICHIERMED");
2836 // Update Python script
2837 // set name of mesh before export
2838 TPythonDump() << _gen_i << ".SetName("
2839 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2841 // check names of groups
2847 //================================================================================
2849 * \brief Export to med file
2851 //================================================================================
2853 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2854 CORBA::Boolean auto_groups,
2855 SMESH::MED_VERSION theVersion,
2856 CORBA::Boolean overwrite,
2857 CORBA::Boolean autoDimension)
2858 throw(SALOME::SALOME_Exception)
2862 _preMeshInfo->FullLoadFromFile();
2864 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2865 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2867 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2868 << file << "', " << auto_groups << ", "
2869 << theVersion << ", " << overwrite << ", "
2870 << autoDimension << " )";
2872 SMESH_CATCH( SMESH::throwCorbaException );
2875 //================================================================================
2877 * \brief Export a mesh to a med file
2879 //================================================================================
2881 void SMESH_Mesh_i::ExportToMED (const char* file,
2882 CORBA::Boolean auto_groups,
2883 SMESH::MED_VERSION theVersion)
2884 throw(SALOME::SALOME_Exception)
2886 ExportToMEDX(file,auto_groups,theVersion,true);
2889 //================================================================================
2891 * \brief Export a mesh to a med file
2893 //================================================================================
2895 void SMESH_Mesh_i::ExportMED (const char* file,
2896 CORBA::Boolean auto_groups)
2897 throw(SALOME::SALOME_Exception)
2899 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2902 //================================================================================
2904 * \brief Export a mesh to a SAUV file
2906 //================================================================================
2908 void SMESH_Mesh_i::ExportSAUV (const char* file,
2909 CORBA::Boolean auto_groups)
2910 throw(SALOME::SALOME_Exception)
2912 Unexpect aCatch(SALOME_SalomeException);
2914 _preMeshInfo->FullLoadFromFile();
2916 string aMeshName = prepareMeshNameAndGroups(file, true);
2917 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
2918 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2919 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2923 //================================================================================
2925 * \brief Export a mesh to a DAT file
2927 //================================================================================
2929 void SMESH_Mesh_i::ExportDAT (const char *file)
2930 throw(SALOME::SALOME_Exception)
2932 Unexpect aCatch(SALOME_SalomeException);
2934 _preMeshInfo->FullLoadFromFile();
2936 // Update Python script
2937 // check names of groups
2939 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
2942 PrepareForWriting(file);
2943 _impl->ExportDAT(file);
2946 //================================================================================
2948 * \brief Export a mesh to an UNV file
2950 //================================================================================
2952 void SMESH_Mesh_i::ExportUNV (const char *file)
2953 throw(SALOME::SALOME_Exception)
2955 Unexpect aCatch(SALOME_SalomeException);
2957 _preMeshInfo->FullLoadFromFile();
2959 // Update Python script
2960 // check names of groups
2962 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
2965 PrepareForWriting(file);
2966 _impl->ExportUNV(file);
2969 //================================================================================
2971 * \brief Export a mesh to an STL file
2973 //================================================================================
2975 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2976 throw(SALOME::SALOME_Exception)
2978 Unexpect aCatch(SALOME_SalomeException);
2980 _preMeshInfo->FullLoadFromFile();
2982 // Update Python script
2983 // check names of groups
2985 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2986 << ".ExportSTL( r'" << file << "', " << isascii << " )";
2989 PrepareForWriting(file);
2990 _impl->ExportSTL(file, isascii);
2993 //================================================================================
2995 * \brief Export a part of mesh to a med file
2997 //================================================================================
2999 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3001 CORBA::Boolean auto_groups,
3002 SMESH::MED_VERSION version,
3003 CORBA::Boolean overwrite,
3004 CORBA::Boolean autoDimension,
3005 const GEOM::ListOfFields& fields,
3006 const char* geomAssocFields)
3007 throw (SALOME::SALOME_Exception)
3011 _preMeshInfo->FullLoadFromFile();
3014 bool have0dField = false;
3015 if ( fields.length() > 0 )
3017 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3018 if ( shapeToMesh->_is_nil() )
3019 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3021 for ( size_t i = 0; i < fields.length(); ++i )
3023 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3024 THROW_SALOME_CORBA_EXCEPTION
3025 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3026 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3027 if ( fieldShape->_is_nil() )
3028 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3029 if ( !fieldShape->IsSame( shapeToMesh ) )
3030 THROW_SALOME_CORBA_EXCEPTION
3031 ( "Field defined not on shape", SALOME::BAD_PARAM);
3032 if ( fields[i]->GetDimension() == 0 )
3035 if ( geomAssocFields )
3036 for ( int i = 0; geomAssocFields[i]; ++i )
3037 switch ( geomAssocFields[i] ) {
3038 case 'v':case 'e':case 'f':case 's': break;
3039 case 'V':case 'E':case 'F':case 'S': break;
3040 default: THROW_SALOME_CORBA_EXCEPTION
3041 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3045 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3049 string aMeshName = "Mesh";
3050 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3051 if ( CORBA::is_nil( meshPart ) ||
3052 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3054 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3055 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3056 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3057 meshDS = _impl->GetMeshDS();
3062 _preMeshInfo->FullLoadFromFile();
3064 PrepareForWriting(file, overwrite);
3066 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3067 if ( !aStudy->_is_nil() ) {
3068 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3069 if ( !SO->_is_nil() ) {
3070 CORBA::String_var name = SO->GetName();
3074 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3075 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3076 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3077 meshDS = tmpDSDeleter._obj = partDS;
3082 if ( _impl->HasShapeToMesh() )
3084 DriverMED_W_Field fieldWriter;
3085 fieldWriter.SetFile( file );
3086 fieldWriter.SetMeshName( aMeshName );
3087 fieldWriter.AddODOnVertices( have0dField );
3089 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3093 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3094 goList->length( fields.length() );
3095 for ( size_t i = 0; i < fields.length(); ++i )
3097 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3100 TPythonDump() << _this() << ".ExportPartToMED( "
3101 << meshPart << ", r'" << file << "', "
3102 << auto_groups << ", " << version << ", " << overwrite << ", "
3103 << autoDimension << ", " << goList
3104 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3106 SMESH_CATCH( SMESH::throwCorbaException );
3109 //================================================================================
3111 * Write GEOM fields to MED file
3113 //================================================================================
3115 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3116 SMESHDS_Mesh* meshDS,
3117 const GEOM::ListOfFields& fields,
3118 const char* geomAssocFields)
3120 #define METH "SMESH_Mesh_i::exportMEDFields() "
3122 if (( fields.length() < 1 ) &&
3123 ( !geomAssocFields || !geomAssocFields[0] ))
3126 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3127 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3128 std::vector< int > subIdsByDim[ 4 ];
3129 const double noneDblValue = 0.;
3130 const double noneIntValue = 0;
3132 for ( size_t iF = 0; iF < fields.length(); ++iF )
3136 int dim = fields[ iF ]->GetDimension();
3137 SMDSAbs_ElementType elemType;
3138 TopAbs_ShapeEnum shapeType;
3140 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3141 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3142 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3143 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3145 continue; // skip fields on whole shape
3147 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3148 if ( dataType == GEOM::FDT_String )
3150 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3151 if ( stepIDs->length() < 1 )
3153 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3154 if ( comps->length() < 1 )
3156 CORBA::String_var name = fields[ iF ]->GetName();
3158 if ( !fieldWriter.Set( meshDS,
3162 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3165 for ( size_t iC = 0; iC < comps->length(); ++iC )
3166 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3168 // find sub-shape IDs
3170 std::vector< int >& subIds = subIdsByDim[ dim ];
3171 if ( subIds.empty() )
3172 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3173 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3174 subIds.push_back( id );
3178 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3182 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3184 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3185 if ( step->_is_nil() )
3188 CORBA::Long stamp = step->GetStamp();
3189 CORBA::Long id = step->GetID();
3190 fieldWriter.SetDtIt( int( stamp ), int( id ));
3192 // fill dblVals or intVals
3195 case GEOM::FDT_Double:
3197 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3198 if ( dblStep->_is_nil() ) continue;
3199 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3200 if ( vv->length() != subIds.size() )
3201 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3202 for ( size_t i = 0; i < vv->length(); ++i )
3203 dblVals[ subIds[ i ]] = vv[ i ];
3208 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3209 if ( intStep->_is_nil() ) continue;
3210 GEOM::ListOfLong_var vv = intStep->GetValues();
3211 if ( vv->length() != subIds.size() )
3212 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3213 for ( size_t i = 0; i < vv->length(); ++i )
3214 intVals[ subIds[ i ]] = (int) vv[ i ];
3217 case GEOM::FDT_Bool:
3219 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3220 if ( boolStep->_is_nil() ) continue;
3221 GEOM::short_array_var vv = boolStep->GetValues();
3222 if ( vv->length() != subIds.size() )
3223 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3224 for ( size_t i = 0; i < vv->length(); ++i )
3225 intVals[ subIds[ i ]] = (int) vv[ i ];
3231 // pass values to fieldWriter
3232 elemIt = fieldWriter.GetOrderedElems();
3233 if ( dataType == GEOM::FDT_Double )
3234 while ( elemIt->more() )
3236 const SMDS_MeshElement* e = elemIt->next();
3237 const int shapeID = e->getshapeId();
3238 if ( shapeID < 1 || shapeID >= dblVals.size() )
3239 fieldWriter.AddValue( noneDblValue );
3241 fieldWriter.AddValue( dblVals[ shapeID ]);
3244 while ( elemIt->more() )
3246 const SMDS_MeshElement* e = elemIt->next();
3247 const int shapeID = e->getshapeId();
3248 if ( shapeID < 1 || shapeID >= intVals.size() )
3249 fieldWriter.AddValue( (double) noneIntValue );
3251 fieldWriter.AddValue( (double) intVals[ shapeID ]);
3255 fieldWriter.Perform();
3256 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3257 if ( res && res->IsKO() )
3259 if ( res->myComment.empty() )
3260 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3262 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3268 if ( !geomAssocFields || !geomAssocFields[0] )
3271 // write geomAssocFields
3273 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3274 shapeDim[ TopAbs_COMPOUND ] = 3;
3275 shapeDim[ TopAbs_COMPSOLID ] = 3;
3276 shapeDim[ TopAbs_SOLID ] = 3;
3277 shapeDim[ TopAbs_SHELL ] = 2;
3278 shapeDim[ TopAbs_FACE ] = 2;
3279 shapeDim[ TopAbs_WIRE ] = 1;
3280 shapeDim[ TopAbs_EDGE ] = 1;
3281 shapeDim[ TopAbs_VERTEX ] = 0;
3282 shapeDim[ TopAbs_SHAPE ] = 3;
3284 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3286 std::vector< std::string > compNames;
3287 switch ( geomAssocFields[ iF ]) {
3289 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3290 compNames.push_back( "dim" );
3293 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3296 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3299 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3303 compNames.push_back( "id" );
3304 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3305 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3307 fieldWriter.SetDtIt( -1, -1 );
3309 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3313 if ( compNames.size() == 2 ) // _vertices_
3314 while ( elemIt->more() )
3316 const SMDS_MeshElement* e = elemIt->next();
3317 const int shapeID = e->getshapeId();
3320 fieldWriter.AddValue( (double) -1 );
3321 fieldWriter.AddValue( (double) -1 );
3325 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3326 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3327 fieldWriter.AddValue( (double) shapeID );
3331 while ( elemIt->more() )
3333 const SMDS_MeshElement* e = elemIt->next();
3334 const int shapeID = e->getshapeId();
3336 fieldWriter.AddValue( (double) -1 );
3338 fieldWriter.AddValue( (double) shapeID );
3342 fieldWriter.Perform();
3343 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3344 if ( res && res->IsKO() )
3346 if ( res->myComment.empty() )
3347 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3349 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3352 } // loop on geomAssocFields
3357 //================================================================================
3359 * \brief Export a part of mesh to a DAT file
3361 //================================================================================
3363 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3365 throw (SALOME::SALOME_Exception)
3367 Unexpect aCatch(SALOME_SalomeException);
3369 _preMeshInfo->FullLoadFromFile();
3371 PrepareForWriting(file);
3373 SMESH_MeshPartDS partDS( meshPart );
3374 _impl->ExportDAT(file,&partDS);
3376 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3377 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3379 //================================================================================
3381 * \brief Export a part of mesh to an UNV file
3383 //================================================================================
3385 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3387 throw (SALOME::SALOME_Exception)
3389 Unexpect aCatch(SALOME_SalomeException);
3391 _preMeshInfo->FullLoadFromFile();
3393 PrepareForWriting(file);
3395 SMESH_MeshPartDS partDS( meshPart );
3396 _impl->ExportUNV(file, &partDS);
3398 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3399 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3401 //================================================================================
3403 * \brief Export a part of mesh to an STL file
3405 //================================================================================
3407 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3409 ::CORBA::Boolean isascii)
3410 throw (SALOME::SALOME_Exception)
3412 Unexpect aCatch(SALOME_SalomeException);
3414 _preMeshInfo->FullLoadFromFile();
3416 PrepareForWriting(file);
3418 SMESH_MeshPartDS partDS( meshPart );
3419 _impl->ExportSTL(file, isascii, &partDS);
3421 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3422 << meshPart<< ", r'" << file << "', " << isascii << ")";
3425 //================================================================================
3427 * \brief Export a part of mesh to an STL file
3429 //================================================================================
3431 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3433 CORBA::Boolean overwrite)
3434 throw (SALOME::SALOME_Exception)
3437 Unexpect aCatch(SALOME_SalomeException);
3439 _preMeshInfo->FullLoadFromFile();
3441 PrepareForWriting(file,overwrite);
3443 SMESH_MeshPartDS partDS( meshPart );
3444 _impl->ExportCGNS(file, &partDS);
3446 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3447 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3449 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3453 //================================================================================
3455 * \brief Export a part of mesh to a GMF file
3457 //================================================================================
3459 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3461 bool withRequiredGroups)
3462 throw (SALOME::SALOME_Exception)
3464 Unexpect aCatch(SALOME_SalomeException);
3466 _preMeshInfo->FullLoadFromFile();
3468 PrepareForWriting(file,/*overwrite=*/true);
3470 SMESH_MeshPartDS partDS( meshPart );
3471 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3473 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3474 << meshPart<< ", r'"
3476 << withRequiredGroups << ")";
3479 //=============================================================================
3481 * Return computation progress [0.,1]
3483 //=============================================================================
3485 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3489 return _impl->GetComputeProgress();
3491 SMESH_CATCH( SMESH::doNothing );
3495 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3497 Unexpect aCatch(SALOME_SalomeException);
3499 return _preMeshInfo->NbNodes();
3501 return _impl->NbNodes();
3504 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3506 Unexpect aCatch(SALOME_SalomeException);
3508 return _preMeshInfo->NbElements();
3510 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3513 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3515 Unexpect aCatch(SALOME_SalomeException);
3517 return _preMeshInfo->Nb0DElements();
3519 return _impl->Nb0DElements();
3522 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3524 Unexpect aCatch(SALOME_SalomeException);
3526 return _preMeshInfo->NbBalls();
3528 return _impl->NbBalls();
3531 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3533 Unexpect aCatch(SALOME_SalomeException);
3535 return _preMeshInfo->NbEdges();
3537 return _impl->NbEdges();
3540 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3541 throw(SALOME::SALOME_Exception)
3543 Unexpect aCatch(SALOME_SalomeException);
3545 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3547 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3550 //=============================================================================
3552 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3554 Unexpect aCatch(SALOME_SalomeException);
3556 return _preMeshInfo->NbFaces();
3558 return _impl->NbFaces();
3561 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3563 Unexpect aCatch(SALOME_SalomeException);
3565 return _preMeshInfo->NbTriangles();
3567 return _impl->NbTriangles();
3570 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3572 Unexpect aCatch(SALOME_SalomeException);
3574 return _preMeshInfo->NbBiQuadTriangles();
3576 return _impl->NbBiQuadTriangles();
3579 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3581 Unexpect aCatch(SALOME_SalomeException);
3583 return _preMeshInfo->NbQuadrangles();
3585 return _impl->NbQuadrangles();
3588 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3590 Unexpect aCatch(SALOME_SalomeException);
3592 return _preMeshInfo->NbBiQuadQuadrangles();
3594 return _impl->NbBiQuadQuadrangles();
3597 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3599 Unexpect aCatch(SALOME_SalomeException);
3601 return _preMeshInfo->NbPolygons();
3603 return _impl->NbPolygons();
3606 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3607 throw(SALOME::SALOME_Exception)
3609 Unexpect aCatch(SALOME_SalomeException);
3611 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3613 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3616 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3617 throw(SALOME::SALOME_Exception)
3619 Unexpect aCatch(SALOME_SalomeException);
3621 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3623 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3626 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3627 throw(SALOME::SALOME_Exception)
3629 Unexpect aCatch(SALOME_SalomeException);
3631 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3633 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3636 //=============================================================================
3638 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3640 Unexpect aCatch(SALOME_SalomeException);
3642 return _preMeshInfo->NbVolumes();
3644 return _impl->NbVolumes();
3647 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3649 Unexpect aCatch(SALOME_SalomeException);
3651 return _preMeshInfo->NbTetras();
3653 return _impl->NbTetras();
3656 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3658 Unexpect aCatch(SALOME_SalomeException);
3660 return _preMeshInfo->NbHexas();
3662 return _impl->NbHexas();
3665 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3667 Unexpect aCatch(SALOME_SalomeException);
3669 return _preMeshInfo->NbTriQuadHexas();
3671 return _impl->NbTriQuadraticHexas();
3674 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3676 Unexpect aCatch(SALOME_SalomeException);
3678 return _preMeshInfo->NbPyramids();
3680 return _impl->NbPyramids();
3683 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3685 Unexpect aCatch(SALOME_SalomeException);
3687 return _preMeshInfo->NbPrisms();
3689 return _impl->NbPrisms();
3692 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3694 Unexpect aCatch(SALOME_SalomeException);
3696 return _preMeshInfo->NbHexPrisms();
3698 return _impl->NbHexagonalPrisms();
3701 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3703 Unexpect aCatch(SALOME_SalomeException);
3705 return _preMeshInfo->NbPolyhedrons();
3707 return _impl->NbPolyhedrons();
3710 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3711 throw(SALOME::SALOME_Exception)
3713 Unexpect aCatch(SALOME_SalomeException);
3715 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3717 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3720 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3721 throw(SALOME::SALOME_Exception)
3723 Unexpect aCatch(SALOME_SalomeException);
3725 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3727 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3730 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3731 throw(SALOME::SALOME_Exception)
3733 Unexpect aCatch(SALOME_SalomeException);
3735 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3737 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3740 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3741 throw(SALOME::SALOME_Exception)
3743 Unexpect aCatch(SALOME_SalomeException);
3745 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3747 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3750 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3751 throw(SALOME::SALOME_Exception)
3753 Unexpect aCatch(SALOME_SalomeException);
3755 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3757 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3760 //=============================================================================
3762 * Returns nb of published sub-meshes
3764 //=============================================================================
3766 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3768 Unexpect aCatch(SALOME_SalomeException);
3769 return _mapSubMesh_i.size();
3772 //=============================================================================
3774 * Dumps mesh into a string
3776 //=============================================================================
3778 char* SMESH_Mesh_i::Dump()
3782 return CORBA::string_dup( os.str().c_str() );
3785 //=============================================================================
3787 * Method of SMESH_IDSource interface
3789 //=============================================================================
3791 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3793 return GetElementsId();
3796 //=============================================================================
3798 * Returns ids of all elements
3800 //=============================================================================
3802 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3803 throw (SALOME::SALOME_Exception)
3805 Unexpect aCatch(SALOME_SalomeException);
3807 _preMeshInfo->FullLoadFromFile();
3809 SMESH::long_array_var aResult = new SMESH::long_array();
3810 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3812 if ( aSMESHDS_Mesh == NULL )
3813 return aResult._retn();
3815 long nbElements = NbElements();
3816 aResult->length( nbElements );
3817 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3818 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3819 aResult[i] = anIt->next()->GetID();
3821 return aResult._retn();
3825 //=============================================================================
3827 * Returns ids of all elements of given type
3829 //=============================================================================
3831 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3832 throw (SALOME::SALOME_Exception)
3834 Unexpect aCatch(SALOME_SalomeException);
3836 _preMeshInfo->FullLoadFromFile();
3838 SMESH::long_array_var aResult = new SMESH::long_array();
3839 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3841 if ( aSMESHDS_Mesh == NULL )
3842 return aResult._retn();
3844 long nbElements = NbElements();
3846 // No sense in returning ids of elements along with ids of nodes:
3847 // when theElemType == SMESH::ALL, return node ids only if
3848 // there are no elements
3849 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3850 return GetNodesId();
3852 aResult->length( nbElements );
3856 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3857 while ( i < nbElements && anIt->more() )
3858 aResult[i++] = anIt->next()->GetID();
3860 aResult->length( i );
3862 return aResult._retn();
3865 //=============================================================================
3867 * Returns ids of all nodes
3869 //=============================================================================
3871 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3872 throw (SALOME::SALOME_Exception)
3874 Unexpect aCatch(SALOME_SalomeException);
3876 _preMeshInfo->FullLoadFromFile();
3878 SMESH::long_array_var aResult = new SMESH::long_array();
3879 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3881 if ( aSMESHDS_Mesh == NULL )
3882 return aResult._retn();
3884 long nbNodes = NbNodes();
3885 aResult->length( nbNodes );
3886 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3887 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3888 aResult[i] = anIt->next()->GetID();
3890 return aResult._retn();
3893 //=============================================================================
3897 //=============================================================================
3899 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3900 throw (SALOME::SALOME_Exception)
3902 SMESH::ElementType type;
3906 _preMeshInfo->FullLoadFromFile();
3908 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3910 SMESH_CATCH( SMESH::throwCorbaException );
3915 //=============================================================================
3919 //=============================================================================
3921 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3922 throw (SALOME::SALOME_Exception)
3925 _preMeshInfo->FullLoadFromFile();
3927 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3929 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3931 return ( SMESH::EntityType ) e->GetEntityType();
3934 //=============================================================================
3938 //=============================================================================
3940 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
3941 throw (SALOME::SALOME_Exception)
3944 _preMeshInfo->FullLoadFromFile();
3946 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3948 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3950 return ( SMESH::GeometryType ) e->GetGeomType();
3953 //=============================================================================
3955 * Returns ID of elements for given submesh
3957 //=============================================================================
3958 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3959 throw (SALOME::SALOME_Exception)
3961 SMESH::long_array_var aResult = new SMESH::long_array();
3965 _preMeshInfo->FullLoadFromFile();
3967 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3968 if(!SM) return aResult._retn();
3970 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3971 if(!SDSM) return aResult._retn();
3973 aResult->length(SDSM->NbElements());
3975 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3977 while ( eIt->more() ) {
3978 aResult[i++] = eIt->next()->GetID();
3981 SMESH_CATCH( SMESH::throwCorbaException );
3983 return aResult._retn();
3986 //=============================================================================
3988 * Returns ID of nodes for given submesh
3989 * If param all==true - returns all nodes, else -
3990 * returns only nodes on shapes.
3992 //=============================================================================
3994 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3996 throw (SALOME::SALOME_Exception)
3998 SMESH::long_array_var aResult = new SMESH::long_array();
4002 _preMeshInfo->FullLoadFromFile();
4004 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4005 if(!SM) return aResult._retn();
4007 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4008 if(!SDSM) return aResult._retn();
4011 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4012 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4013 while ( nIt->more() ) {
4014 const SMDS_MeshNode* elem = nIt->next();
4015 theElems.insert( elem->GetID() );
4018 else { // all nodes of submesh elements
4019 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4020 while ( eIt->more() ) {
4021 const SMDS_MeshElement* anElem = eIt->next();
4022 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4023 while ( nIt->more() ) {
4024 const SMDS_MeshElement* elem = nIt->next();
4025 theElems.insert( elem->GetID() );
4030 aResult->length(theElems.size());
4031 set<int>::iterator itElem;
4033 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4034 aResult[i++] = *itElem;
4036 SMESH_CATCH( SMESH::throwCorbaException );
4038 return aResult._retn();
4041 //=============================================================================
4043 * Returns type of elements for given submesh
4045 //=============================================================================
4047 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4048 throw (SALOME::SALOME_Exception)
4050 SMESH::ElementType type;
4054 _preMeshInfo->FullLoadFromFile();
4056 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4057 if(!SM) return SMESH::ALL;
4059 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4060 if(!SDSM) return SMESH::ALL;
4062 if(SDSM->NbElements()==0)
4063 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4065 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4066 const SMDS_MeshElement* anElem = eIt->next();
4068 type = ( SMESH::ElementType ) anElem->GetType();
4070 SMESH_CATCH( SMESH::throwCorbaException );
4076 //=============================================================================
4078 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4080 //=============================================================================
4082 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4085 _preMeshInfo->FullLoadFromFile();
4087 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4089 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4094 //=============================================================================
4096 * Get XYZ coordinates of node as list of double
4097 * If there is not node for given ID - returns empty list
4099 //=============================================================================
4101 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4104 _preMeshInfo->FullLoadFromFile();
4106 SMESH::double_array_var aResult = new SMESH::double_array();
4107 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4108 if ( aSMESHDS_Mesh == NULL )
4109 return aResult._retn();
4112 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4114 return aResult._retn();
4118 aResult[0] = aNode->X();
4119 aResult[1] = aNode->Y();
4120 aResult[2] = aNode->Z();
4121 return aResult._retn();
4125 //=============================================================================
4127 * For given node returns list of IDs of inverse elements
4128 * If there is not node for given ID - returns empty list
4130 //=============================================================================
4132 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4135 _preMeshInfo->FullLoadFromFile();
4137 SMESH::long_array_var aResult = new SMESH::long_array();
4138 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4139 if ( aSMESHDS_Mesh == NULL )
4140 return aResult._retn();
4143 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4145 return aResult._retn();
4147 // find inverse elements
4148 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4149 aResult->length( aNode->NbInverseElements() );
4150 for( int i = 0; eIt->more(); ++i )
4152 const SMDS_MeshElement* elem = eIt->next();
4153 aResult[ i ] = elem->GetID();
4155 return aResult._retn();
4158 //=============================================================================
4160 * \brief Return position of a node on shape
4162 //=============================================================================
4164 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4167 _preMeshInfo->FullLoadFromFile();
4169 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4170 aNodePosition->shapeID = 0;
4171 aNodePosition->shapeType = GEOM::SHAPE;
4173 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4174 if ( !mesh ) return aNodePosition;
4176 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4178 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4180 aNodePosition->shapeID = aNode->getshapeId();
4181 switch ( pos->GetTypeOfPosition() ) {
4183 aNodePosition->shapeType = GEOM::EDGE;
4184 aNodePosition->params.length(1);
4185 aNodePosition->params[0] =
4186 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4189 aNodePosition->shapeType = GEOM::FACE;
4190 aNodePosition->params.length(2);
4191 aNodePosition->params[0] =
4192 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4193 aNodePosition->params[1] =
4194 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4196 case SMDS_TOP_VERTEX:
4197 aNodePosition->shapeType = GEOM::VERTEX;
4199 case SMDS_TOP_3DSPACE:
4200 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4201 aNodePosition->shapeType = GEOM::SOLID;
4202 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4203 aNodePosition->shapeType = GEOM::SHELL;
4209 return aNodePosition;
4212 //=============================================================================
4214 * \brief Return position of an element on shape
4216 //=============================================================================
4218 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4221 _preMeshInfo->FullLoadFromFile();
4223 SMESH::ElementPosition anElementPosition;
4224 anElementPosition.shapeID = 0;
4225 anElementPosition.shapeType = GEOM::SHAPE;
4227 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4228 if ( !mesh ) return anElementPosition;
4230 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4232 anElementPosition.shapeID = anElem->getshapeId();
4233 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4234 if ( !aSp.IsNull() ) {
4235 switch ( aSp.ShapeType() ) {
4237 anElementPosition.shapeType = GEOM::EDGE;
4240 anElementPosition.shapeType = GEOM::FACE;
4243 anElementPosition.shapeType = GEOM::VERTEX;
4246 anElementPosition.shapeType = GEOM::SOLID;
4249 anElementPosition.shapeType = GEOM::SHELL;
4255 return anElementPosition;
4258 //=============================================================================
4260 * If given element is node returns IDs of shape from position
4261 * If there is not node for given ID - returns -1
4263 //=============================================================================
4265 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4268 _preMeshInfo->FullLoadFromFile();
4270 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4271 if ( aSMESHDS_Mesh == NULL )
4275 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4277 return aNode->getshapeId();
4284 //=============================================================================
4286 * For given element returns ID of result shape after
4287 * ::FindShape() from SMESH_MeshEditor
4288 * If there is not element for given ID - returns -1
4290 //=============================================================================
4292 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4295 _preMeshInfo->FullLoadFromFile();
4297 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4298 if ( aSMESHDS_Mesh == NULL )
4301 // try to find element
4302 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4306 ::SMESH_MeshEditor aMeshEditor(_impl);
4307 int index = aMeshEditor.FindShape( elem );
4315 //=============================================================================
4317 * Returns number of nodes for given element
4318 * If there is not element for given ID - returns -1
4320 //=============================================================================
4322 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4325 _preMeshInfo->FullLoadFromFile();
4327 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4328 if ( aSMESHDS_Mesh == NULL ) return -1;
4329 // try to find element
4330 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4331 if(!elem) return -1;
4332 return elem->NbNodes();
4336 //=============================================================================
4338 * Returns ID of node by given index for given element
4339 * If there is not element for given ID - returns -1
4340 * If there is not node for given index - returns -2
4342 //=============================================================================
4344 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4347 _preMeshInfo->FullLoadFromFile();
4349 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4350 if ( aSMESHDS_Mesh == NULL ) return -1;
4351 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4352 if(!elem) return -1;
4353 if( index>=elem->NbNodes() || index<0 ) return -1;
4354 return elem->GetNode(index)->GetID();
4357 //=============================================================================
4359 * Returns IDs of nodes of given element
4361 //=============================================================================
4363 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4366 _preMeshInfo->FullLoadFromFile();
4368 SMESH::long_array_var aResult = new SMESH::long_array();
4369 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4371 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4373 aResult->length( elem->NbNodes() );
4374 for ( int i = 0; i < elem->NbNodes(); ++i )
4375 aResult[ i ] = elem->GetNode( i )->GetID();
4378 return aResult._retn();
4381 //=============================================================================
4383 * Returns true if given node is medium node
4384 * in given quadratic element
4386 //=============================================================================
4388 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4391 _preMeshInfo->FullLoadFromFile();
4393 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4394 if ( aSMESHDS_Mesh == NULL ) return false;
4396 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4397 if(!aNode) return false;
4398 // try to find element
4399 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4400 if(!elem) return false;
4402 return elem->IsMediumNode(aNode);
4406 //=============================================================================
4408 * Returns true if given node is medium node
4409 * in one of quadratic elements
4411 //=============================================================================
4413 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4414 SMESH::ElementType theElemType)
4417 _preMeshInfo->FullLoadFromFile();
4419 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4420 if ( aSMESHDS_Mesh == NULL ) return false;
4423 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4424 if(!aNode) return false;
4426 SMESH_MesherHelper aHelper( *(_impl) );
4428 SMDSAbs_ElementType aType;
4429 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4430 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4431 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4432 else aType = SMDSAbs_All;
4434 return aHelper.IsMedium(aNode,aType);
4438 //=============================================================================
4440 * Returns number of edges for given element
4442 //=============================================================================
4444 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4447 _preMeshInfo->FullLoadFromFile();
4449 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4450 if ( aSMESHDS_Mesh == NULL ) return -1;
4451 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4452 if(!elem) return -1;
4453 return elem->NbEdges();
4457 //=============================================================================
4459 * Returns number of faces for given element
4461 //=============================================================================
4463 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4466 _preMeshInfo->FullLoadFromFile();
4468 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4469 if ( aSMESHDS_Mesh == NULL ) return -1;
4470 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4471 if(!elem) return -1;
4472 return elem->NbFaces();
4475 //=======================================================================
4476 //function : GetElemFaceNodes
4477 //purpose : Returns nodes of given face (counted from zero) for given element.
4478 //=======================================================================
4480 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4481 CORBA::Short faceIndex)
4484 _preMeshInfo->FullLoadFromFile();
4486 SMESH::long_array_var aResult = new SMESH::long_array();
4487 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4489 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4491 SMDS_VolumeTool vtool( elem );
4492 if ( faceIndex < vtool.NbFaces() )
4494 aResult->length( vtool.NbFaceNodes( faceIndex ));
4495 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4496 for ( int i = 0; i < aResult->length(); ++i )
4497 aResult[ i ] = nn[ i ]->GetID();
4501 return aResult._retn();
4504 //=======================================================================
4505 //function : GetElemFaceNodes
4506 //purpose : Returns three components of normal of given mesh face.
4507 //=======================================================================
4509 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4510 CORBA::Boolean normalized)
4513 _preMeshInfo->FullLoadFromFile();
4515 SMESH::double_array_var aResult = new SMESH::double_array();
4517 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4520 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4522 aResult->length( 3 );
4523 aResult[ 0 ] = normal.X();
4524 aResult[ 1 ] = normal.Y();
4525 aResult[ 2 ] = normal.Z();
4528 return aResult._retn();
4531 //=======================================================================
4532 //function : FindElementByNodes
4533 //purpose : Returns an element based on all given nodes.
4534 //=======================================================================
4536 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4539 _preMeshInfo->FullLoadFromFile();
4541 CORBA::Long elemID(0);
4542 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4544 vector< const SMDS_MeshNode * > nn( nodes.length() );
4545 for ( int i = 0; i < nodes.length(); ++i )
4546 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4549 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4550 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4551 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4552 _impl->NbVolumes( ORDER_QUADRATIC )))
4553 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4555 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4560 //=============================================================================
4562 * Returns true if given element is polygon
4564 //=============================================================================
4566 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4569 _preMeshInfo->FullLoadFromFile();
4571 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4572 if ( aSMESHDS_Mesh == NULL ) return false;
4573 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4574 if(!elem) return false;
4575 return elem->IsPoly();
4579 //=============================================================================
4581 * Returns true if given element is quadratic
4583 //=============================================================================
4585 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4588 _preMeshInfo->FullLoadFromFile();
4590 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4591 if ( aSMESHDS_Mesh == NULL ) return false;
4592 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4593 if(!elem) return false;
4594 return elem->IsQuadratic();
4597 //=============================================================================
4599 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4601 //=============================================================================
4603 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4606 _preMeshInfo->FullLoadFromFile();
4608 if ( const SMDS_BallElement* ball =
4609 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4610 return ball->GetDiameter();
4615 //=============================================================================
4617 * Returns bary center for given element
4619 //=============================================================================
4621 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4624 _preMeshInfo->FullLoadFromFile();
4626 SMESH::double_array_var aResult = new SMESH::double_array();
4627 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4628 if ( aSMESHDS_Mesh == NULL )
4629 return aResult._retn();
4631 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4633 return aResult._retn();
4635 if(elem->GetType()==SMDSAbs_Volume) {
4636 SMDS_VolumeTool aTool;
4637 if(aTool.Set(elem)) {
4639 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4644 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4646 double x=0., y=0., z=0.;
4647 for(; anIt->more(); ) {
4649 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4663 return aResult._retn();
4666 //================================================================================
4668 * \brief Create a group of elements preventing computation of a sub-shape
4670 //================================================================================
4672 SMESH::ListOfGroups*
4673 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4674 const char* theGroupName )
4675 throw ( SALOME::SALOME_Exception )
4677 Unexpect aCatch(SALOME_SalomeException);
4679 if ( !theGroupName || strlen( theGroupName) == 0 )
4680 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4682 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4684 // submesh by subshape id
4685 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4686 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4689 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4690 if ( error && !error->myBadElements.empty())
4692 // sort bad elements by type
4693 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4694 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4695 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4696 for ( ; elemIt != elemEnd; ++elemIt )
4698 const SMDS_MeshElement* elem = *elemIt;
4699 if ( !elem ) continue;
4701 if ( elem->GetID() < 1 )
4703 // elem is a temporary element, make a real element
4704 vector< const SMDS_MeshNode* > nodes;
4705 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4706 while ( nIt->more() && elem )
4708 nodes.push_back( nIt->next() );
4709 if ( nodes.back()->GetID() < 1 )
4710 elem = 0; // a temporary element on temporary nodes
4714 ::SMESH_MeshEditor editor( _impl );
4715 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4719 elemsByType[ elem->GetType() ].push_back( elem );
4722 // how many groups to create?
4724 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4725 nbTypes += int( !elemsByType[ i ].empty() );
4726 groups->length( nbTypes );
4729 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4731 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4732 if ( elems.empty() ) continue;
4734 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4735 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4737 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4738 SMESH::SMESH_Mesh_var mesh = _this();
4739 SALOMEDS::SObject_wrap aSO =
4740 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4741 GEOM::GEOM_Object::_nil(), theGroupName);
4742 aSO->_is_nil(); // avoid "unused variable" warning
4744 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4745 if ( !grp_i ) continue;
4747 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4748 for ( size_t iE = 0; iE < elems.size(); ++iE )
4749 grpDS->SMDSGroup().Add( elems[ iE ]);
4754 return groups._retn();
4757 //=============================================================================
4759 * Create and publish group servants if any groups were imported or created anyhow
4761 //=============================================================================
4763 void SMESH_Mesh_i::CreateGroupServants()
4765 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4766 SMESH::SMESH_Mesh_var aMesh = _this();
4769 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4770 while ( groupIt->more() )
4772 ::SMESH_Group* group = groupIt->next();
4773 int anId = group->GetGroupDS()->GetID();
4775 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4776 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4778 addedIDs.insert( anId );
4780 SMESH_GroupBase_i* aGroupImpl;
4782 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4783 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4785 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4786 shape = groupOnGeom->GetShape();
4789 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4792 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4793 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4794 aGroupImpl->Register();
4796 // register CORBA object for persistence
4797 int nextId = _gen_i->RegisterObject( groupVar );
4798 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4799 else { nextId = 0; } // avoid "unused variable" warning in release mode
4801 // publishing the groups in the study
4802 if ( !aStudy->_is_nil() ) {
4803 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4804 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4807 if ( !addedIDs.empty() )
4810 set<int>::iterator id = addedIDs.begin();
4811 for ( ; id != addedIDs.end(); ++id )
4813 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4814 int i = std::distance( _mapGroups.begin(), it );
4815 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4820 //=============================================================================
4822 * \brief Return groups cantained in _mapGroups by their IDs
4824 //=============================================================================
4826 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4828 int nbGroups = groupIDs.size();
4829 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4830 aList->length( nbGroups );
4832 list<int>::const_iterator ids = groupIDs.begin();
4833 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4835 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4836 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4837 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4839 aList->length( nbGroups );
4840 return aList._retn();
4843 //=============================================================================
4845 * \brief Return information about imported file
4847 //=============================================================================
4849 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4851 SMESH::MedFileInfo_var res( _medFileInfo );
4852 if ( !res.operator->() ) {
4853 res = new SMESH::MedFileInfo;
4855 res->fileSize = res->major = res->minor = res->release = -1;
4860 //=============================================================================
4862 * \brief Pass names of mesh groups from study to mesh DS
4864 //=============================================================================
4866 void SMESH_Mesh_i::checkGroupNames()
4868 int nbGrp = NbGroups();
4872 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4873 if ( aStudy->_is_nil() )
4874 return; // nothing to do
4876 SMESH::ListOfGroups* grpList = 0;
4877 // avoid dump of "GetGroups"
4879 // store python dump into a local variable inside local scope
4880 SMESH::TPythonDump pDump; // do not delete this line of code
4881 grpList = GetGroups();
4884 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4885 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4888 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4889 if ( aGrpSO->_is_nil() )
4891 // correct name of the mesh group if necessary
4892 const char* guiName = aGrpSO->GetName();
4893 if ( strcmp(guiName, aGrp->GetName()) )
4894 aGrp->SetName( guiName );
4898 //=============================================================================
4900 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4902 //=============================================================================
4903 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4905 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4909 //=============================================================================
4911 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4913 //=============================================================================
4915 char* SMESH_Mesh_i::GetParameters()
4917 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4920 //=============================================================================
4922 * \brief Returns list of notebook variables used for last Mesh operation
4924 //=============================================================================
4925 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4927 SMESH::string_array_var aResult = new SMESH::string_array();
4928 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4930 CORBA::String_var aParameters = GetParameters();
4931 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4932 if ( !aStudy->_is_nil()) {
4933 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4934 if(aSections->length() > 0) {
4935 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4936 aResult->length(aVars.length());
4937 for(int i = 0;i < aVars.length();i++)
4938 aResult[i] = CORBA::string_dup( aVars[i]);
4942 return aResult._retn();
4945 //=======================================================================
4946 //function : GetTypes
4947 //purpose : Returns types of elements it contains
4948 //=======================================================================
4950 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4953 return _preMeshInfo->GetTypes();
4955 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4959 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4960 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4961 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4962 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4963 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4964 types->length( nbTypes );
4966 return types._retn();
4969 //=======================================================================
4970 //function : GetMesh
4971 //purpose : Returns self
4972 //=======================================================================
4974 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4976 return SMESH::SMESH_Mesh::_duplicate( _this() );
4979 //=======================================================================
4980 //function : IsMeshInfoCorrect
4981 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4982 // * happen if mesh data is not yet fully loaded from the file of study.
4983 //=======================================================================
4985 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4987 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4990 //=============================================================================
4992 * \brief Returns number of mesh elements per each \a EntityType
4994 //=============================================================================
4996 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4999 return _preMeshInfo->GetMeshInfo();
5001 SMESH::long_array_var aRes = new SMESH::long_array();
5002 aRes->length(SMESH::Entity_Last);
5003 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5005 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5007 return aRes._retn();
5008 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5009 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5010 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5011 return aRes._retn();
5014 //=============================================================================
5016 * \brief Returns number of mesh elements per each \a ElementType
5018 //=============================================================================
5020 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5022 SMESH::long_array_var aRes = new SMESH::long_array();
5023 aRes->length(SMESH::NB_ELEMENT_TYPES);
5024 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5027 const SMDS_MeshInfo* meshInfo = 0;
5029 meshInfo = _preMeshInfo;
5030 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5031 meshInfo = & meshDS->GetMeshInfo();
5034 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5035 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5037 return aRes._retn();
5040 //=============================================================================
5042 * Collect statistic of mesh elements given by iterator
5044 //=============================================================================
5046 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5047 SMESH::long_array& theInfo)
5049 if (!theItr) return;
5050 while (theItr->more())
5051 theInfo[ theItr->next()->GetEntityType() ]++;
5053 //=============================================================================
5055 * Returns mesh unstructed grid information.
5057 //=============================================================================
5059 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5061 SALOMEDS::TMPFile_var SeqFile;
5062 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5063 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5065 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5066 aWriter->WriteToOutputStringOn();
5067 aWriter->SetInputData(aGrid);
5068 aWriter->SetFileTypeToBinary();
5070 char* str = aWriter->GetOutputString();
5071 int size = aWriter->GetOutputStringLength();
5073 //Allocate octect buffer of required size
5074 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5075 //Copy ostrstream content to the octect buffer
5076 memcpy(OctetBuf, str, size);
5077 //Create and return TMPFile
5078 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5082 return SeqFile._retn();
5085 //=============================================================================
5086 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5087 * SMESH::ElementType type) */
5089 using namespace SMESH::Controls;
5090 //-----------------------------------------------------------------------------
5091 struct PredicateIterator : public SMDS_ElemIterator
5093 SMDS_ElemIteratorPtr _elemIter;
5094 PredicatePtr _predicate;
5095 const SMDS_MeshElement* _elem;
5097 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5098 PredicatePtr predicate):
5099 _elemIter(iterator), _predicate(predicate)
5107 virtual const SMDS_MeshElement* next()
5109 const SMDS_MeshElement* res = _elem;
5111 while ( _elemIter->more() && !_elem )
5113 _elem = _elemIter->next();
5114 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5121 //-----------------------------------------------------------------------------
5122 struct IDSourceIterator : public SMDS_ElemIterator
5124 const CORBA::Long* _idPtr;
5125 const CORBA::Long* _idEndPtr;
5126 SMESH::long_array_var _idArray;
5127 const SMDS_Mesh* _mesh;
5128 const SMDSAbs_ElementType _type;
5129 const SMDS_MeshElement* _elem;
5131 IDSourceIterator( const SMDS_Mesh* mesh,
5132 const CORBA::Long* ids,
5134 SMDSAbs_ElementType type):
5135 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5137 if ( _idPtr && nbIds && _mesh )
5140 IDSourceIterator( const SMDS_Mesh* mesh,
5141 SMESH::long_array* idArray,
5142 SMDSAbs_ElementType type):
5143 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5145 if ( idArray && _mesh )
5147 _idPtr = &_idArray[0];
5148 _idEndPtr = _idPtr + _idArray->length();
5156 virtual const SMDS_MeshElement* next()
5158 const SMDS_MeshElement* res = _elem;
5160 while ( _idPtr < _idEndPtr && !_elem )
5162 if ( _type == SMDSAbs_Node )
5164 _elem = _mesh->FindNode( *_idPtr++ );
5166 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5167 _elem->GetType() != _type )
5175 //-----------------------------------------------------------------------------
5177 struct NodeOfElemIterator : public SMDS_ElemIterator
5179 TColStd_MapOfInteger _checkedNodeIDs;
5180 SMDS_ElemIteratorPtr _elemIter;
5181 SMDS_ElemIteratorPtr _nodeIter;
5182 const SMDS_MeshElement* _node;
5184 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5186 if ( _elemIter && _elemIter->more() )
5188 _nodeIter = _elemIter->next()->nodesIterator();
5196 virtual const SMDS_MeshElement* next()
5198 const SMDS_MeshElement* res = _node;
5200 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5202 if ( _nodeIter->more() )
5204 _node = _nodeIter->next();
5205 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5210 _nodeIter = _elemIter->next()->nodesIterator();
5218 //=============================================================================
5220 * Return iterator on elements of given type in given object
5222 //=============================================================================
5224 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5225 SMESH::ElementType theType)
5227 SMDS_ElemIteratorPtr elemIt;
5228 bool typeOK = false;
5229 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5231 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5232 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5233 if ( !mesh_i ) return elemIt;
5234 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5236 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5238 elemIt = meshDS->elementsIterator( elemType );
5241 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5243 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5246 elemIt = sm->GetElements();
5247 if ( elemType != SMDSAbs_Node )
5249 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5250 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5254 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5256 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5257 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
5259 elemIt = groupDS->GetElements();
5260 typeOK = ( groupDS->GetType() == elemType );
5263 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5265 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
5267 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5268 if ( pred_i && pred_i->GetPredicate() )
5270 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5271 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5272 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5273 typeOK = ( filterType == elemType );
5279 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5280 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5281 if ( isNodes && elemType != SMDSAbs_Node )
5283 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5286 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5287 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5291 SMESH::long_array_var ids = theObject->GetIDs();
5292 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5294 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
5297 if ( elemIt && elemIt->more() && !typeOK )
5299 if ( elemType == SMDSAbs_Node )
5301 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5305 elemIt = SMDS_ElemIteratorPtr();
5311 //=============================================================================
5312 namespace // Finding concurrent hypotheses
5313 //=============================================================================
5317 * \brief mapping of mesh dimension into shape type
5319 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5321 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5323 case 0: aType = TopAbs_VERTEX; break;
5324 case 1: aType = TopAbs_EDGE; break;
5325 case 2: aType = TopAbs_FACE; break;
5327 default:aType = TopAbs_SOLID; break;
5332 //-----------------------------------------------------------------------------
5334 * \brief Internal structure used to find concurent submeshes
5336 * It represents a pair < submesh, concurent dimension >, where
5337 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5338 * with another submesh. In other words, it is dimension of a hypothesis assigned
5345 int _dim; //!< a dimension the algo can build (concurrent dimension)
5346 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5347 TopTools_MapOfShape _shapeMap;
5348 SMESH_subMesh* _subMesh;
5349 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5351 //-----------------------------------------------------------------------------
5352 // Return the algorithm
5353 const SMESH_Algo* GetAlgo() const
5354 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5356 //-----------------------------------------------------------------------------
5358 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5360 const TopoDS_Shape& theShape)
5362 _subMesh = (SMESH_subMesh*)theSubMesh;
5363 SetShape( theDim, theShape );
5366 //-----------------------------------------------------------------------------
5368 void SetShape(const int theDim,
5369 const TopoDS_Shape& theShape)
5372 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5373 if (_dim >= _ownDim)
5374 _shapeMap.Add( theShape );
5376 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5377 for( ; anExp.More(); anExp.Next() )
5378 _shapeMap.Add( anExp.Current() );
5382 //-----------------------------------------------------------------------------
5383 //! Check sharing of sub-shapes
5384 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5385 const TopTools_MapOfShape& theToFind,
5386 const TopAbs_ShapeEnum theType)
5388 bool isShared = false;
5389 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5390 for (; !isShared && anItr.More(); anItr.Next() )
5392 const TopoDS_Shape aSubSh = anItr.Key();
5393 // check for case when concurrent dimensions are same
5394 isShared = theToFind.Contains( aSubSh );
5395 // check for sub-shape with concurrent dimension
5396 TopExp_Explorer anExp( aSubSh, theType );
5397 for ( ; !isShared && anExp.More(); anExp.Next() )
5398 isShared = theToFind.Contains( anExp.Current() );
5403 //-----------------------------------------------------------------------------
5404 //! check algorithms
5405 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5406 const SMESHDS_Hypothesis* theA2)
5408 if ( !theA1 || !theA2 ||
5409 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5410 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5411 return false; // one of the hypothesis is not algorithm
5412 // check algorithm names (should be equal)
5413 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5417 //-----------------------------------------------------------------------------
5418 //! Check if sub-shape hypotheses are concurrent
5419 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5421 if ( _subMesh == theOther->_subMesh )
5422 return false; // same sub-shape - should not be
5424 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5425 // any of the two submeshes is not on COMPOUND shape )
5426 // -> no concurrency
5427 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5428 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5429 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5430 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5431 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5434 // bool checkSubShape = ( _dim >= theOther->_dim )
5435 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5436 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5437 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5438 if ( !checkSubShape )
5441 // check algorithms to be same
5442 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5443 return true; // different algorithms -> concurrency !
5445 // check hypothesises for concurrence (skip first as algorithm)
5447 // pointers should be same, because it is referened from mesh hypothesis partition
5448 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5449 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5450 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5451 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5453 // the submeshes are concurrent if their algorithms has different parameters
5454 return nbSame != theOther->_hypotheses.size() - 1;
5457 // Return true if algorithm of this SMESH_DimHyp is used if no
5458 // sub-mesh order is imposed by the user
5459 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5461 // NeedDiscreteBoundary() algo has a higher priority
5462 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5463 theOther->GetAlgo()->NeedDiscreteBoundary() )
5464 return !this->GetAlgo()->NeedDiscreteBoundary();
5466 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5469 }; // end of SMESH_DimHyp
5470 //-----------------------------------------------------------------------------
5472 typedef list<const SMESH_DimHyp*> TDimHypList;
5474 //-----------------------------------------------------------------------------
5476 void addDimHypInstance(const int theDim,
5477 const TopoDS_Shape& theShape,
5478 const SMESH_Algo* theAlgo,
5479 const SMESH_subMesh* theSubMesh,
5480 const list <const SMESHDS_Hypothesis*>& theHypList,
5481 TDimHypList* theDimHypListArr )
5483 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5484 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5485 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5486 dimHyp->_hypotheses.push_front(theAlgo);
5487 listOfdimHyp.push_back( dimHyp );
5490 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5491 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5492 theHypList.begin(), theHypList.end() );
5495 //-----------------------------------------------------------------------------
5496 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5497 TDimHypList& theListOfConcurr)
5499 if ( theListOfConcurr.empty() )
5501 theListOfConcurr.push_back( theDimHyp );
5505 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5506 while ( hypIt != theListOfConcurr.end() &&
5507 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5509 theListOfConcurr.insert( hypIt, theDimHyp );
5513 //-----------------------------------------------------------------------------
5514 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5515 const TDimHypList& theListOfDimHyp,
5516 TDimHypList& theListOfConcurrHyp,
5517 set<int>& theSetOfConcurrId )
5519 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5520 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5522 const SMESH_DimHyp* curDimHyp = *rIt;
5523 if ( curDimHyp == theDimHyp )
5524 break; // meet own dimHyp pointer in same dimension
5526 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5527 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5529 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5534 //-----------------------------------------------------------------------------
5535 void unionLists(TListOfInt& theListOfId,
5536 TListOfListOfInt& theListOfListOfId,
5539 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5540 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5542 continue; //skip already treated lists
5543 // check if other list has any same submesh object
5544 TListOfInt& otherListOfId = *it;
5545 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5546 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5549 // union two lists (from source into target)
5550 TListOfInt::iterator it2 = otherListOfId.begin();
5551 for ( ; it2 != otherListOfId.end(); it2++ ) {
5552 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5553 theListOfId.push_back(*it2);
5555 // clear source list
5556 otherListOfId.clear();
5559 //-----------------------------------------------------------------------------
5561 //! free memory allocated for dimension-hypothesis objects
5562 void removeDimHyps( TDimHypList* theArrOfList )
5564 for (int i = 0; i < 4; i++ ) {
5565 TDimHypList& listOfdimHyp = theArrOfList[i];
5566 TDimHypList::const_iterator it = listOfdimHyp.begin();
5567 for ( ; it != listOfdimHyp.end(); it++ )
5572 //-----------------------------------------------------------------------------
5574 * \brief find common submeshes with given submesh
5575 * \param theSubMeshList list of already collected submesh to check
5576 * \param theSubMesh given submesh to intersect with other
5577 * \param theCommonSubMeshes collected common submeshes
5579 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5580 const SMESH_subMesh* theSubMesh,
5581 set<const SMESH_subMesh*>& theCommon )
5585 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5586 for ( ; it != theSubMeshList.end(); it++ )
5587 theSubMesh->FindIntersection( *it, theCommon );
5588 theSubMeshList.push_back( theSubMesh );
5589 //theCommon.insert( theSubMesh );
5592 //-----------------------------------------------------------------------------
5593 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5595 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5596 for ( ; listsIt != smLists.end(); ++listsIt )
5598 const TListOfInt& smIDs = *listsIt;
5599 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5607 //=============================================================================
5609 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5611 //=============================================================================
5613 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5615 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5616 if ( isSubMeshInList( submeshID, anOrder ))
5619 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5620 return isSubMeshInList( submeshID, allConurrent );
5623 //=============================================================================
5625 * \brief Return submesh objects list in meshing order
5627 //=============================================================================
5629 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5631 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5633 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5635 return aResult._retn();
5637 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5638 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5639 anOrder.splice( anOrder.end(), allConurrent );
5642 TListOfListOfInt::iterator listIt = anOrder.begin();
5643 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5644 unionLists( *listIt, anOrder, listIndx + 1 );
5646 // convert submesh ids into interface instances
5647 // and dump command into python
5648 convertMeshOrder( anOrder, aResult, false );
5650 return aResult._retn();
5653 //=============================================================================
5655 * \brief Finds concurrent sub-meshes
5657 //=============================================================================
5659 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5661 TListOfListOfInt anOrder;
5662 ::SMESH_Mesh& mesh = GetImpl();
5664 // collect submeshes and detect concurrent algorithms and hypothesises
5665 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5667 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5668 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5669 ::SMESH_subMesh* sm = (*i_sm).second;
5671 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5673 // list of assigned hypothesises
5674 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5675 // Find out dimensions where the submesh can be concurrent.
5676 // We define the dimensions by algo of each of hypotheses in hypList
5677 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5678 for( ; hypIt != hypList.end(); hypIt++ ) {
5679 SMESH_Algo* anAlgo = 0;
5680 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5681 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5682 // hyp it-self is algo
5683 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5685 // try to find algorithm with help of sub-shapes
5686 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5687 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5688 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5691 continue; // no algorithm assigned to a current submesh
5693 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5694 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5696 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5697 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5698 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5700 } // end iterations on submesh
5702 // iterate on created dimension-hypotheses and check for concurrents
5703 for ( int i = 0; i < 4; i++ ) {
5704 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5705 // check for concurrents in own and other dimensions (step-by-step)
5706 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5707 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5708 const SMESH_DimHyp* dimHyp = *dhIt;
5709 TDimHypList listOfConcurr;
5710 set<int> setOfConcurrIds;
5711 // looking for concurrents and collect into own list
5712 for ( int j = i; j < 4; j++ )
5713 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5714 // check if any concurrents found
5715 if ( listOfConcurr.size() > 0 ) {
5716 // add own submesh to list of concurrent
5717 addInOrderOfPriority( dimHyp, listOfConcurr );
5718 list<int> listOfConcurrIds;
5719 TDimHypList::iterator hypIt = listOfConcurr.begin();
5720 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5721 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5722 anOrder.push_back( listOfConcurrIds );
5727 removeDimHyps(dimHypListArr);
5729 // now, minimise the number of concurrent groups
5730 // Here we assume that lists of submeshes can have same submesh
5731 // in case of multi-dimension algorithms, as result
5732 // list with common submesh has to be united into one list
5734 TListOfListOfInt::iterator listIt = anOrder.begin();
5735 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5736 unionLists( *listIt, anOrder, listIndx + 1 );
5742 //=============================================================================
5744 * \brief Set submesh object order
5745 * \param theSubMeshArray submesh array order
5747 //=============================================================================
5749 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5752 _preMeshInfo->ForgetOrLoad();
5755 ::SMESH_Mesh& mesh = GetImpl();
5757 TPythonDump aPythonDump; // prevent dump of called methods
5758 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5760 TListOfListOfInt subMeshOrder;
5761 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5763 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5764 TListOfInt subMeshIds;
5766 aPythonDump << ", ";
5767 aPythonDump << "[ ";
5768 // Collect subMeshes which should be clear
5769 // do it list-by-list, because modification of submesh order
5770 // take effect between concurrent submeshes only
5771 set<const SMESH_subMesh*> subMeshToClear;
5772 list<const SMESH_subMesh*> subMeshList;
5773 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5775 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5777 aPythonDump << ", ";
5778 aPythonDump << subMesh;
5779 subMeshIds.push_back( subMesh->GetId() );
5780 // detect common parts of submeshes
5781 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5782 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5784 aPythonDump << " ]";
5785 subMeshOrder.push_back( subMeshIds );
5787 // clear collected submeshes
5788 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5789 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5790 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5791 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5793 aPythonDump << " ])";
5795 mesh.SetMeshOrder( subMeshOrder );
5801 //=============================================================================
5803 * \brief Convert submesh ids into submesh interfaces
5805 //=============================================================================
5807 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5808 SMESH::submesh_array_array& theResOrder,
5809 const bool theIsDump)
5811 int nbSet = theIdsOrder.size();
5812 TPythonDump aPythonDump; // prevent dump of called methods
5814 aPythonDump << "[ ";
5815 theResOrder.length(nbSet);
5816 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5818 for( ; it != theIdsOrder.end(); it++ ) {
5819 // translate submesh identificators into submesh objects
5820 // takeing into account real number of concurrent lists
5821 const TListOfInt& aSubOrder = (*it);
5822 if (!aSubOrder.size())
5825 aPythonDump << "[ ";
5826 // convert shape indeces into interfaces
5827 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5828 aResSubSet->length(aSubOrder.size());
5829 TListOfInt::const_iterator subIt = aSubOrder.begin();
5831 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5832 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5834 SMESH::SMESH_subMesh_var subMesh =
5835 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5838 aPythonDump << ", ";
5839 aPythonDump << subMesh;
5841 aResSubSet[ j++ ] = subMesh;
5844 aPythonDump << " ]";
5846 theResOrder[ listIndx++ ] = aResSubSet;
5848 // correct number of lists
5849 theResOrder.length( listIndx );
5852 // finilise python dump
5853 aPythonDump << " ]";
5854 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5858 //================================================================================
5860 // Implementation of SMESH_MeshPartDS
5862 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5863 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5865 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5866 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5868 _meshDS = mesh_i->GetImpl().GetMeshDS();
5870 SetPersistentId( _meshDS->GetPersistentId() );
5872 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5874 // <meshPart> is the whole mesh
5875 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5877 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5878 myGroupSet = _meshDS->GetGroups();
5883 SMESH::long_array_var anIDs = meshPart->GetIDs();
5884 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5885 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5887 for (int i=0; i < anIDs->length(); i++)
5888 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5889 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5894 for (int i=0; i < anIDs->length(); i++)
5895 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5896 if ( _elements[ e->GetType() ].insert( e ).second )
5899 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5900 while ( nIt->more() )
5902 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5903 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5910 _meshDS = 0; // to enforce iteration on _elements and _nodes
5913 // -------------------------------------------------------------------------------------
5914 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5915 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5918 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5919 for ( ; partIt != meshPart.end(); ++partIt )
5920 if ( const SMDS_MeshElement * e = *partIt )
5921 if ( _elements[ e->GetType() ].insert( e ).second )
5924 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5925 while ( nIt->more() )
5927 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5928 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5934 // -------------------------------------------------------------------------------------
5935 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5937 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5939 typedef SMDS_SetIterator
5940 <const SMDS_MeshElement*,
5941 TIDSortedElemSet::const_iterator,
5942 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5943 SMDS_MeshElement::GeomFilter
5946 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5948 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5949 _elements[type].end(),
5950 SMDS_MeshElement::GeomFilter( geomType )));
5952 // -------------------------------------------------------------------------------------
5953 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5955 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5957 typedef SMDS_SetIterator
5958 <const SMDS_MeshElement*,
5959 TIDSortedElemSet::const_iterator,
5960 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5961 SMDS_MeshElement::EntityFilter
5964 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5966 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5967 _elements[type].end(),
5968 SMDS_MeshElement::EntityFilter( entity )));
5970 // -------------------------------------------------------------------------------------
5971 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5973 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5974 if ( type == SMDSAbs_All && !_meshDS )
5976 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5978 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5979 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5981 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5983 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5984 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5986 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5987 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5989 // -------------------------------------------------------------------------------------
5990 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5991 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5993 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5994 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5995 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5997 // -------------------------------------------------------------------------------------
5998 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5999 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6000 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6001 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6002 #undef _GET_ITER_DEFINE
6004 // END Implementation of SMESH_MeshPartDS
6006 //================================================================================