1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
100 int SMESH_Mesh_i::_idGenerator = 0;
102 //=============================================================================
106 //=============================================================================
108 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
110 : SALOME::GenericObj_i( thePOA )
114 _id = _idGenerator++;
116 _previewEditor = NULL;
121 //=============================================================================
125 //=============================================================================
127 SMESH_Mesh_i::~SMESH_Mesh_i()
130 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
131 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
132 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
134 aGroup->UnRegister();
135 SMESH::SMESH_GroupBase_var( itGr->second );
140 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
141 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
142 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
144 aSubMesh->UnRegister();
145 SMESH::SMESH_subMesh_var( itSM->second );
147 _mapSubMeshIor.clear();
149 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
150 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
151 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
152 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
153 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
154 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
157 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
161 // clear cached shapes if no more meshes remain; (the cache is blame,
162 // together with publishing, of spent time increasing in issue 22874)
163 if ( _impl->NbMeshes() == 1 )
164 _gen_i->GetShapeReader()->ClearClientBuffer();
166 delete _editor; _editor = NULL;
167 delete _previewEditor; _previewEditor = NULL;
168 delete _impl; _impl = NULL;
169 delete _preMeshInfo; _preMeshInfo = NULL;
172 //=============================================================================
176 * Associates <this> mesh with <theShape> and puts a reference
177 * to <theShape> into the current study;
178 * the previous shape is substituted by the new one.
180 //=============================================================================
182 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
183 throw (SALOME::SALOME_Exception)
185 Unexpect aCatch(SALOME_SalomeException);
187 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
189 catch(SALOME_Exception & S_ex) {
190 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
192 // to track changes of GEOM groups
193 SMESH::SMESH_Mesh_var mesh = _this();
194 addGeomGroupData( theShapeObject, mesh );
195 if ( !CORBA::is_nil( theShapeObject ))
196 _mainShapeTick = theShapeObject->GetTick();
199 //================================================================================
201 * \brief return true if mesh has a shape to build a shape on
203 //================================================================================
205 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
206 throw (SALOME::SALOME_Exception)
208 Unexpect aCatch(SALOME_SalomeException);
211 res = _impl->HasShapeToMesh();
213 catch(SALOME_Exception & S_ex) {
214 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
219 //=======================================================================
220 //function : GetShapeToMesh
222 //=======================================================================
224 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
225 throw (SALOME::SALOME_Exception)
227 Unexpect aCatch(SALOME_SalomeException);
228 GEOM::GEOM_Object_var aShapeObj;
230 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
233 aShapeObj = _gen_i->ShapeToGeomObject( S );
234 if ( aShapeObj->_is_nil() )
236 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
237 // find GEOM_Object by entry (IPAL52735)
238 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
239 for ( ; data != _geomGroupData.end(); ++data )
240 if ( data->_smeshObject->_is_equivalent( _this() ))
242 SALOMEDS::SObject_wrap so = SMESH_Gen_i::getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
243 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
244 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
250 catch(SALOME_Exception & S_ex) {
251 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
253 return aShapeObj._retn();
256 //================================================================================
258 * \brief Return false if the mesh is not yet fully loaded from the study file
260 //================================================================================
262 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
264 Unexpect aCatch(SALOME_SalomeException);
265 return !_preMeshInfo;
268 //================================================================================
270 * \brief Load full mesh data from the study file
272 //================================================================================
274 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
276 Unexpect aCatch(SALOME_SalomeException);
278 _preMeshInfo->FullLoadFromFile();
281 //================================================================================
283 * \brief Remove all nodes and elements
285 //================================================================================
287 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
289 Unexpect aCatch(SALOME_SalomeException);
291 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
295 //CheckGeomGroupModif(); // issue 20145
297 catch(SALOME_Exception & S_ex) {
298 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
301 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
304 //================================================================================
306 * \brief Remove all nodes and elements for indicated shape
308 //================================================================================
310 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
311 throw (SALOME::SALOME_Exception)
313 Unexpect aCatch(SALOME_SalomeException);
315 _preMeshInfo->FullLoadFromFile();
318 _impl->ClearSubMesh( ShapeID );
320 catch(SALOME_Exception & S_ex) {
321 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
323 _impl->GetMeshDS()->Modified();
325 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
328 //=============================================================================
330 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
332 //=============================================================================
334 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
336 SMESH::DriverMED_ReadStatus res;
339 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
340 res = SMESH::DRS_OK; break;
341 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
342 res = SMESH::DRS_EMPTY; break;
343 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
344 res = SMESH::DRS_WARN_RENUMBER; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
346 res = SMESH::DRS_WARN_SKIP_ELEM; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
348 res = SMESH::DRS_WARN_DESCENDING; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
351 res = SMESH::DRS_FAIL; break;
356 //=============================================================================
358 * Convert ::SMESH_ComputeError to SMESH::ComputeError
360 //=============================================================================
362 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
364 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
365 errVar->subShapeID = -1;
366 errVar->hasBadMesh = false;
368 if ( !errorPtr || errorPtr->IsOK() )
370 errVar->code = SMESH::COMPERR_OK;
374 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
375 errVar->comment = errorPtr->myComment.c_str();
377 return errVar._retn();
380 //=============================================================================
384 * Imports mesh data from MED file
386 //=============================================================================
388 SMESH::DriverMED_ReadStatus
389 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
390 throw ( SALOME::SALOME_Exception )
392 Unexpect aCatch(SALOME_SalomeException);
395 status = _impl->MEDToMesh( theFileName, theMeshName );
397 catch( SALOME_Exception& S_ex ) {
398 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
401 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
404 CreateGroupServants();
406 int major, minor, release;
407 major = minor = release = 0;
408 MED::GetMEDVersion(theFileName, major, minor, release);
409 _medFileInfo = new SMESH::MedFileInfo();
410 _medFileInfo->fileName = theFileName;
411 _medFileInfo->fileSize = 0;
412 _medFileInfo->major = major;
413 _medFileInfo->minor = minor;
414 _medFileInfo->release = release;
415 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
417 return ConvertDriverMEDReadStatus(status);
420 //================================================================================
422 * \brief Imports mesh data from the CGNS file
424 //================================================================================
426 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
427 const int theMeshIndex,
428 std::string& theMeshName )
429 throw ( SALOME::SALOME_Exception )
431 Unexpect aCatch(SALOME_SalomeException);
434 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
436 catch( SALOME_Exception& S_ex ) {
437 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
440 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
443 CreateGroupServants();
445 return ConvertDriverMEDReadStatus(status);
448 //=============================================================================
452 * Imports mesh data from MED file
454 //=============================================================================
456 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
457 throw ( SALOME::SALOME_Exception )
461 // Read mesh with name = <theMeshName> into SMESH_Mesh
462 _impl->UNVToMesh( theFileName );
464 CreateGroupServants();
466 SMESH_CATCH( SMESH::throwCorbaException );
471 //=============================================================================
475 * Imports mesh data from STL file
477 //=============================================================================
478 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
479 throw ( SALOME::SALOME_Exception )
483 // Read mesh with name = <theMeshName> into SMESH_Mesh
484 std::string name = _impl->STLToMesh( theFileName );
487 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
488 _gen_i->SetName( meshSO, name.c_str() );
491 SMESH_CATCH( SMESH::throwCorbaException );
496 //================================================================================
498 * \brief Function used in SMESH_CATCH by ImportGMFFile()
500 //================================================================================
504 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
506 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
510 //================================================================================
512 * \brief Imports data from a GMF file and returns an error description
514 //================================================================================
516 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
517 bool theMakeRequiredGroups )
518 throw (SALOME::SALOME_Exception)
520 SMESH_ComputeErrorPtr error;
523 #define SMESH_CAUGHT error =
526 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
528 SMESH_CATCH( exceptionToComputeError );
532 CreateGroupServants();
534 return ConvertComputeError( error );
537 //=============================================================================
541 //=============================================================================
543 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
545 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
546 (SMESH_Hypothesis::Hypothesis_Status theStatus)
549 RETURNCASE( HYP_OK );
550 RETURNCASE( HYP_MISSING );
551 RETURNCASE( HYP_CONCURRENT );
552 RETURNCASE( HYP_BAD_PARAMETER );
553 RETURNCASE( HYP_HIDDEN_ALGO );
554 RETURNCASE( HYP_HIDING_ALGO );
555 RETURNCASE( HYP_UNKNOWN_FATAL );
556 RETURNCASE( HYP_INCOMPATIBLE );
557 RETURNCASE( HYP_NOTCONFORM );
558 RETURNCASE( HYP_ALREADY_EXIST );
559 RETURNCASE( HYP_BAD_DIM );
560 RETURNCASE( HYP_BAD_SUBSHAPE );
561 RETURNCASE( HYP_BAD_GEOMETRY );
562 RETURNCASE( HYP_NEED_SHAPE );
563 RETURNCASE( HYP_INCOMPAT_HYPS );
566 return SMESH::HYP_UNKNOWN_FATAL;
569 //=============================================================================
573 * calls internal addHypothesis() and then adds a reference to <anHyp> under
574 * the SObject actually having a reference to <aSubShape>.
575 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
577 //=============================================================================
579 SMESH::Hypothesis_Status
580 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
581 SMESH::SMESH_Hypothesis_ptr anHyp,
582 CORBA::String_out anErrorText)
583 throw(SALOME::SALOME_Exception)
585 Unexpect aCatch(SALOME_SalomeException);
587 _preMeshInfo->ForgetOrLoad();
590 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
591 anErrorText = error.c_str();
593 SMESH::SMESH_Mesh_var mesh( _this() );
594 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
596 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
598 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
600 // Update Python script
601 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
602 << aSubShape << ", " << anHyp << " )";
604 return ConvertHypothesisStatus(status);
607 //=============================================================================
611 //=============================================================================
613 SMESH_Hypothesis::Hypothesis_Status
614 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
615 SMESH::SMESH_Hypothesis_ptr anHyp,
616 std::string* anErrorText)
618 if(MYDEBUG) MESSAGE("addHypothesis");
620 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
621 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
623 if (CORBA::is_nil( anHyp ))
624 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
626 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
629 TopoDS_Shape myLocSubShape;
630 //use PseudoShape in case if mesh has no shape
632 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
634 myLocSubShape = _impl->GetShapeToMesh();
636 const int hypId = anHyp->GetId();
638 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
639 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
641 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
643 // assure there is a corresponding submesh
644 if ( !_impl->IsMainShape( myLocSubShape )) {
645 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
646 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
647 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
650 else if ( anErrorText )
652 *anErrorText = error;
655 catch(SALOME_Exception & S_ex)
657 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
662 //=============================================================================
666 //=============================================================================
668 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
669 SMESH::SMESH_Hypothesis_ptr anHyp)
670 throw(SALOME::SALOME_Exception)
672 Unexpect aCatch(SALOME_SalomeException);
674 _preMeshInfo->ForgetOrLoad();
676 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
677 SMESH::SMESH_Mesh_var mesh = _this();
679 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
681 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
683 // Update Python script
684 if(_impl->HasShapeToMesh())
685 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
686 << aSubShape << ", " << anHyp << " )";
688 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
691 return ConvertHypothesisStatus(status);
694 //=============================================================================
698 //=============================================================================
700 SMESH_Hypothesis::Hypothesis_Status
701 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
702 SMESH::SMESH_Hypothesis_ptr anHyp)
704 if(MYDEBUG) MESSAGE("removeHypothesis()");
706 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
707 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
709 if (CORBA::is_nil( anHyp ))
710 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
712 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
715 TopoDS_Shape myLocSubShape;
716 //use PseudoShape in case if mesh has no shape
717 if( _impl->HasShapeToMesh() )
718 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
720 myLocSubShape = _impl->GetShapeToMesh();
722 const int hypId = anHyp->GetId();
723 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
724 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
726 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
730 catch(SALOME_Exception & S_ex)
732 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
737 //=============================================================================
741 //=============================================================================
743 SMESH::ListOfHypothesis *
744 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
745 throw(SALOME::SALOME_Exception)
747 Unexpect aCatch(SALOME_SalomeException);
748 if (MYDEBUG) MESSAGE("GetHypothesisList");
749 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
750 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
752 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
755 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
756 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
757 myLocSubShape = _impl->GetShapeToMesh();
758 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
759 int i = 0, n = aLocalList.size();
762 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
763 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
764 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
766 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
767 if ( id_hypptr != _mapHypo.end() )
768 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
772 catch(SALOME_Exception & S_ex) {
773 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
776 return aList._retn();
779 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
781 Unexpect aCatch(SALOME_SalomeException);
782 if (MYDEBUG) MESSAGE("GetSubMeshes");
784 SMESH::submesh_array_var aList = new SMESH::submesh_array();
787 TPythonDump aPythonDump;
788 if ( !_mapSubMeshIor.empty() )
792 aList->length( _mapSubMeshIor.size() );
794 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
795 for ( ; it != _mapSubMeshIor.end(); it++ ) {
796 if ( CORBA::is_nil( it->second )) continue;
797 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
799 if (i > 1) aPythonDump << ", ";
800 aPythonDump << it->second;
804 catch(SALOME_Exception & S_ex) {
805 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
808 // Update Python script
809 if ( !_mapSubMeshIor.empty() )
810 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
812 return aList._retn();
815 //=============================================================================
819 //=============================================================================
821 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
822 const char* theName )
823 throw(SALOME::SALOME_Exception)
825 Unexpect aCatch(SALOME_SalomeException);
826 if (CORBA::is_nil(aSubShape))
827 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
829 SMESH::SMESH_subMesh_var subMesh;
830 SMESH::SMESH_Mesh_var aMesh = _this();
832 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
834 //Get or Create the SMESH_subMesh object implementation
836 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
838 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
840 TopoDS_Iterator it( myLocSubShape );
842 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
844 subMesh = getSubMesh( subMeshId );
846 // create a new subMesh object servant if there is none for the shape
847 if ( subMesh->_is_nil() )
848 subMesh = createSubMesh( aSubShape );
849 if ( _gen_i->CanPublishInStudy( subMesh ))
851 SALOMEDS::SObject_wrap aSO =
852 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
853 if ( !aSO->_is_nil()) {
854 // Update Python script
855 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
856 << aSubShape << ", '" << theName << "' )";
860 catch(SALOME_Exception & S_ex) {
861 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
863 return subMesh._retn();
866 //=============================================================================
870 //=============================================================================
872 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
873 throw (SALOME::SALOME_Exception)
877 if ( theSubMesh->_is_nil() )
880 GEOM::GEOM_Object_var aSubShape;
881 // Remove submesh's SObject
882 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
883 if ( !anSO->_is_nil() ) {
884 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
885 SALOMEDS::SObject_wrap anObj, aRef;
886 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
887 anObj->ReferencedObject( aRef.inout() ))
889 CORBA::Object_var obj = aRef->GetObject();
890 aSubShape = GEOM::GEOM_Object::_narrow( obj );
892 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
893 // aSubShape = theSubMesh->GetSubShape();
895 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
896 builder->RemoveObjectWithChildren( anSO );
898 // Update Python script
899 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
902 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
904 _preMeshInfo->ForgetOrLoad();
906 SMESH_CATCH( SMESH::throwCorbaException );
909 //=============================================================================
913 //=============================================================================
915 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
916 const char* theName )
917 throw(SALOME::SALOME_Exception)
919 Unexpect aCatch(SALOME_SalomeException);
921 _preMeshInfo->FullLoadFromFile();
923 SMESH::SMESH_Group_var aNewGroup =
924 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
926 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
928 SMESH::SMESH_Mesh_var mesh = _this();
929 SALOMEDS::SObject_wrap aSO =
930 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
931 if ( !aSO->_is_nil())
932 // Update Python script
933 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
934 << theElemType << ", '" << theName << "' )";
936 return aNewGroup._retn();
939 //=============================================================================
943 //=============================================================================
944 SMESH::SMESH_GroupOnGeom_ptr
945 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
947 GEOM::GEOM_Object_ptr theGeomObj)
948 throw(SALOME::SALOME_Exception)
950 Unexpect aCatch(SALOME_SalomeException);
952 _preMeshInfo->FullLoadFromFile();
954 SMESH::SMESH_GroupOnGeom_var aNewGroup;
956 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
957 if ( !aShape.IsNull() )
960 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
962 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
964 SMESH::SMESH_Mesh_var mesh = _this();
965 SALOMEDS::SObject_wrap aSO =
966 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
967 if ( !aSO->_is_nil())
968 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
969 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
973 return aNewGroup._retn();
976 //================================================================================
978 * \brief Creates a group whose contents is defined by filter
979 * \param theElemType - group type
980 * \param theName - group name
981 * \param theFilter - the filter
982 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
984 //================================================================================
986 SMESH::SMESH_GroupOnFilter_ptr
987 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
989 SMESH::Filter_ptr theFilter )
990 throw (SALOME::SALOME_Exception)
992 Unexpect aCatch(SALOME_SalomeException);
994 _preMeshInfo->FullLoadFromFile();
996 if ( CORBA::is_nil( theFilter ))
997 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
999 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1001 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1003 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1004 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1007 if ( !aNewGroup->_is_nil() )
1008 aNewGroup->SetFilter( theFilter );
1010 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1012 SMESH::SMESH_Mesh_var mesh = _this();
1013 SALOMEDS::SObject_wrap aSO =
1014 _gen_i->PublishGroup( 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::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1042 if ( !aGroupSO->_is_nil() )
1044 // Update Python script
1045 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1047 // Remove group's SObject
1048 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1049 builder->RemoveObjectWithChildren( aGroupSO );
1051 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1053 // Remove the group from SMESH data structures
1054 removeGroup( aGroup->GetLocalID() );
1056 SMESH_CATCH( SMESH::throwCorbaException );
1059 //=============================================================================
1061 * Remove group with its contents
1063 //=============================================================================
1065 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1066 throw (SALOME::SALOME_Exception)
1070 _preMeshInfo->FullLoadFromFile();
1072 if ( theGroup->_is_nil() )
1075 vector<int> nodeIds; // to remove nodes becoming free
1076 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1077 if ( !isNodal && !theGroup->IsEmpty() )
1079 CORBA::Long elemID = theGroup->GetID( 1 );
1080 int nbElemNodes = GetElemNbNodes( elemID );
1081 if ( nbElemNodes > 0 )
1082 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1085 // Retrieve contents
1086 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1087 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1088 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1089 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1090 elems.assign( elemBeg, elemEnd );
1092 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1095 RemoveGroup( theGroup );
1098 for ( size_t i = 0; i < elems.size(); ++i )
1100 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1104 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1105 nodeIds.push_back( nIt->next()->GetID() );
1107 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1111 _impl->GetMeshDS()->RemoveElement( elems[i] );
1115 // Remove free nodes
1116 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1117 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1118 if ( n->NbInverseElements() == 0 )
1119 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1121 // Update Python script (theGroup must be alive for this)
1122 pyDump << SMESH::SMESH_Mesh_var(_this())
1123 << ".RemoveGroupWithContents( " << theGroup << " )";
1125 SMESH_CATCH( SMESH::throwCorbaException );
1128 //================================================================================
1130 * \brief Get the list of groups existing in the mesh
1131 * \retval SMESH::ListOfGroups * - list of groups
1133 //================================================================================
1135 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1137 Unexpect aCatch(SALOME_SalomeException);
1138 if (MYDEBUG) MESSAGE("GetGroups");
1140 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1143 TPythonDump aPythonDump;
1144 if ( !_mapGroups.empty() )
1146 aPythonDump << "[ ";
1148 aList->length( _mapGroups.size() );
1150 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1151 for ( ; it != _mapGroups.end(); it++ ) {
1152 if ( CORBA::is_nil( it->second )) continue;
1153 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1155 if (i > 1) aPythonDump << ", ";
1156 aPythonDump << it->second;
1160 catch(SALOME_Exception & S_ex) {
1161 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1163 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1165 return aList._retn();
1168 //=============================================================================
1170 * Get number of groups existing in the mesh
1172 //=============================================================================
1174 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1176 Unexpect aCatch(SALOME_SalomeException);
1177 return _mapGroups.size();
1180 //=============================================================================
1182 * New group including all mesh elements present in initial groups is created.
1184 //=============================================================================
1186 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1187 SMESH::SMESH_GroupBase_ptr theGroup2,
1188 const char* theName )
1189 throw (SALOME::SALOME_Exception)
1191 SMESH::SMESH_Group_var aResGrp;
1195 _preMeshInfo->FullLoadFromFile();
1197 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1198 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1200 if ( theGroup1->GetType() != theGroup2->GetType() )
1201 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1206 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1207 if ( aResGrp->_is_nil() )
1208 return SMESH::SMESH_Group::_nil();
1210 aResGrp->AddFrom( theGroup1 );
1211 aResGrp->AddFrom( theGroup2 );
1213 // Update Python script
1214 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1215 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1217 SMESH_CATCH( SMESH::throwCorbaException );
1219 return aResGrp._retn();
1222 //=============================================================================
1224 * \brief New group including all mesh elements present in initial groups is created.
1225 * \param theGroups list of groups
1226 * \param theName name of group to be created
1227 * \return pointer to the new group
1229 //=============================================================================
1231 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1232 const char* theName )
1233 throw (SALOME::SALOME_Exception)
1235 SMESH::SMESH_Group_var aResGrp;
1238 _preMeshInfo->FullLoadFromFile();
1241 return SMESH::SMESH_Group::_nil();
1246 SMESH::ElementType aType = SMESH::ALL;
1247 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1249 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1250 if ( CORBA::is_nil( aGrp ) )
1252 if ( aType == SMESH::ALL )
1253 aType = aGrp->GetType();
1254 else if ( aType != aGrp->GetType() )
1255 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1258 if ( aType == SMESH::ALL )
1259 return SMESH::SMESH_Group::_nil();
1264 aResGrp = CreateGroup( aType, theName );
1265 if ( aResGrp->_is_nil() )
1266 return SMESH::SMESH_Group::_nil();
1268 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1269 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1271 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1272 if ( !CORBA::is_nil( aGrp ) )
1274 aResGrp->AddFrom( aGrp );
1275 if ( g > 0 ) pyDump << ", ";
1279 pyDump << " ], '" << theName << "' )";
1281 SMESH_CATCH( SMESH::throwCorbaException );
1283 return aResGrp._retn();
1286 //=============================================================================
1288 * New group is created. All mesh elements that are
1289 * present in both initial groups are added to the new one.
1291 //=============================================================================
1293 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1294 SMESH::SMESH_GroupBase_ptr theGroup2,
1295 const char* theName )
1296 throw (SALOME::SALOME_Exception)
1298 SMESH::SMESH_Group_var aResGrp;
1303 _preMeshInfo->FullLoadFromFile();
1305 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1306 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1308 if ( theGroup1->GetType() != theGroup2->GetType() )
1309 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1313 // Create Intersection
1314 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1315 if ( aResGrp->_is_nil() )
1316 return aResGrp._retn();
1318 SMESHDS_GroupBase* groupDS1 = 0;
1319 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1320 groupDS1 = grp_i->GetGroupDS();
1322 SMESHDS_GroupBase* groupDS2 = 0;
1323 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1324 groupDS2 = grp_i->GetGroupDS();
1326 SMESHDS_Group* resGroupDS = 0;
1327 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1328 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1330 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1332 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1333 while ( elemIt1->more() )
1335 const SMDS_MeshElement* e = elemIt1->next();
1336 if ( groupDS2->Contains( e ))
1337 resGroupDS->SMDSGroup().Add( e );
1340 // Update Python script
1341 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1342 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1344 SMESH_CATCH( SMESH::throwCorbaException );
1346 return aResGrp._retn();
1349 //=============================================================================
1351 \brief Intersect list of groups. New group is created. All mesh elements that
1352 are present in all initial groups simultaneously are added to the new one.
1353 \param theGroups list of groups
1354 \param theName name of group to be created
1355 \return pointer on the group
1357 //=============================================================================
1358 SMESH::SMESH_Group_ptr
1359 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1360 const char* theName )
1361 throw (SALOME::SALOME_Exception)
1363 SMESH::SMESH_Group_var aResGrp;
1368 _preMeshInfo->FullLoadFromFile();
1371 return SMESH::SMESH_Group::_nil();
1373 // check types and get SMESHDS_GroupBase's
1374 SMESH::ElementType aType = SMESH::ALL;
1375 vector< SMESHDS_GroupBase* > groupVec;
1376 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1378 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1379 if ( CORBA::is_nil( aGrp ) )
1381 if ( aType == SMESH::ALL )
1382 aType = aGrp->GetType();
1383 else if ( aType != aGrp->GetType() )
1384 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1387 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1388 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1390 if ( grpDS->IsEmpty() )
1395 groupVec.push_back( grpDS );
1398 if ( aType == SMESH::ALL ) // all groups are nil
1399 return SMESH::SMESH_Group::_nil();
1404 aResGrp = CreateGroup( aType, theName );
1406 SMESHDS_Group* resGroupDS = 0;
1407 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1408 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1409 if ( !resGroupDS || groupVec.empty() )
1410 return aResGrp._retn();
1413 size_t i, nb = groupVec.size();
1414 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1415 while ( elemIt1->more() )
1417 const SMDS_MeshElement* e = elemIt1->next();
1419 for ( i = 1; ( i < nb && inAll ); ++i )
1420 inAll = groupVec[i]->Contains( e );
1423 resGroupDS->SMDSGroup().Add( e );
1426 // Update Python script
1427 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1428 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1430 SMESH_CATCH( SMESH::throwCorbaException );
1432 return aResGrp._retn();
1435 //=============================================================================
1437 * New group is created. All mesh elements that are present in
1438 * a main group but is not present in a tool group are added to the new one
1440 //=============================================================================
1442 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1443 SMESH::SMESH_GroupBase_ptr theGroup2,
1444 const char* theName )
1445 throw (SALOME::SALOME_Exception)
1447 SMESH::SMESH_Group_var aResGrp;
1452 _preMeshInfo->FullLoadFromFile();
1454 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1455 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1457 if ( theGroup1->GetType() != theGroup2->GetType() )
1458 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1462 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1463 if ( aResGrp->_is_nil() )
1464 return aResGrp._retn();
1466 SMESHDS_GroupBase* groupDS1 = 0;
1467 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1468 groupDS1 = grp_i->GetGroupDS();
1470 SMESHDS_GroupBase* groupDS2 = 0;
1471 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1472 groupDS2 = grp_i->GetGroupDS();
1474 SMESHDS_Group* resGroupDS = 0;
1475 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1476 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1478 if ( groupDS1 && groupDS2 && resGroupDS )
1480 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1481 while ( elemIt1->more() )
1483 const SMDS_MeshElement* e = elemIt1->next();
1484 if ( !groupDS2->Contains( e ))
1485 resGroupDS->SMDSGroup().Add( e );
1488 // Update Python script
1489 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1490 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1492 SMESH_CATCH( SMESH::throwCorbaException );
1494 return aResGrp._retn();
1497 //=============================================================================
1499 \brief Cut lists of groups. New group is created. All mesh elements that are
1500 present in main groups but do not present in tool groups are added to the new one
1501 \param theMainGroups list of main groups
1502 \param theToolGroups list of tool groups
1503 \param theName name of group to be created
1504 \return pointer on the group
1506 //=============================================================================
1507 SMESH::SMESH_Group_ptr
1508 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1509 const SMESH::ListOfGroups& theToolGroups,
1510 const char* theName )
1511 throw (SALOME::SALOME_Exception)
1513 SMESH::SMESH_Group_var aResGrp;
1518 _preMeshInfo->FullLoadFromFile();
1521 return SMESH::SMESH_Group::_nil();
1523 // check types and get SMESHDS_GroupBase's
1524 SMESH::ElementType aType = SMESH::ALL;
1525 vector< SMESHDS_GroupBase* > toolGroupVec;
1526 vector< SMDS_ElemIteratorPtr > mainIterVec;
1528 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1530 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1531 if ( CORBA::is_nil( aGrp ) )
1533 if ( aType == SMESH::ALL )
1534 aType = aGrp->GetType();
1535 else if ( aType != aGrp->GetType() )
1536 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1538 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1539 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1540 if ( !grpDS->IsEmpty() )
1541 mainIterVec.push_back( grpDS->GetElements() );
1543 if ( aType == SMESH::ALL ) // all main groups are nil
1544 return SMESH::SMESH_Group::_nil();
1545 if ( mainIterVec.empty() ) // all main groups are empty
1546 return aResGrp._retn();
1548 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1550 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1551 if ( CORBA::is_nil( aGrp ) )
1553 if ( aType != aGrp->GetType() )
1554 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1556 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1557 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1558 toolGroupVec.push_back( grpDS );
1564 aResGrp = CreateGroup( aType, theName );
1566 SMESHDS_Group* resGroupDS = 0;
1567 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1568 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1570 return aResGrp._retn();
1573 size_t i, nb = toolGroupVec.size();
1574 SMDS_ElemIteratorPtr mainElemIt
1575 ( new SMDS_IteratorOnIterators
1576 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1577 while ( mainElemIt->more() )
1579 const SMDS_MeshElement* e = mainElemIt->next();
1581 for ( i = 0; ( i < nb && !isIn ); ++i )
1582 isIn = toolGroupVec[i]->Contains( e );
1585 resGroupDS->SMDSGroup().Add( e );
1588 // Update Python script
1589 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1590 << ".CutListOfGroups( " << theMainGroups << ", "
1591 << theToolGroups << ", '" << theName << "' )";
1593 SMESH_CATCH( SMESH::throwCorbaException );
1595 return aResGrp._retn();
1598 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1600 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1601 bool & toStopChecking )
1603 toStopChecking = ( nbCommon < nbChecked );
1604 return nbCommon == nbNodes;
1606 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1607 bool & toStopChecking )
1609 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1610 return nbCommon == nbCorners;
1612 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1613 bool & toStopChecking )
1615 return nbCommon > 0;
1617 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1618 bool & toStopChecking )
1620 return nbCommon >= (nbNodes+1) / 2;
1624 //=============================================================================
1626 * Create a group of entities basing on nodes of other groups.
1627 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1628 * \param [in] anElemType - a type of elements to include to the new group.
1629 * \param [in] theName - a name of the new group.
1630 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1631 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1632 * new group provided that it is based on nodes of an element of \a aListOfGroups
1633 * \return SMESH_Group - the created group
1635 // IMP 19939, bug 22010, IMP 22635
1636 //=============================================================================
1638 SMESH::SMESH_Group_ptr
1639 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1640 SMESH::ElementType theElemType,
1641 const char* theName,
1642 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1643 CORBA::Boolean theUnderlyingOnly)
1644 throw (SALOME::SALOME_Exception)
1646 SMESH::SMESH_Group_var aResGrp;
1650 _preMeshInfo->FullLoadFromFile();
1652 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1654 if ( !theName || !aMeshDS )
1655 return SMESH::SMESH_Group::_nil();
1657 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1659 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1660 SMESH_Comment nbCoNoStr( "SMESH.");
1661 switch ( theNbCommonNodes ) {
1662 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1663 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1664 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1665 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1666 default: return aResGrp._retn();
1668 int nbChecked, nbCommon, nbNodes, nbCorners;
1674 aResGrp = CreateGroup( theElemType, theName );
1675 if ( aResGrp->_is_nil() )
1676 return SMESH::SMESH_Group::_nil();
1678 SMESHDS_GroupBase* groupBaseDS =
1679 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1680 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1682 vector<bool> isNodeInGroups;
1684 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1686 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1687 if ( CORBA::is_nil( aGrp ) )
1689 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1690 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1693 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1694 if ( !elIt ) continue;
1696 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1698 while ( elIt->more() ) {
1699 const SMDS_MeshElement* el = elIt->next();
1700 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1701 while ( nIt->more() )
1702 resGroupCore.Add( nIt->next() );
1705 // get elements of theElemType based on nodes of every element of group
1706 else if ( theUnderlyingOnly )
1708 while ( elIt->more() )
1710 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1711 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1712 TIDSortedElemSet checkedElems;
1713 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1714 while ( nIt->more() )
1716 const SMDS_MeshNode* n = nIt->next();
1717 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1718 // check nodes of elements of theElemType around el
1719 while ( elOfTypeIt->more() )
1721 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1722 if ( !checkedElems.insert( elOfType ).second ) continue;
1723 nbNodes = elOfType->NbNodes();
1724 nbCorners = elOfType->NbCornerNodes();
1726 bool toStopChecking = false;
1727 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1728 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1729 if ( elNodes.count( nIt2->next() ) &&
1730 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1732 resGroupCore.Add( elOfType );
1739 // get all nodes of elements of groups
1742 while ( elIt->more() )
1744 const SMDS_MeshElement* el = elIt->next(); // an element of group
1745 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1746 while ( nIt->more() )
1748 const SMDS_MeshNode* n = nIt->next();
1749 if ( n->GetID() >= (int) isNodeInGroups.size() )
1750 isNodeInGroups.resize( n->GetID() + 1, false );
1751 isNodeInGroups[ n->GetID() ] = true;
1757 // Get elements of theElemType based on a certain number of nodes of elements of groups
1758 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1760 const SMDS_MeshNode* n;
1761 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1762 const int isNodeInGroupsSize = isNodeInGroups.size();
1763 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1765 if ( !isNodeInGroups[ iN ] ||
1766 !( n = aMeshDS->FindNode( iN )))
1769 // check nodes of elements of theElemType around n
1770 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1771 while ( elOfTypeIt->more() )
1773 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1774 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1779 nbNodes = elOfType->NbNodes();
1780 nbCorners = elOfType->NbCornerNodes();
1782 bool toStopChecking = false;
1783 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1784 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1786 const int nID = nIt->next()->GetID();
1787 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1788 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1790 resGroupCore.Add( elOfType );
1798 // Update Python script
1799 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1800 << ".CreateDimGroup( "
1801 << theGroups << ", " << theElemType << ", '" << theName << "', "
1802 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1804 SMESH_CATCH( SMESH::throwCorbaException );
1806 return aResGrp._retn();
1809 //================================================================================
1811 * \brief Remember GEOM group data
1813 //================================================================================
1815 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1816 CORBA::Object_ptr theSmeshObj)
1818 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1821 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1822 if ( groupSO->_is_nil() )
1825 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1826 GEOM::GEOM_IGroupOperations_wrap groupOp =
1827 geomGen->GetIGroupOperations();
1828 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1831 _geomGroupData.push_back( TGeomGroupData() );
1832 TGeomGroupData & groupData = _geomGroupData.back();
1834 CORBA::String_var entry = groupSO->GetID();
1835 groupData._groupEntry = entry.in();
1837 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1838 groupData._indices.insert( ids[i] );
1840 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1841 // shape index in SMESHDS
1842 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1843 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1846 //================================================================================
1848 * Remove GEOM group data relating to removed smesh object
1850 //================================================================================
1852 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1854 list<TGeomGroupData>::iterator
1855 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1856 for ( ; data != dataEnd; ++data ) {
1857 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1858 _geomGroupData.erase( data );
1864 //================================================================================
1866 * \brief Return new group contents if it has been changed and update group data
1868 //================================================================================
1870 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1872 TopoDS_Shape newShape;
1875 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
1876 if ( !groupSO->_is_nil() )
1878 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1879 if ( CORBA::is_nil( groupObj )) return newShape;
1880 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1882 // get indices of group items
1883 set<int> curIndices;
1884 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1885 GEOM::GEOM_IGroupOperations_wrap groupOp =
1886 geomGen->GetIGroupOperations();
1887 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1888 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1889 curIndices.insert( ids[i] );
1891 if ( groupData._indices == curIndices )
1892 return newShape; // group not changed
1895 groupData._indices = curIndices;
1897 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1898 if ( !geomClient ) return newShape;
1899 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1900 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1901 newShape = _gen_i->GeomObjectToShape( geomGroup );
1904 if ( newShape.IsNull() ) {
1905 // geom group becomes empty - return empty compound
1906 TopoDS_Compound compound;
1907 BRep_Builder().MakeCompound(compound);
1908 newShape = compound;
1915 //-----------------------------------------------------------------------------
1917 * \brief Storage of shape and index used in CheckGeomGroupModif()
1919 struct TIndexedShape
1922 TopoDS_Shape _shape;
1923 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1925 //-----------------------------------------------------------------------------
1927 * \brief Data to re-create a group on geometry
1929 struct TGroupOnGeomData
1933 SMDSAbs_ElementType _type;
1935 Quantity_Color _color;
1939 //=============================================================================
1941 * \brief Update data if geometry changes
1945 //=============================================================================
1947 void SMESH_Mesh_i::CheckGeomModif()
1949 if ( !_impl->HasShapeToMesh() ) return;
1951 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1952 //if ( mainGO->_is_nil() ) return;
1954 // Update after group modification
1956 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1957 called by other mesh (IPAL52735) */
1958 mainGO->GetType() == GEOM_GROUP ||
1959 mainGO->GetTick() == _mainShapeTick )
1961 CheckGeomGroupModif();
1965 // Update after shape transformation like Translate
1967 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1968 if ( !geomClient ) return;
1969 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1970 if ( geomGen->_is_nil() ) return;
1972 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1973 geomClient->RemoveShapeFromBuffer( ior.in() );
1975 // Update data taking into account that
1976 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1979 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1980 if ( newShape.IsNull() )
1983 _mainShapeTick = mainGO->GetTick();
1985 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1987 // store data of groups on geometry
1988 vector< TGroupOnGeomData > groupsData;
1989 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1990 groupsData.reserve( groups.size() );
1991 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1992 for ( ; g != groups.end(); ++g )
1993 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1995 TGroupOnGeomData data;
1996 data._oldID = group->GetID();
1997 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1998 data._type = group->GetType();
1999 data._name = group->GetStoreName();
2000 data._color = group->GetColor();
2001 groupsData.push_back( data );
2003 // store assigned hypotheses
2004 vector< pair< int, THypList > > ids2Hyps;
2005 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2006 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2008 const TopoDS_Shape& s = s2hyps.Key();
2009 const THypList& hyps = s2hyps.ChangeValue();
2010 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2013 // change shape to mesh
2014 int oldNbSubShapes = meshDS->MaxShapeIndex();
2015 _impl->ShapeToMesh( TopoDS_Shape() );
2016 _impl->ShapeToMesh( newShape );
2018 // re-add shapes of geom groups
2019 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2020 for ( ; data != _geomGroupData.end(); ++data )
2022 TopoDS_Shape newShape = newGroupShape( *data );
2023 if ( !newShape.IsNull() )
2025 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2027 TopoDS_Compound compound;
2028 BRep_Builder().MakeCompound( compound );
2029 BRep_Builder().Add( compound, newShape );
2030 newShape = compound;
2032 _impl->GetSubMesh( newShape );
2035 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2036 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2037 SALOME::INTERNAL_ERROR );
2039 // re-assign hypotheses
2040 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2042 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2043 const THypList& hyps = ids2Hyps[i].second;
2044 THypList::const_iterator h = hyps.begin();
2045 for ( ; h != hyps.end(); ++h )
2046 _impl->AddHypothesis( s, (*h)->GetID() );
2050 for ( size_t i = 0; i < groupsData.size(); ++i )
2052 const TGroupOnGeomData& data = groupsData[i];
2054 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2055 if ( i2g == _mapGroups.end() ) continue;
2057 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2058 if ( !gr_i ) continue;
2061 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2062 meshDS->IndexToShape( data._shapeID ));
2065 _mapGroups.erase( i2g );
2069 g->GetGroupDS()->SetColor( data._color );
2070 gr_i->changeLocalId( id );
2071 _mapGroups[ id ] = i2g->second;
2072 if ( data._oldID != id )
2073 _mapGroups.erase( i2g );
2077 // update _mapSubMesh
2078 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2079 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2080 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2084 //=============================================================================
2086 * \brief Update objects depending on changed geom groups
2088 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2089 * issue 0020210: Update of a smesh group after modification of the associated geom group
2091 //=============================================================================
2093 void SMESH_Mesh_i::CheckGeomGroupModif()
2095 if ( !_impl->HasShapeToMesh() ) return;
2097 CORBA::Long nbEntities = NbNodes() + NbElements();
2099 // Check if group contents changed
2101 typedef map< string, TopoDS_Shape > TEntry2Geom;
2102 TEntry2Geom newGroupContents;
2104 list<TGeomGroupData>::iterator
2105 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2106 for ( ; data != dataEnd; ++data )
2108 pair< TEntry2Geom::iterator, bool > it_new =
2109 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2110 bool processedGroup = !it_new.second;
2111 TopoDS_Shape& newShape = it_new.first->second;
2112 if ( !processedGroup )
2113 newShape = newGroupShape( *data );
2114 if ( newShape.IsNull() )
2115 continue; // no changes
2118 _preMeshInfo->ForgetOrLoad();
2120 if ( processedGroup ) { // update group indices
2121 list<TGeomGroupData>::iterator data2 = data;
2122 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2123 data->_indices = data2->_indices;
2126 // Update SMESH objects according to new GEOM group contents
2128 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2129 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2131 int oldID = submesh->GetId();
2132 if ( !_mapSubMeshIor.count( oldID ))
2134 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2136 // update hypotheses
2137 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2138 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2139 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2141 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2142 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2144 // care of submeshes
2145 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2146 int newID = newSubmesh->GetId();
2147 if ( newID != oldID ) {
2148 _mapSubMesh [ newID ] = newSubmesh;
2149 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2150 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2151 _mapSubMesh. erase(oldID);
2152 _mapSubMesh_i. erase(oldID);
2153 _mapSubMeshIor.erase(oldID);
2154 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2159 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2160 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2161 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2163 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2165 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2166 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2167 ds->SetShape( newShape );
2172 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2173 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2175 // Remove groups and submeshes basing on removed sub-shapes
2177 TopTools_MapOfShape newShapeMap;
2178 TopoDS_Iterator shapeIt( newShape );
2179 for ( ; shapeIt.More(); shapeIt.Next() )
2180 newShapeMap.Add( shapeIt.Value() );
2182 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2183 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2185 if ( newShapeMap.Contains( shapeIt.Value() ))
2187 TopTools_IndexedMapOfShape oldShapeMap;
2188 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2189 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2191 const TopoDS_Shape& oldShape = oldShapeMap(i);
2192 int oldInd = meshDS->ShapeToIndex( oldShape );
2194 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2195 if ( i_smIor != _mapSubMeshIor.end() ) {
2196 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2199 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2200 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2202 // check if a group bases on oldInd shape
2203 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2204 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2205 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2206 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2208 RemoveGroup( i_grp->second ); // several groups can base on same shape
2209 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2214 // Reassign hypotheses and update groups after setting the new shape to mesh
2216 // collect anassigned hypotheses
2217 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2218 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2219 TShapeHypList assignedHyps;
2220 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2222 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2223 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2224 if ( !hyps.empty() ) {
2225 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2226 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2227 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2230 // collect shapes supporting groups
2231 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2232 TShapeTypeList groupData;
2233 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2234 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2235 for ( ; grIt != groups.end(); ++grIt )
2237 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2239 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2241 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2243 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2244 _impl->ShapeToMesh( newShape );
2246 // reassign hypotheses
2247 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2248 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2250 TIndexedShape& geom = indS_hyps->first;
2251 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2252 int oldID = geom._index;
2253 int newID = meshDS->ShapeToIndex( geom._shape );
2254 if ( oldID == 1 ) { // main shape
2256 geom._shape = newShape;
2260 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2261 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2262 // care of sub-meshes
2263 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2264 if ( newID != oldID ) {
2265 _mapSubMesh [ newID ] = newSubmesh;
2266 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2267 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2268 _mapSubMesh. erase(oldID);
2269 _mapSubMesh_i. erase(oldID);
2270 _mapSubMeshIor.erase(oldID);
2271 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2275 TShapeTypeList::iterator geomType = groupData.begin();
2276 for ( ; geomType != groupData.end(); ++geomType )
2278 const TIndexedShape& geom = geomType->first;
2279 int oldID = geom._index;
2280 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2283 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2284 CORBA::String_var name = groupSO->GetName();
2286 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2288 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2289 group_i->changeLocalId( newID );
2292 break; // everything has been updated
2295 } // loop on group data
2299 CORBA::Long newNbEntities = NbNodes() + NbElements();
2300 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2301 if ( newNbEntities != nbEntities )
2303 // Add all SObjects with icons to soToUpdateIcons
2304 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2306 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2307 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2308 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2310 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2311 i_gr != _mapGroups.end(); ++i_gr ) // groups
2312 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2315 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2316 for ( ; so != soToUpdateIcons.end(); ++so )
2317 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2320 //=============================================================================
2322 * \brief Create standalone group from a group on geometry or filter
2324 //=============================================================================
2326 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2327 throw (SALOME::SALOME_Exception)
2329 SMESH::SMESH_Group_var aGroup;
2334 _preMeshInfo->FullLoadFromFile();
2336 if ( theGroup->_is_nil() )
2337 return aGroup._retn();
2339 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2341 return aGroup._retn();
2343 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2345 const int anId = aGroupToRem->GetLocalID();
2346 if ( !_impl->ConvertToStandalone( anId ) )
2347 return aGroup._retn();
2348 removeGeomGroupData( theGroup );
2350 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2352 // remove old instance of group from own map
2353 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2354 _mapGroups.erase( anId );
2356 SALOMEDS::StudyBuilder_var builder;
2357 SALOMEDS::SObject_wrap aGroupSO;
2358 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2359 if ( !aStudy->_is_nil() ) {
2360 builder = aStudy->NewBuilder();
2361 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2362 if ( !aGroupSO->_is_nil() )
2364 // remove reference to geometry
2365 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2366 for ( ; chItr->More(); chItr->Next() )
2367 // Remove group's child SObject
2368 builder->RemoveObject( chItr->Value() );
2370 // Update Python script
2371 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2372 << ".ConvertToStandalone( " << aGroupSO << " )";
2374 // change icon of Group on Filter
2377 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2378 const int isEmpty = ( elemTypes->length() == 0 );
2381 SALOMEDS::GenericAttribute_wrap anAttr =
2382 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2383 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2384 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2390 // remember new group in own map
2391 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2392 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2394 // register CORBA object for persistence
2395 _gen_i->RegisterObject( aGroup );
2397 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2398 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2399 //aGroup->Register();
2400 aGroupToRem->UnRegister();
2402 SMESH_CATCH( SMESH::throwCorbaException );
2404 return aGroup._retn();
2407 //=============================================================================
2411 //=============================================================================
2413 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2415 if(MYDEBUG) MESSAGE( "createSubMesh" );
2416 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2417 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2418 const int subMeshId = mySubMesh->GetId();
2420 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2421 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2423 _mapSubMesh [subMeshId] = mySubMesh;
2424 _mapSubMesh_i [subMeshId] = subMeshServant;
2425 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2427 subMeshServant->Register();
2429 // register CORBA object for persistence
2430 int nextId = _gen_i->RegisterObject( subMesh );
2431 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2432 else { nextId = 0; } // avoid "unused variable" warning
2434 // to track changes of GEOM groups
2435 addGeomGroupData( theSubShapeObject, subMesh );
2437 return subMesh._retn();
2440 //=======================================================================
2441 //function : getSubMesh
2443 //=======================================================================
2445 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2447 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2448 if ( it == _mapSubMeshIor.end() )
2449 return SMESH::SMESH_subMesh::_nil();
2451 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2454 //=============================================================================
2458 //=============================================================================
2460 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2461 GEOM::GEOM_Object_ptr theSubShapeObject )
2463 bool isHypChanged = false;
2464 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2465 return isHypChanged;
2467 const int subMeshId = theSubMesh->GetId();
2469 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2471 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2473 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2476 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2477 isHypChanged = !hyps.empty();
2478 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2479 for ( ; hyp != hyps.end(); ++hyp )
2480 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2487 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2488 isHypChanged = ( aHypList->length() > 0 );
2489 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2490 removeHypothesis( theSubShapeObject, aHypList[i] );
2493 catch( const SALOME::SALOME_Exception& ) {
2494 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2496 removeGeomGroupData( theSubShapeObject );
2500 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2501 if ( id_smi != _mapSubMesh_i.end() )
2502 id_smi->second->UnRegister();
2504 // remove a CORBA object
2505 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2506 if ( id_smptr != _mapSubMeshIor.end() )
2507 SMESH::SMESH_subMesh_var( id_smptr->second );
2509 _mapSubMesh.erase(subMeshId);
2510 _mapSubMesh_i.erase(subMeshId);
2511 _mapSubMeshIor.erase(subMeshId);
2513 return isHypChanged;
2516 //=============================================================================
2520 //=============================================================================
2522 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2523 const char* theName,
2524 const TopoDS_Shape& theShape,
2525 const SMESH_PredicatePtr& thePredicate )
2527 std::string newName;
2528 if ( !theName || !theName[0] )
2530 std::set< std::string > presentNames;
2531 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2532 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2534 CORBA::String_var name = i_gr->second->GetName();
2535 presentNames.insert( name.in() );
2538 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2539 } while ( !presentNames.insert( newName ).second );
2540 theName = newName.c_str();
2543 SMESH::SMESH_GroupBase_var aGroup;
2544 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2546 SMESH_GroupBase_i* aGroupImpl;
2547 if ( !theShape.IsNull() )
2548 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2549 else if ( thePredicate )
2550 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2552 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2554 aGroup = aGroupImpl->_this();
2555 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2556 aGroupImpl->Register();
2558 // register CORBA object for persistence
2559 int nextId = _gen_i->RegisterObject( aGroup );
2560 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2561 else { nextId = 0; } // avoid "unused variable" warning in release mode
2563 // to track changes of GEOM groups
2564 if ( !theShape.IsNull() ) {
2565 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2566 addGeomGroupData( geom, aGroup );
2569 return aGroup._retn();
2572 //=============================================================================
2574 * SMESH_Mesh_i::removeGroup
2576 * Should be called by ~SMESH_Group_i()
2578 //=============================================================================
2580 void SMESH_Mesh_i::removeGroup( const int theId )
2582 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2583 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2584 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2585 _mapGroups.erase( theId );
2586 removeGeomGroupData( group );
2587 if ( !_impl->RemoveGroup( theId ))
2589 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2590 RemoveGroup( group );
2592 group->UnRegister();
2596 //=============================================================================
2600 //=============================================================================
2602 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2603 throw(SALOME::SALOME_Exception)
2605 SMESH::log_array_var aLog;
2609 _preMeshInfo->FullLoadFromFile();
2611 list < SMESHDS_Command * >logDS = _impl->GetLog();
2612 aLog = new SMESH::log_array;
2614 int lg = logDS.size();
2617 list < SMESHDS_Command * >::iterator its = logDS.begin();
2618 while(its != logDS.end()){
2619 SMESHDS_Command *com = *its;
2620 int comType = com->GetType();
2622 int lgcom = com->GetNumber();
2624 const list < int >&intList = com->GetIndexes();
2625 int inum = intList.size();
2627 list < int >::const_iterator ii = intList.begin();
2628 const list < double >&coordList = com->GetCoords();
2629 int rnum = coordList.size();
2631 list < double >::const_iterator ir = coordList.begin();
2632 aLog[indexLog].commandType = comType;
2633 aLog[indexLog].number = lgcom;
2634 aLog[indexLog].coords.length(rnum);
2635 aLog[indexLog].indexes.length(inum);
2636 for(int i = 0; i < rnum; i++){
2637 aLog[indexLog].coords[i] = *ir;
2638 //MESSAGE(" "<<i<<" "<<ir.Value());
2641 for(int i = 0; i < inum; i++){
2642 aLog[indexLog].indexes[i] = *ii;
2643 //MESSAGE(" "<<i<<" "<<ii.Value());
2652 SMESH_CATCH( SMESH::throwCorbaException );
2654 return aLog._retn();
2658 //=============================================================================
2662 //=============================================================================
2664 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2668 SMESH_CATCH( SMESH::throwCorbaException );
2671 //=============================================================================
2675 //=============================================================================
2677 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2682 //=============================================================================
2685 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2686 // issue 0020918: groups removal is caused by hyp modification
2687 // issue 0021208: to forget not loaded mesh data at hyp modification
2688 struct TCallUp_i : public SMESH_Mesh::TCallUp
2690 SMESH_Mesh_i* _mesh;
2691 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2692 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2693 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2694 virtual void Load () { _mesh->Load(); }
2698 //================================================================================
2700 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2702 //================================================================================
2704 void SMESH_Mesh_i::onHypothesisModified()
2707 _preMeshInfo->ForgetOrLoad();
2710 //=============================================================================
2714 //=============================================================================
2716 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2718 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2721 _impl->SetCallUp( new TCallUp_i(this));
2724 //=============================================================================
2728 //=============================================================================
2730 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2732 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2736 //=============================================================================
2738 * Return mesh editor
2740 //=============================================================================
2742 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2743 throw (SALOME::SALOME_Exception)
2745 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2749 _preMeshInfo->FullLoadFromFile();
2751 // Create MeshEditor
2753 _editor = new SMESH_MeshEditor_i( this, false );
2754 aMeshEdVar = _editor->_this();
2756 // Update Python script
2757 TPythonDump() << _editor << " = "
2758 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2760 SMESH_CATCH( SMESH::throwCorbaException );
2762 return aMeshEdVar._retn();
2765 //=============================================================================
2767 * Return mesh edition previewer
2769 //=============================================================================
2771 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2772 throw (SALOME::SALOME_Exception)
2774 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2778 _preMeshInfo->FullLoadFromFile();
2780 if ( !_previewEditor )
2781 _previewEditor = new SMESH_MeshEditor_i( this, true );
2782 aMeshEdVar = _previewEditor->_this();
2784 SMESH_CATCH( SMESH::throwCorbaException );
2786 return aMeshEdVar._retn();
2789 //================================================================================
2791 * \brief Return true if the mesh has been edited since a last total re-compute
2792 * and those modifications may prevent successful partial re-compute
2794 //================================================================================
2796 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2798 Unexpect aCatch(SALOME_SalomeException);
2799 return _impl->HasModificationsToDiscard();
2802 //================================================================================
2804 * \brief Returns a random unique color
2806 //================================================================================
2808 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2810 const int MAX_ATTEMPTS = 100;
2812 double tolerance = 0.5;
2813 SALOMEDS::Color col;
2817 // generate random color
2818 double red = (double)rand() / RAND_MAX;
2819 double green = (double)rand() / RAND_MAX;
2820 double blue = (double)rand() / RAND_MAX;
2821 // check existence in the list of the existing colors
2822 bool matched = false;
2823 std::list<SALOMEDS::Color>::const_iterator it;
2824 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2825 SALOMEDS::Color color = *it;
2826 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2827 matched = tol < tolerance;
2829 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2830 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2838 //=============================================================================
2840 * Sets auto-color mode. If it is on, groups get unique random colors
2842 //=============================================================================
2844 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2846 Unexpect aCatch(SALOME_SalomeException);
2847 _impl->SetAutoColor(theAutoColor);
2849 TPythonDump pyDump; // not to dump group->SetColor() from below code
2850 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2852 std::list<SALOMEDS::Color> aReservedColors;
2853 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2854 for ( ; it != _mapGroups.end(); it++ ) {
2855 if ( CORBA::is_nil( it->second )) continue;
2856 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2857 it->second->SetColor( aColor );
2858 aReservedColors.push_back( aColor );
2862 //=============================================================================
2864 * Returns true if auto-color mode is on
2866 //=============================================================================
2868 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2870 Unexpect aCatch(SALOME_SalomeException);
2871 return _impl->GetAutoColor();
2874 //=============================================================================
2876 * Checks if there are groups with equal names
2878 //=============================================================================
2880 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2882 return _impl->HasDuplicatedGroupNamesMED();
2885 //================================================================================
2887 * \brief Care of a file before exporting mesh into it
2889 //================================================================================
2891 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2893 SMESH_File aFile( file );
2895 if (aFile.exists()) {
2896 // existing filesystem node
2897 if ( !aFile.isDirectory() ) {
2898 if ( aFile.openForWriting() ) {
2899 if ( overwrite && ! aFile.remove()) {
2900 msg << "Can't replace " << aFile.getName();
2903 msg << "Can't write into " << aFile.getName();
2906 msg << "Location " << aFile.getName() << " is not a file";
2910 // nonexisting file; check if it can be created
2911 if ( !aFile.openForWriting() ) {
2912 msg << "You cannot create the file "
2914 << ". Check the directory existence and access rights";
2922 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2926 //================================================================================
2928 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2929 * \param file - file name
2930 * \param overwrite - to erase the file or not
2931 * \retval string - mesh name
2933 //================================================================================
2935 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2936 CORBA::Boolean overwrite)
2939 PrepareForWriting(file, overwrite);
2940 string aMeshName = "Mesh";
2941 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2942 if ( !aStudy->_is_nil() ) {
2943 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
2944 if ( !aMeshSO->_is_nil() ) {
2945 CORBA::String_var name = aMeshSO->GetName();
2947 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2948 if ( !aStudy->GetProperties()->IsLocked() )
2950 SALOMEDS::GenericAttribute_wrap anAttr;
2951 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2952 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2953 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2954 ASSERT(!aFileName->_is_nil());
2955 aFileName->SetValue(file);
2956 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2957 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2958 ASSERT(!aFileType->_is_nil());
2959 aFileType->SetValue("FICHIERMED");
2963 // Update Python script
2964 // set name of mesh before export
2965 TPythonDump() << _gen_i << ".SetName("
2966 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2968 // check names of groups
2974 //================================================================================
2976 * \brief Export to MED file
2978 //================================================================================
2980 void SMESH_Mesh_i::ExportMED(const char* file,
2981 CORBA::Boolean auto_groups,
2982 CORBA::Boolean overwrite,
2983 CORBA::Boolean autoDimension)
2984 throw(SALOME::SALOME_Exception)
2986 //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
2989 _preMeshInfo->FullLoadFromFile();
2991 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2992 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, 0, autoDimension );
2994 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
2995 << file << "', " << auto_groups << ", "
2996 << overwrite << ", "
2997 << autoDimension << " )";
2999 SMESH_CATCH( SMESH::throwCorbaException );
3002 //================================================================================
3004 * \brief Export a mesh to a SAUV file
3006 //================================================================================
3008 void SMESH_Mesh_i::ExportSAUV (const char* file,
3009 CORBA::Boolean auto_groups)
3010 throw(SALOME::SALOME_Exception)
3012 Unexpect aCatch(SALOME_SalomeException);
3014 _preMeshInfo->FullLoadFromFile();
3016 string aMeshName = prepareMeshNameAndGroups(file, true);
3017 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3018 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3019 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3023 //================================================================================
3025 * \brief Export a mesh to a DAT file
3027 //================================================================================
3029 void SMESH_Mesh_i::ExportDAT (const char *file)
3030 throw(SALOME::SALOME_Exception)
3032 Unexpect aCatch(SALOME_SalomeException);
3034 _preMeshInfo->FullLoadFromFile();
3036 // Update Python script
3037 // check names of groups
3039 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3042 PrepareForWriting(file);
3043 _impl->ExportDAT(file);
3046 //================================================================================
3048 * \brief Export a mesh to an UNV file
3050 //================================================================================
3052 void SMESH_Mesh_i::ExportUNV (const char *file)
3053 throw(SALOME::SALOME_Exception)
3055 Unexpect aCatch(SALOME_SalomeException);
3057 _preMeshInfo->FullLoadFromFile();
3059 // Update Python script
3060 // check names of groups
3062 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3065 PrepareForWriting(file);
3066 _impl->ExportUNV(file);
3069 //================================================================================
3071 * \brief Export a mesh to an STL file
3073 //================================================================================
3075 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3076 throw(SALOME::SALOME_Exception)
3078 Unexpect aCatch(SALOME_SalomeException);
3080 _preMeshInfo->FullLoadFromFile();
3082 // Update Python script
3083 // check names of groups
3085 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3086 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3088 CORBA::String_var name;
3089 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3090 if ( !so->_is_nil() )
3091 name = so->GetName();
3094 PrepareForWriting( file );
3095 _impl->ExportSTL( file, isascii, name.in() );
3098 //================================================================================
3100 * \brief Export a part of mesh to a med file
3102 //================================================================================
3104 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3106 CORBA::Boolean auto_groups,
3107 CORBA::Boolean overwrite,
3108 CORBA::Boolean autoDimension,
3109 const GEOM::ListOfFields& fields,
3110 const char* geomAssocFields)
3111 throw (SALOME::SALOME_Exception)
3115 _preMeshInfo->FullLoadFromFile();
3118 bool have0dField = false;
3119 if ( fields.length() > 0 )
3121 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3122 if ( shapeToMesh->_is_nil() )
3123 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3125 for ( size_t i = 0; i < fields.length(); ++i )
3127 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3128 THROW_SALOME_CORBA_EXCEPTION
3129 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3130 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3131 if ( fieldShape->_is_nil() )
3132 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3133 if ( !fieldShape->IsSame( shapeToMesh ) )
3134 THROW_SALOME_CORBA_EXCEPTION
3135 ( "Field defined not on shape", SALOME::BAD_PARAM);
3136 if ( fields[i]->GetDimension() == 0 )
3139 if ( geomAssocFields )
3140 for ( int i = 0; geomAssocFields[i]; ++i )
3141 switch ( geomAssocFields[i] ) {
3142 case 'v':case 'e':case 'f':case 's': break;
3143 case 'V':case 'E':case 'F':case 'S': break;
3144 default: THROW_SALOME_CORBA_EXCEPTION
3145 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3149 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3153 string aMeshName = "Mesh";
3154 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3155 if ( CORBA::is_nil( meshPart ) ||
3156 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3158 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3159 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3160 0, autoDimension, /*addODOnVertices=*/have0dField);
3161 meshDS = _impl->GetMeshDS();
3166 _preMeshInfo->FullLoadFromFile();
3168 PrepareForWriting(file, overwrite);
3170 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3171 if ( !SO->_is_nil() ) {
3172 CORBA::String_var name = SO->GetName();
3176 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3177 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3178 partDS, autoDimension, /*addODOnVertices=*/have0dField);
3179 meshDS = tmpDSDeleter._obj = partDS;
3184 if ( _impl->HasShapeToMesh() )
3186 DriverMED_W_Field fieldWriter;
3187 fieldWriter.SetFile( file );
3188 fieldWriter.SetMeshName( aMeshName );
3189 fieldWriter.AddODOnVertices( have0dField );
3191 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3195 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3196 goList->length( fields.length() );
3197 for ( size_t i = 0; i < fields.length(); ++i )
3199 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3202 TPythonDump() << _this() << ".ExportPartToMED( "
3203 << meshPart << ", r'" << file << "', "
3204 << auto_groups << ", " << overwrite << ", "
3205 << autoDimension << ", " << goList
3206 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3208 SMESH_CATCH( SMESH::throwCorbaException );
3211 //================================================================================
3213 * Write GEOM fields to MED file
3215 //================================================================================
3217 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3218 SMESHDS_Mesh* meshDS,
3219 const GEOM::ListOfFields& fields,
3220 const char* geomAssocFields)
3222 #define METH "SMESH_Mesh_i::exportMEDFields() "
3224 if (( fields.length() < 1 ) &&
3225 ( !geomAssocFields || !geomAssocFields[0] ))
3228 std::vector< std::vector< double > > dblVals;
3229 std::vector< std::vector< int > > intVals;
3230 std::vector< int > subIdsByDim[ 4 ];
3231 const double noneDblValue = 0.;
3232 const double noneIntValue = 0;
3234 for ( size_t iF = 0; iF < fields.length(); ++iF )
3238 int dim = fields[ iF ]->GetDimension();
3239 SMDSAbs_ElementType elemType;
3240 TopAbs_ShapeEnum shapeType;
3242 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3243 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3244 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3245 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3247 continue; // skip fields on whole shape
3249 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3250 if ( dataType == GEOM::FDT_String )
3252 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3253 if ( stepIDs->length() < 1 )
3255 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3256 if ( comps->length() < 1 )
3258 CORBA::String_var name = fields[ iF ]->GetName();
3260 if ( !fieldWriter.Set( meshDS,
3264 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3267 for ( size_t iC = 0; iC < comps->length(); ++iC )
3268 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3270 dblVals.resize( comps->length() );
3271 intVals.resize( comps->length() );
3273 // find sub-shape IDs
3275 std::vector< int >& subIds = subIdsByDim[ dim ];
3276 if ( subIds.empty() )
3277 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3278 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3279 subIds.push_back( id );
3283 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3287 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3289 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3290 if ( step->_is_nil() )
3293 CORBA::Long stamp = step->GetStamp();
3294 CORBA::Long id = step->GetID();
3295 fieldWriter.SetDtIt( int( stamp ), int( id ));
3297 // fill dblVals or intVals
3298 for ( size_t iC = 0; iC < comps->length(); ++iC )
3299 if ( dataType == GEOM::FDT_Double )
3301 dblVals[ iC ].clear();
3302 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3306 intVals[ iC ].clear();
3307 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3311 case GEOM::FDT_Double:
3313 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3314 if ( dblStep->_is_nil() ) continue;
3315 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3316 if ( vv->length() != subIds.size() * comps->length() )
3317 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3318 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3319 for ( size_t iC = 0; iC < comps->length(); ++iC )
3320 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3325 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3326 if ( intStep->_is_nil() ) continue;
3327 GEOM::ListOfLong_var vv = intStep->GetValues();
3328 if ( vv->length() != subIds.size() * comps->length() )
3329 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3330 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3331 for ( size_t iC = 0; iC < comps->length(); ++iC )
3332 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3335 case GEOM::FDT_Bool:
3337 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3338 if ( boolStep->_is_nil() ) continue;
3339 GEOM::short_array_var vv = boolStep->GetValues();
3340 if ( vv->length() != subIds.size() * comps->length() )
3341 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3342 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3343 for ( size_t iC = 0; iC < comps->length(); ++iC )
3344 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3350 // pass values to fieldWriter
3351 elemIt = fieldWriter.GetOrderedElems();
3352 if ( dataType == GEOM::FDT_Double )
3353 while ( elemIt->more() )
3355 const SMDS_MeshElement* e = elemIt->next();
3356 const int shapeID = e->getshapeId();
3357 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3358 for ( size_t iC = 0; iC < comps->length(); ++iC )
3359 fieldWriter.AddValue( noneDblValue );
3361 for ( size_t iC = 0; iC < comps->length(); ++iC )
3362 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3365 while ( elemIt->more() )
3367 const SMDS_MeshElement* e = elemIt->next();
3368 const int shapeID = e->getshapeId();
3369 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3370 for ( size_t iC = 0; iC < comps->length(); ++iC )
3371 fieldWriter.AddValue( (double) noneIntValue );
3373 for ( size_t iC = 0; iC < comps->length(); ++iC )
3374 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3378 fieldWriter.Perform();
3379 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3380 if ( res && res->IsKO() )
3382 if ( res->myComment.empty() )
3383 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3385 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3391 if ( !geomAssocFields || !geomAssocFields[0] )
3394 // write geomAssocFields
3396 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3397 shapeDim[ TopAbs_COMPOUND ] = 3;
3398 shapeDim[ TopAbs_COMPSOLID ] = 3;
3399 shapeDim[ TopAbs_SOLID ] = 3;
3400 shapeDim[ TopAbs_SHELL ] = 2;
3401 shapeDim[ TopAbs_FACE ] = 2;
3402 shapeDim[ TopAbs_WIRE ] = 1;
3403 shapeDim[ TopAbs_EDGE ] = 1;
3404 shapeDim[ TopAbs_VERTEX ] = 0;
3405 shapeDim[ TopAbs_SHAPE ] = 3;
3407 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3409 std::vector< std::string > compNames;
3410 switch ( geomAssocFields[ iF ]) {
3412 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3413 compNames.push_back( "dim" );
3416 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3419 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3422 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3426 compNames.push_back( "id" );
3427 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3428 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3430 fieldWriter.SetDtIt( -1, -1 );
3432 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3436 if ( compNames.size() == 2 ) // _vertices_
3437 while ( elemIt->more() )
3439 const SMDS_MeshElement* e = elemIt->next();
3440 const int shapeID = e->getshapeId();
3443 fieldWriter.AddValue( (double) -1 );
3444 fieldWriter.AddValue( (double) -1 );
3448 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3449 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3450 fieldWriter.AddValue( (double) shapeID );
3454 while ( elemIt->more() )
3456 const SMDS_MeshElement* e = elemIt->next();
3457 const int shapeID = e->getshapeId();
3459 fieldWriter.AddValue( (double) -1 );
3461 fieldWriter.AddValue( (double) shapeID );
3465 fieldWriter.Perform();
3466 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3467 if ( res && res->IsKO() )
3469 if ( res->myComment.empty() )
3470 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3472 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3475 } // loop on geomAssocFields
3480 //================================================================================
3482 * \brief Export a part of mesh to a DAT file
3484 //================================================================================
3486 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3488 throw (SALOME::SALOME_Exception)
3490 Unexpect aCatch(SALOME_SalomeException);
3492 _preMeshInfo->FullLoadFromFile();
3494 PrepareForWriting(file);
3496 SMESH_MeshPartDS partDS( meshPart );
3497 _impl->ExportDAT(file,&partDS);
3499 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3500 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3502 //================================================================================
3504 * \brief Export a part of mesh to an UNV file
3506 //================================================================================
3508 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3510 throw (SALOME::SALOME_Exception)
3512 Unexpect aCatch(SALOME_SalomeException);
3514 _preMeshInfo->FullLoadFromFile();
3516 PrepareForWriting(file);
3518 SMESH_MeshPartDS partDS( meshPart );
3519 _impl->ExportUNV(file, &partDS);
3521 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3522 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3524 //================================================================================
3526 * \brief Export a part of mesh to an STL file
3528 //================================================================================
3530 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3532 ::CORBA::Boolean isascii)
3533 throw (SALOME::SALOME_Exception)
3535 Unexpect aCatch(SALOME_SalomeException);
3537 _preMeshInfo->FullLoadFromFile();
3539 PrepareForWriting(file);
3541 CORBA::String_var name;
3542 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3543 if ( !so->_is_nil() )
3544 name = so->GetName();
3546 SMESH_MeshPartDS partDS( meshPart );
3547 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3549 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3550 << meshPart<< ", r'" << file << "', " << isascii << ")";
3553 //================================================================================
3555 * \brief Export a part of mesh to an STL file
3557 //================================================================================
3559 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3561 CORBA::Boolean overwrite,
3562 CORBA::Boolean groupElemsByType)
3563 throw (SALOME::SALOME_Exception)
3566 Unexpect aCatch(SALOME_SalomeException);
3568 _preMeshInfo->FullLoadFromFile();
3570 PrepareForWriting(file,overwrite);
3572 std::string meshName("");
3573 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3574 if ( !so->_is_nil() )
3576 CORBA::String_var name = so->GetName();
3577 meshName = name.in();
3581 SMESH_MeshPartDS partDS( meshPart );
3582 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3584 SMESH_CATCH( SMESH::throwCorbaException );
3586 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3587 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3589 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3593 //================================================================================
3595 * \brief Export a part of mesh to a GMF file
3597 //================================================================================
3599 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3601 bool withRequiredGroups)
3602 throw (SALOME::SALOME_Exception)
3604 Unexpect aCatch(SALOME_SalomeException);
3606 _preMeshInfo->FullLoadFromFile();
3608 PrepareForWriting(file,/*overwrite=*/true);
3610 SMESH_MeshPartDS partDS( meshPart );
3611 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3613 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3614 << meshPart<< ", r'"
3616 << withRequiredGroups << ")";
3619 //=============================================================================
3621 * Return computation progress [0.,1]
3623 //=============================================================================
3625 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3629 return _impl->GetComputeProgress();
3631 SMESH_CATCH( SMESH::doNothing );
3635 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3637 Unexpect aCatch(SALOME_SalomeException);
3639 return _preMeshInfo->NbNodes();
3641 return _impl->NbNodes();
3644 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3646 Unexpect aCatch(SALOME_SalomeException);
3648 return _preMeshInfo->NbElements();
3650 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3653 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3655 Unexpect aCatch(SALOME_SalomeException);
3657 return _preMeshInfo->Nb0DElements();
3659 return _impl->Nb0DElements();
3662 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3664 Unexpect aCatch(SALOME_SalomeException);
3666 return _preMeshInfo->NbBalls();
3668 return _impl->NbBalls();
3671 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3673 Unexpect aCatch(SALOME_SalomeException);
3675 return _preMeshInfo->NbEdges();
3677 return _impl->NbEdges();
3680 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3681 throw(SALOME::SALOME_Exception)
3683 Unexpect aCatch(SALOME_SalomeException);
3685 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3687 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3690 //=============================================================================
3692 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3694 Unexpect aCatch(SALOME_SalomeException);
3696 return _preMeshInfo->NbFaces();
3698 return _impl->NbFaces();
3701 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3703 Unexpect aCatch(SALOME_SalomeException);
3705 return _preMeshInfo->NbTriangles();
3707 return _impl->NbTriangles();
3710 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3712 Unexpect aCatch(SALOME_SalomeException);
3714 return _preMeshInfo->NbBiQuadTriangles();
3716 return _impl->NbBiQuadTriangles();
3719 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3721 Unexpect aCatch(SALOME_SalomeException);
3723 return _preMeshInfo->NbQuadrangles();
3725 return _impl->NbQuadrangles();
3728 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3730 Unexpect aCatch(SALOME_SalomeException);
3732 return _preMeshInfo->NbBiQuadQuadrangles();
3734 return _impl->NbBiQuadQuadrangles();
3737 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3739 Unexpect aCatch(SALOME_SalomeException);
3741 return _preMeshInfo->NbPolygons();
3743 return _impl->NbPolygons();
3746 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3748 Unexpect aCatch(SALOME_SalomeException);
3750 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3752 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3755 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3756 throw(SALOME::SALOME_Exception)
3758 Unexpect aCatch(SALOME_SalomeException);
3760 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3762 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3765 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3766 throw(SALOME::SALOME_Exception)
3768 Unexpect aCatch(SALOME_SalomeException);
3770 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3772 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3775 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3776 throw(SALOME::SALOME_Exception)
3778 Unexpect aCatch(SALOME_SalomeException);
3780 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3782 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3785 //=============================================================================
3787 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3789 Unexpect aCatch(SALOME_SalomeException);
3791 return _preMeshInfo->NbVolumes();
3793 return _impl->NbVolumes();
3796 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3798 Unexpect aCatch(SALOME_SalomeException);
3800 return _preMeshInfo->NbTetras();
3802 return _impl->NbTetras();
3805 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3807 Unexpect aCatch(SALOME_SalomeException);
3809 return _preMeshInfo->NbHexas();
3811 return _impl->NbHexas();
3814 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3816 Unexpect aCatch(SALOME_SalomeException);
3818 return _preMeshInfo->NbTriQuadHexas();
3820 return _impl->NbTriQuadraticHexas();
3823 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3825 Unexpect aCatch(SALOME_SalomeException);
3827 return _preMeshInfo->NbPyramids();
3829 return _impl->NbPyramids();
3832 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3834 Unexpect aCatch(SALOME_SalomeException);
3836 return _preMeshInfo->NbPrisms();
3838 return _impl->NbPrisms();
3841 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3843 Unexpect aCatch(SALOME_SalomeException);
3845 return _preMeshInfo->NbHexPrisms();
3847 return _impl->NbHexagonalPrisms();
3850 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3852 Unexpect aCatch(SALOME_SalomeException);
3854 return _preMeshInfo->NbPolyhedrons();
3856 return _impl->NbPolyhedrons();
3859 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3860 throw(SALOME::SALOME_Exception)
3862 Unexpect aCatch(SALOME_SalomeException);
3864 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3866 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3869 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3870 throw(SALOME::SALOME_Exception)
3872 Unexpect aCatch(SALOME_SalomeException);
3874 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3876 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3879 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3880 throw(SALOME::SALOME_Exception)
3882 Unexpect aCatch(SALOME_SalomeException);
3884 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3886 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3889 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3890 throw(SALOME::SALOME_Exception)
3892 Unexpect aCatch(SALOME_SalomeException);
3894 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3896 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3899 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3900 throw(SALOME::SALOME_Exception)
3902 Unexpect aCatch(SALOME_SalomeException);
3904 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3906 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3909 //=============================================================================
3911 * Returns nb of published sub-meshes
3913 //=============================================================================
3915 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3917 Unexpect aCatch(SALOME_SalomeException);
3918 return _mapSubMesh_i.size();
3921 //=============================================================================
3923 * Dumps mesh into a string
3925 //=============================================================================
3927 char* SMESH_Mesh_i::Dump()
3931 return CORBA::string_dup( os.str().c_str() );
3934 //=============================================================================
3936 * Method of SMESH_IDSource interface
3938 //=============================================================================
3940 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3942 return GetElementsId();
3945 //=============================================================================
3947 * Returns ids of all elements
3949 //=============================================================================
3951 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3952 throw (SALOME::SALOME_Exception)
3954 Unexpect aCatch(SALOME_SalomeException);
3956 _preMeshInfo->FullLoadFromFile();
3958 SMESH::long_array_var aResult = new SMESH::long_array();
3959 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3961 if ( aSMESHDS_Mesh == NULL )
3962 return aResult._retn();
3964 long nbElements = NbElements();
3965 aResult->length( nbElements );
3966 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3967 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3968 aResult[i] = anIt->next()->GetID();
3970 return aResult._retn();
3974 //=============================================================================
3976 * Returns ids of all elements of given type
3978 //=============================================================================
3980 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3981 throw (SALOME::SALOME_Exception)
3983 Unexpect aCatch(SALOME_SalomeException);
3985 _preMeshInfo->FullLoadFromFile();
3987 SMESH::long_array_var aResult = new SMESH::long_array();
3988 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3990 if ( aSMESHDS_Mesh == NULL )
3991 return aResult._retn();
3993 long nbElements = NbElements();
3995 // No sense in returning ids of elements along with ids of nodes:
3996 // when theElemType == SMESH::ALL, return node ids only if
3997 // there are no elements
3998 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3999 return GetNodesId();
4001 aResult->length( nbElements );
4005 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4006 while ( i < nbElements && anIt->more() )
4007 aResult[i++] = anIt->next()->GetID();
4009 aResult->length( i );
4011 return aResult._retn();
4014 //=============================================================================
4016 * Returns ids of all nodes
4018 //=============================================================================
4020 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4021 throw (SALOME::SALOME_Exception)
4023 Unexpect aCatch(SALOME_SalomeException);
4025 _preMeshInfo->FullLoadFromFile();
4027 SMESH::long_array_var aResult = new SMESH::long_array();
4028 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4030 if ( aMeshDS == NULL )
4031 return aResult._retn();
4033 long nbNodes = NbNodes();
4034 aResult->length( nbNodes );
4035 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4036 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4037 aResult[i] = anIt->next()->GetID();
4039 return aResult._retn();
4042 //=============================================================================
4046 //=============================================================================
4048 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4049 throw (SALOME::SALOME_Exception)
4051 SMESH::ElementType type = SMESH::ALL;
4055 _preMeshInfo->FullLoadFromFile();
4057 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4059 SMESH_CATCH( SMESH::throwCorbaException );
4064 //=============================================================================
4068 //=============================================================================
4070 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4071 throw (SALOME::SALOME_Exception)
4074 _preMeshInfo->FullLoadFromFile();
4076 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4078 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4080 return ( SMESH::EntityType ) e->GetEntityType();
4083 //=============================================================================
4087 //=============================================================================
4089 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4090 throw (SALOME::SALOME_Exception)
4093 _preMeshInfo->FullLoadFromFile();
4095 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4097 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4099 return ( SMESH::GeometryType ) e->GetGeomType();
4102 //=============================================================================
4104 * Returns ID of elements for given submesh
4106 //=============================================================================
4107 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4108 throw (SALOME::SALOME_Exception)
4110 SMESH::long_array_var aResult = new SMESH::long_array();
4114 _preMeshInfo->FullLoadFromFile();
4116 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4117 if(!SM) return aResult._retn();
4119 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4120 if(!SDSM) return aResult._retn();
4122 aResult->length(SDSM->NbElements());
4124 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4126 while ( eIt->more() ) {
4127 aResult[i++] = eIt->next()->GetID();
4130 SMESH_CATCH( SMESH::throwCorbaException );
4132 return aResult._retn();
4135 //=============================================================================
4137 * Returns ID of nodes for given submesh
4138 * If param all==true - returns all nodes, else -
4139 * returns only nodes on shapes.
4141 //=============================================================================
4143 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4145 throw (SALOME::SALOME_Exception)
4147 SMESH::long_array_var aResult = new SMESH::long_array();
4151 _preMeshInfo->FullLoadFromFile();
4153 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4154 if(!SM) return aResult._retn();
4156 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4157 if(!SDSM) return aResult._retn();
4160 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4161 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4162 while ( nIt->more() ) {
4163 const SMDS_MeshNode* elem = nIt->next();
4164 theElems.insert( elem->GetID() );
4167 else { // all nodes of submesh elements
4168 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4169 while ( eIt->more() ) {
4170 const SMDS_MeshElement* anElem = eIt->next();
4171 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4172 while ( nIt->more() ) {
4173 const SMDS_MeshElement* elem = nIt->next();
4174 theElems.insert( elem->GetID() );
4179 aResult->length(theElems.size());
4180 set<int>::iterator itElem;
4182 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4183 aResult[i++] = *itElem;
4185 SMESH_CATCH( SMESH::throwCorbaException );
4187 return aResult._retn();
4190 //=============================================================================
4192 * Returns type of elements for given submesh
4194 //=============================================================================
4196 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4197 throw (SALOME::SALOME_Exception)
4199 SMESH::ElementType type = SMESH::ALL;
4203 _preMeshInfo->FullLoadFromFile();
4205 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4206 if(!SM) return SMESH::ALL;
4208 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4209 if(!SDSM) return SMESH::ALL;
4211 if(SDSM->NbElements()==0)
4212 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4214 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4215 const SMDS_MeshElement* anElem = eIt->next();
4217 type = ( SMESH::ElementType ) anElem->GetType();
4219 SMESH_CATCH( SMESH::throwCorbaException );
4225 //=============================================================================
4227 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4229 //=============================================================================
4231 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4234 _preMeshInfo->FullLoadFromFile();
4236 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4237 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4242 //=============================================================================
4244 * Get XYZ coordinates of node as list of double
4245 * If there is not node for given ID - returns empty list
4247 //=============================================================================
4249 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4252 _preMeshInfo->FullLoadFromFile();
4254 SMESH::double_array_var aResult = new SMESH::double_array();
4255 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4256 if ( aMeshDS == NULL )
4257 return aResult._retn();
4260 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4262 return aResult._retn();
4266 aResult[0] = aNode->X();
4267 aResult[1] = aNode->Y();
4268 aResult[2] = aNode->Z();
4269 return aResult._retn();
4273 //=============================================================================
4275 * For given node returns list of IDs of inverse elements
4276 * If there is not node for given ID - returns empty list
4278 //=============================================================================
4280 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4283 _preMeshInfo->FullLoadFromFile();
4285 SMESH::long_array_var aResult = new SMESH::long_array();
4286 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4287 if ( aMeshDS == NULL )
4288 return aResult._retn();
4291 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4293 return aResult._retn();
4295 // find inverse elements
4296 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4297 aResult->length( aNode->NbInverseElements() );
4298 for( int i = 0; eIt->more(); ++i )
4300 const SMDS_MeshElement* elem = eIt->next();
4301 aResult[ i ] = elem->GetID();
4303 return aResult._retn();
4306 //=============================================================================
4308 * \brief Return position of a node on shape
4310 //=============================================================================
4312 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4315 _preMeshInfo->FullLoadFromFile();
4317 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4318 aNodePosition->shapeID = 0;
4319 aNodePosition->shapeType = GEOM::SHAPE;
4321 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4322 if ( !mesh ) return aNodePosition;
4324 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4326 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4328 aNodePosition->shapeID = aNode->getshapeId();
4329 switch ( pos->GetTypeOfPosition() ) {
4331 aNodePosition->shapeType = GEOM::EDGE;
4332 aNodePosition->params.length(1);
4333 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4335 case SMDS_TOP_FACE: {
4336 SMDS_FacePositionPtr fPos = pos;
4337 aNodePosition->shapeType = GEOM::FACE;
4338 aNodePosition->params.length(2);
4339 aNodePosition->params[0] = fPos->GetUParameter();
4340 aNodePosition->params[1] = fPos->GetVParameter();
4343 case SMDS_TOP_VERTEX:
4344 aNodePosition->shapeType = GEOM::VERTEX;
4346 case SMDS_TOP_3DSPACE:
4347 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4348 aNodePosition->shapeType = GEOM::SOLID;
4349 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4350 aNodePosition->shapeType = GEOM::SHELL;
4356 return aNodePosition;
4359 //=============================================================================
4361 * \brief Return position of an element on shape
4363 //=============================================================================
4365 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4368 _preMeshInfo->FullLoadFromFile();
4370 SMESH::ElementPosition anElementPosition;
4371 anElementPosition.shapeID = 0;
4372 anElementPosition.shapeType = GEOM::SHAPE;
4374 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4375 if ( !mesh ) return anElementPosition;
4377 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4379 anElementPosition.shapeID = anElem->getshapeId();
4380 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4381 if ( !aSp.IsNull() ) {
4382 switch ( aSp.ShapeType() ) {
4384 anElementPosition.shapeType = GEOM::EDGE;
4387 anElementPosition.shapeType = GEOM::FACE;
4390 anElementPosition.shapeType = GEOM::VERTEX;
4393 anElementPosition.shapeType = GEOM::SOLID;
4396 anElementPosition.shapeType = GEOM::SHELL;
4402 return anElementPosition;
4405 //=============================================================================
4407 * If given element is node returns IDs of shape from position
4408 * If there is not node for given ID - returns -1
4410 //=============================================================================
4412 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4415 _preMeshInfo->FullLoadFromFile();
4417 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4418 if ( aMeshDS == NULL )
4422 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4424 return aNode->getshapeId();
4431 //=============================================================================
4433 * For given element returns ID of result shape after
4434 * ::FindShape() from SMESH_MeshEditor
4435 * If there is not element for given ID - returns -1
4437 //=============================================================================
4439 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4442 _preMeshInfo->FullLoadFromFile();
4444 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4445 if ( aMeshDS == NULL )
4448 // try to find element
4449 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4453 ::SMESH_MeshEditor aMeshEditor(_impl);
4454 int index = aMeshEditor.FindShape( elem );
4462 //=============================================================================
4464 * Returns number of nodes for given element
4465 * If there is not element for given ID - returns -1
4467 //=============================================================================
4469 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4472 _preMeshInfo->FullLoadFromFile();
4474 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4475 if ( aMeshDS == NULL ) return -1;
4476 // try to find element
4477 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4478 if(!elem) return -1;
4479 return elem->NbNodes();
4483 //=============================================================================
4485 * Returns ID of node by given index for given element
4486 * If there is not element for given ID - returns -1
4487 * If there is not node for given index - returns -2
4489 //=============================================================================
4491 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4494 _preMeshInfo->FullLoadFromFile();
4496 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4497 if ( aMeshDS == NULL ) return -1;
4498 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4499 if(!elem) return -1;
4500 if( index>=elem->NbNodes() || index<0 ) return -1;
4501 return elem->GetNode(index)->GetID();
4504 //=============================================================================
4506 * Returns IDs of nodes of given element
4508 //=============================================================================
4510 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4513 _preMeshInfo->FullLoadFromFile();
4515 SMESH::long_array_var aResult = new SMESH::long_array();
4516 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4518 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4520 aResult->length( elem->NbNodes() );
4521 for ( int i = 0; i < elem->NbNodes(); ++i )
4522 aResult[ i ] = elem->GetNode( i )->GetID();
4525 return aResult._retn();
4528 //=============================================================================
4530 * Returns true if given node is medium node
4531 * in given quadratic element
4533 //=============================================================================
4535 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4538 _preMeshInfo->FullLoadFromFile();
4540 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4541 if ( aMeshDS == NULL ) return false;
4543 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4544 if(!aNode) return false;
4545 // try to find element
4546 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4547 if(!elem) return false;
4549 return elem->IsMediumNode(aNode);
4553 //=============================================================================
4555 * Returns true if given node is medium node
4556 * in one of quadratic elements
4558 //=============================================================================
4560 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4561 SMESH::ElementType theElemType)
4564 _preMeshInfo->FullLoadFromFile();
4566 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4567 if ( aMeshDS == NULL ) return false;
4570 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4571 if(!aNode) return false;
4573 SMESH_MesherHelper aHelper( *(_impl) );
4575 SMDSAbs_ElementType aType;
4576 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4577 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4578 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4579 else aType = SMDSAbs_All;
4581 return aHelper.IsMedium(aNode,aType);
4585 //=============================================================================
4587 * Returns number of edges for given element
4589 //=============================================================================
4591 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4594 _preMeshInfo->FullLoadFromFile();
4596 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4597 if ( aMeshDS == NULL ) return -1;
4598 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4599 if(!elem) return -1;
4600 return elem->NbEdges();
4604 //=============================================================================
4606 * Returns number of faces for given element
4608 //=============================================================================
4610 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4613 _preMeshInfo->FullLoadFromFile();
4615 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4616 if ( aMeshDS == NULL ) return -1;
4617 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4618 if(!elem) return -1;
4619 return elem->NbFaces();
4622 //=======================================================================
4623 //function : GetElemFaceNodes
4624 //purpose : Returns nodes of given face (counted from zero) for given element.
4625 //=======================================================================
4627 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4628 CORBA::Short faceIndex)
4631 _preMeshInfo->FullLoadFromFile();
4633 SMESH::long_array_var aResult = new SMESH::long_array();
4634 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4636 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4638 SMDS_VolumeTool vtool( elem );
4639 if ( faceIndex < vtool.NbFaces() )
4641 aResult->length( vtool.NbFaceNodes( faceIndex ));
4642 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4643 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4644 aResult[ i ] = nn[ i ]->GetID();
4648 return aResult._retn();
4651 //=======================================================================
4652 //function : GetElemFaceNodes
4653 //purpose : Returns three components of normal of given mesh face.
4654 //=======================================================================
4656 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4657 CORBA::Boolean normalized)
4660 _preMeshInfo->FullLoadFromFile();
4662 SMESH::double_array_var aResult = new SMESH::double_array();
4664 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4667 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4669 aResult->length( 3 );
4670 aResult[ 0 ] = normal.X();
4671 aResult[ 1 ] = normal.Y();
4672 aResult[ 2 ] = normal.Z();
4675 return aResult._retn();
4678 //=======================================================================
4679 //function : FindElementByNodes
4680 //purpose : Returns an element based on all given nodes.
4681 //=======================================================================
4683 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4686 _preMeshInfo->FullLoadFromFile();
4688 CORBA::Long elemID(0);
4689 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4691 vector< const SMDS_MeshNode * > nn( nodes.length() );
4692 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4693 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4696 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4697 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4698 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4699 _impl->NbVolumes( ORDER_QUADRATIC )))
4700 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4702 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4707 //================================================================================
4709 * \brief Return elements including all given nodes.
4711 //================================================================================
4713 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4714 SMESH::ElementType elemType)
4717 _preMeshInfo->FullLoadFromFile();
4719 SMESH::long_array_var result = new SMESH::long_array();
4721 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4723 vector< const SMDS_MeshNode * > nn( nodes.length() );
4724 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4725 nn[i] = mesh->FindNode( nodes[i] );
4727 std::vector<const SMDS_MeshElement *> elems;
4728 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4729 result->length( elems.size() );
4730 for ( size_t i = 0; i < elems.size(); ++i )
4731 result[i] = elems[i]->GetID();
4733 return result._retn();
4736 //=============================================================================
4738 * Returns true if given element is polygon
4740 //=============================================================================
4742 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4745 _preMeshInfo->FullLoadFromFile();
4747 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4748 if ( aMeshDS == NULL ) return false;
4749 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4750 if(!elem) return false;
4751 return elem->IsPoly();
4755 //=============================================================================
4757 * Returns true if given element is quadratic
4759 //=============================================================================
4761 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4764 _preMeshInfo->FullLoadFromFile();
4766 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4767 if ( aMeshDS == NULL ) return false;
4768 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4769 if(!elem) return false;
4770 return elem->IsQuadratic();
4773 //=============================================================================
4775 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4777 //=============================================================================
4779 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4782 _preMeshInfo->FullLoadFromFile();
4784 if ( const SMDS_BallElement* ball =
4785 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4786 return ball->GetDiameter();
4791 //=============================================================================
4793 * Returns bary center for given element
4795 //=============================================================================
4797 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4800 _preMeshInfo->FullLoadFromFile();
4802 SMESH::double_array_var aResult = new SMESH::double_array();
4803 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4804 if ( aMeshDS == NULL )
4805 return aResult._retn();
4807 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4809 return aResult._retn();
4811 if(elem->GetType()==SMDSAbs_Volume) {
4812 SMDS_VolumeTool aTool;
4813 if(aTool.Set(elem)) {
4815 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4820 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4822 double x=0., y=0., z=0.;
4823 for(; anIt->more(); ) {
4825 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4839 return aResult._retn();
4842 //================================================================================
4844 * \brief Create a group of elements preventing computation of a sub-shape
4846 //================================================================================
4848 SMESH::ListOfGroups*
4849 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4850 const char* theGroupName )
4851 throw ( SALOME::SALOME_Exception )
4853 Unexpect aCatch(SALOME_SalomeException);
4855 if ( !theGroupName || strlen( theGroupName) == 0 )
4856 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4858 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4859 ::SMESH_MeshEditor::ElemFeatures elemType;
4861 // submesh by subshape id
4862 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4863 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4866 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4867 if ( error && error->HasBadElems() )
4869 // sort bad elements by type
4870 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4871 const list<const SMDS_MeshElement*>& badElems =
4872 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
4873 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
4874 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
4875 for ( ; elemIt != elemEnd; ++elemIt )
4877 const SMDS_MeshElement* elem = *elemIt;
4878 if ( !elem ) continue;
4880 if ( elem->GetID() < 1 )
4882 // elem is a temporary element, make a real element
4883 vector< const SMDS_MeshNode* > nodes;
4884 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4885 while ( nIt->more() && elem )
4887 nodes.push_back( nIt->next() );
4888 if ( nodes.back()->GetID() < 1 )
4889 elem = 0; // a temporary element on temporary nodes
4893 ::SMESH_MeshEditor editor( _impl );
4894 elem = editor.AddElement( nodes, elemType.Init( elem ));
4898 elemsByType[ elem->GetType() ].push_back( elem );
4901 // how many groups to create?
4903 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4904 nbTypes += int( !elemsByType[ i ].empty() );
4905 groups->length( nbTypes );
4908 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4910 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4911 if ( elems.empty() ) continue;
4913 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4914 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4916 SMESH::SMESH_Mesh_var mesh = _this();
4917 SALOMEDS::SObject_wrap aSO =
4918 _gen_i->PublishGroup( mesh, groups[ iG ],
4919 GEOM::GEOM_Object::_nil(), theGroupName);
4921 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4922 if ( !grp_i ) continue;
4924 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4925 for ( size_t iE = 0; iE < elems.size(); ++iE )
4926 grpDS->SMDSGroup().Add( elems[ iE ]);
4931 return groups._retn();
4934 //=============================================================================
4936 * Create and publish group servants if any groups were imported or created anyhow
4938 //=============================================================================
4940 void SMESH_Mesh_i::CreateGroupServants()
4942 SMESH::SMESH_Mesh_var aMesh = _this();
4945 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4946 while ( groupIt->more() )
4948 ::SMESH_Group* group = groupIt->next();
4949 int anId = group->GetGroupDS()->GetID();
4951 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4952 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4954 addedIDs.insert( anId );
4956 SMESH_GroupBase_i* aGroupImpl;
4958 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4959 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4961 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4962 shape = groupOnGeom->GetShape();
4965 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4968 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4969 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4970 aGroupImpl->Register();
4972 // register CORBA object for persistence
4973 int nextId = _gen_i->RegisterObject( groupVar );
4974 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4975 else { nextId = 0; } // avoid "unused variable" warning in release mode
4977 // publishing the groups in the study
4978 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4979 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
4981 if ( !addedIDs.empty() )
4984 set<int>::iterator id = addedIDs.begin();
4985 for ( ; id != addedIDs.end(); ++id )
4987 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4988 int i = std::distance( _mapGroups.begin(), it );
4989 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4994 //=============================================================================
4996 * \brief Return groups cantained in _mapGroups by their IDs
4998 //=============================================================================
5000 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5002 int nbGroups = groupIDs.size();
5003 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5004 aList->length( nbGroups );
5006 list<int>::const_iterator ids = groupIDs.begin();
5007 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5009 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5010 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5011 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5013 aList->length( nbGroups );
5014 return aList._retn();
5017 //=============================================================================
5019 * \brief Return information about imported file
5021 //=============================================================================
5023 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5025 SMESH::MedFileInfo_var res( _medFileInfo );
5026 if ( !res.operator->() ) {
5027 res = new SMESH::MedFileInfo;
5029 res->fileSize = res->major = res->minor = res->release = -1;
5034 //=============================================================================
5036 * \brief Pass names of mesh groups from study to mesh DS
5038 //=============================================================================
5040 void SMESH_Mesh_i::checkGroupNames()
5042 int nbGrp = NbGroups();
5046 SMESH::ListOfGroups* grpList = 0;
5047 // avoid dump of "GetGroups"
5049 // store python dump into a local variable inside local scope
5050 SMESH::TPythonDump pDump; // do not delete this line of code
5051 grpList = GetGroups();
5054 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5055 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5058 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5059 if ( aGrpSO->_is_nil() )
5061 // correct name of the mesh group if necessary
5062 const char* guiName = aGrpSO->GetName();
5063 if ( strcmp(guiName, aGrp->GetName()) )
5064 aGrp->SetName( guiName );
5068 //=============================================================================
5070 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5072 //=============================================================================
5073 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5075 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5079 //=============================================================================
5081 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5083 //=============================================================================
5085 char* SMESH_Mesh_i::GetParameters()
5087 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5090 //=============================================================================
5092 * \brief Returns list of notebook variables used for last Mesh operation
5094 //=============================================================================
5095 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5097 SMESH::string_array_var aResult = new SMESH::string_array();
5098 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5100 CORBA::String_var aParameters = GetParameters();
5101 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5102 if ( aSections->length() > 0 ) {
5103 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5104 aResult->length( aVars.length() );
5105 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5106 aResult[i] = CORBA::string_dup( aVars[i] );
5109 return aResult._retn();
5112 //=======================================================================
5113 //function : GetTypes
5114 //purpose : Returns types of elements it contains
5115 //=======================================================================
5117 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5120 return _preMeshInfo->GetTypes();
5122 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5126 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5127 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5128 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5129 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5130 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5131 if (_impl->NbNodes() &&
5132 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5133 types->length( nbTypes );
5135 return types._retn();
5138 //=======================================================================
5139 //function : GetMesh
5140 //purpose : Returns self
5141 //=======================================================================
5143 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5145 return SMESH::SMESH_Mesh::_duplicate( _this() );
5148 //=======================================================================
5149 //function : IsMeshInfoCorrect
5150 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5151 // * happen if mesh data is not yet fully loaded from the file of study.
5152 //=======================================================================
5154 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5156 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5159 //=============================================================================
5161 * \brief Returns number of mesh elements per each \a EntityType
5163 //=============================================================================
5165 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5168 return _preMeshInfo->GetMeshInfo();
5170 SMESH::long_array_var aRes = new SMESH::long_array();
5171 aRes->length(SMESH::Entity_Last);
5172 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5174 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5176 return aRes._retn();
5177 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5178 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5179 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5180 return aRes._retn();
5183 //=============================================================================
5185 * \brief Returns number of mesh elements per each \a ElementType
5187 //=============================================================================
5189 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5191 SMESH::long_array_var aRes = new SMESH::long_array();
5192 aRes->length(SMESH::NB_ELEMENT_TYPES);
5193 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5196 const SMDS_MeshInfo* meshInfo = 0;
5198 meshInfo = _preMeshInfo;
5199 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5200 meshInfo = & meshDS->GetMeshInfo();
5203 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5204 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5206 return aRes._retn();
5209 //=============================================================================
5211 * Collect statistic of mesh elements given by iterator
5213 //=============================================================================
5215 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5216 SMESH::long_array& theInfo)
5218 if (!theItr) return;
5219 while (theItr->more())
5220 theInfo[ theItr->next()->GetEntityType() ]++;
5222 //=============================================================================
5224 * Returns mesh unstructed grid information.
5226 //=============================================================================
5228 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5230 SALOMEDS::TMPFile_var SeqFile;
5231 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5232 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5234 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5235 aWriter->WriteToOutputStringOn();
5236 aWriter->SetInputData(aGrid);
5237 aWriter->SetFileTypeToBinary();
5239 char* str = aWriter->GetOutputString();
5240 int size = aWriter->GetOutputStringLength();
5242 //Allocate octect buffer of required size
5243 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5244 //Copy ostrstream content to the octect buffer
5245 memcpy(OctetBuf, str, size);
5246 //Create and return TMPFile
5247 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5251 return SeqFile._retn();
5254 //=============================================================================
5255 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5256 * SMESH::ElementType type) */
5258 using namespace SMESH::Controls;
5259 //-----------------------------------------------------------------------------
5260 struct PredicateIterator : public SMDS_ElemIterator
5262 SMDS_ElemIteratorPtr _elemIter;
5263 PredicatePtr _predicate;
5264 const SMDS_MeshElement* _elem;
5266 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5267 PredicatePtr predicate):
5268 _elemIter(iterator), _predicate(predicate)
5276 virtual const SMDS_MeshElement* next()
5278 const SMDS_MeshElement* res = _elem;
5280 while ( _elemIter->more() && !_elem )
5282 _elem = _elemIter->next();
5283 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5290 //-----------------------------------------------------------------------------
5291 struct IDSourceIterator : public SMDS_ElemIterator
5293 const CORBA::Long* _idPtr;
5294 const CORBA::Long* _idEndPtr;
5295 SMESH::long_array_var _idArray;
5296 const SMDS_Mesh* _mesh;
5297 const SMDSAbs_ElementType _type;
5298 const SMDS_MeshElement* _elem;
5300 IDSourceIterator( const SMDS_Mesh* mesh,
5301 const CORBA::Long* ids,
5303 SMDSAbs_ElementType type):
5304 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5306 if ( _idPtr && nbIds && _mesh )
5309 IDSourceIterator( const SMDS_Mesh* mesh,
5310 SMESH::long_array* idArray,
5311 SMDSAbs_ElementType type):
5312 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5314 if ( idArray && _mesh )
5316 _idPtr = &_idArray[0];
5317 _idEndPtr = _idPtr + _idArray->length();
5325 virtual const SMDS_MeshElement* next()
5327 const SMDS_MeshElement* res = _elem;
5329 while ( _idPtr < _idEndPtr && !_elem )
5331 if ( _type == SMDSAbs_Node )
5333 _elem = _mesh->FindNode( *_idPtr++ );
5335 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5336 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5344 //-----------------------------------------------------------------------------
5346 struct NodeOfElemIterator : public SMDS_ElemIterator
5348 TColStd_MapOfInteger _checkedNodeIDs;
5349 SMDS_ElemIteratorPtr _elemIter;
5350 SMDS_ElemIteratorPtr _nodeIter;
5351 const SMDS_MeshElement* _node;
5353 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5355 if ( _elemIter && _elemIter->more() )
5357 _nodeIter = _elemIter->next()->nodesIterator();
5365 virtual const SMDS_MeshElement* next()
5367 const SMDS_MeshElement* res = _node;
5369 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5371 if ( _nodeIter->more() )
5373 _node = _nodeIter->next();
5374 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5379 _nodeIter = _elemIter->next()->nodesIterator();
5387 //=============================================================================
5389 * Return iterator on elements of given type in given object
5391 //=============================================================================
5393 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5394 SMESH::ElementType theType)
5396 SMDS_ElemIteratorPtr elemIt;
5397 bool typeOK = ( theType == SMESH::ALL );
5398 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5400 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5401 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5402 if ( !mesh_i ) return elemIt;
5403 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5405 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5407 elemIt = meshDS->elementsIterator( elemType );
5410 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5412 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5415 elemIt = sm->GetElements();
5416 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5418 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5419 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5423 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5425 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5426 if ( groupDS && ( elemType == groupDS->GetType() ||
5427 elemType == SMDSAbs_Node ||
5428 elemType == SMDSAbs_All ))
5430 elemIt = groupDS->GetElements();
5431 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5434 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5436 if ( filter_i->GetElementType() == theType ||
5437 elemType == SMDSAbs_Node ||
5438 elemType == SMDSAbs_All)
5440 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5441 if ( pred_i && pred_i->GetPredicate() )
5443 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5444 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5445 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5446 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5452 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5453 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5454 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5456 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5459 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5460 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5464 SMESH::long_array_var ids = theObject->GetIDs();
5465 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5467 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5470 if ( elemIt && elemIt->more() && !typeOK )
5472 if ( elemType == SMDSAbs_Node )
5474 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5478 elemIt = SMDS_ElemIteratorPtr();
5484 //=============================================================================
5485 namespace // Finding concurrent hypotheses
5486 //=============================================================================
5490 * \brief mapping of mesh dimension into shape type
5492 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5494 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5496 case 0: aType = TopAbs_VERTEX; break;
5497 case 1: aType = TopAbs_EDGE; break;
5498 case 2: aType = TopAbs_FACE; break;
5500 default:aType = TopAbs_SOLID; break;
5505 //-----------------------------------------------------------------------------
5507 * \brief Internal structure used to find concurrent submeshes
5509 * It represents a pair < submesh, concurrent dimension >, where
5510 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5511 * with another submesh. In other words, it is dimension of a hypothesis assigned
5518 int _dim; //!< a dimension the algo can build (concurrent dimension)
5519 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5520 TopTools_MapOfShape _shapeMap;
5521 SMESH_subMesh* _subMesh;
5522 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5524 //-----------------------------------------------------------------------------
5525 // Return the algorithm
5526 const SMESH_Algo* GetAlgo() const
5527 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5529 //-----------------------------------------------------------------------------
5531 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5533 const TopoDS_Shape& theShape)
5535 _subMesh = (SMESH_subMesh*)theSubMesh;
5536 SetShape( theDim, theShape );
5539 //-----------------------------------------------------------------------------
5541 void SetShape(const int theDim,
5542 const TopoDS_Shape& theShape)
5545 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5546 if (_dim >= _ownDim)
5547 _shapeMap.Add( theShape );
5549 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5550 for( ; anExp.More(); anExp.Next() )
5551 _shapeMap.Add( anExp.Current() );
5555 //-----------------------------------------------------------------------------
5556 //! Check sharing of sub-shapes
5557 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5558 const TopTools_MapOfShape& theToFind,
5559 const TopAbs_ShapeEnum theType)
5561 bool isShared = false;
5562 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5563 for (; !isShared && anItr.More(); anItr.Next() )
5565 const TopoDS_Shape aSubSh = anItr.Key();
5566 // check for case when concurrent dimensions are same
5567 isShared = theToFind.Contains( aSubSh );
5568 // check for sub-shape with concurrent dimension
5569 TopExp_Explorer anExp( aSubSh, theType );
5570 for ( ; !isShared && anExp.More(); anExp.Next() )
5571 isShared = theToFind.Contains( anExp.Current() );
5576 //-----------------------------------------------------------------------------
5577 //! check algorithms
5578 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5579 const SMESHDS_Hypothesis* theA2)
5581 if ( !theA1 || !theA2 ||
5582 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5583 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5584 return false; // one of the hypothesis is not algorithm
5585 // check algorithm names (should be equal)
5586 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5590 //-----------------------------------------------------------------------------
5591 //! Check if sub-shape hypotheses are concurrent
5592 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5594 if ( _subMesh == theOther->_subMesh )
5595 return false; // same sub-shape - should not be
5597 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5598 // any of the two submeshes is not on COMPOUND shape )
5599 // -> no concurrency
5600 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5601 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5602 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5603 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5604 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5607 // bool checkSubShape = ( _dim >= theOther->_dim )
5608 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5609 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5610 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5611 if ( !checkSubShape )
5614 // check algorithms to be same
5615 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5616 return true; // different algorithms -> concurrency !
5618 // check hypothesises for concurrence (skip first as algorithm)
5620 // pointers should be same, because it is referened from mesh hypothesis partition
5621 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5622 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5623 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5624 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5626 // the submeshes are concurrent if their algorithms has different parameters
5627 return nbSame != (int)theOther->_hypotheses.size() - 1;
5630 // Return true if algorithm of this SMESH_DimHyp is used if no
5631 // sub-mesh order is imposed by the user
5632 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5634 // NeedDiscreteBoundary() algo has a higher priority
5635 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5636 theOther->GetAlgo()->NeedDiscreteBoundary() )
5637 return !this->GetAlgo()->NeedDiscreteBoundary();
5639 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5642 }; // end of SMESH_DimHyp
5643 //-----------------------------------------------------------------------------
5645 typedef list<const SMESH_DimHyp*> TDimHypList;
5647 //-----------------------------------------------------------------------------
5649 void addDimHypInstance(const int theDim,
5650 const TopoDS_Shape& theShape,
5651 const SMESH_Algo* theAlgo,
5652 const SMESH_subMesh* theSubMesh,
5653 const list <const SMESHDS_Hypothesis*>& theHypList,
5654 TDimHypList* theDimHypListArr )
5656 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5657 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5658 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5659 dimHyp->_hypotheses.push_front(theAlgo);
5660 listOfdimHyp.push_back( dimHyp );
5663 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5664 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5665 theHypList.begin(), theHypList.end() );
5668 //-----------------------------------------------------------------------------
5669 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5670 TDimHypList& theListOfConcurr)
5672 if ( theListOfConcurr.empty() )
5674 theListOfConcurr.push_back( theDimHyp );
5678 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5679 while ( hypIt != theListOfConcurr.end() &&
5680 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5682 theListOfConcurr.insert( hypIt, theDimHyp );
5686 //-----------------------------------------------------------------------------
5687 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5688 const TDimHypList& theListOfDimHyp,
5689 TDimHypList& theListOfConcurrHyp,
5690 set<int>& theSetOfConcurrId )
5692 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5693 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5695 const SMESH_DimHyp* curDimHyp = *rIt;
5696 if ( curDimHyp == theDimHyp )
5697 break; // meet own dimHyp pointer in same dimension
5699 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5700 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5702 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5707 //-----------------------------------------------------------------------------
5708 void unionLists(TListOfInt& theListOfId,
5709 TListOfListOfInt& theListOfListOfId,
5712 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5713 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5715 continue; //skip already treated lists
5716 // check if other list has any same submesh object
5717 TListOfInt& otherListOfId = *it;
5718 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5719 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5722 // union two lists (from source into target)
5723 TListOfInt::iterator it2 = otherListOfId.begin();
5724 for ( ; it2 != otherListOfId.end(); it2++ ) {
5725 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5726 theListOfId.push_back(*it2);
5728 // clear source list
5729 otherListOfId.clear();
5732 //-----------------------------------------------------------------------------
5734 //! free memory allocated for dimension-hypothesis objects
5735 void removeDimHyps( TDimHypList* theArrOfList )
5737 for (int i = 0; i < 4; i++ ) {
5738 TDimHypList& listOfdimHyp = theArrOfList[i];
5739 TDimHypList::const_iterator it = listOfdimHyp.begin();
5740 for ( ; it != listOfdimHyp.end(); it++ )
5745 //-----------------------------------------------------------------------------
5747 * \brief find common submeshes with given submesh
5748 * \param theSubMeshList list of already collected submesh to check
5749 * \param theSubMesh given submesh to intersect with other
5750 * \param theCommonSubMeshes collected common submeshes
5752 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5753 const SMESH_subMesh* theSubMesh,
5754 set<const SMESH_subMesh*>& theCommon )
5758 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5759 for ( ; it != theSubMeshList.end(); it++ )
5760 theSubMesh->FindIntersection( *it, theCommon );
5761 theSubMeshList.push_back( theSubMesh );
5762 //theCommon.insert( theSubMesh );
5765 //-----------------------------------------------------------------------------
5766 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5768 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5769 for ( ; listsIt != smLists.end(); ++listsIt )
5771 const TListOfInt& smIDs = *listsIt;
5772 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5780 //=============================================================================
5782 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5784 //=============================================================================
5786 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5788 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5789 if ( isSubMeshInList( submeshID, anOrder ))
5792 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5793 return isSubMeshInList( submeshID, allConurrent );
5796 //=============================================================================
5798 * \brief Return submesh objects list in meshing order
5800 //=============================================================================
5802 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5804 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5806 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5808 return aResult._retn();
5810 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5811 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5812 anOrder.splice( anOrder.end(), allConurrent );
5815 TListOfListOfInt::iterator listIt = anOrder.begin();
5816 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5817 unionLists( *listIt, anOrder, listIndx + 1 );
5819 // convert submesh ids into interface instances
5820 // and dump command into python
5821 convertMeshOrder( anOrder, aResult, false );
5823 return aResult._retn();
5826 //=============================================================================
5828 * \brief Finds concurrent sub-meshes
5830 //=============================================================================
5832 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5834 TListOfListOfInt anOrder;
5835 ::SMESH_Mesh& mesh = GetImpl();
5837 // collect submeshes and detect concurrent algorithms and hypothesises
5838 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5840 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5841 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5842 ::SMESH_subMesh* sm = (*i_sm).second;
5844 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5846 // list of assigned hypothesises
5847 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5848 // Find out dimensions where the submesh can be concurrent.
5849 // We define the dimensions by algo of each of hypotheses in hypList
5850 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5851 for( ; hypIt != hypList.end(); hypIt++ ) {
5852 SMESH_Algo* anAlgo = 0;
5853 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5854 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5855 // hyp it-self is algo
5856 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5858 // try to find algorithm with help of sub-shapes
5859 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5860 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5861 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5864 continue; // no algorithm assigned to a current submesh
5866 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5867 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5869 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5870 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5871 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5873 } // end iterations on submesh
5875 // iterate on created dimension-hypotheses and check for concurrents
5876 for ( int i = 0; i < 4; i++ ) {
5877 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5878 // check for concurrents in own and other dimensions (step-by-step)
5879 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5880 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5881 const SMESH_DimHyp* dimHyp = *dhIt;
5882 TDimHypList listOfConcurr;
5883 set<int> setOfConcurrIds;
5884 // looking for concurrents and collect into own list
5885 for ( int j = i; j < 4; j++ )
5886 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5887 // check if any concurrents found
5888 if ( listOfConcurr.size() > 0 ) {
5889 // add own submesh to list of concurrent
5890 addInOrderOfPriority( dimHyp, listOfConcurr );
5891 list<int> listOfConcurrIds;
5892 TDimHypList::iterator hypIt = listOfConcurr.begin();
5893 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5894 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5895 anOrder.push_back( listOfConcurrIds );
5900 removeDimHyps(dimHypListArr);
5902 // now, minimize the number of concurrent groups
5903 // Here we assume that lists of submeshes can have same submesh
5904 // in case of multi-dimension algorithms, as result
5905 // list with common submesh has to be united into one list
5907 TListOfListOfInt::iterator listIt = anOrder.begin();
5908 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5909 unionLists( *listIt, anOrder, listIndx + 1 );
5915 //=============================================================================
5917 * \brief Set submesh object order
5918 * \param theSubMeshArray submesh array order
5920 //=============================================================================
5922 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5925 _preMeshInfo->ForgetOrLoad();
5928 ::SMESH_Mesh& mesh = GetImpl();
5930 TPythonDump aPythonDump; // prevent dump of called methods
5931 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5933 TListOfListOfInt subMeshOrder;
5934 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5936 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5937 TListOfInt subMeshIds;
5939 aPythonDump << ", ";
5940 aPythonDump << "[ ";
5941 // Collect subMeshes which should be clear
5942 // do it list-by-list, because modification of submesh order
5943 // take effect between concurrent submeshes only
5944 set<const SMESH_subMesh*> subMeshToClear;
5945 list<const SMESH_subMesh*> subMeshList;
5946 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5948 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5950 aPythonDump << ", ";
5951 aPythonDump << subMesh;
5952 subMeshIds.push_back( subMesh->GetId() );
5953 // detect common parts of submeshes
5954 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5955 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5957 aPythonDump << " ]";
5958 subMeshOrder.push_back( subMeshIds );
5960 // clear collected submeshes
5961 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5962 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5963 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5964 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5966 aPythonDump << " ])";
5968 mesh.SetMeshOrder( subMeshOrder );
5974 //=============================================================================
5976 * \brief Convert submesh ids into submesh interfaces
5978 //=============================================================================
5980 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5981 SMESH::submesh_array_array& theResOrder,
5982 const bool theIsDump)
5984 int nbSet = theIdsOrder.size();
5985 TPythonDump aPythonDump; // prevent dump of called methods
5987 aPythonDump << "[ ";
5988 theResOrder.length(nbSet);
5989 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5991 for( ; it != theIdsOrder.end(); it++ ) {
5992 // translate submesh identificators into submesh objects
5993 // takeing into account real number of concurrent lists
5994 const TListOfInt& aSubOrder = (*it);
5995 if (!aSubOrder.size())
5998 aPythonDump << "[ ";
5999 // convert shape indices into interfaces
6000 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6001 aResSubSet->length(aSubOrder.size());
6002 TListOfInt::const_iterator subIt = aSubOrder.begin();
6004 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6005 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6007 SMESH::SMESH_subMesh_var subMesh =
6008 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6011 aPythonDump << ", ";
6012 aPythonDump << subMesh;
6014 aResSubSet[ j++ ] = subMesh;
6017 aPythonDump << " ]";
6019 theResOrder[ listIndx++ ] = aResSubSet;
6021 // correct number of lists
6022 theResOrder.length( listIndx );
6025 // finilise python dump
6026 aPythonDump << " ]";
6027 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6031 namespace // utils used by SMESH_MeshPartDS
6034 * \brief Class used to access to protected data of SMDS_MeshInfo
6036 struct TMeshInfo : public SMDS_MeshInfo
6038 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6041 * \brief Element holing its ID only
6043 struct TElemID : public SMDS_LinearEdge
6045 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6049 //================================================================================
6051 // Implementation of SMESH_MeshPartDS
6053 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6054 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6056 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6057 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6060 _meshDS = mesh_i->GetImpl().GetMeshDS();
6062 SetPersistentId( _meshDS->GetPersistentId() );
6064 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6066 // <meshPart> is the whole mesh
6067 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6069 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6070 myGroupSet = _meshDS->GetGroups();
6075 SMESH::long_array_var anIDs = meshPart->GetIDs();
6076 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6077 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6079 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6080 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6081 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6086 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6087 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6088 if ( _elements[ e->GetType() ].insert( e ).second )
6091 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6092 while ( nIt->more() )
6094 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6095 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6102 ShapeToMesh( _meshDS->ShapeToMesh() );
6104 _meshDS = 0; // to enforce iteration on _elements and _nodes
6107 // -------------------------------------------------------------------------------------
6108 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6109 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6112 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6113 for ( ; partIt != meshPart.end(); ++partIt )
6114 if ( const SMDS_MeshElement * e = *partIt )
6115 if ( _elements[ e->GetType() ].insert( e ).second )
6118 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6119 while ( nIt->more() )
6121 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6122 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6128 // -------------------------------------------------------------------------------------
6129 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6131 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6133 TElemID elem( IDelem );
6134 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6135 if ( !_elements[ iType ].empty() )
6137 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6138 if ( it != _elements[ iType ].end() )
6143 // -------------------------------------------------------------------------------------
6144 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6146 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6148 typedef SMDS_SetIterator
6149 <const SMDS_MeshElement*,
6150 TIDSortedElemSet::const_iterator,
6151 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6152 SMDS_MeshElement::GeomFilter
6155 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6157 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6158 _elements[type].end(),
6159 SMDS_MeshElement::GeomFilter( geomType )));
6161 // -------------------------------------------------------------------------------------
6162 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6164 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6166 typedef SMDS_SetIterator
6167 <const SMDS_MeshElement*,
6168 TIDSortedElemSet::const_iterator,
6169 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6170 SMDS_MeshElement::EntityFilter
6173 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6175 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6176 _elements[type].end(),
6177 SMDS_MeshElement::EntityFilter( entity )));
6179 // -------------------------------------------------------------------------------------
6180 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6182 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6183 if ( type == SMDSAbs_All && !_meshDS )
6185 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6187 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6188 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6190 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6192 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6193 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6195 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6196 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6198 // -------------------------------------------------------------------------------------
6199 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6200 iterType SMESH_MeshPartDS::methName() const \
6202 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6203 return _meshDS ? _meshDS->methName() : iterType \
6204 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6206 // -------------------------------------------------------------------------------------
6207 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6208 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6209 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6210 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6211 #undef _GET_ITER_DEFINE
6213 // END Implementation of SMESH_MeshPartDS
6215 //================================================================================