1 // Copyright (C) 2007-2011 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.
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_SMESHDS_Mesh.h"
30 #include "SMDS_EdgePosition.hxx"
31 #include "SMDS_ElemIterator.hxx"
32 #include "SMDS_FacePosition.hxx"
33 #include "SMDS_IteratorOnIterators.hxx"
34 #include "SMDS_SetIterator.hxx"
35 #include "SMDS_VolumeTool.hxx"
36 #include "SMESHDS_Command.hxx"
37 #include "SMESHDS_CommandType.hxx"
38 #include "SMESHDS_GroupOnGeom.hxx"
39 #include "SMESH_Filter_i.hxx"
40 #include "SMESH_Gen_i.hxx"
41 #include "SMESH_Group.hxx"
42 #include "SMESH_Group_i.hxx"
43 #include "SMESH_MEDMesh_i.hxx"
44 #include "SMESH_MeshEditor.hxx"
45 #include "SMESH_MeshEditor_i.hxx"
46 #include "SMESH_MesherHelper.hxx"
47 #include "SMESH_PreMeshInfo.hxx"
48 #include "SMESH_PythonDump.hxx"
49 #include "SMESH_subMesh_i.hxx"
52 #include <SALOME_NamingService.hxx>
53 #include <Utils_CorbaException.hxx>
54 #include <Utils_ExceptHandlers.hxx>
55 #include <Utils_SINGLETON.hxx>
56 #include <utilities.h>
57 #include <GEOMImpl_Types.hxx>
60 #include <BRep_Builder.hxx>
61 #include <OSD_Directory.hxx>
62 #include <OSD_File.hxx>
63 #include <OSD_Path.hxx>
64 #include <OSD_Protection.hxx>
65 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
66 #include <TColStd_MapOfInteger.hxx>
67 #include <TColStd_SequenceOfInteger.hxx>
68 #include <TCollection_AsciiString.hxx>
70 #include <TopExp_Explorer.hxx>
71 #include <TopoDS_Compound.hxx>
72 #include <TopTools_MapOfShape.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
83 static int MYDEBUG = 0;
85 static int MYDEBUG = 0;
89 using SMESH::TPythonDump;
91 int SMESH_Mesh_i::_idGenerator = 0;
93 //To disable automatic genericobj management, the following line should be commented.
94 //Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
95 #define WITHGENERICOBJ
97 //=============================================================================
101 //=============================================================================
103 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
105 CORBA::Long studyId )
106 : SALOME::GenericObj_i( thePOA )
108 MESSAGE("SMESH_Mesh_i");
111 _id = _idGenerator++;
116 //=============================================================================
120 //=============================================================================
122 SMESH_Mesh_i::~SMESH_Mesh_i()
124 MESSAGE("~SMESH_Mesh_i");
126 #ifdef WITHGENERICOBJ
128 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
129 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
130 if ( CORBA::is_nil( itGr->second ))
132 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
134 // this method is called from destructor of group (PAL6331)
135 //_impl->RemoveGroup( aGroup->GetLocalID() );
136 aGroup->myMeshServant = 0;
137 aGroup->UnRegister();
143 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
144 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
145 if ( CORBA::is_nil( itSM->second ))
147 SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
149 aSubMesh->UnRegister();
152 _mapSubMeshIor.clear();
154 // destroy hypotheses
155 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
156 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
157 if ( CORBA::is_nil( itH->second ))
159 SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
167 delete _impl; _impl = NULL;
169 if ( _preMeshInfo ) 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 addGeomGroupData( theShapeObject, _this() );
196 //================================================================================
198 * \brief return true if mesh has a shape to build a shape on
200 //================================================================================
202 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
203 throw (SALOME::SALOME_Exception)
205 Unexpect aCatch(SALOME_SalomeException);
208 res = _impl->HasShapeToMesh();
210 catch(SALOME_Exception & S_ex) {
211 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
216 //=======================================================================
217 //function : GetShapeToMesh
219 //=======================================================================
221 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
222 throw (SALOME::SALOME_Exception)
224 Unexpect aCatch(SALOME_SalomeException);
225 GEOM::GEOM_Object_var aShapeObj;
227 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
229 aShapeObj = _gen_i->ShapeToGeomObject( S );
231 catch(SALOME_Exception & S_ex) {
232 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
234 return aShapeObj._retn();
237 //================================================================================
239 * \brief Return false if the mesh is not yet fully loaded from the study file
241 //================================================================================
243 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
245 Unexpect aCatch(SALOME_SalomeException);
246 return !_preMeshInfo;
249 //================================================================================
251 * \brief Load full mesh data from the study file
253 //================================================================================
255 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
257 Unexpect aCatch(SALOME_SalomeException);
259 _preMeshInfo->FullLoadFromFile();
262 //================================================================================
264 * \brief Remove all nodes and elements
266 //================================================================================
268 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
270 Unexpect aCatch(SALOME_SalomeException);
272 _preMeshInfo->ForgetAllData();
276 CheckGeomGroupModif(); // issue 20145
278 catch(SALOME_Exception & S_ex) {
279 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
281 TPythonDump() << _this() << ".Clear()";
284 //================================================================================
286 * \brief Remove all nodes and elements for indicated shape
288 //================================================================================
290 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
291 throw (SALOME::SALOME_Exception)
293 Unexpect aCatch(SALOME_SalomeException);
295 _preMeshInfo->FullLoadFromFile();
298 _impl->ClearSubMesh( ShapeID );
300 catch(SALOME_Exception & S_ex) {
301 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
305 //=============================================================================
309 //=============================================================================
311 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
313 SMESH::DriverMED_ReadStatus res;
316 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
317 res = SMESH::DRS_OK; break;
318 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
319 res = SMESH::DRS_EMPTY; break;
320 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
321 res = SMESH::DRS_WARN_RENUMBER; break;
322 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
323 res = SMESH::DRS_WARN_SKIP_ELEM; break;
324 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
326 res = SMESH::DRS_FAIL; break;
331 //=============================================================================
335 * Imports mesh data from MED file
337 //=============================================================================
339 SMESH::DriverMED_ReadStatus
340 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
341 throw ( SALOME::SALOME_Exception )
343 Unexpect aCatch(SALOME_SalomeException);
346 status = _impl->MEDToMesh( theFileName, theMeshName );
348 catch( SALOME_Exception& S_ex ) {
349 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
352 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
355 CreateGroupServants();
357 int major, minor, release;
358 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
359 major = minor = release = -1;
360 _medFileInfo = new SALOME_MED::MedFileInfo();
361 _medFileInfo->fileName = theFileName;
362 _medFileInfo->fileSize = 0;
365 if ( ::_stati64( theFileName, &d ) != -1 )
368 if ( ::stat64( theFileName, &d ) != -1 )
370 _medFileInfo->fileSize = d.st_size;
371 _medFileInfo->major = major;
372 _medFileInfo->minor = minor;
373 _medFileInfo->release = release;
375 return ConvertDriverMEDReadStatus(status);
378 //================================================================================
380 * \brief Imports mesh data from the CGNS file
382 //================================================================================
384 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
385 const int theMeshIndex,
386 std::string& theMeshName )
387 throw ( SALOME::SALOME_Exception )
389 Unexpect aCatch(SALOME_SalomeException);
392 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
394 catch( SALOME_Exception& S_ex ) {
395 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
398 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
401 CreateGroupServants();
403 return ConvertDriverMEDReadStatus(status);
406 //================================================================================
408 * \brief Return string representation of a MED file version comprising nbDigits
410 //================================================================================
412 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
414 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
416 return CORBA::string_dup( ver.c_str() );
419 //=============================================================================
423 * Imports mesh data from MED file
425 //=============================================================================
427 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
428 throw ( SALOME::SALOME_Exception )
430 // Read mesh with name = <theMeshName> into SMESH_Mesh
431 _impl->UNVToMesh( theFileName );
433 CreateGroupServants();
438 //=============================================================================
442 * Imports mesh data from STL file
444 //=============================================================================
445 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
446 throw ( SALOME::SALOME_Exception )
448 // Read mesh with name = <theMeshName> into SMESH_Mesh
449 _impl->STLToMesh( theFileName );
454 //=============================================================================
458 //=============================================================================
460 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
462 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
463 (SMESH_Hypothesis::Hypothesis_Status theStatus)
466 RETURNCASE( HYP_OK );
467 RETURNCASE( HYP_MISSING );
468 RETURNCASE( HYP_CONCURENT );
469 RETURNCASE( HYP_BAD_PARAMETER );
470 RETURNCASE( HYP_HIDDEN_ALGO );
471 RETURNCASE( HYP_HIDING_ALGO );
472 RETURNCASE( HYP_UNKNOWN_FATAL );
473 RETURNCASE( HYP_INCOMPATIBLE );
474 RETURNCASE( HYP_NOTCONFORM );
475 RETURNCASE( HYP_ALREADY_EXIST );
476 RETURNCASE( HYP_BAD_DIM );
477 RETURNCASE( HYP_BAD_SUBSHAPE );
478 RETURNCASE( HYP_BAD_GEOMETRY );
479 RETURNCASE( HYP_NEED_SHAPE );
482 return SMESH::HYP_UNKNOWN_FATAL;
485 //=============================================================================
489 * calls internal addHypothesis() and then adds a reference to <anHyp> under
490 * the SObject actually having a reference to <aSubShape>.
491 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
493 //=============================================================================
495 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
496 SMESH::SMESH_Hypothesis_ptr anHyp)
497 throw(SALOME::SALOME_Exception)
499 Unexpect aCatch(SALOME_SalomeException);
501 _preMeshInfo->ForgetOrLoad();
503 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
505 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
506 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
507 aSubShapeObject, anHyp );
509 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
511 // Update Python script
512 if(_impl->HasShapeToMesh()) {
513 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
514 << aSubShapeObject << ", " << anHyp << " )";
517 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
520 return ConvertHypothesisStatus(status);
523 //=============================================================================
527 //=============================================================================
529 SMESH_Hypothesis::Hypothesis_Status
530 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
531 SMESH::SMESH_Hypothesis_ptr anHyp)
533 if(MYDEBUG) MESSAGE("addHypothesis");
535 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
536 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
539 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
540 if (CORBA::is_nil(myHyp))
541 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
544 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
547 TopoDS_Shape myLocSubShape;
548 //use PseudoShape in case if mesh has no shape
550 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
552 myLocSubShape = _impl->GetShapeToMesh();
554 int hypId = myHyp->GetId();
555 status = _impl->AddHypothesis(myLocSubShape, hypId);
556 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
557 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
558 #ifdef WITHGENERICOBJ
559 _mapHypo[hypId]->Register();
561 // assure there is a corresponding submesh
562 if ( !_impl->IsMainShape( myLocSubShape )) {
563 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
564 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
565 createSubMesh( aSubShapeObject );
569 catch(SALOME_Exception & S_ex)
571 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
576 //=============================================================================
580 //=============================================================================
582 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
583 SMESH::SMESH_Hypothesis_ptr anHyp)
584 throw(SALOME::SALOME_Exception)
586 Unexpect aCatch(SALOME_SalomeException);
588 _preMeshInfo->ForgetOrLoad();
590 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
592 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
593 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
594 aSubShapeObject, anHyp );
596 // Update Python script
597 // Update Python script
598 if(_impl->HasShapeToMesh()) {
599 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
600 << aSubShapeObject << ", " << anHyp << " )";
603 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
607 return ConvertHypothesisStatus(status);
610 //=============================================================================
614 //=============================================================================
616 SMESH_Hypothesis::Hypothesis_Status
617 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
618 SMESH::SMESH_Hypothesis_ptr anHyp)
620 if(MYDEBUG) MESSAGE("removeHypothesis()");
621 // **** proposer liste de sub-shape (selection multiple)
623 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
624 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
626 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
627 if (CORBA::is_nil(myHyp))
628 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
630 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
633 TopoDS_Shape myLocSubShape;
634 //use PseudoShape in case if mesh has no shape
636 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
638 myLocSubShape = _impl->GetShapeToMesh();
640 int hypId = myHyp->GetId();
641 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
642 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes
643 // _mapHypo.erase( hypId );
645 catch(SALOME_Exception & S_ex)
647 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
652 //=============================================================================
656 //=============================================================================
658 SMESH::ListOfHypothesis *
659 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
660 throw(SALOME::SALOME_Exception)
662 Unexpect aCatch(SALOME_SalomeException);
663 if (MYDEBUG) MESSAGE("GetHypothesisList");
664 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
665 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
667 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
670 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
671 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
672 myLocSubShape = _impl->GetShapeToMesh();
673 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
674 int i = 0, n = aLocalList.size();
677 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
678 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
679 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
680 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
685 catch(SALOME_Exception & S_ex) {
686 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
689 return aList._retn();
692 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
694 Unexpect aCatch(SALOME_SalomeException);
695 if (MYDEBUG) MESSAGE("GetSubMeshes");
697 SMESH::submesh_array_var aList = new SMESH::submesh_array();
700 TPythonDump aPythonDump;
701 if ( !_mapSubMeshIor.empty() )
705 aList->length( _mapSubMeshIor.size() );
707 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
708 for ( ; it != _mapSubMeshIor.end(); it++ ) {
709 if ( CORBA::is_nil( it->second )) continue;
710 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
712 if (i > 1) aPythonDump << ", ";
713 aPythonDump << it->second;
717 catch(SALOME_Exception & S_ex) {
718 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
721 // Update Python script
722 if ( !_mapSubMeshIor.empty() )
723 aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
725 return aList._retn();
728 //=============================================================================
732 //=============================================================================
733 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
734 const char* theName )
735 throw(SALOME::SALOME_Exception)
737 Unexpect aCatch(SALOME_SalomeException);
738 MESSAGE("SMESH_Mesh_i::GetSubMesh");
739 if (CORBA::is_nil(aSubShapeObject))
740 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
743 SMESH::SMESH_subMesh_var subMesh;
744 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
746 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
748 //Get or Create the SMESH_subMesh object implementation
750 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
752 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
754 TopoDS_Iterator it( myLocSubShape );
756 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
758 subMesh = getSubMesh( subMeshId );
760 // create a new subMesh object servant if there is none for the shape
761 if ( subMesh->_is_nil() )
762 subMesh = createSubMesh( aSubShapeObject );
763 if ( _gen_i->CanPublishInStudy( subMesh )) {
764 SALOMEDS::SObject_var aSO =
765 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
766 subMesh, aSubShapeObject, theName );
767 if ( !aSO->_is_nil()) {
768 // Update Python script
769 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
770 << aSubShapeObject << ", '" << theName << "' )";
774 catch(SALOME_Exception & S_ex) {
775 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
777 return subMesh._retn();
780 //=============================================================================
784 //=============================================================================
786 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
787 throw (SALOME::SALOME_Exception)
789 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
790 if ( theSubMesh->_is_nil() )
793 GEOM::GEOM_Object_var aSubShapeObject;
794 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
795 if ( !aStudy->_is_nil() ) {
796 // Remove submesh's SObject
797 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
798 if ( !anSO->_is_nil() ) {
799 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
800 SALOMEDS::SObject_var anObj, aRef;
801 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
802 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
804 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
805 // aSubShapeObject = theSubMesh->GetSubShape();
807 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
809 // Update Python script
810 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
814 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
816 _preMeshInfo->ForgetOrLoad();
819 //=============================================================================
823 //=============================================================================
825 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
826 const char* theName )
827 throw(SALOME::SALOME_Exception)
829 Unexpect aCatch(SALOME_SalomeException);
831 _preMeshInfo->FullLoadFromFile();
833 SMESH::SMESH_Group_var aNewGroup =
834 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
836 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
837 SALOMEDS::SObject_var aSO =
838 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
839 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
840 if ( !aSO->_is_nil()) {
841 // Update Python script
842 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
843 << theElemType << ", '" << theName << "' )";
846 return aNewGroup._retn();
850 //=============================================================================
854 //=============================================================================
855 SMESH::SMESH_GroupOnGeom_ptr
856 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
858 GEOM::GEOM_Object_ptr theGeomObj)
859 throw(SALOME::SALOME_Exception)
861 Unexpect aCatch(SALOME_SalomeException);
863 _preMeshInfo->FullLoadFromFile();
865 SMESH::SMESH_GroupOnGeom_var aNewGroup;
867 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
868 if ( !aShape.IsNull() )
870 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
871 ( createGroup( theElemType, theName, aShape ));
873 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
874 SALOMEDS::SObject_var aSO =
875 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
876 aNewGroup, theGeomObj, theName);
877 if ( !aSO->_is_nil()) {
878 // Update Python script
879 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
880 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
885 return aNewGroup._retn();
888 //================================================================================
890 * \brief Creates a group whose contents is defined by filter
891 * \param theElemType - group type
892 * \param theName - group name
893 * \param theFilter - the filter
894 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
896 //================================================================================
898 SMESH::SMESH_GroupOnFilter_ptr
899 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
901 SMESH::Filter_ptr theFilter )
902 throw (SALOME::SALOME_Exception)
904 Unexpect aCatch(SALOME_SalomeException);
906 _preMeshInfo->FullLoadFromFile();
908 if ( CORBA::is_nil( theFilter ))
909 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
911 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
913 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
915 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
916 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
919 if ( !aNewGroup->_is_nil() )
920 aNewGroup->SetFilter( theFilter );
922 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
924 SALOMEDS::SObject_var aSO =
925 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
926 GEOM::GEOM_Object::_nil(), theName);
927 if ( !aSO->_is_nil()) {
928 // Update Python script
929 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
930 << theElemType << ", '" << theName << "', " << theFilter << " )";
934 return aNewGroup._retn();
937 //=============================================================================
941 //=============================================================================
943 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
944 throw (SALOME::SALOME_Exception)
946 if ( theGroup->_is_nil() )
949 SMESH_GroupBase_i* aGroup =
950 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
954 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
955 if ( !aStudy->_is_nil() ) {
956 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
958 if ( !aGroupSO->_is_nil() ) {
959 // Update Python script
960 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
962 // Remove group's SObject
963 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
967 // Remove the group from SMESH data structures
968 removeGroup( aGroup->GetLocalID() );
971 //=============================================================================
973 * Remove group with its contents
975 //=============================================================================
977 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
978 throw (SALOME::SALOME_Exception)
981 _preMeshInfo->FullLoadFromFile();
983 if ( theGroup->_is_nil() )
986 SMESH_GroupBase_i* aGroup =
987 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
991 SMESH::long_array_var anIds = aGroup->GetListOfID();
992 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
994 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
997 if ( aGroup->GetType() == SMESH::NODE )
998 aMeshEditor->RemoveNodes( anIds );
1000 aMeshEditor->RemoveElements( anIds );
1003 RemoveGroup( theGroup );
1005 // Update Python script
1006 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
1009 //================================================================================
1011 * \brief Get the list of groups existing in the mesh
1012 * \retval SMESH::ListOfGroups * - list of groups
1014 //================================================================================
1016 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1018 Unexpect aCatch(SALOME_SalomeException);
1019 if (MYDEBUG) MESSAGE("GetGroups");
1021 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1024 TPythonDump aPythonDump;
1025 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1026 aPythonDump << "[ ";
1029 aList->length( _mapGroups.size() );
1031 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1032 for ( ; it != _mapGroups.end(); it++ ) {
1033 if ( CORBA::is_nil( it->second )) continue;
1034 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1036 if (i > 1) aPythonDump << ", ";
1037 aPythonDump << it->second;
1041 catch(SALOME_Exception & S_ex) {
1042 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1045 // Update Python script
1046 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1047 aPythonDump << " ] = " << _this() << ".GetGroups()";
1049 return aList._retn();
1052 //=============================================================================
1054 * Get number of groups existing in the mesh
1056 //=============================================================================
1058 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1060 Unexpect aCatch(SALOME_SalomeException);
1061 return _mapGroups.size();
1064 //=============================================================================
1066 * New group is created. All mesh elements that are
1067 * present in initial groups are added to the new one
1069 //=============================================================================
1070 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1071 SMESH::SMESH_GroupBase_ptr theGroup2,
1072 const char* theName )
1073 throw (SALOME::SALOME_Exception)
1076 _preMeshInfo->FullLoadFromFile();
1080 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1081 theGroup1->GetType() != theGroup2->GetType() )
1082 return SMESH::SMESH_Group::_nil();
1085 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1086 if ( aResGrp->_is_nil() )
1087 return SMESH::SMESH_Group::_nil();
1089 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1090 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1092 TColStd_MapOfInteger aResMap;
1094 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1095 aResMap.Add( anIds1[ i1 ] );
1097 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1098 aResMap.Add( anIds2[ i2 ] );
1100 SMESH::long_array_var aResIds = new SMESH::long_array;
1101 aResIds->length( aResMap.Extent() );
1104 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1105 for( ; anIter.More(); anIter.Next() )
1106 aResIds[ resI++ ] = anIter.Key();
1108 aResGrp->Add( aResIds );
1110 // Clear python lines, created by CreateGroup() and Add()
1111 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1112 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1113 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1115 // Update Python script
1116 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
1117 << theGroup1 << ", " << theGroup2 << ", '"
1118 << theName << "' )";
1120 return aResGrp._retn();
1124 return SMESH::SMESH_Group::_nil();
1128 //=============================================================================
1130 \brief Union list of groups. New group is created. All mesh elements that are
1131 present in initial groups are added to the new one.
1132 \param theGroups list of groups
1133 \param theName name of group to be created
1134 \return pointer on the group
1136 //=============================================================================
1137 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1138 const char* theName )
1139 throw (SALOME::SALOME_Exception)
1142 _preMeshInfo->FullLoadFromFile();
1145 return SMESH::SMESH_Group::_nil();
1149 vector< int > anIds;
1150 SMESH::ElementType aType = SMESH::ALL;
1151 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1153 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1154 if ( CORBA::is_nil( aGrp ) )
1158 SMESH::ElementType aCurrType = aGrp->GetType();
1159 if ( aType == SMESH::ALL )
1163 if ( aType != aCurrType )
1164 return SMESH::SMESH_Group::_nil();
1168 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1169 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1171 int aCurrId = aCurrIds[ i ];
1172 anIds.push_back( aCurrId );
1177 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1178 if ( aResGrp->_is_nil() )
1179 return SMESH::SMESH_Group::_nil();
1181 // Create array of identifiers
1182 SMESH::long_array_var aResIds = new SMESH::long_array;
1183 aResIds->length( anIds.size() );
1185 //NCollection_Map< int >::Iterator anIter( anIds );
1186 for ( int i = 0; i<anIds.size(); i++ )
1188 aResIds[ i ] = anIds[i];
1190 aResGrp->Add( aResIds );
1192 // Clear python lines, created by CreateGroup() and Add()
1193 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1194 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1195 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1197 // Update Python script
1199 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1200 << &theGroups << ", '" << theName << "' )";
1202 return aResGrp._retn();
1206 return SMESH::SMESH_Group::_nil();
1210 //=============================================================================
1212 * New group is created. All mesh elements that are
1213 * present in both initial groups are added to the new one.
1215 //=============================================================================
1216 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1217 SMESH::SMESH_GroupBase_ptr theGroup2,
1218 const char* theName )
1219 throw (SALOME::SALOME_Exception)
1222 _preMeshInfo->FullLoadFromFile();
1224 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1225 theGroup1->GetType() != theGroup2->GetType() )
1226 return SMESH::SMESH_Group::_nil();
1228 // Create Intersection
1229 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1230 if ( aResGrp->_is_nil() )
1233 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1234 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1236 TColStd_MapOfInteger aMap1;
1238 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1239 aMap1.Add( anIds1[ i1 ] );
1241 TColStd_SequenceOfInteger aSeq;
1243 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1244 if ( aMap1.Contains( anIds2[ i2 ] ) )
1245 aSeq.Append( anIds2[ i2 ] );
1247 SMESH::long_array_var aResIds = new SMESH::long_array;
1248 aResIds->length( aSeq.Length() );
1250 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1251 aResIds[ resI ] = aSeq( resI + 1 );
1253 aResGrp->Add( aResIds );
1255 // Clear python lines, created by CreateGroup() and Add()
1256 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1257 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1258 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1260 // Update Python script
1261 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1262 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1264 return aResGrp._retn();
1267 //=============================================================================
1269 \brief Intersect list of groups. New group is created. All mesh elements that
1270 are present in all initial groups simultaneously are added to the new one.
1271 \param theGroups list of groups
1272 \param theName name of group to be created
1273 \return pointer on the group
1275 //=============================================================================
1276 SMESH::SMESH_Group_ptr
1277 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1278 const char* theName )
1279 throw (SALOME::SALOME_Exception)
1282 _preMeshInfo->FullLoadFromFile();
1285 return SMESH::SMESH_Group::_nil();
1289 NCollection_DataMap< int, int > anIdToCount;
1290 SMESH::ElementType aType = SMESH::ALL;
1291 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1293 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1294 if ( CORBA::is_nil( aGrp ) )
1298 SMESH::ElementType aCurrType = aGrp->GetType();
1299 if ( aType == SMESH::ALL )
1303 if ( aType != aCurrType )
1304 return SMESH::SMESH_Group::_nil();
1307 // calculates number of occurance ids in groups
1308 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1309 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1311 int aCurrId = aCurrIds[ i ];
1312 if ( !anIdToCount.IsBound( aCurrId ) )
1313 anIdToCount.Bind( aCurrId, 1 );
1315 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1319 // create map of ids
1320 int nbGrp = theGroups.length();
1321 vector< int > anIds;
1322 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1323 for ( ; anIter.More(); anIter.Next() )
1325 int aCurrId = anIter.Key();
1326 int aCurrNb = anIter.Value();
1327 if ( aCurrNb == nbGrp )
1328 anIds.push_back( aCurrId );
1332 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1333 if ( aResGrp->_is_nil() )
1334 return SMESH::SMESH_Group::_nil();
1336 // Create array of identifiers
1337 SMESH::long_array_var aResIds = new SMESH::long_array;
1338 aResIds->length( anIds.size() );
1340 //NCollection_Map< int >::Iterator aListIter( anIds );
1341 for ( int i = 0; i<anIds.size(); i++ )
1343 aResIds[ i ] = anIds[i];
1345 aResGrp->Add( aResIds );
1347 // Clear python lines, created by CreateGroup() and Add()
1348 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1349 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1350 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1352 // Update Python script
1354 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1355 << &theGroups << ", '" << theName << "' )";
1357 return aResGrp._retn();
1361 return SMESH::SMESH_Group::_nil();
1365 //=============================================================================
1367 * New group is created. All mesh elements that are present in
1368 * main group but do not present in tool group are added to the new one
1370 //=============================================================================
1371 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1372 SMESH::SMESH_GroupBase_ptr theGroup2,
1373 const char* theName )
1374 throw (SALOME::SALOME_Exception)
1377 _preMeshInfo->FullLoadFromFile();
1379 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1380 theGroup1->GetType() != theGroup2->GetType() )
1381 return SMESH::SMESH_Group::_nil();
1384 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1385 if ( aResGrp->_is_nil() )
1388 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1389 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1391 TColStd_MapOfInteger aMap2;
1393 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1394 aMap2.Add( anIds2[ i2 ] );
1396 TColStd_SequenceOfInteger aSeq;
1397 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1398 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1399 aSeq.Append( anIds1[ i1 ] );
1401 SMESH::long_array_var aResIds = new SMESH::long_array;
1402 aResIds->length( aSeq.Length() );
1404 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1405 aResIds[ resI ] = aSeq( resI + 1 );
1407 aResGrp->Add( aResIds );
1409 // Clear python lines, created by CreateGroup() and Add()
1410 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1411 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1412 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1414 // Update Python script
1415 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1416 << theGroup1 << ", " << theGroup2 << ", '"
1417 << theName << "' )";
1419 return aResGrp._retn();
1422 //=============================================================================
1424 \brief Cut lists of groups. New group is created. All mesh elements that are
1425 present in main groups but do not present in tool groups are added to the new one
1426 \param theMainGroups list of main groups
1427 \param theToolGroups list of tool groups
1428 \param theName name of group to be created
1429 \return pointer on the group
1431 //=============================================================================
1432 SMESH::SMESH_Group_ptr
1433 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1434 const SMESH::ListOfGroups& theToolGroups,
1435 const char* theName )
1436 throw (SALOME::SALOME_Exception)
1439 _preMeshInfo->FullLoadFromFile();
1442 return SMESH::SMESH_Group::_nil();
1446 set< int > aToolIds;
1447 SMESH::ElementType aType = SMESH::ALL;
1449 // iterate through tool groups
1450 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1452 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1453 if ( CORBA::is_nil( aGrp ) )
1457 SMESH::ElementType aCurrType = aGrp->GetType();
1458 if ( aType == SMESH::ALL )
1462 if ( aType != aCurrType )
1463 return SMESH::SMESH_Group::_nil();
1467 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1468 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1470 int aCurrId = aCurrIds[ i ];
1471 aToolIds.insert( aCurrId );
1475 vector< int > anIds; // result
1477 // Iterate through main group
1478 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1480 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1481 if ( CORBA::is_nil( aGrp ) )
1485 SMESH::ElementType aCurrType = aGrp->GetType();
1486 if ( aType == SMESH::ALL )
1490 if ( aType != aCurrType )
1491 return SMESH::SMESH_Group::_nil();
1495 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1496 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1498 int aCurrId = aCurrIds[ i ];
1499 if ( !aToolIds.count( aCurrId ) )
1500 anIds.push_back( aCurrId );
1505 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1506 if ( aResGrp->_is_nil() )
1507 return SMESH::SMESH_Group::_nil();
1509 // Create array of identifiers
1510 SMESH::long_array_var aResIds = new SMESH::long_array;
1511 aResIds->length( anIds.size() );
1513 for (int i=0; i<anIds.size(); i++ )
1515 aResIds[ i ] = anIds[i];
1517 aResGrp->Add( aResIds );
1519 // Clear python lines, created by CreateGroup() and Add()
1520 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1521 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1522 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1524 // Update Python script
1526 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1527 << &theMainGroups << ", " << &theToolGroups << ", '"
1528 << theName << "' )";
1530 return aResGrp._retn();
1534 return SMESH::SMESH_Group::_nil();
1538 //=============================================================================
1540 \brief Create groups of entities from existing groups of superior dimensions
1542 1) extract all nodes from each group,
1543 2) combine all elements of specified dimension laying on these nodes.
1544 \param theGroups list of source groups
1545 \param theElemType dimension of elements
1546 \param theName name of new group
1547 \return pointer on new group
1549 //=============================================================================
1550 SMESH::SMESH_Group_ptr
1551 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1552 SMESH::ElementType theElemType,
1553 const char* theName )
1554 throw (SALOME::SALOME_Exception)
1557 _preMeshInfo->FullLoadFromFile();
1559 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1561 if ( !theName || !aMeshDS )
1562 return SMESH::SMESH_Group::_nil();
1564 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1568 // Create map of nodes from all groups
1570 set< int > aNodeMap;
1572 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1574 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1575 if ( CORBA::is_nil( aGrp ) )
1578 SMESH::ElementType aType = aGrp->GetType();
1579 if ( aType == SMESH::ALL )
1581 else if ( aType == SMESH::NODE )
1583 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1584 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1586 int aCurrId = aCurrIds[ i ];
1587 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1589 aNodeMap.insert( aNode->GetID() );
1594 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1595 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1597 int aCurrId = aCurrIds[ i ];
1598 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1601 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1602 while( aNodeIter->more() )
1604 const SMDS_MeshNode* aNode =
1605 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1607 aNodeMap.insert( aNode->GetID() );
1613 // Get result identifiers
1615 vector< int > aResultIds;
1616 if ( theElemType == SMESH::NODE )
1618 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1619 set<int>::iterator iter = aNodeMap.begin();
1620 for ( ; iter != aNodeMap.end(); iter++ )
1621 aResultIds.push_back( *iter);
1625 // Create list of elements of given dimension constructed on the nodes
1626 vector< int > anElemList;
1627 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1628 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1629 set<int>::iterator iter = aNodeMap.begin();
1630 for ( ; iter != aNodeMap.end(); iter++ )
1632 const SMDS_MeshElement* aNode =
1633 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1637 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1638 while( anElemIter->more() )
1640 const SMDS_MeshElement* anElem =
1641 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1642 if ( anElem && anElem->GetType() == anElemType )
1643 anElemList.push_back( anElem->GetID() );
1647 // check whether all nodes of elements are present in nodes map
1648 for (int i=0; i< anElemList.size(); i++)
1650 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1655 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1656 while( aNodeIter->more() )
1658 const SMDS_MeshNode* aNode =
1659 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1660 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1667 aResultIds.push_back( anElem->GetID() );
1673 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1674 if ( aResGrp->_is_nil() )
1675 return SMESH::SMESH_Group::_nil();
1677 // Create array of identifiers
1678 SMESH::long_array_var aResIds = new SMESH::long_array;
1679 aResIds->length( aResultIds.size() );
1681 for (int i=0; i< aResultIds.size(); i++)
1682 aResIds[ i ] = aResultIds[i];
1683 aResGrp->Add( aResIds );
1685 // Remove strings corresponding to group creation
1686 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1687 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1688 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1690 // Update Python script
1692 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1693 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1695 return aResGrp._retn();
1699 return SMESH::SMESH_Group::_nil();
1703 //================================================================================
1705 * \brief Remember GEOM group data
1707 //================================================================================
1709 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1710 CORBA::Object_ptr theSmeshObj)
1712 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1715 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1716 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1717 if ( groupSO->_is_nil() )
1720 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1721 GEOM::GEOM_IGroupOperations_var groupOp =
1722 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1723 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1726 _geomGroupData.push_back( TGeomGroupData() );
1727 TGeomGroupData & groupData = _geomGroupData.back();
1729 CORBA::String_var entry = groupSO->GetID();
1730 groupData._groupEntry = entry.in();
1732 for ( int i = 0; i < ids->length(); ++i )
1733 groupData._indices.insert( ids[i] );
1735 groupData._smeshObject = theSmeshObj;
1738 //================================================================================
1740 * Remove GEOM group data relating to removed smesh object
1742 //================================================================================
1744 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1746 list<TGeomGroupData>::iterator
1747 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1748 for ( ; data != dataEnd; ++data ) {
1749 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1750 _geomGroupData.erase( data );
1756 //================================================================================
1758 * \brief Return new group contents if it has been changed and update group data
1760 //================================================================================
1762 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1764 TopoDS_Shape newShape;
1767 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1768 if ( study->_is_nil() ) return newShape; // means "not changed"
1769 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1770 if ( !groupSO->_is_nil() )
1772 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1773 if ( CORBA::is_nil( groupObj )) return newShape;
1774 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1776 // get indices of group items
1777 set<int> curIndices;
1778 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1779 GEOM::GEOM_IGroupOperations_var groupOp =
1780 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1781 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1782 for ( int i = 0; i < ids->length(); ++i )
1783 curIndices.insert( ids[i] );
1785 if ( groupData._indices == curIndices )
1786 return newShape; // group not changed
1789 groupData._indices = curIndices;
1791 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1792 if ( !geomClient ) return newShape;
1793 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1794 geomClient->RemoveShapeFromBuffer( groupIOR );
1795 newShape = _gen_i->GeomObjectToShape( geomGroup );
1798 if ( newShape.IsNull() ) {
1799 // geom group becomes empty - return empty compound
1800 TopoDS_Compound compound;
1801 BRep_Builder().MakeCompound(compound);
1802 newShape = compound;
1809 //=============================================================================
1811 * \brief Storage of shape and index used in CheckGeomGroupModif()
1813 //=============================================================================
1814 struct TIndexedShape
1817 TopoDS_Shape _shape;
1818 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1821 //=============================================================================
1823 * \brief Update objects depending on changed geom groups
1825 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1826 * issue 0020210: Update of a smesh group after modification of the associated geom group
1828 //=============================================================================
1830 void SMESH_Mesh_i::CheckGeomGroupModif()
1832 if ( !_impl->HasShapeToMesh() ) return;
1834 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1835 if ( study->_is_nil() ) return;
1837 CORBA::Long nbEntities = NbNodes() + NbElements();
1839 // Check if group contents changed
1841 typedef map< string, TopoDS_Shape > TEntry2Geom;
1842 TEntry2Geom newGroupContents;
1844 list<TGeomGroupData>::iterator
1845 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1846 for ( ; data != dataEnd; ++data )
1848 pair< TEntry2Geom::iterator, bool > it_new =
1849 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1850 bool processedGroup = !it_new.second;
1851 TopoDS_Shape& newShape = it_new.first->second;
1852 if ( !processedGroup )
1853 newShape = newGroupShape( *data );
1854 if ( newShape.IsNull() )
1855 continue; // no changes
1858 _preMeshInfo->ForgetOrLoad();
1860 if ( processedGroup ) { // update group indices
1861 list<TGeomGroupData>::iterator data2 = data;
1862 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1863 data->_indices = data2->_indices;
1866 // Update SMESH objects according to new GEOM group contents
1868 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1869 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1871 int oldID = submesh->GetId();
1872 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1874 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1876 // update hypotheses
1877 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1878 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1879 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1881 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1882 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1884 // care of submeshes
1885 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1886 int newID = newSubmesh->GetId();
1887 if ( newID != oldID ) {
1888 _mapSubMesh [ newID ] = newSubmesh;
1889 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1890 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1891 _mapSubMesh. erase(oldID);
1892 _mapSubMesh_i. erase(oldID);
1893 _mapSubMeshIor.erase(oldID);
1894 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1899 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1900 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1901 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1903 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1905 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1906 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1907 ds->SetShape( newShape );
1912 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1913 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1915 // Remove groups and submeshes basing on removed sub-shapes
1917 TopTools_MapOfShape newShapeMap;
1918 TopoDS_Iterator shapeIt( newShape );
1919 for ( ; shapeIt.More(); shapeIt.Next() )
1920 newShapeMap.Add( shapeIt.Value() );
1922 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1923 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1925 if ( newShapeMap.Contains( shapeIt.Value() ))
1927 TopTools_IndexedMapOfShape oldShapeMap;
1928 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1929 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1931 const TopoDS_Shape& oldShape = oldShapeMap(i);
1932 int oldInd = meshDS->ShapeToIndex( oldShape );
1934 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1935 if ( i_smIor != _mapSubMeshIor.end() ) {
1936 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1939 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1940 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1942 // check if a group bases on oldInd shape
1943 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1944 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1945 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1946 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1948 RemoveGroup( i_grp->second ); // several groups can base on same shape
1949 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1954 // Reassign hypotheses and update groups after setting the new shape to mesh
1956 // collect anassigned hypotheses
1957 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1958 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1959 TShapeHypList assignedHyps;
1960 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1962 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1963 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1964 if ( !hyps.empty() ) {
1965 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1966 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1967 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1970 // collect shapes supporting groups
1971 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1972 TShapeTypeList groupData;
1973 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1974 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1975 for ( ; grIt != groups.end(); ++grIt )
1977 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1979 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1981 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1982 _impl->ShapeToMesh( newShape );
1984 // reassign hypotheses
1985 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1986 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1988 TIndexedShape& geom = indS_hyps->first;
1989 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1990 int oldID = geom._index;
1991 int newID = meshDS->ShapeToIndex( geom._shape );
1994 if ( oldID == 1 ) { // main shape
1996 geom._shape = newShape;
1998 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1999 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2000 // care of submeshes
2001 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2002 if ( newID != oldID ) {
2003 _mapSubMesh [ newID ] = newSubmesh;
2004 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2005 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2006 _mapSubMesh. erase(oldID);
2007 _mapSubMesh_i. erase(oldID);
2008 _mapSubMeshIor.erase(oldID);
2009 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2013 TShapeTypeList::iterator geomType = groupData.begin();
2014 for ( ; geomType != groupData.end(); ++geomType )
2016 const TIndexedShape& geom = geomType->first;
2017 int oldID = geom._index;
2018 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2021 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2022 CORBA::String_var name = groupSO->GetName();
2024 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2026 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2027 group_i->changeLocalId( newID );
2030 break; // everything has been updated
2033 } // loop on group data
2037 CORBA::Long newNbEntities = NbNodes() + NbElements();
2038 list< SALOMEDS::SObject_var > soToUpdateIcons;
2039 if ( newNbEntities != nbEntities )
2041 // Add all SObjects with icons to soToUpdateIcons
2042 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2044 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2045 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2046 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2048 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2049 i_gr != _mapGroups.end(); ++i_gr ) // groups
2050 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2053 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
2054 for ( ; so != soToUpdateIcons.end(); ++so )
2055 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2058 //=============================================================================
2060 * \brief Create standalone group from a group on geometry or filter
2062 //=============================================================================
2064 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2067 _preMeshInfo->FullLoadFromFile();
2069 SMESH::SMESH_Group_var aGroup;
2070 if ( theGroup->_is_nil() )
2071 return aGroup._retn();
2073 Unexpect aCatch(SALOME_SalomeException);
2075 SMESH_GroupBase_i* aGroupToRem =
2076 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2078 return aGroup._retn();
2080 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2082 int anId = aGroupToRem->GetLocalID();
2083 if ( !_impl->ConvertToStandalone( anId ) )
2084 return aGroup._retn();
2085 removeGeomGroupData( theGroup );
2087 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2089 // remove old instance of group from own map
2090 _mapGroups.erase( anId );
2092 SALOMEDS::StudyBuilder_var builder;
2093 SALOMEDS::SObject_var aGroupSO;
2094 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2095 if ( !aStudy->_is_nil() ) {
2096 builder = aStudy->NewBuilder();
2097 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2098 if ( !aGroupSO->_is_nil() ) {
2100 // remove reference to geometry
2101 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
2102 for ( ; chItr->More(); chItr->Next() )
2103 // Remove group's child SObject
2104 builder->RemoveObject( chItr->Value() );
2106 // Update Python script
2107 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2108 << aGroupSO << " )";
2110 // change icon of Group on Filter
2113 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2114 const int isEmpty = ( elemTypes->length() == 0 );
2117 SALOMEDS::GenericAttribute_var anAttr =
2118 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2119 SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
2120 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2126 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2127 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2128 aGroupImpl->Register();
2129 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2131 // remember new group in own map
2132 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2133 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2135 // register CORBA object for persistence
2136 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
2138 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
2140 return aGroup._retn();
2143 //=============================================================================
2147 //=============================================================================
2149 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2151 if(MYDEBUG) MESSAGE( "createSubMesh" );
2152 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2154 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2155 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2156 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2157 SMESH::SMESH_subMesh_var subMesh
2158 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2160 _mapSubMesh[subMeshId] = mySubMesh;
2161 _mapSubMesh_i[subMeshId] = subMeshServant;
2162 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2164 // register CORBA object for persistence
2165 int nextId = _gen_i->RegisterObject( subMesh );
2166 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2168 // to track changes of GEOM groups
2169 addGeomGroupData( theSubShapeObject, subMesh );
2171 return subMesh._retn();
2174 //=======================================================================
2175 //function : getSubMesh
2177 //=======================================================================
2179 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2181 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2182 if ( it == _mapSubMeshIor.end() )
2183 return SMESH::SMESH_subMesh::_nil();
2185 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2189 //=============================================================================
2193 //=============================================================================
2195 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2196 GEOM::GEOM_Object_ptr theSubShapeObject )
2198 bool isHypChanged = false;
2199 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2200 return isHypChanged;
2202 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2204 CORBA::Long shapeId = theSubMesh->GetId();
2205 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2207 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2210 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2211 isHypChanged = !hyps.empty();
2212 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2213 for ( ; hyp != hyps.end(); ++hyp )
2214 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2221 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2222 isHypChanged = ( aHypList->length() > 0 );
2223 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2224 removeHypothesis( theSubShapeObject, aHypList[i] );
2227 catch( const SALOME::SALOME_Exception& ) {
2228 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2230 removeGeomGroupData( theSubShapeObject );
2232 int subMeshId = theSubMesh->GetId();
2234 _mapSubMesh.erase(subMeshId);
2235 _mapSubMesh_i.erase(subMeshId);
2236 _mapSubMeshIor.erase(subMeshId);
2238 return isHypChanged;
2241 //=============================================================================
2245 //=============================================================================
2247 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2248 const char* theName,
2249 const TopoDS_Shape& theShape,
2250 const SMESH_PredicatePtr& thePredicate )
2252 std::string newName;
2253 if ( !theName || strlen( theName ) == 0 )
2255 std::set< std::string > presentNames;
2256 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2257 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2258 presentNames.insert( i_gr->second->GetName() );
2260 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2261 } while ( !presentNames.insert( newName ).second );
2262 theName = newName.c_str();
2265 SMESH::SMESH_GroupBase_var aGroup;
2266 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2268 SMESH_GroupBase_i* aGroupImpl;
2269 if ( !theShape.IsNull() )
2270 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2271 else if ( thePredicate )
2272 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2274 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2276 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2277 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2278 aGroupImpl->Register();
2279 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2281 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2282 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2284 // register CORBA object for persistence
2285 int nextId = _gen_i->RegisterObject( aGroup );
2286 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2288 // to track changes of GEOM groups
2289 if ( !theShape.IsNull() ) {
2290 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2291 addGeomGroupData( geom, aGroup );
2294 return aGroup._retn();
2297 //=============================================================================
2299 * SMESH_Mesh_i::removeGroup
2301 * Should be called by ~SMESH_Group_i()
2303 //=============================================================================
2305 void SMESH_Mesh_i::removeGroup( const int theId )
2307 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2308 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2309 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2310 _mapGroups.erase( theId );
2311 removeGeomGroupData( group );
2312 if (! _impl->RemoveGroup( theId ))
2314 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2315 RemoveGroup( group );
2320 //=============================================================================
2324 //=============================================================================
2326 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2327 throw(SALOME::SALOME_Exception)
2330 _preMeshInfo->FullLoadFromFile();
2332 SMESH::log_array_var aLog;
2334 list < SMESHDS_Command * >logDS = _impl->GetLog();
2335 aLog = new SMESH::log_array;
2337 int lg = logDS.size();
2340 list < SMESHDS_Command * >::iterator its = logDS.begin();
2341 while(its != logDS.end()){
2342 SMESHDS_Command *com = *its;
2343 int comType = com->GetType();
2345 int lgcom = com->GetNumber();
2347 const list < int >&intList = com->GetIndexes();
2348 int inum = intList.size();
2350 list < int >::const_iterator ii = intList.begin();
2351 const list < double >&coordList = com->GetCoords();
2352 int rnum = coordList.size();
2354 list < double >::const_iterator ir = coordList.begin();
2355 aLog[indexLog].commandType = comType;
2356 aLog[indexLog].number = lgcom;
2357 aLog[indexLog].coords.length(rnum);
2358 aLog[indexLog].indexes.length(inum);
2359 for(int i = 0; i < rnum; i++){
2360 aLog[indexLog].coords[i] = *ir;
2361 //MESSAGE(" "<<i<<" "<<ir.Value());
2364 for(int i = 0; i < inum; i++){
2365 aLog[indexLog].indexes[i] = *ii;
2366 //MESSAGE(" "<<i<<" "<<ii.Value());
2375 catch(SALOME_Exception & S_ex){
2376 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2378 return aLog._retn();
2382 //=============================================================================
2386 //=============================================================================
2388 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2390 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2394 //=============================================================================
2398 //=============================================================================
2400 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2402 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2406 //=============================================================================
2410 //=============================================================================
2412 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2417 //=============================================================================
2420 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2421 // issue 0020918: groups removal is caused by hyp modification
2422 // issue 0021208: to forget not loaded mesh data at hyp modification
2423 struct TCallUp_i : public SMESH_Mesh::TCallUp
2425 SMESH_Mesh_i* _mesh;
2426 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2427 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2428 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2429 virtual void Load () { _mesh->Load(); }
2433 //================================================================================
2435 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2437 //================================================================================
2439 void SMESH_Mesh_i::onHypothesisModified()
2442 _preMeshInfo->ForgetOrLoad();
2445 //=============================================================================
2449 //=============================================================================
2451 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2453 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2456 _impl->SetCallUp( new TCallUp_i(this));
2459 //=============================================================================
2463 //=============================================================================
2465 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2467 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2471 //=============================================================================
2473 * Return mesh editor
2475 //=============================================================================
2477 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2480 _preMeshInfo->FullLoadFromFile();
2482 // Create MeshEditor
2483 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2484 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2486 // Update Python script
2487 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2489 return aMesh._retn();
2492 //=============================================================================
2494 * Return mesh edition previewer
2496 //=============================================================================
2498 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2501 _preMeshInfo->FullLoadFromFile();
2503 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2504 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2505 return aMesh._retn();
2508 //================================================================================
2510 * \brief Return true if the mesh has been edited since a last total re-compute
2511 * and those modifications may prevent successful partial re-compute
2513 //================================================================================
2515 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2517 Unexpect aCatch(SALOME_SalomeException);
2518 return _impl->HasModificationsToDiscard();
2521 //================================================================================
2523 * \brief Returns a random unique color
2525 //================================================================================
2527 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2529 const int MAX_ATTEMPTS = 100;
2531 double tolerance = 0.5;
2532 SALOMEDS::Color col;
2536 // generate random color
2537 double red = (double)rand() / RAND_MAX;
2538 double green = (double)rand() / RAND_MAX;
2539 double blue = (double)rand() / RAND_MAX;
2540 // check existence in the list of the existing colors
2541 bool matched = false;
2542 std::list<SALOMEDS::Color>::const_iterator it;
2543 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2544 SALOMEDS::Color color = *it;
2545 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2546 matched = tol < tolerance;
2548 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2549 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2557 //=============================================================================
2559 * Sets auto-color mode. If it is on, groups get unique random colors
2561 //=============================================================================
2563 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2565 Unexpect aCatch(SALOME_SalomeException);
2566 _impl->SetAutoColor(theAutoColor);
2568 TPythonDump pyDump; // not to dump group->SetColor() from below code
2569 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2571 std::list<SALOMEDS::Color> aReservedColors;
2572 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2573 for ( ; it != _mapGroups.end(); it++ ) {
2574 if ( CORBA::is_nil( it->second )) continue;
2575 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2576 it->second->SetColor( aColor );
2577 aReservedColors.push_back( aColor );
2581 //=============================================================================
2583 * Returns true if auto-color mode is on
2585 //=============================================================================
2587 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2589 Unexpect aCatch(SALOME_SalomeException);
2590 return _impl->GetAutoColor();
2593 //=============================================================================
2595 * Checks if there are groups with equal names
2597 //=============================================================================
2599 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2601 return _impl->HasDuplicatedGroupNamesMED();
2604 //================================================================================
2606 * \brief Care of a file before exporting mesh into it
2608 //================================================================================
2610 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2612 TCollection_AsciiString aFullName ((char*)file);
2613 OSD_Path aPath (aFullName);
2614 OSD_File aFile (aPath);
2615 if (aFile.Exists()) {
2616 // existing filesystem node
2617 if (aFile.KindOfFile() == OSD_FILE) {
2618 if (aFile.IsWriteable()) {
2623 if (aFile.Failed()) {
2624 TCollection_AsciiString msg ("File ");
2625 msg += aFullName + " cannot be replaced.";
2626 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2629 TCollection_AsciiString msg ("File ");
2630 msg += aFullName + " cannot be overwritten.";
2631 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2634 TCollection_AsciiString msg ("Location ");
2635 msg += aFullName + " is not a file.";
2636 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2639 // nonexisting file; check if it can be created
2641 aFile.Build(OSD_WriteOnly, OSD_Protection());
2642 if (aFile.Failed()) {
2643 TCollection_AsciiString msg ("You cannot create the file ");
2644 msg += aFullName + ". Check the directory existance and access rights.";
2645 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2653 //================================================================================
2655 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2656 * \param file - file name
2657 * \param overwrite - to erase the file or not
2658 * \retval string - mesh name
2660 //================================================================================
2662 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2663 CORBA::Boolean overwrite)
2666 PrepareForWriting(file, overwrite);
2667 string aMeshName = "Mesh";
2668 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2669 if ( !aStudy->_is_nil() ) {
2670 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2671 if ( !aMeshSO->_is_nil() ) {
2672 CORBA::String_var name = aMeshSO->GetName();
2674 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2675 if ( !aStudy->GetProperties()->IsLocked() )
2677 SALOMEDS::GenericAttribute_var anAttr;
2678 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2679 SALOMEDS::AttributeExternalFileDef_var aFileName;
2680 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2681 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2682 ASSERT(!aFileName->_is_nil());
2683 aFileName->SetValue(file);
2684 SALOMEDS::AttributeFileType_var aFileType;
2685 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2686 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2687 ASSERT(!aFileType->_is_nil());
2688 aFileType->SetValue("FICHIERMED");
2692 // Update Python script
2693 // set name of mesh before export
2694 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2696 // check names of groups
2702 //================================================================================
2704 * \brief Export to med file
2706 //================================================================================
2708 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2709 CORBA::Boolean auto_groups,
2710 SMESH::MED_VERSION theVersion,
2711 CORBA::Boolean overwrite)
2712 throw(SALOME::SALOME_Exception)
2714 Unexpect aCatch(SALOME_SalomeException);
2716 _preMeshInfo->FullLoadFromFile();
2718 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2719 TPythonDump() << _this() << ".ExportToMEDX( r'"
2720 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2722 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2725 //================================================================================
2727 * \brief Export a mesh to a med file
2729 //================================================================================
2731 void SMESH_Mesh_i::ExportToMED (const char* file,
2732 CORBA::Boolean auto_groups,
2733 SMESH::MED_VERSION theVersion)
2734 throw(SALOME::SALOME_Exception)
2736 ExportToMEDX(file,auto_groups,theVersion,true);
2739 //================================================================================
2741 * \brief Export a mesh to a med file
2743 //================================================================================
2745 void SMESH_Mesh_i::ExportMED (const char* file,
2746 CORBA::Boolean auto_groups)
2747 throw(SALOME::SALOME_Exception)
2749 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2752 //================================================================================
2754 * \brief Export a mesh to a SAUV file
2756 //================================================================================
2758 void SMESH_Mesh_i::ExportSAUV (const char* file,
2759 CORBA::Boolean auto_groups)
2760 throw(SALOME::SALOME_Exception)
2762 Unexpect aCatch(SALOME_SalomeException);
2764 _preMeshInfo->FullLoadFromFile();
2766 string aMeshName = prepareMeshNameAndGroups(file, true);
2767 TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2768 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2772 //================================================================================
2774 * \brief Export a mesh to a DAT file
2776 //================================================================================
2778 void SMESH_Mesh_i::ExportDAT (const char *file)
2779 throw(SALOME::SALOME_Exception)
2781 Unexpect aCatch(SALOME_SalomeException);
2783 _preMeshInfo->FullLoadFromFile();
2785 // Update Python script
2786 // check names of groups
2788 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2791 PrepareForWriting(file);
2792 _impl->ExportDAT(file);
2795 //================================================================================
2797 * \brief Export a mesh to an UNV file
2799 //================================================================================
2801 void SMESH_Mesh_i::ExportUNV (const char *file)
2802 throw(SALOME::SALOME_Exception)
2804 Unexpect aCatch(SALOME_SalomeException);
2806 _preMeshInfo->FullLoadFromFile();
2808 // Update Python script
2809 // check names of groups
2811 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2814 PrepareForWriting(file);
2815 _impl->ExportUNV(file);
2818 //================================================================================
2820 * \brief Export a mesh to an STL file
2822 //================================================================================
2824 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2825 throw(SALOME::SALOME_Exception)
2827 Unexpect aCatch(SALOME_SalomeException);
2829 _preMeshInfo->FullLoadFromFile();
2831 // Update Python script
2832 // check names of groups
2834 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2837 PrepareForWriting(file);
2838 _impl->ExportSTL(file, isascii);
2841 //=============================================================================
2843 * \brief Class providing SMESHDS_Mesh API to SMESH_IDSource.
2844 * It is used to export a part of mesh as a whole mesh.
2846 class SMESH_MeshPartDS : public SMESHDS_Mesh
2849 SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart);
2851 virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const;
2852 virtual SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const;
2853 virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const;
2854 virtual SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const;
2855 virtual SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const;
2857 virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
2860 TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ];
2861 SMESHDS_Mesh* _meshDS;
2863 * \brief Class used to access to protected data of SMDS_MeshInfo
2865 struct TMeshInfo : public SMDS_MeshInfo
2867 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
2871 //================================================================================
2873 * \brief Export a part of mesh to a med file
2875 //================================================================================
2877 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2879 CORBA::Boolean auto_groups,
2880 ::SMESH::MED_VERSION version,
2881 ::CORBA::Boolean overwrite)
2882 throw (SALOME::SALOME_Exception)
2884 Unexpect aCatch(SALOME_SalomeException);
2886 _preMeshInfo->FullLoadFromFile();
2888 PrepareForWriting(file, overwrite);
2890 string aMeshName = "Mesh";
2891 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2892 if ( !aStudy->_is_nil() ) {
2893 SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2894 if ( !SO->_is_nil() ) {
2895 CORBA::String_var name = SO->GetName();
2899 SMESH_MeshPartDS partDS( meshPart );
2900 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2902 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2903 << auto_groups << ", " << version << ", " << overwrite << " )";
2906 //================================================================================
2908 * \brief Export a part of mesh to a DAT file
2910 //================================================================================
2912 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2914 throw (SALOME::SALOME_Exception)
2916 Unexpect aCatch(SALOME_SalomeException);
2918 _preMeshInfo->FullLoadFromFile();
2920 PrepareForWriting(file);
2922 SMESH_MeshPartDS partDS( meshPart );
2923 _impl->ExportDAT(file,&partDS);
2925 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2927 //================================================================================
2929 * \brief Export a part of mesh to an UNV file
2931 //================================================================================
2933 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2935 throw (SALOME::SALOME_Exception)
2937 Unexpect aCatch(SALOME_SalomeException);
2939 _preMeshInfo->FullLoadFromFile();
2941 PrepareForWriting(file);
2943 SMESH_MeshPartDS partDS( meshPart );
2944 _impl->ExportUNV(file, &partDS);
2946 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2948 //================================================================================
2950 * \brief Export a part of mesh to an STL file
2952 //================================================================================
2954 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2956 ::CORBA::Boolean isascii)
2957 throw (SALOME::SALOME_Exception)
2959 Unexpect aCatch(SALOME_SalomeException);
2961 _preMeshInfo->FullLoadFromFile();
2963 PrepareForWriting(file);
2965 SMESH_MeshPartDS partDS( meshPart );
2966 _impl->ExportSTL(file, isascii, &partDS);
2968 TPythonDump() << _this() << ".ExportPartToSTL( "
2969 << meshPart<< ", r'" << file << "', " << isascii << ")";
2972 //================================================================================
2974 * \brief Export a part of mesh to an STL file
2976 //================================================================================
2978 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2980 CORBA::Boolean overwrite)
2981 throw (SALOME::SALOME_Exception)
2984 Unexpect aCatch(SALOME_SalomeException);
2986 _preMeshInfo->FullLoadFromFile();
2988 PrepareForWriting(file,overwrite);
2990 SMESH_MeshPartDS partDS( meshPart );
2991 _impl->ExportCGNS(file, &partDS);
2993 TPythonDump() << _this() << ".ExportCGNS( "
2994 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2996 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3000 //=============================================================================
3002 * Return implementation of SALOME_MED::MESH interfaces
3004 //=============================================================================
3006 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
3008 Unexpect aCatch(SALOME_SalomeException);
3010 _preMeshInfo->FullLoadFromFile();
3012 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
3013 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
3014 return aMesh._retn();
3017 //=============================================================================
3019 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3021 Unexpect aCatch(SALOME_SalomeException);
3023 return _preMeshInfo->NbNodes();
3025 return _impl->NbNodes();
3028 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3030 Unexpect aCatch(SALOME_SalomeException);
3032 return _preMeshInfo->NbElements();
3034 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
3037 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3039 Unexpect aCatch(SALOME_SalomeException);
3041 return _preMeshInfo->Nb0DElements();
3043 return _impl->Nb0DElements();
3046 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3048 Unexpect aCatch(SALOME_SalomeException);
3050 return _preMeshInfo->NbEdges();
3052 return _impl->NbEdges();
3055 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3056 throw(SALOME::SALOME_Exception)
3058 Unexpect aCatch(SALOME_SalomeException);
3060 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3062 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3065 //=============================================================================
3067 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3069 Unexpect aCatch(SALOME_SalomeException);
3071 return _preMeshInfo->NbFaces();
3073 return _impl->NbFaces();
3076 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3078 Unexpect aCatch(SALOME_SalomeException);
3080 return _preMeshInfo->NbTriangles();
3082 return _impl->NbTriangles();
3085 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3087 Unexpect aCatch(SALOME_SalomeException);
3089 return _preMeshInfo->NbQuadrangles();
3091 return _impl->NbQuadrangles();
3094 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3096 Unexpect aCatch(SALOME_SalomeException);
3098 return _preMeshInfo->NbBiQuadQuadrangles();
3100 return _impl->NbBiQuadQuadrangles();
3103 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3105 Unexpect aCatch(SALOME_SalomeException);
3107 return _preMeshInfo->NbPolygons();
3109 return _impl->NbPolygons();
3112 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3113 throw(SALOME::SALOME_Exception)
3115 Unexpect aCatch(SALOME_SalomeException);
3117 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3119 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3122 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3123 throw(SALOME::SALOME_Exception)
3125 Unexpect aCatch(SALOME_SalomeException);
3127 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3129 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3132 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3133 throw(SALOME::SALOME_Exception)
3135 Unexpect aCatch(SALOME_SalomeException);
3137 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3139 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3142 //=============================================================================
3144 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3146 Unexpect aCatch(SALOME_SalomeException);
3148 return _preMeshInfo->NbVolumes();
3150 return _impl->NbVolumes();
3153 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3155 Unexpect aCatch(SALOME_SalomeException);
3157 return _preMeshInfo->NbTetras();
3159 return _impl->NbTetras();
3162 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3164 Unexpect aCatch(SALOME_SalomeException);
3166 return _preMeshInfo->NbHexas();
3168 return _impl->NbHexas();
3171 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3173 Unexpect aCatch(SALOME_SalomeException);
3175 return _preMeshInfo->NbTriQuadHexas();
3177 return _impl->NbTriQuadraticHexas();
3180 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3182 Unexpect aCatch(SALOME_SalomeException);
3184 return _preMeshInfo->NbPyramids();
3186 return _impl->NbPyramids();
3189 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3191 Unexpect aCatch(SALOME_SalomeException);
3193 return _preMeshInfo->NbPrisms();
3195 return _impl->NbPrisms();
3198 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3200 Unexpect aCatch(SALOME_SalomeException);
3202 return _preMeshInfo->NbHexPrisms();
3204 return _impl->NbHexagonalPrisms();
3207 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3209 Unexpect aCatch(SALOME_SalomeException);
3211 return _preMeshInfo->NbPolyhedrons();
3213 return _impl->NbPolyhedrons();
3216 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3217 throw(SALOME::SALOME_Exception)
3219 Unexpect aCatch(SALOME_SalomeException);
3221 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3223 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3226 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3227 throw(SALOME::SALOME_Exception)
3229 Unexpect aCatch(SALOME_SalomeException);
3231 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3233 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3236 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3237 throw(SALOME::SALOME_Exception)
3239 Unexpect aCatch(SALOME_SalomeException);
3241 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3243 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3246 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3247 throw(SALOME::SALOME_Exception)
3249 Unexpect aCatch(SALOME_SalomeException);
3251 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3253 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3256 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3257 throw(SALOME::SALOME_Exception)
3259 Unexpect aCatch(SALOME_SalomeException);
3261 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3263 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3266 //=============================================================================
3268 * Returns nb of published sub-meshes
3270 //=============================================================================
3272 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3274 Unexpect aCatch(SALOME_SalomeException);
3275 return _mapSubMesh_i.size();
3278 //=============================================================================
3280 * Dumps mesh into a string
3282 //=============================================================================
3284 char* SMESH_Mesh_i::Dump()
3288 return CORBA::string_dup( os.str().c_str() );
3291 //=============================================================================
3293 * Method of SMESH_IDSource interface
3295 //=============================================================================
3297 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3299 return GetElementsId();
3302 //=============================================================================
3304 * Returns ids of all elements
3306 //=============================================================================
3308 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3309 throw (SALOME::SALOME_Exception)
3311 Unexpect aCatch(SALOME_SalomeException);
3313 _preMeshInfo->FullLoadFromFile();
3315 SMESH::long_array_var aResult = new SMESH::long_array();
3316 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3318 if ( aSMESHDS_Mesh == NULL )
3319 return aResult._retn();
3321 long nbElements = NbElements();
3322 aResult->length( nbElements );
3323 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3324 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3325 aResult[i] = anIt->next()->GetID();
3327 return aResult._retn();
3331 //=============================================================================
3333 * Returns ids of all elements of given type
3335 //=============================================================================
3337 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3338 throw (SALOME::SALOME_Exception)
3340 Unexpect aCatch(SALOME_SalomeException);
3342 _preMeshInfo->FullLoadFromFile();
3344 SMESH::long_array_var aResult = new SMESH::long_array();
3345 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3347 if ( aSMESHDS_Mesh == NULL )
3348 return aResult._retn();
3350 long nbElements = NbElements();
3352 // No sense in returning ids of elements along with ids of nodes:
3353 // when theElemType == SMESH::ALL, return node ids only if
3354 // there are no elements
3355 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3356 return GetNodesId();
3358 aResult->length( nbElements );
3362 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3363 while ( i < nbElements && anIt->more() ) {
3364 const SMDS_MeshElement* anElem = anIt->next();
3365 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3366 aResult[i++] = anElem->GetID();
3369 aResult->length( i );
3371 return aResult._retn();
3374 //=============================================================================
3376 * Returns ids of all nodes
3378 //=============================================================================
3380 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3381 throw (SALOME::SALOME_Exception)
3383 Unexpect aCatch(SALOME_SalomeException);
3385 _preMeshInfo->FullLoadFromFile();
3387 SMESH::long_array_var aResult = new SMESH::long_array();
3388 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3390 if ( aSMESHDS_Mesh == NULL )
3391 return aResult._retn();
3393 long nbNodes = NbNodes();
3394 aResult->length( nbNodes );
3395 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3396 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3397 aResult[i] = anIt->next()->GetID();
3399 return aResult._retn();
3402 //=============================================================================
3406 //=============================================================================
3408 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3409 throw (SALOME::SALOME_Exception)
3412 _preMeshInfo->FullLoadFromFile();
3414 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3417 //=============================================================================
3421 //=============================================================================
3423 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3424 throw (SALOME::SALOME_Exception)
3427 _preMeshInfo->FullLoadFromFile();
3429 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3431 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3433 return ( SMESH::EntityType ) e->GetEntityType();
3436 //=============================================================================
3438 * Returns ID of elements for given submesh
3440 //=============================================================================
3441 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3442 throw (SALOME::SALOME_Exception)
3445 _preMeshInfo->FullLoadFromFile();
3447 SMESH::long_array_var aResult = new SMESH::long_array();
3449 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3450 if(!SM) return aResult._retn();
3452 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3453 if(!SDSM) return aResult._retn();
3455 aResult->length(SDSM->NbElements());
3457 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3459 while ( eIt->more() ) {
3460 aResult[i++] = eIt->next()->GetID();
3463 return aResult._retn();
3467 //=============================================================================
3469 * Returns ID of nodes for given submesh
3470 * If param all==true - returns all nodes, else -
3471 * returns only nodes on shapes.
3473 //=============================================================================
3474 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3476 throw (SALOME::SALOME_Exception)
3479 _preMeshInfo->FullLoadFromFile();
3481 SMESH::long_array_var aResult = new SMESH::long_array();
3483 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3484 if(!SM) return aResult._retn();
3486 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3487 if(!SDSM) return aResult._retn();
3490 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3491 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3492 while ( nIt->more() ) {
3493 const SMDS_MeshNode* elem = nIt->next();
3494 theElems.insert( elem->GetID() );
3497 else { // all nodes of submesh elements
3498 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3499 while ( eIt->more() ) {
3500 const SMDS_MeshElement* anElem = eIt->next();
3501 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3502 while ( nIt->more() ) {
3503 const SMDS_MeshElement* elem = nIt->next();
3504 theElems.insert( elem->GetID() );
3509 aResult->length(theElems.size());
3510 set<int>::iterator itElem;
3512 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3513 aResult[i++] = *itElem;
3515 return aResult._retn();
3518 //=============================================================================
3520 * Returns type of elements for given submesh
3522 //=============================================================================
3524 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3525 throw (SALOME::SALOME_Exception)
3528 _preMeshInfo->FullLoadFromFile();
3530 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3531 if(!SM) return SMESH::ALL;
3533 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3534 if(!SDSM) return SMESH::ALL;
3536 if(SDSM->NbElements()==0)
3537 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3539 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3540 const SMDS_MeshElement* anElem = eIt->next();
3541 return ( SMESH::ElementType ) anElem->GetType();
3545 //=============================================================================
3547 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3549 //=============================================================================
3551 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3554 _preMeshInfo->FullLoadFromFile();
3556 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3558 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3563 //=============================================================================
3565 * Get XYZ coordinates of node as list of double
3566 * If there is not node for given ID - returns empty list
3568 //=============================================================================
3570 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3573 _preMeshInfo->FullLoadFromFile();
3575 SMESH::double_array_var aResult = new SMESH::double_array();
3576 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3577 if ( aSMESHDS_Mesh == NULL )
3578 return aResult._retn();
3581 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3583 return aResult._retn();
3587 aResult[0] = aNode->X();
3588 aResult[1] = aNode->Y();
3589 aResult[2] = aNode->Z();
3590 return aResult._retn();
3594 //=============================================================================
3596 * For given node returns list of IDs of inverse elements
3597 * If there is not node for given ID - returns empty list
3599 //=============================================================================
3601 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3604 _preMeshInfo->FullLoadFromFile();
3606 SMESH::long_array_var aResult = new SMESH::long_array();
3607 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3608 if ( aSMESHDS_Mesh == NULL )
3609 return aResult._retn();
3612 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3614 return aResult._retn();
3616 // find inverse elements
3617 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3618 TColStd_SequenceOfInteger IDs;
3619 while(eIt->more()) {
3620 const SMDS_MeshElement* elem = eIt->next();
3621 IDs.Append(elem->GetID());
3623 if(IDs.Length()>0) {
3624 aResult->length(IDs.Length());
3626 for(; i<=IDs.Length(); i++) {
3627 aResult[i-1] = IDs.Value(i);
3630 return aResult._retn();
3633 //=============================================================================
3635 * \brief Return position of a node on shape
3637 //=============================================================================
3639 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3642 _preMeshInfo->FullLoadFromFile();
3644 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3645 aNodePosition->shapeID = 0;
3646 aNodePosition->shapeType = GEOM::SHAPE;
3648 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3649 if ( !mesh ) return aNodePosition;
3651 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3653 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3655 aNodePosition->shapeID = aNode->getshapeId();
3656 switch ( pos->GetTypeOfPosition() ) {
3658 aNodePosition->shapeType = GEOM::EDGE;
3659 aNodePosition->params.length(1);
3660 aNodePosition->params[0] =
3661 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3664 aNodePosition->shapeType = GEOM::FACE;
3665 aNodePosition->params.length(2);
3666 aNodePosition->params[0] =
3667 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3668 aNodePosition->params[1] =
3669 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3671 case SMDS_TOP_VERTEX:
3672 aNodePosition->shapeType = GEOM::VERTEX;
3674 case SMDS_TOP_3DSPACE:
3675 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3676 aNodePosition->shapeType = GEOM::SOLID;
3677 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3678 aNodePosition->shapeType = GEOM::SHELL;
3684 return aNodePosition;
3687 //=============================================================================
3689 * If given element is node returns IDs of shape from position
3690 * If there is not node for given ID - returns -1
3692 //=============================================================================
3694 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3697 _preMeshInfo->FullLoadFromFile();
3699 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3700 if ( aSMESHDS_Mesh == NULL )
3704 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3706 return aNode->getshapeId();
3713 //=============================================================================
3715 * For given element returns ID of result shape after
3716 * ::FindShape() from SMESH_MeshEditor
3717 * If there is not element for given ID - returns -1
3719 //=============================================================================
3721 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3724 _preMeshInfo->FullLoadFromFile();
3726 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3727 if ( aSMESHDS_Mesh == NULL )
3730 // try to find element
3731 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3735 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3736 ::SMESH_MeshEditor aMeshEditor(_impl);
3737 int index = aMeshEditor.FindShape( elem );
3745 //=============================================================================
3747 * Returns number of nodes for given element
3748 * If there is not element for given ID - returns -1
3750 //=============================================================================
3752 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3755 _preMeshInfo->FullLoadFromFile();
3757 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3758 if ( aSMESHDS_Mesh == NULL ) return -1;
3759 // try to find element
3760 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3761 if(!elem) return -1;
3762 return elem->NbNodes();
3766 //=============================================================================
3768 * Returns ID of node by given index for given element
3769 * If there is not element for given ID - returns -1
3770 * If there is not node for given index - returns -2
3772 //=============================================================================
3774 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3777 _preMeshInfo->FullLoadFromFile();
3779 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3780 if ( aSMESHDS_Mesh == NULL ) return -1;
3781 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3782 if(!elem) return -1;
3783 if( index>=elem->NbNodes() || index<0 ) return -1;
3784 return elem->GetNode(index)->GetID();
3787 //=============================================================================
3789 * Returns IDs of nodes of given element
3791 //=============================================================================
3793 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3796 _preMeshInfo->FullLoadFromFile();
3798 SMESH::long_array_var aResult = new SMESH::long_array();
3799 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3801 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3803 aResult->length( elem->NbNodes() );
3804 for ( int i = 0; i < elem->NbNodes(); ++i )
3805 aResult[ i ] = elem->GetNode( i )->GetID();
3808 return aResult._retn();
3811 //=============================================================================
3813 * Returns true if given node is medium node
3814 * in given quadratic element
3816 //=============================================================================
3818 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3821 _preMeshInfo->FullLoadFromFile();
3823 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3824 if ( aSMESHDS_Mesh == NULL ) return false;
3826 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3827 if(!aNode) return false;
3828 // try to find element
3829 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3830 if(!elem) return false;
3832 return elem->IsMediumNode(aNode);
3836 //=============================================================================
3838 * Returns true if given node is medium node
3839 * in one of quadratic elements
3841 //=============================================================================
3843 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3844 SMESH::ElementType theElemType)
3847 _preMeshInfo->FullLoadFromFile();
3849 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3850 if ( aSMESHDS_Mesh == NULL ) return false;
3853 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3854 if(!aNode) return false;
3856 SMESH_MesherHelper aHelper( *(_impl) );
3858 SMDSAbs_ElementType aType;
3859 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3860 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3861 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3862 else aType = SMDSAbs_All;
3864 return aHelper.IsMedium(aNode,aType);
3868 //=============================================================================
3870 * Returns number of edges for given element
3872 //=============================================================================
3874 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3877 _preMeshInfo->FullLoadFromFile();
3879 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3880 if ( aSMESHDS_Mesh == NULL ) return -1;
3881 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3882 if(!elem) return -1;
3883 return elem->NbEdges();
3887 //=============================================================================
3889 * Returns number of faces for given element
3891 //=============================================================================
3893 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3896 _preMeshInfo->FullLoadFromFile();
3898 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3899 if ( aSMESHDS_Mesh == NULL ) return -1;
3900 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3901 if(!elem) return -1;
3902 return elem->NbFaces();
3905 //=======================================================================
3906 //function : GetElemFaceNodes
3907 //purpose : Returns nodes of given face (counted from zero) for given element.
3908 //=======================================================================
3910 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3911 CORBA::Short faceIndex)
3914 _preMeshInfo->FullLoadFromFile();
3916 SMESH::long_array_var aResult = new SMESH::long_array();
3917 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3919 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3921 SMDS_VolumeTool vtool( elem );
3922 if ( faceIndex < vtool.NbFaces() )
3924 aResult->length( vtool.NbFaceNodes( faceIndex ));
3925 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3926 for ( int i = 0; i < aResult->length(); ++i )
3927 aResult[ i ] = nn[ i ]->GetID();
3931 return aResult._retn();
3934 //=======================================================================
3935 //function : FindElementByNodes
3936 //purpose : Returns an element based on all given nodes.
3937 //=======================================================================
3939 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3942 _preMeshInfo->FullLoadFromFile();
3944 CORBA::Long elemID(0);
3945 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3947 vector< const SMDS_MeshNode * > nn( nodes.length() );
3948 for ( int i = 0; i < nodes.length(); ++i )
3949 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3952 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3953 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
3954 _impl->NbFaces ( ORDER_QUADRATIC ) ||
3955 _impl->NbVolumes( ORDER_QUADRATIC )))
3956 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3958 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3963 //=============================================================================
3965 * Returns true if given element is polygon
3967 //=============================================================================
3969 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3972 _preMeshInfo->FullLoadFromFile();
3974 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3975 if ( aSMESHDS_Mesh == NULL ) return false;
3976 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3977 if(!elem) return false;
3978 return elem->IsPoly();
3982 //=============================================================================
3984 * Returns true if given element is quadratic
3986 //=============================================================================
3988 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3991 _preMeshInfo->FullLoadFromFile();
3993 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3994 if ( aSMESHDS_Mesh == NULL ) return false;
3995 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3996 if(!elem) return false;
3997 return elem->IsQuadratic();
4001 //=============================================================================
4003 * Returns bary center for given element
4005 //=============================================================================
4007 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4010 _preMeshInfo->FullLoadFromFile();
4012 SMESH::double_array_var aResult = new SMESH::double_array();
4013 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4014 if ( aSMESHDS_Mesh == NULL )
4015 return aResult._retn();
4017 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4019 return aResult._retn();
4021 if(elem->GetType()==SMDSAbs_Volume) {
4022 SMDS_VolumeTool aTool;
4023 if(aTool.Set(elem)) {
4025 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4030 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4032 double x=0., y=0., z=0.;
4033 for(; anIt->more(); ) {
4035 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4049 return aResult._retn();
4053 //=============================================================================
4055 * Create and publish group servants if any groups were imported or created anyhow
4057 //=============================================================================
4059 void SMESH_Mesh_i::CreateGroupServants()
4061 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
4064 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4065 while ( groupIt->more() )
4067 ::SMESH_Group* group = groupIt->next();
4068 int anId = group->GetGroupDS()->GetID();
4070 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4071 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4073 addedIDs.insert( anId );
4075 SMESH_GroupBase_i* aGroupImpl;
4077 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4078 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4080 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4081 shape = groupOnGeom->GetShape();
4084 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4087 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
4088 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
4089 aGroupImpl->Register();
4091 SMESH::SMESH_GroupBase_var groupVar =
4092 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
4093 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4095 // register CORBA object for persistence
4096 int nextId = _gen_i->RegisterObject( groupVar );
4097 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
4099 // publishing the groups in the study
4100 if ( !aStudy->_is_nil() ) {
4101 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4102 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
4105 if ( !addedIDs.empty() )
4108 set<int>::iterator id = addedIDs.begin();
4109 for ( ; id != addedIDs.end(); ++id )
4111 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4112 int i = std::distance( _mapGroups.begin(), it );
4113 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
4118 //=============================================================================
4120 * \brief Return groups cantained in _mapGroups by their IDs
4122 //=============================================================================
4124 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4126 int nbGroups = groupIDs.size();
4127 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4128 aList->length( nbGroups );
4130 list<int>::const_iterator ids = groupIDs.begin();
4131 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4133 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4134 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4135 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4137 aList->length( nbGroups );
4138 return aList._retn();
4141 //=============================================================================
4143 * \brief Return information about imported file
4145 //=============================================================================
4147 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4149 SALOME_MED::MedFileInfo_var res( _medFileInfo );
4150 if ( !res.operator->() ) {
4151 res = new SALOME_MED::MedFileInfo;
4153 res->fileSize = res->major = res->minor = res->release = -1;
4158 //=============================================================================
4160 * \brief Pass names of mesh groups from study to mesh DS
4162 //=============================================================================
4164 void SMESH_Mesh_i::checkGroupNames()
4166 int nbGrp = NbGroups();
4170 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
4171 if ( aStudy->_is_nil() )
4172 return; // nothing to do
4174 SMESH::ListOfGroups* grpList = 0;
4175 // avoid dump of "GetGroups"
4177 // store python dump into a local variable inside local scope
4178 SMESH::TPythonDump pDump; // do not delete this line of code
4179 grpList = GetGroups();
4182 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4183 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4186 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4187 if ( aGrpSO->_is_nil() )
4189 // correct name of the mesh group if necessary
4190 const char* guiName = aGrpSO->GetName();
4191 if ( strcmp(guiName, aGrp->GetName()) )
4192 aGrp->SetName( guiName );
4196 //=============================================================================
4198 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4200 //=============================================================================
4201 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4203 // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
4204 // CORBA::string_dup(theParameters));
4205 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters);
4208 //=============================================================================
4210 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4212 //=============================================================================
4213 char* SMESH_Mesh_i::GetParameters()
4215 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4216 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
4219 //=============================================================================
4221 * \brief Returns list of notebook variables used for last Mesh operation
4223 //=============================================================================
4224 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4226 SMESH::string_array_var aResult = new SMESH::string_array();
4227 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4229 char *aParameters = GetParameters();
4230 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
4231 if(!aStudy->_is_nil()) {
4232 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4233 if(aSections->length() > 0) {
4234 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4235 aResult->length(aVars.length());
4236 for(int i = 0;i < aVars.length();i++)
4237 aResult[i] = CORBA::string_dup( aVars[i]);
4241 return aResult._retn();
4244 //=======================================================================
4245 //function : GetTypes
4246 //purpose : Returns types of elements it contains
4247 //=======================================================================
4249 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4252 return _preMeshInfo->GetTypes();
4254 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4258 if (_impl->NbEdges())
4259 types[nbTypes++] = SMESH::EDGE;
4260 if (_impl->NbFaces())
4261 types[nbTypes++] = SMESH::FACE;
4262 if (_impl->NbVolumes())
4263 types[nbTypes++] = SMESH::VOLUME;
4264 if (_impl->Nb0DElements())
4265 types[nbTypes++] = SMESH::ELEM0D;
4266 types->length( nbTypes );
4268 return types._retn();
4271 //=======================================================================
4272 //function : GetMesh
4273 //purpose : Returns self
4274 //=======================================================================
4276 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4278 return SMESH::SMESH_Mesh::_duplicate( _this() );
4281 //=======================================================================
4282 //function : IsMeshInfoCorrect
4283 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4284 // * happen if mesh data is not yet fully loaded from the file of study.
4285 //=======================================================================
4287 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4289 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4292 //=============================================================================
4294 * \brief Returns statistic of mesh elements
4296 //=============================================================================
4298 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4301 return _preMeshInfo->GetMeshInfo();
4303 SMESH::long_array_var aRes = new SMESH::long_array();
4304 aRes->length(SMESH::Entity_Last);
4305 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4307 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4309 return aRes._retn();
4310 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4311 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4312 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4313 return aRes._retn();
4316 //=============================================================================
4318 * \brief Collect statistic of mesh elements given by iterator
4320 //=============================================================================
4322 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4323 SMESH::long_array& theInfo)
4325 if (!theItr) return;
4326 while (theItr->more())
4327 theInfo[ theItr->next()->GetEntityType() ]++;
4330 //=============================================================================
4332 * \brief mapping of mesh dimension into shape type
4334 //=============================================================================
4336 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4338 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4340 case 0: aType = TopAbs_VERTEX; break;
4341 case 1: aType = TopAbs_EDGE; break;
4342 case 2: aType = TopAbs_FACE; break;
4344 default:aType = TopAbs_SOLID; break;
4349 //=============================================================================
4351 * \brief Internal structure used to find concurent submeshes
4353 * It represents a pair < submesh, concurent dimension >, where
4354 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4355 * with another submesh. In other words, it is dimension of a hypothesis assigned
4358 //=============================================================================
4364 int _dim; //!< a dimension the algo can build (concurrent dimension)
4365 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4366 TopTools_MapOfShape _shapeMap;
4367 SMESH_subMesh* _subMesh;
4368 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
4371 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4373 const TopoDS_Shape& theShape)
4375 _subMesh = (SMESH_subMesh*)theSubMesh;
4376 SetShape( theDim, theShape );
4380 void SetShape(const int theDim,
4381 const TopoDS_Shape& theShape)
4384 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4385 if (_dim >= _ownDim)
4386 _shapeMap.Add( theShape );
4388 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4389 for( ; anExp.More(); anExp.Next() )
4390 _shapeMap.Add( anExp.Current() );
4394 //! Check sharing of sub-shapes
4395 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4396 const TopTools_MapOfShape& theToFind,
4397 const TopAbs_ShapeEnum theType)
4399 bool isShared = false;
4400 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4401 for (; !isShared && anItr.More(); anItr.Next() )
4403 const TopoDS_Shape aSubSh = anItr.Key();
4404 // check for case when concurrent dimensions are same
4405 isShared = theToFind.Contains( aSubSh );
4406 // check for sub-shape with concurrent dimension
4407 TopExp_Explorer anExp( aSubSh, theType );
4408 for ( ; !isShared && anExp.More(); anExp.Next() )
4409 isShared = theToFind.Contains( anExp.Current() );
4414 //! check algorithms
4415 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4416 const SMESHDS_Hypothesis* theA2)
4418 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4419 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4420 return false; // one of the hypothesis is not algorithm
4421 // check algorithm names (should be equal)
4422 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4426 //! Check if sub-shape hypotheses are concurrent
4427 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4429 if ( _subMesh == theOther->_subMesh )
4430 return false; // same sub-shape - should not be
4432 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4433 // any of the two submeshes is not on COMPOUND shape )
4434 // -> no concurrency
4435 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4436 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4437 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4440 // bool checkSubShape = ( _dim >= theOther->_dim )
4441 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4442 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4443 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4444 if ( !checkSubShape )
4447 // check algorithms to be same
4448 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
4449 return true; // different algorithms
4451 // check hypothesises for concurrence (skip first as algorithm)
4453 // pointers should be same, becase it is referenes from mesh hypothesis partition
4454 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
4455 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
4456 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
4457 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
4459 // the submeshes are concurrent if their algorithms has different parameters
4460 return nbSame != theOther->_hypothesises.size() - 1;
4463 }; // end of SMESH_DimHyp
4465 typedef list<SMESH_DimHyp*> TDimHypList;
4467 static void addDimHypInstance(const int theDim,
4468 const TopoDS_Shape& theShape,
4469 const SMESH_Algo* theAlgo,
4470 const SMESH_subMesh* theSubMesh,
4471 const list <const SMESHDS_Hypothesis*>& theHypList,
4472 TDimHypList* theDimHypListArr )
4474 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4475 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4476 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4477 listOfdimHyp.push_back( dimHyp );
4480 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
4481 dimHyp->_hypothesises.push_front(theAlgo);
4482 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
4483 for( ; hypIt != theHypList.end(); hypIt++ )
4484 dimHyp->_hypothesises.push_back( *hypIt );
4487 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
4488 const TDimHypList& theListOfDimHyp,
4489 TListOfInt& theListOfConcurr )
4491 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4492 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
4493 const SMESH_DimHyp* curDimHyp = *rIt;
4494 if ( curDimHyp == theDimHyp )
4495 break; // meet own dimHyp pointer in same dimension
4496 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
4497 if ( find( theListOfConcurr.begin(),
4498 theListOfConcurr.end(),
4499 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
4500 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
4504 static void unionLists(TListOfInt& theListOfId,
4505 TListOfListOfInt& theListOfListOfId,
4508 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4509 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4511 continue; //skip already treated lists
4512 // check if other list has any same submesh object
4513 TListOfInt& otherListOfId = *it;
4514 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4515 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4518 // union two lists (from source into target)
4519 TListOfInt::iterator it2 = otherListOfId.begin();
4520 for ( ; it2 != otherListOfId.end(); it2++ ) {
4521 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4522 theListOfId.push_back(*it2);
4524 // clear source list
4525 otherListOfId.clear();
4529 //! free memory allocated for dimension-hypothesis objects
4530 static void removeDimHyps( TDimHypList* theArrOfList )
4532 for (int i = 0; i < 4; i++ ) {
4533 TDimHypList& listOfdimHyp = theArrOfList[i];
4534 TDimHypList::const_iterator it = listOfdimHyp.begin();
4535 for ( ; it != listOfdimHyp.end(); it++ )
4540 //=============================================================================
4542 * \brief Return submesh objects list in meshing order
4544 //=============================================================================
4546 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4548 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4550 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4552 return aResult._retn();
4554 ::SMESH_Mesh& mesh = GetImpl();
4555 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4556 if ( !anOrder.size() ) {
4558 // collect submeshes detecting concurrent algorithms and hypothesises
4559 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4561 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4562 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4563 ::SMESH_subMesh* sm = (*i_sm).second;
4565 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4567 // list of assigned hypothesises
4568 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4569 // Find out dimensions where the submesh can be concurrent.
4570 // We define the dimensions by algo of each of hypotheses in hypList
4571 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4572 for( ; hypIt != hypList.end(); hypIt++ ) {
4573 SMESH_Algo* anAlgo = 0;
4574 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4575 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4576 // hyp it-self is algo
4577 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4579 // try to find algorithm with help of sub-shapes
4580 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4581 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4582 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4585 continue; // no assigned algorithm to current submesh
4587 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4588 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
4590 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4591 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4592 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4594 } // end iterations on submesh
4596 // iterate on created dimension-hypotheses and check for concurrents
4597 for ( int i = 0; i < 4; i++ ) {
4598 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
4599 // check for concurrents in own and other dimensions (step-by-step)
4600 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4601 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4602 const SMESH_DimHyp* dimHyp = *dhIt;
4603 TListOfInt listOfConcurr;
4604 // looking for concurrents and collect into own list
4605 for ( int j = i; j < 4; j++ )
4606 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
4607 // check if any concurrents found
4608 if ( listOfConcurr.size() > 0 ) {
4609 // add own submesh to list of concurrent
4610 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
4611 anOrder.push_back( listOfConcurr );
4616 removeDimHyps(dimHypListArr);
4618 // now, minimise the number of concurrent groups
4619 // Here we assume that lists of submeshes can have same submesh
4620 // in case of multi-dimension algorithms, as result
4621 // list with common submesh has to be united into one list
4623 TListOfListOfInt::iterator listIt = anOrder.begin();
4624 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4625 unionLists( *listIt, anOrder, listIndx + 1 );
4627 // convert submesh ids into interface instances
4628 // and dump command into python
4629 convertMeshOrder( anOrder, aResult, false );
4631 return aResult._retn();
4634 //=============================================================================
4636 * \brief find common submeshes with given submesh
4637 * \param theSubMeshList list of already collected submesh to check
4638 * \param theSubMesh given submesh to intersect with other
4639 * \param theCommonSubMeshes collected common submeshes
4641 //=============================================================================
4643 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4644 const SMESH_subMesh* theSubMesh,
4645 set<const SMESH_subMesh*>& theCommon )
4649 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4650 for ( ; it != theSubMeshList.end(); it++ )
4651 theSubMesh->FindIntersection( *it, theCommon );
4652 theSubMeshList.push_back( theSubMesh );
4653 //theCommon.insert( theSubMesh );
4656 //=============================================================================
4658 * \brief Set submesh object order
4659 * \param theSubMeshArray submesh array order
4661 //=============================================================================
4663 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4666 _preMeshInfo->ForgetOrLoad();
4669 ::SMESH_Mesh& mesh = GetImpl();
4671 TPythonDump aPythonDump; // prevent dump of called methods
4672 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4674 TListOfListOfInt subMeshOrder;
4675 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4677 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4678 TListOfInt subMeshIds;
4679 aPythonDump << "[ ";
4680 // Collect subMeshes which should be clear
4681 // do it list-by-list, because modification of submesh order
4682 // take effect between concurrent submeshes only
4683 set<const SMESH_subMesh*> subMeshToClear;
4684 list<const SMESH_subMesh*> subMeshList;
4685 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4687 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4689 aPythonDump << ", ";
4690 aPythonDump << subMesh;
4691 subMeshIds.push_back( subMesh->GetId() );
4692 // detect common parts of submeshes
4693 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4694 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4696 aPythonDump << " ]";
4697 subMeshOrder.push_back( subMeshIds );
4699 // clear collected submeshes
4700 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4701 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
4702 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
4704 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4705 // ClearSubMesh( *clrIt );
4708 aPythonDump << " ])";
4710 mesh.SetMeshOrder( subMeshOrder );
4716 //=============================================================================
4718 * \brief Convert submesh ids into submesh interfaces
4720 //=============================================================================
4722 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4723 SMESH::submesh_array_array& theResOrder,
4724 const bool theIsDump)
4726 int nbSet = theIdsOrder.size();
4727 TPythonDump aPythonDump; // prevent dump of called methods
4729 aPythonDump << "[ ";
4730 theResOrder.length(nbSet);
4731 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4733 for( ; it != theIdsOrder.end(); it++ ) {
4734 // translate submesh identificators into submesh objects
4735 // takeing into account real number of concurrent lists
4736 const TListOfInt& aSubOrder = (*it);
4737 if (!aSubOrder.size())
4740 aPythonDump << "[ ";
4741 // convert shape indeces into interfaces
4742 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4743 aResSubSet->length(aSubOrder.size());
4744 TListOfInt::const_iterator subIt = aSubOrder.begin();
4745 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4746 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4748 SMESH::SMESH_subMesh_var subMesh =
4749 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4752 aPythonDump << ", ";
4753 aPythonDump << subMesh;
4755 aResSubSet[ j++ ] = subMesh;
4758 aPythonDump << " ]";
4759 theResOrder[ listIndx++ ] = aResSubSet;
4761 // correct number of lists
4762 theResOrder.length( listIndx );
4765 // finilise python dump
4766 aPythonDump << " ]";
4767 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4771 //================================================================================
4773 // Implementation of SMESH_MeshPartDS
4775 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4776 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
4778 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4779 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4781 _meshDS = mesh_i->GetImpl().GetMeshDS();
4783 SetPersistentId( _meshDS->GetPersistentId() );
4785 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4787 // <meshPart> is the whole mesh
4788 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4790 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
4791 myGroupSet = _meshDS->GetGroups();
4796 SMESH::long_array_var anIDs = meshPart->GetIDs();
4797 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4798 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4800 for (int i=0; i < anIDs->length(); i++)
4801 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4802 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4807 for (int i=0; i < anIDs->length(); i++)
4808 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4809 if ( _elements[ e->GetType() ].insert( e ).second )
4812 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4813 while ( nIt->more() )
4815 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4816 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4823 _meshDS = 0; // to enforce iteration on _elements and _nodes
4826 // -------------------------------------------------------------------------------------
4827 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
4829 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4830 if ( type == SMDSAbs_All && !_meshDS )
4832 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
4834 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4835 if ( !_elements[i].empty() && i != SMDSAbs_Node )
4837 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
4839 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
4840 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
4842 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
4843 ( new TIter( _elements[type].begin(), _elements[type].end() ));
4845 // -------------------------------------------------------------------------------------
4846 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
4847 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
4849 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
4850 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
4851 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
4853 // -------------------------------------------------------------------------------------
4854 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
4855 _GET_ITER_DEFINE( SMDS_0DElementIteratorPtr, elements0dIterator, SMDS_Mesh0DElement, SMDSAbs_0DElement)
4856 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
4857 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
4858 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
4859 #undef _GET_ITER_DEFINE
4861 // END Implementation of SMESH_MeshPartDS
4863 //================================================================================