1 // Copyright (C) 2007-2015 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);
4743 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4744 if ( !grp_i ) continue;
4746 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4747 for ( size_t iE = 0; iE < elems.size(); ++iE )
4748 grpDS->SMDSGroup().Add( elems[ iE ]);
4753 return groups._retn();
4756 //=============================================================================
4758 * Create and publish group servants if any groups were imported or created anyhow
4760 //=============================================================================
4762 void SMESH_Mesh_i::CreateGroupServants()
4764 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4765 SMESH::SMESH_Mesh_var aMesh = _this();
4768 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4769 while ( groupIt->more() )
4771 ::SMESH_Group* group = groupIt->next();
4772 int anId = group->GetGroupDS()->GetID();
4774 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4775 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4777 addedIDs.insert( anId );
4779 SMESH_GroupBase_i* aGroupImpl;
4781 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4782 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4784 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4785 shape = groupOnGeom->GetShape();
4788 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4791 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4792 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4793 aGroupImpl->Register();
4795 // register CORBA object for persistence
4796 int nextId = _gen_i->RegisterObject( groupVar );
4797 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4798 else { nextId = 0; } // avoid "unused variable" warning in release mode
4800 // publishing the groups in the study
4801 if ( !aStudy->_is_nil() ) {
4802 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4803 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4806 if ( !addedIDs.empty() )
4809 set<int>::iterator id = addedIDs.begin();
4810 for ( ; id != addedIDs.end(); ++id )
4812 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4813 int i = std::distance( _mapGroups.begin(), it );
4814 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4819 //=============================================================================
4821 * \brief Return groups cantained in _mapGroups by their IDs
4823 //=============================================================================
4825 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4827 int nbGroups = groupIDs.size();
4828 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4829 aList->length( nbGroups );
4831 list<int>::const_iterator ids = groupIDs.begin();
4832 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4834 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4835 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4836 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4838 aList->length( nbGroups );
4839 return aList._retn();
4842 //=============================================================================
4844 * \brief Return information about imported file
4846 //=============================================================================
4848 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4850 SMESH::MedFileInfo_var res( _medFileInfo );
4851 if ( !res.operator->() ) {
4852 res = new SMESH::MedFileInfo;
4854 res->fileSize = res->major = res->minor = res->release = -1;
4859 //=============================================================================
4861 * \brief Pass names of mesh groups from study to mesh DS
4863 //=============================================================================
4865 void SMESH_Mesh_i::checkGroupNames()
4867 int nbGrp = NbGroups();
4871 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4872 if ( aStudy->_is_nil() )
4873 return; // nothing to do
4875 SMESH::ListOfGroups* grpList = 0;
4876 // avoid dump of "GetGroups"
4878 // store python dump into a local variable inside local scope
4879 SMESH::TPythonDump pDump; // do not delete this line of code
4880 grpList = GetGroups();
4883 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4884 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4887 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4888 if ( aGrpSO->_is_nil() )
4890 // correct name of the mesh group if necessary
4891 const char* guiName = aGrpSO->GetName();
4892 if ( strcmp(guiName, aGrp->GetName()) )
4893 aGrp->SetName( guiName );
4897 //=============================================================================
4899 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4901 //=============================================================================
4902 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4904 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4908 //=============================================================================
4910 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4912 //=============================================================================
4914 char* SMESH_Mesh_i::GetParameters()
4916 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4919 //=============================================================================
4921 * \brief Returns list of notebook variables used for last Mesh operation
4923 //=============================================================================
4924 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4926 SMESH::string_array_var aResult = new SMESH::string_array();
4927 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4929 CORBA::String_var aParameters = GetParameters();
4930 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4931 if ( !aStudy->_is_nil()) {
4932 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4933 if(aSections->length() > 0) {
4934 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4935 aResult->length(aVars.length());
4936 for(int i = 0;i < aVars.length();i++)
4937 aResult[i] = CORBA::string_dup( aVars[i]);
4941 return aResult._retn();
4944 //=======================================================================
4945 //function : GetTypes
4946 //purpose : Returns types of elements it contains
4947 //=======================================================================
4949 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4952 return _preMeshInfo->GetTypes();
4954 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4958 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4959 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4960 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4961 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4962 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4963 types->length( nbTypes );
4965 return types._retn();
4968 //=======================================================================
4969 //function : GetMesh
4970 //purpose : Returns self
4971 //=======================================================================
4973 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4975 return SMESH::SMESH_Mesh::_duplicate( _this() );
4978 //=======================================================================
4979 //function : IsMeshInfoCorrect
4980 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4981 // * happen if mesh data is not yet fully loaded from the file of study.
4982 //=======================================================================
4984 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4986 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4989 //=============================================================================
4991 * \brief Returns number of mesh elements per each \a EntityType
4993 //=============================================================================
4995 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4998 return _preMeshInfo->GetMeshInfo();
5000 SMESH::long_array_var aRes = new SMESH::long_array();
5001 aRes->length(SMESH::Entity_Last);
5002 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5004 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5006 return aRes._retn();
5007 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5008 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5009 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5010 return aRes._retn();
5013 //=============================================================================
5015 * \brief Returns number of mesh elements per each \a ElementType
5017 //=============================================================================
5019 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5021 SMESH::long_array_var aRes = new SMESH::long_array();
5022 aRes->length(SMESH::NB_ELEMENT_TYPES);
5023 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5026 const SMDS_MeshInfo* meshInfo = 0;
5028 meshInfo = _preMeshInfo;
5029 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5030 meshInfo = & meshDS->GetMeshInfo();
5033 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5034 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5036 return aRes._retn();
5039 //=============================================================================
5041 * Collect statistic of mesh elements given by iterator
5043 //=============================================================================
5045 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5046 SMESH::long_array& theInfo)
5048 if (!theItr) return;
5049 while (theItr->more())
5050 theInfo[ theItr->next()->GetEntityType() ]++;
5052 //=============================================================================
5054 * Returns mesh unstructed grid information.
5056 //=============================================================================
5058 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5060 SALOMEDS::TMPFile_var SeqFile;
5061 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5062 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5064 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5065 aWriter->WriteToOutputStringOn();
5066 aWriter->SetInputData(aGrid);
5067 aWriter->SetFileTypeToBinary();
5069 char* str = aWriter->GetOutputString();
5070 int size = aWriter->GetOutputStringLength();
5072 //Allocate octect buffer of required size
5073 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5074 //Copy ostrstream content to the octect buffer
5075 memcpy(OctetBuf, str, size);
5076 //Create and return TMPFile
5077 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5081 return SeqFile._retn();
5084 //=============================================================================
5085 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5086 * SMESH::ElementType type) */
5088 using namespace SMESH::Controls;
5089 //-----------------------------------------------------------------------------
5090 struct PredicateIterator : public SMDS_ElemIterator
5092 SMDS_ElemIteratorPtr _elemIter;
5093 PredicatePtr _predicate;
5094 const SMDS_MeshElement* _elem;
5096 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5097 PredicatePtr predicate):
5098 _elemIter(iterator), _predicate(predicate)
5106 virtual const SMDS_MeshElement* next()
5108 const SMDS_MeshElement* res = _elem;
5110 while ( _elemIter->more() && !_elem )
5112 _elem = _elemIter->next();
5113 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5120 //-----------------------------------------------------------------------------
5121 struct IDSourceIterator : public SMDS_ElemIterator
5123 const CORBA::Long* _idPtr;
5124 const CORBA::Long* _idEndPtr;
5125 SMESH::long_array_var _idArray;
5126 const SMDS_Mesh* _mesh;
5127 const SMDSAbs_ElementType _type;
5128 const SMDS_MeshElement* _elem;
5130 IDSourceIterator( const SMDS_Mesh* mesh,
5131 const CORBA::Long* ids,
5133 SMDSAbs_ElementType type):
5134 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5136 if ( _idPtr && nbIds && _mesh )
5139 IDSourceIterator( const SMDS_Mesh* mesh,
5140 SMESH::long_array* idArray,
5141 SMDSAbs_ElementType type):
5142 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5144 if ( idArray && _mesh )
5146 _idPtr = &_idArray[0];
5147 _idEndPtr = _idPtr + _idArray->length();
5155 virtual const SMDS_MeshElement* next()
5157 const SMDS_MeshElement* res = _elem;
5159 while ( _idPtr < _idEndPtr && !_elem )
5161 if ( _type == SMDSAbs_Node )
5163 _elem = _mesh->FindNode( *_idPtr++ );
5165 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5166 _elem->GetType() != _type )
5174 //-----------------------------------------------------------------------------
5176 struct NodeOfElemIterator : public SMDS_ElemIterator
5178 TColStd_MapOfInteger _checkedNodeIDs;
5179 SMDS_ElemIteratorPtr _elemIter;
5180 SMDS_ElemIteratorPtr _nodeIter;
5181 const SMDS_MeshElement* _node;
5183 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5185 if ( _elemIter && _elemIter->more() )
5187 _nodeIter = _elemIter->next()->nodesIterator();
5195 virtual const SMDS_MeshElement* next()
5197 const SMDS_MeshElement* res = _node;
5199 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5201 if ( _nodeIter->more() )
5203 _node = _nodeIter->next();
5204 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5209 _nodeIter = _elemIter->next()->nodesIterator();
5217 //=============================================================================
5219 * Return iterator on elements of given type in given object
5221 //=============================================================================
5223 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5224 SMESH::ElementType theType)
5226 SMDS_ElemIteratorPtr elemIt;
5227 bool typeOK = false;
5228 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5230 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5231 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5232 if ( !mesh_i ) return elemIt;
5233 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5235 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5237 elemIt = meshDS->elementsIterator( elemType );
5240 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5242 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5245 elemIt = sm->GetElements();
5246 if ( elemType != SMDSAbs_Node )
5248 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5249 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5253 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5255 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5256 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
5258 elemIt = groupDS->GetElements();
5259 typeOK = ( groupDS->GetType() == elemType );
5262 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5264 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
5266 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5267 if ( pred_i && pred_i->GetPredicate() )
5269 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5270 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5271 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5272 typeOK = ( filterType == elemType );
5278 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5279 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5280 if ( isNodes && elemType != SMDSAbs_Node )
5282 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5285 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5286 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5290 SMESH::long_array_var ids = theObject->GetIDs();
5291 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5293 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
5296 if ( elemIt && elemIt->more() && !typeOK )
5298 if ( elemType == SMDSAbs_Node )
5300 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5304 elemIt = SMDS_ElemIteratorPtr();
5310 //=============================================================================
5311 namespace // Finding concurrent hypotheses
5312 //=============================================================================
5316 * \brief mapping of mesh dimension into shape type
5318 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5320 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5322 case 0: aType = TopAbs_VERTEX; break;
5323 case 1: aType = TopAbs_EDGE; break;
5324 case 2: aType = TopAbs_FACE; break;
5326 default:aType = TopAbs_SOLID; break;
5331 //-----------------------------------------------------------------------------
5333 * \brief Internal structure used to find concurent submeshes
5335 * It represents a pair < submesh, concurent dimension >, where
5336 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5337 * with another submesh. In other words, it is dimension of a hypothesis assigned
5344 int _dim; //!< a dimension the algo can build (concurrent dimension)
5345 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5346 TopTools_MapOfShape _shapeMap;
5347 SMESH_subMesh* _subMesh;
5348 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5350 //-----------------------------------------------------------------------------
5351 // Return the algorithm
5352 const SMESH_Algo* GetAlgo() const
5353 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5355 //-----------------------------------------------------------------------------
5357 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5359 const TopoDS_Shape& theShape)
5361 _subMesh = (SMESH_subMesh*)theSubMesh;
5362 SetShape( theDim, theShape );
5365 //-----------------------------------------------------------------------------
5367 void SetShape(const int theDim,
5368 const TopoDS_Shape& theShape)
5371 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5372 if (_dim >= _ownDim)
5373 _shapeMap.Add( theShape );
5375 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5376 for( ; anExp.More(); anExp.Next() )
5377 _shapeMap.Add( anExp.Current() );
5381 //-----------------------------------------------------------------------------
5382 //! Check sharing of sub-shapes
5383 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5384 const TopTools_MapOfShape& theToFind,
5385 const TopAbs_ShapeEnum theType)
5387 bool isShared = false;
5388 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5389 for (; !isShared && anItr.More(); anItr.Next() )
5391 const TopoDS_Shape aSubSh = anItr.Key();
5392 // check for case when concurrent dimensions are same
5393 isShared = theToFind.Contains( aSubSh );
5394 // check for sub-shape with concurrent dimension
5395 TopExp_Explorer anExp( aSubSh, theType );
5396 for ( ; !isShared && anExp.More(); anExp.Next() )
5397 isShared = theToFind.Contains( anExp.Current() );
5402 //-----------------------------------------------------------------------------
5403 //! check algorithms
5404 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5405 const SMESHDS_Hypothesis* theA2)
5407 if ( !theA1 || !theA2 ||
5408 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5409 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5410 return false; // one of the hypothesis is not algorithm
5411 // check algorithm names (should be equal)
5412 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5416 //-----------------------------------------------------------------------------
5417 //! Check if sub-shape hypotheses are concurrent
5418 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5420 if ( _subMesh == theOther->_subMesh )
5421 return false; // same sub-shape - should not be
5423 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5424 // any of the two submeshes is not on COMPOUND shape )
5425 // -> no concurrency
5426 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5427 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5428 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5429 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5430 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5433 // bool checkSubShape = ( _dim >= theOther->_dim )
5434 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5435 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5436 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5437 if ( !checkSubShape )
5440 // check algorithms to be same
5441 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5442 return true; // different algorithms -> concurrency !
5444 // check hypothesises for concurrence (skip first as algorithm)
5446 // pointers should be same, because it is referened from mesh hypothesis partition
5447 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5448 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5449 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5450 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5452 // the submeshes are concurrent if their algorithms has different parameters
5453 return nbSame != theOther->_hypotheses.size() - 1;
5456 // Return true if algorithm of this SMESH_DimHyp is used if no
5457 // sub-mesh order is imposed by the user
5458 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5460 // NeedDiscreteBoundary() algo has a higher priority
5461 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5462 theOther->GetAlgo()->NeedDiscreteBoundary() )
5463 return !this->GetAlgo()->NeedDiscreteBoundary();
5465 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5468 }; // end of SMESH_DimHyp
5469 //-----------------------------------------------------------------------------
5471 typedef list<const SMESH_DimHyp*> TDimHypList;
5473 //-----------------------------------------------------------------------------
5475 void addDimHypInstance(const int theDim,
5476 const TopoDS_Shape& theShape,
5477 const SMESH_Algo* theAlgo,
5478 const SMESH_subMesh* theSubMesh,
5479 const list <const SMESHDS_Hypothesis*>& theHypList,
5480 TDimHypList* theDimHypListArr )
5482 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5483 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5484 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5485 dimHyp->_hypotheses.push_front(theAlgo);
5486 listOfdimHyp.push_back( dimHyp );
5489 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5490 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5491 theHypList.begin(), theHypList.end() );
5494 //-----------------------------------------------------------------------------
5495 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5496 TDimHypList& theListOfConcurr)
5498 if ( theListOfConcurr.empty() )
5500 theListOfConcurr.push_back( theDimHyp );
5504 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5505 while ( hypIt != theListOfConcurr.end() &&
5506 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5508 theListOfConcurr.insert( hypIt, theDimHyp );
5512 //-----------------------------------------------------------------------------
5513 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5514 const TDimHypList& theListOfDimHyp,
5515 TDimHypList& theListOfConcurrHyp,
5516 set<int>& theSetOfConcurrId )
5518 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5519 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5521 const SMESH_DimHyp* curDimHyp = *rIt;
5522 if ( curDimHyp == theDimHyp )
5523 break; // meet own dimHyp pointer in same dimension
5525 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5526 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5528 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5533 //-----------------------------------------------------------------------------
5534 void unionLists(TListOfInt& theListOfId,
5535 TListOfListOfInt& theListOfListOfId,
5538 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5539 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5541 continue; //skip already treated lists
5542 // check if other list has any same submesh object
5543 TListOfInt& otherListOfId = *it;
5544 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5545 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5548 // union two lists (from source into target)
5549 TListOfInt::iterator it2 = otherListOfId.begin();
5550 for ( ; it2 != otherListOfId.end(); it2++ ) {
5551 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5552 theListOfId.push_back(*it2);
5554 // clear source list
5555 otherListOfId.clear();
5558 //-----------------------------------------------------------------------------
5560 //! free memory allocated for dimension-hypothesis objects
5561 void removeDimHyps( TDimHypList* theArrOfList )
5563 for (int i = 0; i < 4; i++ ) {
5564 TDimHypList& listOfdimHyp = theArrOfList[i];
5565 TDimHypList::const_iterator it = listOfdimHyp.begin();
5566 for ( ; it != listOfdimHyp.end(); it++ )
5571 //-----------------------------------------------------------------------------
5573 * \brief find common submeshes with given submesh
5574 * \param theSubMeshList list of already collected submesh to check
5575 * \param theSubMesh given submesh to intersect with other
5576 * \param theCommonSubMeshes collected common submeshes
5578 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5579 const SMESH_subMesh* theSubMesh,
5580 set<const SMESH_subMesh*>& theCommon )
5584 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5585 for ( ; it != theSubMeshList.end(); it++ )
5586 theSubMesh->FindIntersection( *it, theCommon );
5587 theSubMeshList.push_back( theSubMesh );
5588 //theCommon.insert( theSubMesh );
5591 //-----------------------------------------------------------------------------
5592 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5594 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5595 for ( ; listsIt != smLists.end(); ++listsIt )
5597 const TListOfInt& smIDs = *listsIt;
5598 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5606 //=============================================================================
5608 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5610 //=============================================================================
5612 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5614 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5615 if ( isSubMeshInList( submeshID, anOrder ))
5618 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5619 return isSubMeshInList( submeshID, allConurrent );
5622 //=============================================================================
5624 * \brief Return submesh objects list in meshing order
5626 //=============================================================================
5628 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5630 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5632 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5634 return aResult._retn();
5636 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5637 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5638 anOrder.splice( anOrder.end(), allConurrent );
5641 TListOfListOfInt::iterator listIt = anOrder.begin();
5642 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5643 unionLists( *listIt, anOrder, listIndx + 1 );
5645 // convert submesh ids into interface instances
5646 // and dump command into python
5647 convertMeshOrder( anOrder, aResult, false );
5649 return aResult._retn();
5652 //=============================================================================
5654 * \brief Finds concurrent sub-meshes
5656 //=============================================================================
5658 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5660 TListOfListOfInt anOrder;
5661 ::SMESH_Mesh& mesh = GetImpl();
5663 // collect submeshes and detect concurrent algorithms and hypothesises
5664 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5666 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5667 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5668 ::SMESH_subMesh* sm = (*i_sm).second;
5670 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5672 // list of assigned hypothesises
5673 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5674 // Find out dimensions where the submesh can be concurrent.
5675 // We define the dimensions by algo of each of hypotheses in hypList
5676 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5677 for( ; hypIt != hypList.end(); hypIt++ ) {
5678 SMESH_Algo* anAlgo = 0;
5679 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5680 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5681 // hyp it-self is algo
5682 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5684 // try to find algorithm with help of sub-shapes
5685 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5686 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5687 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5690 continue; // no algorithm assigned to a current submesh
5692 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5693 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5695 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5696 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5697 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5699 } // end iterations on submesh
5701 // iterate on created dimension-hypotheses and check for concurrents
5702 for ( int i = 0; i < 4; i++ ) {
5703 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5704 // check for concurrents in own and other dimensions (step-by-step)
5705 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5706 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5707 const SMESH_DimHyp* dimHyp = *dhIt;
5708 TDimHypList listOfConcurr;
5709 set<int> setOfConcurrIds;
5710 // looking for concurrents and collect into own list
5711 for ( int j = i; j < 4; j++ )
5712 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5713 // check if any concurrents found
5714 if ( listOfConcurr.size() > 0 ) {
5715 // add own submesh to list of concurrent
5716 addInOrderOfPriority( dimHyp, listOfConcurr );
5717 list<int> listOfConcurrIds;
5718 TDimHypList::iterator hypIt = listOfConcurr.begin();
5719 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5720 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5721 anOrder.push_back( listOfConcurrIds );
5726 removeDimHyps(dimHypListArr);
5728 // now, minimise the number of concurrent groups
5729 // Here we assume that lists of submeshes can have same submesh
5730 // in case of multi-dimension algorithms, as result
5731 // list with common submesh has to be united into one list
5733 TListOfListOfInt::iterator listIt = anOrder.begin();
5734 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5735 unionLists( *listIt, anOrder, listIndx + 1 );
5741 //=============================================================================
5743 * \brief Set submesh object order
5744 * \param theSubMeshArray submesh array order
5746 //=============================================================================
5748 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5751 _preMeshInfo->ForgetOrLoad();
5754 ::SMESH_Mesh& mesh = GetImpl();
5756 TPythonDump aPythonDump; // prevent dump of called methods
5757 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5759 TListOfListOfInt subMeshOrder;
5760 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5762 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5763 TListOfInt subMeshIds;
5765 aPythonDump << ", ";
5766 aPythonDump << "[ ";
5767 // Collect subMeshes which should be clear
5768 // do it list-by-list, because modification of submesh order
5769 // take effect between concurrent submeshes only
5770 set<const SMESH_subMesh*> subMeshToClear;
5771 list<const SMESH_subMesh*> subMeshList;
5772 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5774 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5776 aPythonDump << ", ";
5777 aPythonDump << subMesh;
5778 subMeshIds.push_back( subMesh->GetId() );
5779 // detect common parts of submeshes
5780 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5781 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5783 aPythonDump << " ]";
5784 subMeshOrder.push_back( subMeshIds );
5786 // clear collected submeshes
5787 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5788 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5789 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5790 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5792 aPythonDump << " ])";
5794 mesh.SetMeshOrder( subMeshOrder );
5800 //=============================================================================
5802 * \brief Convert submesh ids into submesh interfaces
5804 //=============================================================================
5806 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5807 SMESH::submesh_array_array& theResOrder,
5808 const bool theIsDump)
5810 int nbSet = theIdsOrder.size();
5811 TPythonDump aPythonDump; // prevent dump of called methods
5813 aPythonDump << "[ ";
5814 theResOrder.length(nbSet);
5815 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5817 for( ; it != theIdsOrder.end(); it++ ) {
5818 // translate submesh identificators into submesh objects
5819 // takeing into account real number of concurrent lists
5820 const TListOfInt& aSubOrder = (*it);
5821 if (!aSubOrder.size())
5824 aPythonDump << "[ ";
5825 // convert shape indeces into interfaces
5826 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5827 aResSubSet->length(aSubOrder.size());
5828 TListOfInt::const_iterator subIt = aSubOrder.begin();
5830 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5831 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5833 SMESH::SMESH_subMesh_var subMesh =
5834 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5837 aPythonDump << ", ";
5838 aPythonDump << subMesh;
5840 aResSubSet[ j++ ] = subMesh;
5843 aPythonDump << " ]";
5845 theResOrder[ listIndx++ ] = aResSubSet;
5847 // correct number of lists
5848 theResOrder.length( listIndx );
5851 // finilise python dump
5852 aPythonDump << " ]";
5853 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5857 //================================================================================
5859 // Implementation of SMESH_MeshPartDS
5861 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5862 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5864 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5865 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5867 _meshDS = mesh_i->GetImpl().GetMeshDS();
5869 SetPersistentId( _meshDS->GetPersistentId() );
5871 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5873 // <meshPart> is the whole mesh
5874 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5876 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5877 myGroupSet = _meshDS->GetGroups();
5882 SMESH::long_array_var anIDs = meshPart->GetIDs();
5883 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5884 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5886 for (int i=0; i < anIDs->length(); i++)
5887 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5888 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5893 for (int i=0; i < anIDs->length(); i++)
5894 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5895 if ( _elements[ e->GetType() ].insert( e ).second )
5898 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5899 while ( nIt->more() )
5901 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5902 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5909 _meshDS = 0; // to enforce iteration on _elements and _nodes
5912 // -------------------------------------------------------------------------------------
5913 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5914 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5917 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5918 for ( ; partIt != meshPart.end(); ++partIt )
5919 if ( const SMDS_MeshElement * e = *partIt )
5920 if ( _elements[ e->GetType() ].insert( e ).second )
5923 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5924 while ( nIt->more() )
5926 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5927 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5933 // -------------------------------------------------------------------------------------
5934 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5936 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5938 typedef SMDS_SetIterator
5939 <const SMDS_MeshElement*,
5940 TIDSortedElemSet::const_iterator,
5941 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5942 SMDS_MeshElement::GeomFilter
5945 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5947 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5948 _elements[type].end(),
5949 SMDS_MeshElement::GeomFilter( geomType )));
5951 // -------------------------------------------------------------------------------------
5952 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5954 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5956 typedef SMDS_SetIterator
5957 <const SMDS_MeshElement*,
5958 TIDSortedElemSet::const_iterator,
5959 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5960 SMDS_MeshElement::EntityFilter
5963 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5965 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5966 _elements[type].end(),
5967 SMDS_MeshElement::EntityFilter( entity )));
5969 // -------------------------------------------------------------------------------------
5970 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5972 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5973 if ( type == SMDSAbs_All && !_meshDS )
5975 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5977 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5978 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5980 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5982 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5983 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5985 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5986 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5988 // -------------------------------------------------------------------------------------
5989 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5990 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5992 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5993 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5994 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5996 // -------------------------------------------------------------------------------------
5997 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5998 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5999 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6000 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6001 #undef _GET_ITER_DEFINE
6003 // END Implementation of SMESH_MeshPartDS
6005 //================================================================================