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_PythonDump.hxx"
48 #include "SMESH_subMesh_i.hxx"
51 #include <SALOME_NamingService.hxx>
52 #include <Utils_CorbaException.hxx>
53 #include <Utils_ExceptHandlers.hxx>
54 #include <Utils_SINGLETON.hxx>
55 #include <utilities.h>
56 #include <GEOMImpl_Types.hxx>
59 #include <BRep_Builder.hxx>
60 #include <OSD_Directory.hxx>
61 #include <OSD_File.hxx>
62 #include <OSD_Path.hxx>
63 #include <OSD_Protection.hxx>
64 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
65 #include <TColStd_MapOfInteger.hxx>
66 #include <TColStd_SequenceOfInteger.hxx>
67 #include <TCollection_AsciiString.hxx>
69 #include <TopExp_Explorer.hxx>
70 #include <TopoDS_Compound.hxx>
71 #include <TopTools_MapOfShape.hxx>
72 #include <TopTools_MapIteratorOfMapOfShape.hxx>
82 static int MYDEBUG = 0;
84 static int MYDEBUG = 0;
88 using SMESH::TPythonDump;
90 int SMESH_Mesh_i::myIdGenerator = 0;
92 //To disable automatic genericobj management, the following line should be commented.
93 //Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
94 #define WITHGENERICOBJ
96 //=============================================================================
100 //=============================================================================
102 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
104 CORBA::Long studyId )
105 : SALOME::GenericObj_i( thePOA )
107 MESSAGE("SMESH_Mesh_i");
110 _id = myIdGenerator++;
114 //=============================================================================
118 //=============================================================================
120 SMESH_Mesh_i::~SMESH_Mesh_i()
122 MESSAGE("~SMESH_Mesh_i");
124 #ifdef WITHGENERICOBJ
126 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
127 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
128 if ( CORBA::is_nil( itGr->second ))
130 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
132 // this method is called from destructor of group (PAL6331)
133 //_impl->RemoveGroup( aGroup->GetLocalID() );
134 aGroup->myMeshServant = 0;
135 aGroup->UnRegister();
141 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
142 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
143 if ( CORBA::is_nil( itSM->second ))
145 SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
147 aSubMesh->UnRegister();
150 _mapSubMeshIor.clear();
152 // destroy hypotheses
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( CORBA::is_nil( itH->second ))
157 SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
168 //=============================================================================
172 * Associates <this> mesh with <theShape> and puts a reference
173 * to <theShape> into the current study;
174 * the previous shape is substituted by the new one.
176 //=============================================================================
178 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
179 throw (SALOME::SALOME_Exception)
181 Unexpect aCatch(SALOME_SalomeException);
183 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
185 catch(SALOME_Exception & S_ex) {
186 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
188 // to track changes of GEOM groups
189 addGeomGroupData( theShapeObject, _this() );
192 //================================================================================
194 * \brief return true if mesh has a shape to build a shape on
196 //================================================================================
198 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
199 throw (SALOME::SALOME_Exception)
201 Unexpect aCatch(SALOME_SalomeException);
204 res = _impl->HasShapeToMesh();
206 catch(SALOME_Exception & S_ex) {
207 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
212 //=======================================================================
213 //function : GetShapeToMesh
215 //=======================================================================
217 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
218 throw (SALOME::SALOME_Exception)
220 Unexpect aCatch(SALOME_SalomeException);
221 GEOM::GEOM_Object_var aShapeObj;
223 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
225 aShapeObj = _gen_i->ShapeToGeomObject( S );
227 catch(SALOME_Exception & S_ex) {
228 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
230 return aShapeObj._retn();
233 //================================================================================
235 * \brief Remove all nodes and elements
237 //================================================================================
239 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
241 Unexpect aCatch(SALOME_SalomeException);
244 CheckGeomGroupModif(); // issue 20145
246 catch(SALOME_Exception & S_ex) {
247 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
249 TPythonDump() << _this() << ".Clear()";
252 //================================================================================
254 * \brief Remove all nodes and elements for indicated shape
256 //================================================================================
258 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
259 throw (SALOME::SALOME_Exception)
261 Unexpect aCatch(SALOME_SalomeException);
263 _impl->ClearSubMesh( ShapeID );
265 catch(SALOME_Exception & S_ex) {
266 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
270 //=============================================================================
274 //=============================================================================
276 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
278 SMESH::DriverMED_ReadStatus res;
281 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
282 res = SMESH::DRS_OK; break;
283 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
284 res = SMESH::DRS_EMPTY; break;
285 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
286 res = SMESH::DRS_WARN_RENUMBER; break;
287 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
288 res = SMESH::DRS_WARN_SKIP_ELEM; break;
289 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
291 res = SMESH::DRS_FAIL; break;
296 //=============================================================================
300 * Imports mesh data from MED file
302 //=============================================================================
304 SMESH::DriverMED_ReadStatus
305 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
306 throw ( SALOME::SALOME_Exception )
308 Unexpect aCatch(SALOME_SalomeException);
311 status = _impl->MEDToMesh( theFileName, theMeshName );
313 catch( SALOME_Exception& S_ex ) {
314 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
317 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
320 CreateGroupServants();
322 int major, minor, release;
323 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
324 major = minor = release = -1;
325 myFileInfo = new SALOME_MED::MedFileInfo();
326 myFileInfo->fileName = theFileName;
327 myFileInfo->fileSize = 0;
330 if ( ::_stati64( theFileName, &d ) != -1 )
333 if ( ::stat64( theFileName, &d ) != -1 )
335 myFileInfo->fileSize = d.st_size;
336 myFileInfo->major = major;
337 myFileInfo->minor = minor;
338 myFileInfo->release = release;
340 return ConvertDriverMEDReadStatus(status);
343 //================================================================================
345 * \brief Imports mesh data from the CGNS file
347 //================================================================================
349 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
350 const int theMeshIndex,
351 std::string& theMeshName )
352 throw ( SALOME::SALOME_Exception )
354 Unexpect aCatch(SALOME_SalomeException);
357 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
359 catch( SALOME_Exception& S_ex ) {
360 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
363 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
366 CreateGroupServants();
368 return ConvertDriverMEDReadStatus(status);
371 //================================================================================
373 * \brief Return string representation of a MED file version comprising nbDigits
375 //================================================================================
377 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
379 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
381 return CORBA::string_dup( ver.c_str() );
384 //=============================================================================
388 * Imports mesh data from MED file
390 //=============================================================================
392 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
393 throw ( SALOME::SALOME_Exception )
395 // Read mesh with name = <theMeshName> into SMESH_Mesh
396 _impl->UNVToMesh( theFileName );
398 CreateGroupServants();
403 //=============================================================================
407 * Imports mesh data from STL file
409 //=============================================================================
410 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
411 throw ( SALOME::SALOME_Exception )
413 // Read mesh with name = <theMeshName> into SMESH_Mesh
414 _impl->STLToMesh( theFileName );
419 //=============================================================================
423 * Imports mesh data from MED file
425 //=============================================================================
427 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
429 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
430 // int status = _impl->MEDToMesh( theFileName, theMeshName );
431 // CreateGroupServants();
436 //=============================================================================
440 //=============================================================================
442 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
444 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
445 (SMESH_Hypothesis::Hypothesis_Status theStatus)
448 RETURNCASE( HYP_OK );
449 RETURNCASE( HYP_MISSING );
450 RETURNCASE( HYP_CONCURENT );
451 RETURNCASE( HYP_BAD_PARAMETER );
452 RETURNCASE( HYP_HIDDEN_ALGO );
453 RETURNCASE( HYP_HIDING_ALGO );
454 RETURNCASE( HYP_UNKNOWN_FATAL );
455 RETURNCASE( HYP_INCOMPATIBLE );
456 RETURNCASE( HYP_NOTCONFORM );
457 RETURNCASE( HYP_ALREADY_EXIST );
458 RETURNCASE( HYP_BAD_DIM );
459 RETURNCASE( HYP_BAD_SUBSHAPE );
460 RETURNCASE( HYP_BAD_GEOMETRY );
461 RETURNCASE( HYP_NEED_SHAPE );
464 return SMESH::HYP_UNKNOWN_FATAL;
467 //=============================================================================
471 * calls internal addHypothesis() and then adds a reference to <anHyp> under
472 * the SObject actually having a reference to <aSubShape>.
473 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
475 //=============================================================================
477 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
478 SMESH::SMESH_Hypothesis_ptr anHyp)
479 throw(SALOME::SALOME_Exception)
481 Unexpect aCatch(SALOME_SalomeException);
482 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
484 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
485 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
486 aSubShapeObject, anHyp );
488 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
490 // Update Python script
491 if(_impl->HasShapeToMesh()) {
492 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
493 << aSubShapeObject << ", " << anHyp << " )";
496 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
499 return ConvertHypothesisStatus(status);
502 //=============================================================================
506 //=============================================================================
508 SMESH_Hypothesis::Hypothesis_Status
509 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
510 SMESH::SMESH_Hypothesis_ptr anHyp)
512 if(MYDEBUG) MESSAGE("addHypothesis");
514 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
515 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
518 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
519 if (CORBA::is_nil(myHyp))
520 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
523 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
526 TopoDS_Shape myLocSubShape;
527 //use PseudoShape in case if mesh has no shape
529 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
531 myLocSubShape = _impl->GetShapeToMesh();
533 int hypId = myHyp->GetId();
534 status = _impl->AddHypothesis(myLocSubShape, hypId);
535 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
536 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
537 #ifdef WITHGENERICOBJ
538 _mapHypo[hypId]->Register();
540 // assure there is a corresponding submesh
541 if ( !_impl->IsMainShape( myLocSubShape )) {
542 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
543 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
544 createSubMesh( aSubShapeObject );
548 catch(SALOME_Exception & S_ex)
550 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
555 //=============================================================================
559 //=============================================================================
561 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
562 SMESH::SMESH_Hypothesis_ptr anHyp)
563 throw(SALOME::SALOME_Exception)
565 Unexpect aCatch(SALOME_SalomeException);
566 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
568 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
569 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
570 aSubShapeObject, anHyp );
572 // Update Python script
573 // Update Python script
574 if(_impl->HasShapeToMesh()) {
575 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
576 << aSubShapeObject << ", " << anHyp << " )";
579 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
583 return ConvertHypothesisStatus(status);
586 //=============================================================================
590 //=============================================================================
592 SMESH_Hypothesis::Hypothesis_Status
593 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
594 SMESH::SMESH_Hypothesis_ptr anHyp)
596 if(MYDEBUG) MESSAGE("removeHypothesis()");
597 // **** proposer liste de subShape (selection multiple)
599 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
600 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
602 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
603 if (CORBA::is_nil(myHyp))
604 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
606 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
609 TopoDS_Shape myLocSubShape;
610 //use PseudoShape in case if mesh has no shape
612 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
614 myLocSubShape = _impl->GetShapeToMesh();
616 int hypId = myHyp->GetId();
617 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
618 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
619 // _mapHypo.erase( hypId );
621 catch(SALOME_Exception & S_ex)
623 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
628 //=============================================================================
632 //=============================================================================
634 SMESH::ListOfHypothesis *
635 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
636 throw(SALOME::SALOME_Exception)
638 Unexpect aCatch(SALOME_SalomeException);
639 if (MYDEBUG) MESSAGE("GetHypothesisList");
640 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
641 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
643 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
646 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
647 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
648 myLocSubShape = _impl->GetShapeToMesh();
649 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
650 int i = 0, n = aLocalList.size();
653 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
654 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
655 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
656 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
661 catch(SALOME_Exception & S_ex) {
662 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
665 return aList._retn();
668 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
670 Unexpect aCatch(SALOME_SalomeException);
671 if (MYDEBUG) MESSAGE("GetSubMeshes");
673 SMESH::submesh_array_var aList = new SMESH::submesh_array();
676 TPythonDump aPythonDump;
677 if ( !_mapSubMeshIor.empty() )
681 aList->length( _mapSubMeshIor.size() );
683 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
684 for ( ; it != _mapSubMeshIor.end(); it++ ) {
685 if ( CORBA::is_nil( it->second )) continue;
686 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
688 if (i > 1) aPythonDump << ", ";
689 aPythonDump << it->second;
693 catch(SALOME_Exception & S_ex) {
694 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
697 // Update Python script
698 if ( !_mapSubMeshIor.empty() )
699 aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
701 return aList._retn();
704 //=============================================================================
708 //=============================================================================
709 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
710 const char* theName )
711 throw(SALOME::SALOME_Exception)
713 Unexpect aCatch(SALOME_SalomeException);
714 MESSAGE("SMESH_Mesh_i::GetSubMesh");
715 if (CORBA::is_nil(aSubShapeObject))
716 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
719 SMESH::SMESH_subMesh_var subMesh;
720 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
722 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
724 //Get or Create the SMESH_subMesh object implementation
726 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
728 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
730 TopoDS_Iterator it( myLocSubShape );
732 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
734 subMesh = getSubMesh( subMeshId );
736 // create a new subMesh object servant if there is none for the shape
737 if ( subMesh->_is_nil() )
738 subMesh = createSubMesh( aSubShapeObject );
739 if ( _gen_i->CanPublishInStudy( subMesh )) {
740 SALOMEDS::SObject_var aSO =
741 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
742 subMesh, aSubShapeObject, theName );
743 if ( !aSO->_is_nil()) {
744 // Update Python script
745 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
746 << aSubShapeObject << ", '" << theName << "' )";
750 catch(SALOME_Exception & S_ex) {
751 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
753 return subMesh._retn();
756 //=============================================================================
760 //=============================================================================
762 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
763 throw (SALOME::SALOME_Exception)
765 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
766 if ( theSubMesh->_is_nil() )
769 GEOM::GEOM_Object_var aSubShapeObject;
770 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
771 if ( !aStudy->_is_nil() ) {
772 // Remove submesh's SObject
773 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
774 if ( !anSO->_is_nil() ) {
775 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
776 SALOMEDS::SObject_var anObj, aRef;
777 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
778 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
780 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
781 // aSubShapeObject = theSubMesh->GetSubShape();
783 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
785 // Update Python script
786 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
790 removeSubMesh( theSubMesh, aSubShapeObject.in() );
793 //=============================================================================
797 //=============================================================================
799 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
800 const char* theName )
801 throw(SALOME::SALOME_Exception)
803 Unexpect aCatch(SALOME_SalomeException);
804 SMESH::SMESH_Group_var aNewGroup =
805 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
807 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
808 SALOMEDS::SObject_var aSO =
809 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
810 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
811 if ( !aSO->_is_nil()) {
812 // Update Python script
813 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
814 << theElemType << ", '" << theName << "' )";
817 return aNewGroup._retn();
821 //=============================================================================
825 //=============================================================================
826 SMESH::SMESH_GroupOnGeom_ptr
827 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
829 GEOM::GEOM_Object_ptr theGeomObj)
830 throw(SALOME::SALOME_Exception)
832 Unexpect aCatch(SALOME_SalomeException);
833 SMESH::SMESH_GroupOnGeom_var aNewGroup;
835 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
836 if ( !aShape.IsNull() )
838 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
839 ( createGroup( theElemType, theName, aShape ));
841 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
842 SALOMEDS::SObject_var aSO =
843 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
844 aNewGroup, theGeomObj, theName);
845 if ( !aSO->_is_nil()) {
846 // Update Python script
847 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
848 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
853 return aNewGroup._retn();
856 //================================================================================
858 * \brief Creates a group whose contents is defined by filter
859 * \param theElemType - group type
860 * \param theName - group name
861 * \param theFilter - the filter
862 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
864 //================================================================================
866 SMESH::SMESH_GroupOnFilter_ptr
867 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
869 SMESH::Filter_ptr theFilter )
870 throw (SALOME::SALOME_Exception)
872 Unexpect aCatch(SALOME_SalomeException);
874 if ( CORBA::is_nil( theFilter ))
875 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
877 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
879 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
881 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
882 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
885 if ( !aNewGroup->_is_nil() )
886 aNewGroup->SetFilter( theFilter );
888 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
890 SALOMEDS::SObject_var aSO =
891 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
892 GEOM::GEOM_Object::_nil(), theName);
893 if ( !aSO->_is_nil()) {
894 // Update Python script
895 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
896 << theElemType << ", '" << theName << "', " << theFilter << " )";
900 return aNewGroup._retn();
903 //=============================================================================
907 //=============================================================================
909 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
910 throw (SALOME::SALOME_Exception)
912 if ( theGroup->_is_nil() )
915 SMESH_GroupBase_i* aGroup =
916 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
920 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
921 if ( !aStudy->_is_nil() ) {
922 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
924 if ( !aGroupSO->_is_nil() ) {
925 // Update Python script
926 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
928 // Remove group's SObject
929 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
933 // Remove the group from SMESH data structures
934 removeGroup( aGroup->GetLocalID() );
937 //=============================================================================
938 /*! RemoveGroupWithContents
939 * Remove group with its contents
941 //=============================================================================
942 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
943 throw (SALOME::SALOME_Exception)
945 if ( theGroup->_is_nil() )
948 SMESH_GroupBase_i* aGroup =
949 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
953 SMESH::long_array_var anIds = aGroup->GetListOfID();
954 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
956 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
959 if ( aGroup->GetType() == SMESH::NODE )
960 aMeshEditor->RemoveNodes( anIds );
962 aMeshEditor->RemoveElements( anIds );
965 RemoveGroup( theGroup );
967 // Update Python script
968 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
971 //================================================================================
973 * \brief Get the list of groups existing in the mesh
974 * \retval SMESH::ListOfGroups * - list of groups
976 //================================================================================
978 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
980 Unexpect aCatch(SALOME_SalomeException);
981 if (MYDEBUG) MESSAGE("GetGroups");
983 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
986 TPythonDump aPythonDump;
987 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
991 aList->length( _mapGroups.size() );
993 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
994 for ( ; it != _mapGroups.end(); it++ ) {
995 if ( CORBA::is_nil( it->second )) continue;
996 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
998 if (i > 1) aPythonDump << ", ";
999 aPythonDump << it->second;
1003 catch(SALOME_Exception & S_ex) {
1004 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1007 // Update Python script
1008 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1009 aPythonDump << " ] = " << _this() << ".GetGroups()";
1011 return aList._retn();
1014 //=============================================================================
1016 * Get number of groups existing in the mesh
1018 //=============================================================================
1020 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1022 Unexpect aCatch(SALOME_SalomeException);
1023 return _mapGroups.size();
1026 //=============================================================================
1028 * New group is created. All mesh elements that are
1029 * present in initial groups are added to the new one
1031 //=============================================================================
1032 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1033 SMESH::SMESH_GroupBase_ptr theGroup2,
1034 const char* theName )
1035 throw (SALOME::SALOME_Exception)
1039 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1040 theGroup1->GetType() != theGroup2->GetType() )
1041 return SMESH::SMESH_Group::_nil();
1044 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1045 if ( aResGrp->_is_nil() )
1046 return SMESH::SMESH_Group::_nil();
1048 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1049 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1051 TColStd_MapOfInteger aResMap;
1053 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1054 aResMap.Add( anIds1[ i1 ] );
1056 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1057 aResMap.Add( anIds2[ i2 ] );
1059 SMESH::long_array_var aResIds = new SMESH::long_array;
1060 aResIds->length( aResMap.Extent() );
1063 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1064 for( ; anIter.More(); anIter.Next() )
1065 aResIds[ resI++ ] = anIter.Key();
1067 aResGrp->Add( aResIds );
1069 // Clear python lines, created by CreateGroup() and Add()
1070 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1071 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1072 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1074 // Update Python script
1075 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
1076 << theGroup1 << ", " << theGroup2 << ", '"
1077 << theName << "' )";
1079 return aResGrp._retn();
1083 return SMESH::SMESH_Group::_nil();
1087 //=============================================================================
1089 \brief Union list of groups. New group is created. All mesh elements that are
1090 present in initial groups are added to the new one.
1091 \param theGroups list of groups
1092 \param theName name of group to be created
1093 \return pointer on the group
1095 //=============================================================================
1096 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1097 const char* theName )
1098 throw (SALOME::SALOME_Exception)
1101 return SMESH::SMESH_Group::_nil();
1105 vector< int > anIds;
1106 SMESH::ElementType aType = SMESH::ALL;
1107 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1109 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1110 if ( CORBA::is_nil( aGrp ) )
1114 SMESH::ElementType aCurrType = aGrp->GetType();
1115 if ( aType == SMESH::ALL )
1119 if ( aType != aCurrType )
1120 return SMESH::SMESH_Group::_nil();
1124 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1125 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1127 int aCurrId = aCurrIds[ i ];
1128 anIds.push_back( aCurrId );
1133 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1134 if ( aResGrp->_is_nil() )
1135 return SMESH::SMESH_Group::_nil();
1137 // Create array of identifiers
1138 SMESH::long_array_var aResIds = new SMESH::long_array;
1139 aResIds->length( anIds.size() );
1141 //NCollection_Map< int >::Iterator anIter( anIds );
1142 for ( int i = 0; i<anIds.size(); i++ )
1144 aResIds[ i ] = anIds[i];
1146 aResGrp->Add( aResIds );
1148 // Clear python lines, created by CreateGroup() and Add()
1149 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1150 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1151 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1153 // Update Python script
1155 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1156 << &theGroups << ", '" << theName << "' )";
1158 return aResGrp._retn();
1162 return SMESH::SMESH_Group::_nil();
1166 //=============================================================================
1168 * New group is created. All mesh elements that are
1169 * present in both initial groups are added to the new one.
1171 //=============================================================================
1172 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1173 SMESH::SMESH_GroupBase_ptr theGroup2,
1174 const char* theName )
1175 throw (SALOME::SALOME_Exception)
1177 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1178 theGroup1->GetType() != theGroup2->GetType() )
1179 return SMESH::SMESH_Group::_nil();
1181 // Create Intersection
1182 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1183 if ( aResGrp->_is_nil() )
1186 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1187 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1189 TColStd_MapOfInteger aMap1;
1191 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1192 aMap1.Add( anIds1[ i1 ] );
1194 TColStd_SequenceOfInteger aSeq;
1196 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1197 if ( aMap1.Contains( anIds2[ i2 ] ) )
1198 aSeq.Append( anIds2[ i2 ] );
1200 SMESH::long_array_var aResIds = new SMESH::long_array;
1201 aResIds->length( aSeq.Length() );
1203 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1204 aResIds[ resI ] = aSeq( resI + 1 );
1206 aResGrp->Add( aResIds );
1208 // Clear python lines, created by CreateGroup() and Add()
1209 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1210 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1211 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1213 // Update Python script
1214 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1215 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1217 return aResGrp._retn();
1220 //=============================================================================
1222 \brief Intersect list of groups. New group is created. All mesh elements that
1223 are present in all initial groups simultaneously are added to the new one.
1224 \param theGroups list of groups
1225 \param theName name of group to be created
1226 \return pointer on the group
1228 //=============================================================================
1229 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1230 const SMESH::ListOfGroups& theGroups, const char* theName )
1231 throw (SALOME::SALOME_Exception)
1234 return SMESH::SMESH_Group::_nil();
1238 NCollection_DataMap< int, int > anIdToCount;
1239 SMESH::ElementType aType = SMESH::ALL;
1240 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1242 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1243 if ( CORBA::is_nil( aGrp ) )
1247 SMESH::ElementType aCurrType = aGrp->GetType();
1248 if ( aType == SMESH::ALL )
1252 if ( aType != aCurrType )
1253 return SMESH::SMESH_Group::_nil();
1256 // calculates number of occurance ids in groups
1257 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1258 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1260 int aCurrId = aCurrIds[ i ];
1261 if ( !anIdToCount.IsBound( aCurrId ) )
1262 anIdToCount.Bind( aCurrId, 1 );
1264 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1268 // create map of ids
1269 int nbGrp = theGroups.length();
1270 vector< int > anIds;
1271 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1272 for ( ; anIter.More(); anIter.Next() )
1274 int aCurrId = anIter.Key();
1275 int aCurrNb = anIter.Value();
1276 if ( aCurrNb == nbGrp )
1277 anIds.push_back( aCurrId );
1281 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1282 if ( aResGrp->_is_nil() )
1283 return SMESH::SMESH_Group::_nil();
1285 // Create array of identifiers
1286 SMESH::long_array_var aResIds = new SMESH::long_array;
1287 aResIds->length( anIds.size() );
1289 //NCollection_Map< int >::Iterator aListIter( anIds );
1290 for ( int i = 0; i<anIds.size(); i++ )
1292 aResIds[ i ] = anIds[i];
1294 aResGrp->Add( aResIds );
1296 // Clear python lines, created by CreateGroup() and Add()
1297 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1298 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1299 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1301 // Update Python script
1303 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1304 << &theGroups << ", '" << theName << "' )";
1306 return aResGrp._retn();
1310 return SMESH::SMESH_Group::_nil();
1314 //=============================================================================
1316 * New group is created. All mesh elements that are present in
1317 * main group but do not present in tool group are added to the new one
1319 //=============================================================================
1320 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1321 SMESH::SMESH_GroupBase_ptr theGroup2,
1322 const char* theName )
1323 throw (SALOME::SALOME_Exception)
1325 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1326 theGroup1->GetType() != theGroup2->GetType() )
1327 return SMESH::SMESH_Group::_nil();
1330 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1331 if ( aResGrp->_is_nil() )
1334 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1335 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1337 TColStd_MapOfInteger aMap2;
1339 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1340 aMap2.Add( anIds2[ i2 ] );
1342 TColStd_SequenceOfInteger aSeq;
1343 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1344 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1345 aSeq.Append( anIds1[ i1 ] );
1347 SMESH::long_array_var aResIds = new SMESH::long_array;
1348 aResIds->length( aSeq.Length() );
1350 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1351 aResIds[ resI ] = aSeq( resI + 1 );
1353 aResGrp->Add( aResIds );
1355 // Clear python lines, created by CreateGroup() and Add()
1356 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1357 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1358 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1360 // Update Python script
1361 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1362 << theGroup1 << ", " << theGroup2 << ", '"
1363 << theName << "' )";
1365 return aResGrp._retn();
1368 //=============================================================================
1370 \brief Cut lists of groups. New group is created. All mesh elements that are
1371 present in main groups but do not present in tool groups are added to the new one
1372 \param theMainGroups list of main groups
1373 \param theToolGroups list of tool groups
1374 \param theName name of group to be created
1375 \return pointer on the group
1377 //=============================================================================
1378 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1379 const SMESH::ListOfGroups& theMainGroups,
1380 const SMESH::ListOfGroups& theToolGroups,
1381 const char* theName )
1382 throw (SALOME::SALOME_Exception)
1385 return SMESH::SMESH_Group::_nil();
1389 set< int > aToolIds;
1390 SMESH::ElementType aType = SMESH::ALL;
1392 // iterate through tool groups
1393 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1395 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1396 if ( CORBA::is_nil( aGrp ) )
1400 SMESH::ElementType aCurrType = aGrp->GetType();
1401 if ( aType == SMESH::ALL )
1405 if ( aType != aCurrType )
1406 return SMESH::SMESH_Group::_nil();
1410 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1411 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1413 int aCurrId = aCurrIds[ i ];
1414 aToolIds.insert( aCurrId );
1418 vector< int > anIds; // result
1420 // Iterate through main group
1421 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1423 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1424 if ( CORBA::is_nil( aGrp ) )
1428 SMESH::ElementType aCurrType = aGrp->GetType();
1429 if ( aType == SMESH::ALL )
1433 if ( aType != aCurrType )
1434 return SMESH::SMESH_Group::_nil();
1438 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1439 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1441 int aCurrId = aCurrIds[ i ];
1442 if ( !aToolIds.count( aCurrId ) )
1443 anIds.push_back( aCurrId );
1448 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1449 if ( aResGrp->_is_nil() )
1450 return SMESH::SMESH_Group::_nil();
1452 // Create array of identifiers
1453 SMESH::long_array_var aResIds = new SMESH::long_array;
1454 aResIds->length( anIds.size() );
1456 for (int i=0; i<anIds.size(); i++ )
1458 aResIds[ i ] = anIds[i];
1460 aResGrp->Add( aResIds );
1462 // Clear python lines, created by CreateGroup() and Add()
1463 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1464 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1465 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1467 // Update Python script
1469 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1470 << &theMainGroups << ", " << &theToolGroups << ", '"
1471 << theName << "' )";
1473 return aResGrp._retn();
1477 return SMESH::SMESH_Group::_nil();
1481 //=============================================================================
1483 \brief Create groups of entities from existing groups of superior dimensions
1485 1) extract all nodes from each group,
1486 2) combine all elements of specified dimension laying on these nodes.
1487 \param theGroups list of source groups
1488 \param theElemType dimension of elements
1489 \param theName name of new group
1490 \return pointer on new group
1492 //=============================================================================
1493 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1494 const SMESH::ListOfGroups& theGroups,
1495 SMESH::ElementType theElemType,
1496 const char* theName )
1497 throw (SALOME::SALOME_Exception)
1499 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1501 if ( !theName || !aMeshDS )
1502 return SMESH::SMESH_Group::_nil();
1504 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1508 // Create map of nodes from all groups
1510 set< int > aNodeMap;
1512 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1514 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1515 if ( CORBA::is_nil( aGrp ) )
1518 SMESH::ElementType aType = aGrp->GetType();
1519 if ( aType == SMESH::ALL )
1521 else if ( aType == SMESH::NODE )
1523 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1524 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1526 int aCurrId = aCurrIds[ i ];
1527 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1529 aNodeMap.insert( aNode->GetID() );
1534 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1535 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1537 int aCurrId = aCurrIds[ i ];
1538 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1541 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1542 while( aNodeIter->more() )
1544 const SMDS_MeshNode* aNode =
1545 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1547 aNodeMap.insert( aNode->GetID() );
1553 // Get result identifiers
1555 vector< int > aResultIds;
1556 if ( theElemType == SMESH::NODE )
1558 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1559 set<int>::iterator iter = aNodeMap.begin();
1560 for ( ; iter != aNodeMap.end(); iter++ )
1561 aResultIds.push_back( *iter);
1565 // Create list of elements of given dimension constructed on the nodes
1566 vector< int > anElemList;
1567 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1568 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1569 set<int>::iterator iter = aNodeMap.begin();
1570 for ( ; iter != aNodeMap.end(); iter++ )
1572 const SMDS_MeshElement* aNode =
1573 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1577 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1578 while( anElemIter->more() )
1580 const SMDS_MeshElement* anElem =
1581 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1582 if ( anElem && anElem->GetType() == anElemType )
1583 anElemList.push_back( anElem->GetID() );
1587 // check whether all nodes of elements are present in nodes map
1588 //NCollection_Map< int >::Iterator anIter( anElemList );
1589 //for ( ; anIter.More(); anIter.Next() )
1590 for (int i=0; i< anElemList.size(); i++)
1592 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1597 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1598 while( aNodeIter->more() )
1600 const SMDS_MeshNode* aNode =
1601 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1602 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1609 aResultIds.push_back( anElem->GetID() );
1615 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1616 if ( aResGrp->_is_nil() )
1617 return SMESH::SMESH_Group::_nil();
1619 // Create array of identifiers
1620 SMESH::long_array_var aResIds = new SMESH::long_array;
1621 aResIds->length( aResultIds.size() );
1623 //NCollection_Map< int >::Iterator aResIter( aResultIds );
1624 //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1625 for (int i=0; i< aResultIds.size(); i++)
1626 aResIds[ i ] = aResultIds[i];
1627 aResGrp->Add( aResIds );
1629 // Remove strings corresponding to group creation
1630 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1631 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1632 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1634 // Update Python script
1636 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1637 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1639 return aResGrp._retn();
1643 return SMESH::SMESH_Group::_nil();
1647 //================================================================================
1649 * \brief Remember GEOM group data
1651 //================================================================================
1653 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1654 CORBA::Object_ptr theSmeshObj)
1656 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1659 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1660 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1661 if ( groupSO->_is_nil() )
1664 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1665 GEOM::GEOM_IGroupOperations_var groupOp =
1666 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1667 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1670 _geomGroupData.push_back( TGeomGroupData() );
1671 TGeomGroupData & groupData = _geomGroupData.back();
1673 CORBA::String_var entry = groupSO->GetID();
1674 groupData._groupEntry = entry.in();
1676 for ( int i = 0; i < ids->length(); ++i )
1677 groupData._indices.insert( ids[i] );
1679 groupData._smeshObject = theSmeshObj;
1682 //================================================================================
1684 * Remove GEOM group data relating to removed smesh object
1686 //================================================================================
1688 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1690 list<TGeomGroupData>::iterator
1691 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1692 for ( ; data != dataEnd; ++data ) {
1693 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1694 _geomGroupData.erase( data );
1700 //================================================================================
1702 * \brief Return new group contents if it has been changed and update group data
1704 //================================================================================
1706 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1708 TopoDS_Shape newShape;
1711 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1712 if ( study->_is_nil() ) return newShape; // means "not changed"
1713 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1714 if ( !groupSO->_is_nil() )
1716 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1717 if ( CORBA::is_nil( groupObj )) return newShape;
1718 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1720 // get indices of group items
1721 set<int> curIndices;
1722 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1723 GEOM::GEOM_IGroupOperations_var groupOp =
1724 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1725 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1726 for ( int i = 0; i < ids->length(); ++i )
1727 curIndices.insert( ids[i] );
1729 if ( groupData._indices == curIndices )
1730 return newShape; // group not changed
1733 groupData._indices = curIndices;
1735 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1736 if ( !geomClient ) return newShape;
1737 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1738 geomClient->RemoveShapeFromBuffer( groupIOR );
1739 newShape = _gen_i->GeomObjectToShape( geomGroup );
1742 if ( newShape.IsNull() ) {
1743 // geom group becomes empty - return empty compound
1744 TopoDS_Compound compound;
1745 BRep_Builder().MakeCompound(compound);
1746 newShape = compound;
1752 //=============================================================================
1754 * \brief Storage of shape and index used in CheckGeomGroupModif()
1756 //=============================================================================
1757 struct TIndexedShape {
1759 TopoDS_Shape _shape;
1760 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1763 //=============================================================================
1765 * \brief Update objects depending on changed geom groups
1767 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1768 * issue 0020210: Update of a smesh group after modification of the associated geom group
1770 //=============================================================================
1772 void SMESH_Mesh_i::CheckGeomGroupModif()
1774 if ( !_impl->HasShapeToMesh() ) return;
1776 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1777 if ( study->_is_nil() ) return;
1779 CORBA::Long nbEntities = NbNodes() + NbElements();
1781 // Check if group contents changed
1783 typedef map< string, TopoDS_Shape > TEntry2Geom;
1784 TEntry2Geom newGroupContents;
1786 list<TGeomGroupData>::iterator
1787 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1788 for ( ; data != dataEnd; ++data )
1790 pair< TEntry2Geom::iterator, bool > it_new =
1791 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1792 bool processedGroup = !it_new.second;
1793 TopoDS_Shape& newShape = it_new.first->second;
1794 if ( !processedGroup )
1795 newShape = newGroupShape( *data );
1796 if ( newShape.IsNull() )
1797 continue; // no changes
1799 if ( processedGroup ) { // update group indices
1800 list<TGeomGroupData>::iterator data2 = data;
1801 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1802 data->_indices = data2->_indices;
1805 // Update SMESH objects according to new GEOM group contents
1807 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1808 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1810 int oldID = submesh->GetId();
1811 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1813 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1815 // update hypotheses
1816 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1817 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1818 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1820 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1821 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1823 // care of submeshes
1824 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1825 int newID = newSubmesh->GetId();
1826 if ( newID != oldID ) {
1827 _mapSubMesh [ newID ] = newSubmesh;
1828 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1829 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1830 _mapSubMesh. erase(oldID);
1831 _mapSubMesh_i. erase(oldID);
1832 _mapSubMeshIor.erase(oldID);
1833 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1838 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1839 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1840 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1842 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1844 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1845 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1846 ds->SetShape( newShape );
1851 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1852 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1854 // Remove groups and submeshes basing on removed sub-shapes
1856 TopTools_MapOfShape newShapeMap;
1857 TopoDS_Iterator shapeIt( newShape );
1858 for ( ; shapeIt.More(); shapeIt.Next() )
1859 newShapeMap.Add( shapeIt.Value() );
1861 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1862 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1864 if ( newShapeMap.Contains( shapeIt.Value() ))
1866 TopTools_IndexedMapOfShape oldShapeMap;
1867 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1868 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1870 const TopoDS_Shape& oldShape = oldShapeMap(i);
1871 int oldInd = meshDS->ShapeToIndex( oldShape );
1873 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1874 if ( i_smIor != _mapSubMeshIor.end() ) {
1875 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1878 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1879 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1881 // check if a group bases on oldInd shape
1882 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1883 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1884 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1885 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1887 RemoveGroup( i_grp->second ); // several groups can base on same shape
1888 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1893 // Reassign hypotheses and update groups after setting the new shape to mesh
1895 // collect anassigned hypotheses
1896 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1897 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1898 TShapeHypList assignedHyps;
1899 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1901 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1902 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1903 if ( !hyps.empty() ) {
1904 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1905 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1906 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1909 // collect shapes supporting groups
1910 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1911 TShapeTypeList groupData;
1912 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1913 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1914 for ( ; grIt != groups.end(); ++grIt )
1916 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1918 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1920 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1921 _impl->ShapeToMesh( newShape );
1923 // reassign hypotheses
1924 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1925 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1927 TIndexedShape& geom = indS_hyps->first;
1928 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1929 int oldID = geom._index;
1930 int newID = meshDS->ShapeToIndex( geom._shape );
1933 if ( oldID == 1 ) { // main shape
1935 geom._shape = newShape;
1937 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1938 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1939 // care of submeshes
1940 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1941 if ( newID != oldID ) {
1942 _mapSubMesh [ newID ] = newSubmesh;
1943 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1944 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1945 _mapSubMesh. erase(oldID);
1946 _mapSubMesh_i. erase(oldID);
1947 _mapSubMeshIor.erase(oldID);
1948 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1952 TShapeTypeList::iterator geomType = groupData.begin();
1953 for ( ; geomType != groupData.end(); ++geomType )
1955 const TIndexedShape& geom = geomType->first;
1956 int oldID = geom._index;
1957 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1960 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1961 CORBA::String_var name = groupSO->GetName();
1963 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1965 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1966 group_i->changeLocalId( newID );
1969 break; // everything has been updated
1972 } // loop on group data
1976 CORBA::Long newNbEntities = NbNodes() + NbElements();
1977 list< SALOMEDS::SObject_var > soToUpdateIcons;
1978 if ( newNbEntities != nbEntities )
1980 // Add all SObjects with icons
1981 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1983 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1984 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1985 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1987 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1988 i_gr != _mapGroups.end(); ++i_gr ) // groups
1989 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1992 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1993 for ( ; so != soToUpdateIcons.end(); ++so )
1994 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1997 //=============================================================================
1999 * \brief Create standalone group from a group on geometry or filter
2001 //=============================================================================
2003 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2005 SMESH::SMESH_Group_var aGroup;
2006 if ( theGroup->_is_nil() )
2007 return aGroup._retn();
2009 Unexpect aCatch(SALOME_SalomeException);
2011 SMESH_GroupBase_i* aGroupToRem =
2012 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2014 return aGroup._retn();
2016 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2018 int anId = aGroupToRem->GetLocalID();
2019 if ( !_impl->ConvertToStandalone( anId ) )
2020 return aGroup._retn();
2021 removeGeomGroupData( theGroup );
2023 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2025 // remove old instance of group from own map
2026 _mapGroups.erase( anId );
2028 SALOMEDS::StudyBuilder_var builder;
2029 SALOMEDS::SObject_var aGroupSO;
2030 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2031 if ( !aStudy->_is_nil() ) {
2032 builder = aStudy->NewBuilder();
2033 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2034 if ( !aGroupSO->_is_nil() ) {
2036 // remove reference to geometry
2037 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
2038 for ( ; chItr->More(); chItr->Next() )
2039 // Remove group's child SObject
2040 builder->RemoveObject( chItr->Value() );
2042 // Update Python script
2043 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2044 << aGroupSO << " )";
2046 // change icon of Group on Filter
2049 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2050 const int isEmpty = ( elemTypes->length() == 0 );
2053 SALOMEDS::GenericAttribute_var anAttr =
2054 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2055 SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
2056 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2062 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2063 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2064 aGroupImpl->Register();
2065 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2067 // remember new group in own map
2068 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2069 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2071 // register CORBA object for persistence
2072 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
2074 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
2076 return aGroup._retn();
2079 //=============================================================================
2083 //=============================================================================
2085 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2087 if(MYDEBUG) MESSAGE( "createSubMesh" );
2088 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2090 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2091 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2092 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2093 SMESH::SMESH_subMesh_var subMesh
2094 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2096 _mapSubMesh[subMeshId] = mySubMesh;
2097 _mapSubMesh_i[subMeshId] = subMeshServant;
2098 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2100 // register CORBA object for persistence
2101 int nextId = _gen_i->RegisterObject( subMesh );
2102 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2104 // to track changes of GEOM groups
2105 addGeomGroupData( theSubShapeObject, subMesh );
2107 return subMesh._retn();
2110 //=======================================================================
2111 //function : getSubMesh
2113 //=======================================================================
2115 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2117 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2118 if ( it == _mapSubMeshIor.end() )
2119 return SMESH::SMESH_subMesh::_nil();
2121 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2125 //=============================================================================
2129 //=============================================================================
2131 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2132 GEOM::GEOM_Object_ptr theSubShapeObject )
2134 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2135 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2138 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2140 CORBA::Long shapeId = theSubMesh->GetId();
2141 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2143 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2146 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2147 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2148 for ( ; hyp != hyps.end(); ++hyp )
2149 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2156 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2157 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2158 removeHypothesis( theSubShapeObject, aHypList[i] );
2161 catch( const SALOME::SALOME_Exception& ) {
2162 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2164 removeGeomGroupData( theSubShapeObject );
2166 int subMeshId = theSubMesh->GetId();
2168 _mapSubMesh.erase(subMeshId);
2169 _mapSubMesh_i.erase(subMeshId);
2170 _mapSubMeshIor.erase(subMeshId);
2171 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2174 //=============================================================================
2178 //=============================================================================
2180 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2181 const char* theName,
2182 const TopoDS_Shape& theShape,
2183 const SMESH_PredicatePtr& thePredicate )
2185 std::string newName;
2186 if ( !theName || strlen( theName ) == 0 )
2188 std::set< std::string > presentNames;
2189 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2190 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2191 presentNames.insert( i_gr->second->GetName() );
2193 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2194 } while ( !presentNames.insert( newName ).second );
2195 theName = newName.c_str();
2198 SMESH::SMESH_GroupBase_var aGroup;
2199 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2201 SMESH_GroupBase_i* aGroupImpl;
2202 if ( !theShape.IsNull() )
2203 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2204 else if ( thePredicate )
2205 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2207 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2209 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2210 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2211 aGroupImpl->Register();
2212 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2214 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2215 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2217 // register CORBA object for persistence
2218 int nextId = _gen_i->RegisterObject( aGroup );
2219 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2221 // to track changes of GEOM groups
2222 if ( !theShape.IsNull() ) {
2223 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2224 addGeomGroupData( geom, aGroup );
2227 return aGroup._retn();
2230 //=============================================================================
2232 * SMESH_Mesh_i::removeGroup
2234 * Should be called by ~SMESH_Group_i()
2236 //=============================================================================
2238 void SMESH_Mesh_i::removeGroup( const int theId )
2240 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2241 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2242 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2243 _mapGroups.erase( theId );
2244 removeGeomGroupData( group );
2245 if (! _impl->RemoveGroup( theId ))
2247 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2248 RemoveGroup( group );
2253 //=============================================================================
2257 //=============================================================================
2259 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2260 throw(SALOME::SALOME_Exception)
2262 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2264 SMESH::log_array_var aLog;
2266 list < SMESHDS_Command * >logDS = _impl->GetLog();
2267 aLog = new SMESH::log_array;
2269 int lg = logDS.size();
2272 list < SMESHDS_Command * >::iterator its = logDS.begin();
2273 while(its != logDS.end()){
2274 SMESHDS_Command *com = *its;
2275 int comType = com->GetType();
2277 int lgcom = com->GetNumber();
2279 const list < int >&intList = com->GetIndexes();
2280 int inum = intList.size();
2282 list < int >::const_iterator ii = intList.begin();
2283 const list < double >&coordList = com->GetCoords();
2284 int rnum = coordList.size();
2286 list < double >::const_iterator ir = coordList.begin();
2287 aLog[indexLog].commandType = comType;
2288 aLog[indexLog].number = lgcom;
2289 aLog[indexLog].coords.length(rnum);
2290 aLog[indexLog].indexes.length(inum);
2291 for(int i = 0; i < rnum; i++){
2292 aLog[indexLog].coords[i] = *ir;
2293 //MESSAGE(" "<<i<<" "<<ir.Value());
2296 for(int i = 0; i < inum; i++){
2297 aLog[indexLog].indexes[i] = *ii;
2298 //MESSAGE(" "<<i<<" "<<ii.Value());
2307 catch(SALOME_Exception & S_ex){
2308 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2310 return aLog._retn();
2314 //=============================================================================
2318 //=============================================================================
2320 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2322 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2326 //=============================================================================
2330 //=============================================================================
2332 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2334 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2338 //=============================================================================
2342 //=============================================================================
2344 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2349 //=============================================================================
2352 //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from
2353 // SMESH_Mesh::RemoveGroup() (issue 0020918)
2354 struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp
2356 SMESH_Mesh_i* _mesh;
2357 TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2358 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2362 //=============================================================================
2366 //=============================================================================
2368 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2370 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2373 _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this));
2376 //=============================================================================
2380 //=============================================================================
2382 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2384 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2388 //=============================================================================
2390 * Return mesh editor
2392 //=============================================================================
2394 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2396 // Create MeshEditor
2397 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2398 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2400 // Update Python script
2401 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2403 return aMesh._retn();
2406 //=============================================================================
2408 * Return mesh edition previewer
2410 //=============================================================================
2412 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2414 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2415 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2416 return aMesh._retn();
2419 //================================================================================
2421 * \brief Return true if the mesh has been edited since a last total re-compute
2422 * and those modifications may prevent successful partial re-compute
2424 //================================================================================
2426 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2428 Unexpect aCatch(SALOME_SalomeException);
2429 return _impl->HasModificationsToDiscard();
2432 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2434 const int MAX_ATTEMPTS = 100;
2436 double tolerance = 0.5;
2437 SALOMEDS::Color col;
2441 // generate random color
2442 double red = (double)rand() / RAND_MAX;
2443 double green = (double)rand() / RAND_MAX;
2444 double blue = (double)rand() / RAND_MAX;
2445 // check existence in the list of the existing colors
2446 bool matched = false;
2447 std::list<SALOMEDS::Color>::const_iterator it;
2448 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2449 SALOMEDS::Color color = *it;
2450 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2451 matched = tol < tolerance;
2453 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2454 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2462 //=============================================================================
2466 //=============================================================================
2467 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2469 Unexpect aCatch(SALOME_SalomeException);
2470 _impl->SetAutoColor(theAutoColor);
2472 TPythonDump pyDump; // not to dump group->SetColor() from below code
2473 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2475 std::list<SALOMEDS::Color> aReservedColors;
2476 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2477 for ( ; it != _mapGroups.end(); it++ ) {
2478 if ( CORBA::is_nil( it->second )) continue;
2479 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2480 it->second->SetColor( aColor );
2481 aReservedColors.push_back( aColor );
2485 //=============================================================================
2489 //=============================================================================
2490 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2492 Unexpect aCatch(SALOME_SalomeException);
2493 return _impl->GetAutoColor();
2497 //=============================================================================
2499 * Export in different formats
2501 //=============================================================================
2503 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2505 return _impl->HasDuplicatedGroupNamesMED();
2508 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2510 TCollection_AsciiString aFullName ((char*)file);
2511 OSD_Path aPath (aFullName);
2512 OSD_File aFile (aPath);
2513 if (aFile.Exists()) {
2514 // existing filesystem node
2515 if (aFile.KindOfFile() == OSD_FILE) {
2516 if (aFile.IsWriteable()) {
2521 if (aFile.Failed()) {
2522 TCollection_AsciiString msg ("File ");
2523 msg += aFullName + " cannot be replaced.";
2524 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2527 TCollection_AsciiString msg ("File ");
2528 msg += aFullName + " cannot be overwritten.";
2529 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2532 TCollection_AsciiString msg ("Location ");
2533 msg += aFullName + " is not a file.";
2534 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2537 // nonexisting file; check if it can be created
2539 aFile.Build(OSD_WriteOnly, OSD_Protection());
2540 if (aFile.Failed()) {
2541 TCollection_AsciiString msg ("You cannot create the file ");
2542 msg += aFullName + ". Check the directory existance and access rights.";
2543 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2551 string SMESH_Mesh_i::PrepareMeshNameAndGroups(const char* file,
2552 CORBA::Boolean overwrite)
2555 PrepareForWriting(file, overwrite);
2556 string aMeshName = "Mesh";
2557 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2558 if ( !aStudy->_is_nil() ) {
2559 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2560 if ( !aMeshSO->_is_nil() ) {
2561 CORBA::String_var name = aMeshSO->GetName();
2563 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2564 if ( !aStudy->GetProperties()->IsLocked() )
2566 SALOMEDS::GenericAttribute_var anAttr;
2567 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2568 SALOMEDS::AttributeExternalFileDef_var aFileName;
2569 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2570 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2571 ASSERT(!aFileName->_is_nil());
2572 aFileName->SetValue(file);
2573 SALOMEDS::AttributeFileType_var aFileType;
2574 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2575 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2576 ASSERT(!aFileType->_is_nil());
2577 aFileType->SetValue("FICHIERMED");
2581 // Update Python script
2582 // set name of mesh before export
2583 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2585 // check names of groups
2591 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2592 CORBA::Boolean auto_groups,
2593 SMESH::MED_VERSION theVersion,
2594 CORBA::Boolean overwrite)
2595 throw(SALOME::SALOME_Exception)
2597 Unexpect aCatch(SALOME_SalomeException);
2598 string aMeshName = PrepareMeshNameAndGroups(file, overwrite);
2599 TPythonDump() << _this() << ".ExportToMEDX( r'"
2600 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2602 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2605 //================================================================================
2607 * \brief Export a mesh to a med file
2609 //================================================================================
2611 void SMESH_Mesh_i::ExportToMED (const char* file,
2612 CORBA::Boolean auto_groups,
2613 SMESH::MED_VERSION theVersion)
2614 throw(SALOME::SALOME_Exception)
2616 ExportToMEDX(file,auto_groups,theVersion,true);
2619 //================================================================================
2621 * \brief Export a mesh to a med file
2623 //================================================================================
2625 void SMESH_Mesh_i::ExportMED (const char* file,
2626 CORBA::Boolean auto_groups)
2627 throw(SALOME::SALOME_Exception)
2629 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2632 //================================================================================
2634 * \brief Export a mesh to a SAUV file
2636 //================================================================================
2638 void SMESH_Mesh_i::ExportSAUV (const char* file,
2639 CORBA::Boolean auto_groups)
2640 throw(SALOME::SALOME_Exception)
2642 Unexpect aCatch(SALOME_SalomeException);
2643 string aMeshName = PrepareMeshNameAndGroups(file, true);
2644 TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2645 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2649 //================================================================================
2651 * \brief Export a mesh to a DAT file
2653 //================================================================================
2655 void SMESH_Mesh_i::ExportDAT (const char *file)
2656 throw(SALOME::SALOME_Exception)
2658 Unexpect aCatch(SALOME_SalomeException);
2660 // Update Python script
2661 // check names of groups
2663 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2666 PrepareForWriting(file);
2667 _impl->ExportDAT(file);
2670 //================================================================================
2672 * \brief Export a mesh to an UNV file
2674 //================================================================================
2676 void SMESH_Mesh_i::ExportUNV (const char *file)
2677 throw(SALOME::SALOME_Exception)
2679 Unexpect aCatch(SALOME_SalomeException);
2681 // Update Python script
2682 // check names of groups
2684 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2687 PrepareForWriting(file);
2688 _impl->ExportUNV(file);
2691 //================================================================================
2693 * \brief Export a mesh to an STL file
2695 //================================================================================
2697 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2698 throw(SALOME::SALOME_Exception)
2700 Unexpect aCatch(SALOME_SalomeException);
2702 // Update Python script
2703 // check names of groups
2705 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2708 PrepareForWriting(file);
2709 _impl->ExportSTL(file, isascii);
2712 //=============================================================================
2714 * \brief Class providing SMESHDS_Mesh API to SMESH_IDSource.
2715 * It is used to export a part of mesh as a whole mesh.
2717 class SMESH_MeshPartDS : public SMESHDS_Mesh
2720 SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart);
2722 virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const;
2723 virtual SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const;
2724 virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const;
2725 virtual SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const;
2726 virtual SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const;
2728 virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
2731 TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ];
2732 SMESHDS_Mesh* _meshDS;
2734 * \brief Class used to access to protected data of SMDS_MeshInfo
2736 struct TMeshInfo : public SMDS_MeshInfo
2738 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
2742 //================================================================================
2744 * \brief Export a part of mesh to a med file
2746 //================================================================================
2748 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2750 CORBA::Boolean auto_groups,
2751 ::SMESH::MED_VERSION version,
2752 ::CORBA::Boolean overwrite)
2753 throw (SALOME::SALOME_Exception)
2755 Unexpect aCatch(SALOME_SalomeException);
2757 PrepareForWriting(file, overwrite);
2759 string aMeshName = "Mesh";
2760 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2761 if ( !aStudy->_is_nil() ) {
2762 SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2763 if ( !SO->_is_nil() ) {
2764 CORBA::String_var name = SO->GetName();
2768 SMESH_MeshPartDS partDS( meshPart );
2769 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2771 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2772 << auto_groups << ", " << version << ", " << overwrite << " )";
2775 //================================================================================
2777 * \brief Export a part of mesh to a DAT file
2779 //================================================================================
2781 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2783 throw (SALOME::SALOME_Exception)
2785 Unexpect aCatch(SALOME_SalomeException);
2787 PrepareForWriting(file);
2789 SMESH_MeshPartDS partDS( meshPart );
2790 _impl->ExportDAT(file,&partDS);
2792 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2794 //================================================================================
2796 * \brief Export a part of mesh to an UNV file
2798 //================================================================================
2800 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2802 throw (SALOME::SALOME_Exception)
2804 Unexpect aCatch(SALOME_SalomeException);
2806 PrepareForWriting(file);
2808 SMESH_MeshPartDS partDS( meshPart );
2809 _impl->ExportUNV(file, &partDS);
2811 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2813 //================================================================================
2815 * \brief Export a part of mesh to an STL file
2817 //================================================================================
2819 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2821 ::CORBA::Boolean isascii)
2822 throw (SALOME::SALOME_Exception)
2824 Unexpect aCatch(SALOME_SalomeException);
2826 PrepareForWriting(file);
2828 SMESH_MeshPartDS partDS( meshPart );
2829 _impl->ExportSTL(file, isascii, &partDS);
2831 TPythonDump() << _this() << ".ExportPartToSTL( "
2832 << meshPart<< ", r'" << file << "', " << isascii << ")";
2835 //================================================================================
2837 * \brief Export a part of mesh to an STL file
2839 //================================================================================
2841 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2843 CORBA::Boolean overwrite)
2844 throw (SALOME::SALOME_Exception)
2847 Unexpect aCatch(SALOME_SalomeException);
2849 PrepareForWriting(file,overwrite);
2851 SMESH_MeshPartDS partDS( meshPart );
2852 _impl->ExportCGNS(file, &partDS);
2854 TPythonDump() << _this() << ".ExportCGNS( "
2855 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2857 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2861 //=============================================================================
2865 //=============================================================================
2867 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2869 Unexpect aCatch(SALOME_SalomeException);
2870 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2871 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2872 return aMesh._retn();
2875 //=============================================================================
2879 //=============================================================================
2880 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2882 Unexpect aCatch(SALOME_SalomeException);
2883 return _impl->NbNodes();
2886 //=============================================================================
2890 //=============================================================================
2891 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2893 Unexpect aCatch(SALOME_SalomeException);
2894 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2897 //=============================================================================
2901 //=============================================================================
2902 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2904 Unexpect aCatch(SALOME_SalomeException);
2905 return _impl->Nb0DElements();
2908 //=============================================================================
2912 //=============================================================================
2913 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2915 Unexpect aCatch(SALOME_SalomeException);
2916 return _impl->NbEdges();
2919 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2920 throw(SALOME::SALOME_Exception)
2922 Unexpect aCatch(SALOME_SalomeException);
2923 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2926 //=============================================================================
2930 //=============================================================================
2931 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2933 Unexpect aCatch(SALOME_SalomeException);
2934 return _impl->NbFaces();
2937 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2939 Unexpect aCatch(SALOME_SalomeException);
2940 return _impl->NbTriangles();
2943 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2945 Unexpect aCatch(SALOME_SalomeException);
2946 return _impl->NbQuadrangles();
2949 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2951 Unexpect aCatch(SALOME_SalomeException);
2952 return _impl->NbPolygons();
2955 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2956 throw(SALOME::SALOME_Exception)
2958 Unexpect aCatch(SALOME_SalomeException);
2959 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2962 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2963 throw(SALOME::SALOME_Exception)
2965 Unexpect aCatch(SALOME_SalomeException);
2966 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2969 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2970 throw(SALOME::SALOME_Exception)
2972 Unexpect aCatch(SALOME_SalomeException);
2973 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2976 //=============================================================================
2980 //=============================================================================
2981 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2983 Unexpect aCatch(SALOME_SalomeException);
2984 return _impl->NbVolumes();
2987 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2989 Unexpect aCatch(SALOME_SalomeException);
2990 return _impl->NbTetras();
2993 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2995 Unexpect aCatch(SALOME_SalomeException);
2996 return _impl->NbHexas();
2999 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3001 Unexpect aCatch(SALOME_SalomeException);
3002 return _impl->NbPyramids();
3005 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3007 Unexpect aCatch(SALOME_SalomeException);
3008 return _impl->NbPrisms();
3011 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3013 Unexpect aCatch(SALOME_SalomeException);
3014 return _impl->NbPolyhedrons();
3017 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3018 throw(SALOME::SALOME_Exception)
3020 Unexpect aCatch(SALOME_SalomeException);
3021 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3024 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3025 throw(SALOME::SALOME_Exception)
3027 Unexpect aCatch(SALOME_SalomeException);
3028 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3031 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3032 throw(SALOME::SALOME_Exception)
3034 Unexpect aCatch(SALOME_SalomeException);
3035 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3038 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3039 throw(SALOME::SALOME_Exception)
3041 Unexpect aCatch(SALOME_SalomeException);
3042 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3045 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3046 throw(SALOME::SALOME_Exception)
3048 Unexpect aCatch(SALOME_SalomeException);
3049 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3052 //=============================================================================
3056 //=============================================================================
3057 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3059 Unexpect aCatch(SALOME_SalomeException);
3060 return _mapSubMesh_i.size();
3063 //=============================================================================
3067 //=============================================================================
3068 char* SMESH_Mesh_i::Dump()
3072 return CORBA::string_dup( os.str().c_str() );
3075 //=============================================================================
3079 //=============================================================================
3080 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3082 // SMESH::long_array_var aResult = new SMESH::long_array();
3083 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3084 // int aMinId = aSMESHDS_Mesh->MinElementID();
3085 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
3087 // aResult->length(aMaxId - aMinId + 1);
3089 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
3090 // aResult[i++] = id;
3092 // return aResult._retn();
3094 return GetElementsId();
3097 //=============================================================================
3101 //=============================================================================
3103 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3104 throw (SALOME::SALOME_Exception)
3106 Unexpect aCatch(SALOME_SalomeException);
3107 MESSAGE("SMESH_Mesh_i::GetElementsId");
3108 SMESH::long_array_var aResult = new SMESH::long_array();
3109 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3111 if ( aSMESHDS_Mesh == NULL )
3112 return aResult._retn();
3114 long nbElements = NbElements();
3115 aResult->length( nbElements );
3116 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3117 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3118 aResult[i] = anIt->next()->GetID();
3120 return aResult._retn();
3124 //=============================================================================
3128 //=============================================================================
3130 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3131 throw (SALOME::SALOME_Exception)
3133 Unexpect aCatch(SALOME_SalomeException);
3134 MESSAGE("SMESH_subMesh_i::GetElementsByType");
3135 SMESH::long_array_var aResult = new SMESH::long_array();
3136 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3138 if ( aSMESHDS_Mesh == NULL )
3139 return aResult._retn();
3141 long nbElements = NbElements();
3143 // No sense in returning ids of elements along with ids of nodes:
3144 // when theElemType == SMESH::ALL, return node ids only if
3145 // there are no elements
3146 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3147 return GetNodesId();
3149 aResult->length( nbElements );
3153 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3154 while ( i < nbElements && anIt->more() ) {
3155 const SMDS_MeshElement* anElem = anIt->next();
3156 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3157 aResult[i++] = anElem->GetID();
3160 aResult->length( i );
3162 return aResult._retn();
3165 //=============================================================================
3169 //=============================================================================
3171 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3172 throw (SALOME::SALOME_Exception)
3174 Unexpect aCatch(SALOME_SalomeException);
3175 MESSAGE("SMESH_subMesh_i::GetNodesId");
3176 SMESH::long_array_var aResult = new SMESH::long_array();
3177 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3179 if ( aSMESHDS_Mesh == NULL )
3180 return aResult._retn();
3182 long nbNodes = NbNodes();
3183 aResult->length( nbNodes );
3184 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3185 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3186 aResult[i] = anIt->next()->GetID();
3188 return aResult._retn();
3191 //=============================================================================
3195 //=============================================================================
3197 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3198 throw (SALOME::SALOME_Exception)
3200 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3203 //=============================================================================
3207 //=============================================================================
3209 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3210 throw (SALOME::SALOME_Exception)
3212 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3214 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3216 return ( SMESH::EntityType ) e->GetEntityType();
3219 //=============================================================================
3221 * Returns ID of elements for given submesh
3223 //=============================================================================
3224 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3225 throw (SALOME::SALOME_Exception)
3227 SMESH::long_array_var aResult = new SMESH::long_array();
3229 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3230 if(!SM) return aResult._retn();
3232 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3233 if(!SDSM) return aResult._retn();
3235 aResult->length(SDSM->NbElements());
3237 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3239 while ( eIt->more() ) {
3240 aResult[i++] = eIt->next()->GetID();
3243 return aResult._retn();
3247 //=============================================================================
3249 * Returns ID of nodes for given submesh
3250 * If param all==true - returns all nodes, else -
3251 * returns only nodes on shapes.
3253 //=============================================================================
3254 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
3255 throw (SALOME::SALOME_Exception)
3257 SMESH::long_array_var aResult = new SMESH::long_array();
3259 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3260 if(!SM) return aResult._retn();
3262 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3263 if(!SDSM) return aResult._retn();
3266 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3267 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3268 while ( nIt->more() ) {
3269 const SMDS_MeshNode* elem = nIt->next();
3270 theElems.insert( elem->GetID() );
3273 else { // all nodes of submesh elements
3274 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3275 while ( eIt->more() ) {
3276 const SMDS_MeshElement* anElem = eIt->next();
3277 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3278 while ( nIt->more() ) {
3279 const SMDS_MeshElement* elem = nIt->next();
3280 theElems.insert( elem->GetID() );
3285 aResult->length(theElems.size());
3286 set<int>::iterator itElem;
3288 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3289 aResult[i++] = *itElem;
3291 return aResult._retn();
3295 //=============================================================================
3297 * Returns type of elements for given submesh
3299 //=============================================================================
3300 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3301 throw (SALOME::SALOME_Exception)
3303 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3304 if(!SM) return SMESH::ALL;
3306 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3307 if(!SDSM) return SMESH::ALL;
3309 if(SDSM->NbElements()==0)
3310 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3312 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3313 const SMDS_MeshElement* anElem = eIt->next();
3314 return ( SMESH::ElementType ) anElem->GetType();
3318 //=============================================================================
3322 //=============================================================================
3324 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3326 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3328 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3333 //=============================================================================
3335 * Get XYZ coordinates of node as list of double
3336 * If there is not node for given ID - returns empty list
3338 //=============================================================================
3340 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3342 SMESH::double_array_var aResult = new SMESH::double_array();
3343 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3344 if ( aSMESHDS_Mesh == NULL )
3345 return aResult._retn();
3348 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3350 return aResult._retn();
3354 aResult[0] = aNode->X();
3355 aResult[1] = aNode->Y();
3356 aResult[2] = aNode->Z();
3357 return aResult._retn();
3361 //=============================================================================
3363 * For given node returns list of IDs of inverse elements
3364 * If there is not node for given ID - returns empty list
3366 //=============================================================================
3368 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3370 SMESH::long_array_var aResult = new SMESH::long_array();
3371 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3372 if ( aSMESHDS_Mesh == NULL )
3373 return aResult._retn();
3376 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3378 return aResult._retn();
3380 // find inverse elements
3381 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3382 TColStd_SequenceOfInteger IDs;
3383 while(eIt->more()) {
3384 const SMDS_MeshElement* elem = eIt->next();
3385 IDs.Append(elem->GetID());
3387 if(IDs.Length()>0) {
3388 aResult->length(IDs.Length());
3390 for(; i<=IDs.Length(); i++) {
3391 aResult[i-1] = IDs.Value(i);
3394 return aResult._retn();
3397 //=============================================================================
3399 * \brief Return position of a node on shape
3401 //=============================================================================
3403 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3405 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3406 aNodePosition->shapeID = 0;
3407 aNodePosition->shapeType = GEOM::SHAPE;
3409 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3410 if ( !mesh ) return aNodePosition;
3412 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3414 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3416 aNodePosition->shapeID = aNode->getshapeId();
3417 switch ( pos->GetTypeOfPosition() ) {
3419 aNodePosition->shapeType = GEOM::EDGE;
3420 aNodePosition->params.length(1);
3421 aNodePosition->params[0] =
3422 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3425 aNodePosition->shapeType = GEOM::FACE;
3426 aNodePosition->params.length(2);
3427 aNodePosition->params[0] =
3428 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3429 aNodePosition->params[1] =
3430 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3432 case SMDS_TOP_VERTEX:
3433 aNodePosition->shapeType = GEOM::VERTEX;
3435 case SMDS_TOP_3DSPACE:
3436 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3437 aNodePosition->shapeType = GEOM::SOLID;
3438 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3439 aNodePosition->shapeType = GEOM::SHELL;
3445 return aNodePosition;
3448 //=============================================================================
3450 * If given element is node returns IDs of shape from position
3451 * If there is not node for given ID - returns -1
3453 //=============================================================================
3455 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3457 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3458 if ( aSMESHDS_Mesh == NULL )
3462 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3464 return aNode->getshapeId();
3471 //=============================================================================
3473 * For given element returns ID of result shape after
3474 * ::FindShape() from SMESH_MeshEditor
3475 * If there is not element for given ID - returns -1
3477 //=============================================================================
3479 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3481 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3482 if ( aSMESHDS_Mesh == NULL )
3485 // try to find element
3486 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3490 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3491 ::SMESH_MeshEditor aMeshEditor(_impl);
3492 int index = aMeshEditor.FindShape( elem );
3500 //=============================================================================
3502 * Returns number of nodes for given element
3503 * If there is not element for given ID - returns -1
3505 //=============================================================================
3507 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3509 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3510 if ( aSMESHDS_Mesh == NULL ) return -1;
3511 // try to find element
3512 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3513 if(!elem) return -1;
3514 return elem->NbNodes();
3518 //=============================================================================
3520 * Returns ID of node by given index for given element
3521 * If there is not element for given ID - returns -1
3522 * If there is not node for given index - returns -2
3524 //=============================================================================
3526 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3528 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3529 if ( aSMESHDS_Mesh == NULL ) return -1;
3530 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3531 if(!elem) return -1;
3532 if( index>=elem->NbNodes() || index<0 ) return -1;
3533 return elem->GetNode(index)->GetID();
3536 //=============================================================================
3538 * Returns IDs of nodes of given element
3540 //=============================================================================
3542 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3544 SMESH::long_array_var aResult = new SMESH::long_array();
3545 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3547 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3549 aResult->length( elem->NbNodes() );
3550 for ( int i = 0; i < elem->NbNodes(); ++i )
3551 aResult[ i ] = elem->GetNode( i )->GetID();
3554 return aResult._retn();
3557 //=============================================================================
3559 * Returns true if given node is medium node
3560 * in given quadratic element
3562 //=============================================================================
3564 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3566 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3567 if ( aSMESHDS_Mesh == NULL ) return false;
3569 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3570 if(!aNode) return false;
3571 // try to find element
3572 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3573 if(!elem) return false;
3575 return elem->IsMediumNode(aNode);
3579 //=============================================================================
3581 * Returns true if given node is medium node
3582 * in one of quadratic elements
3584 //=============================================================================
3586 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3587 SMESH::ElementType theElemType)
3589 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3590 if ( aSMESHDS_Mesh == NULL ) return false;
3593 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3594 if(!aNode) return false;
3596 SMESH_MesherHelper aHelper( *(_impl) );
3598 SMDSAbs_ElementType aType;
3599 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3600 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3601 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3602 else aType = SMDSAbs_All;
3604 return aHelper.IsMedium(aNode,aType);
3608 //=============================================================================
3610 * Returns number of edges for given element
3612 //=============================================================================
3614 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3616 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3617 if ( aSMESHDS_Mesh == NULL ) return -1;
3618 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3619 if(!elem) return -1;
3620 return elem->NbEdges();
3624 //=============================================================================
3626 * Returns number of faces for given element
3628 //=============================================================================
3630 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3632 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3633 if ( aSMESHDS_Mesh == NULL ) return -1;
3634 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3635 if(!elem) return -1;
3636 return elem->NbFaces();
3639 //=======================================================================
3640 //function : GetElemFaceNodes
3641 //purpose : Returns nodes of given face (counted from zero) for given element.
3642 //=======================================================================
3644 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3645 CORBA::Short faceIndex)
3647 SMESH::long_array_var aResult = new SMESH::long_array();
3648 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3650 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3652 SMDS_VolumeTool vtool( elem );
3653 if ( faceIndex < vtool.NbFaces() )
3655 aResult->length( vtool.NbFaceNodes( faceIndex ));
3656 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3657 for ( int i = 0; i < aResult->length(); ++i )
3658 aResult[ i ] = nn[ i ]->GetID();
3662 return aResult._retn();
3665 //=======================================================================
3666 //function : FindElementByNodes
3667 //purpose : Returns an element based on all given nodes.
3668 //=======================================================================
3670 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3672 CORBA::Long elemID(0);
3673 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3675 vector< const SMDS_MeshNode * > nn( nodes.length() );
3676 for ( int i = 0; i < nodes.length(); ++i )
3677 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3680 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3681 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3682 _impl->NbFaces( ORDER_QUADRATIC ) ||
3683 _impl->NbVolumes( ORDER_QUADRATIC )))
3684 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3686 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3691 //=============================================================================
3693 * Returns true if given element is polygon
3695 //=============================================================================
3697 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3699 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3700 if ( aSMESHDS_Mesh == NULL ) return false;
3701 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3702 if(!elem) return false;
3703 return elem->IsPoly();
3707 //=============================================================================
3709 * Returns true if given element is quadratic
3711 //=============================================================================
3713 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3715 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3716 if ( aSMESHDS_Mesh == NULL ) return false;
3717 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3718 if(!elem) return false;
3719 return elem->IsQuadratic();
3723 //=============================================================================
3725 * Returns bary center for given element
3727 //=============================================================================
3729 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3731 SMESH::double_array_var aResult = new SMESH::double_array();
3732 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3733 if ( aSMESHDS_Mesh == NULL )
3734 return aResult._retn();
3736 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3738 return aResult._retn();
3740 if(elem->GetType()==SMDSAbs_Volume) {
3741 SMDS_VolumeTool aTool;
3742 if(aTool.Set(elem)) {
3744 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3749 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3751 double x=0., y=0., z=0.;
3752 for(; anIt->more(); ) {
3754 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3768 return aResult._retn();
3772 //=============================================================================
3774 * Create and publish group servants if any groups were imported or created anyhow
3776 //=============================================================================
3778 void SMESH_Mesh_i::CreateGroupServants()
3780 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3783 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3784 while ( groupIt->more() )
3786 ::SMESH_Group* group = groupIt->next();
3787 int anId = group->GetGroupDS()->GetID();
3789 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3790 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3792 addedIDs.insert( anId );
3794 SMESH_GroupBase_i* aGroupImpl;
3796 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3797 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3799 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3800 shape = groupOnGeom->GetShape();
3803 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3806 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3807 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3808 aGroupImpl->Register();
3810 SMESH::SMESH_GroupBase_var groupVar =
3811 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3812 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3814 // register CORBA object for persistence
3815 int nextId = _gen_i->RegisterObject( groupVar );
3816 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3818 // publishing the groups in the study
3819 if ( !aStudy->_is_nil() ) {
3820 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3821 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3824 if ( !addedIDs.empty() )
3827 set<int>::iterator id = addedIDs.begin();
3828 for ( ; id != addedIDs.end(); ++id )
3830 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
3831 int i = std::distance( _mapGroups.begin(), it );
3832 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
3837 //=============================================================================
3839 * \brief Return groups cantained in _mapGroups by their IDs
3841 //=============================================================================
3843 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3845 int nbGroups = groupIDs.size();
3846 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3847 aList->length( nbGroups );
3849 list<int>::const_iterator ids = groupIDs.begin();
3850 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3852 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3853 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3854 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3856 aList->length( nbGroups );
3857 return aList._retn();
3860 //=============================================================================
3862 * \brief Return information about imported file
3864 //=============================================================================
3866 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3868 SALOME_MED::MedFileInfo_var res( myFileInfo );
3869 if ( !res.operator->() ) {
3870 res = new SALOME_MED::MedFileInfo;
3872 res->fileSize = res->major = res->minor = res->release = -1;
3877 //=============================================================================
3879 * \brief Check and correct names of mesh groups
3881 //=============================================================================
3883 void SMESH_Mesh_i::checkGroupNames()
3885 int nbGrp = NbGroups();
3889 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3890 if ( aStudy->_is_nil() )
3891 return; // nothing to do
3893 SMESH::ListOfGroups* grpList = 0;
3894 // avoid dump of "GetGroups"
3896 // store python dump into a local variable inside local scope
3897 SMESH::TPythonDump pDump; // do not delete this line of code
3898 grpList = GetGroups();
3901 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3902 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3905 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3906 if ( aGrpSO->_is_nil() )
3908 // correct name of the mesh group if necessary
3909 const char* guiName = aGrpSO->GetName();
3910 if ( strcmp(guiName, aGrp->GetName()) )
3911 aGrp->SetName( guiName );
3915 //=============================================================================
3917 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3919 //=============================================================================
3920 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3922 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3923 CORBA::string_dup(theParameters));
3926 //=============================================================================
3928 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3930 //=============================================================================
3931 char* SMESH_Mesh_i::GetParameters()
3933 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3934 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3937 //=============================================================================
3939 * \brief Returns list of notebook variables used for last Mesh operation
3941 //=============================================================================
3942 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3944 SMESH::string_array_var aResult = new SMESH::string_array();
3945 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3947 char *aParameters = GetParameters();
3948 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3949 if(!aStudy->_is_nil()) {
3950 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3951 if(aSections->length() > 0) {
3952 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3953 aResult->length(aVars.length());
3954 for(int i = 0;i < aVars.length();i++)
3955 aResult[i] = CORBA::string_dup( aVars[i]);
3959 return aResult._retn();
3962 //=======================================================================
3963 //function : GetTypes
3964 //purpose : Returns types of elements it contains
3965 //=======================================================================
3967 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3969 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3973 if (_impl->NbEdges())
3974 types[nbTypes++] = SMESH::EDGE;
3975 if (_impl->NbFaces())
3976 types[nbTypes++] = SMESH::FACE;
3977 if (_impl->NbVolumes())
3978 types[nbTypes++] = SMESH::VOLUME;
3979 if (_impl->Nb0DElements())
3980 types[nbTypes++] = SMESH::ELEM0D;
3981 types->length( nbTypes );
3983 return types._retn();
3986 //=======================================================================
3987 //function : GetMesh
3988 //purpose : Returns self
3989 //=======================================================================
3991 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
3993 return SMESH::SMESH_Mesh::_duplicate( _this() );
3996 //=============================================================================
3998 * \brief Returns statistic of mesh elements
4000 //=============================================================================
4001 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4003 SMESH::long_array_var aRes = new SMESH::long_array();
4004 aRes->length(SMESH::Entity_Last);
4005 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4007 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4009 return aRes._retn();
4010 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4011 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4012 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4013 return aRes._retn();
4016 //=============================================================================
4018 * \brief Collect statistic of mesh elements given by iterator
4020 //=============================================================================
4021 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4022 SMESH::long_array& theInfo)
4024 if (!theItr) return;
4025 while (theItr->more())
4026 theInfo[ theItr->next()->GetEntityType() ]++;
4029 //=============================================================================
4031 * \brief mapping of mesh dimension into shape type
4033 //=============================================================================
4034 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4036 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4038 case 0: aType = TopAbs_VERTEX; break;
4039 case 1: aType = TopAbs_EDGE; break;
4040 case 2: aType = TopAbs_FACE; break;
4042 default:aType = TopAbs_SOLID; break;
4047 //=============================================================================
4049 * \brief Internal structure used to find concurent submeshes
4051 * It represents a pair < submesh, concurent dimension >, where
4052 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4053 * with another submesh. In other words, it is dimension of a hypothesis assigned
4056 //=============================================================================
4062 int _dim; //!< a dimension the algo can build (concurrent dimension)
4063 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4064 TopTools_MapOfShape _shapeMap;
4065 SMESH_subMesh* _subMesh;
4066 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
4069 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4071 const TopoDS_Shape& theShape)
4073 _subMesh = (SMESH_subMesh*)theSubMesh;
4074 SetShape( theDim, theShape );
4078 void SetShape(const int theDim,
4079 const TopoDS_Shape& theShape)
4082 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4083 if (_dim >= _ownDim)
4084 _shapeMap.Add( theShape );
4086 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4087 for( ; anExp.More(); anExp.Next() )
4088 _shapeMap.Add( anExp.Current() );
4092 //! Check sharing of sub shapes
4093 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4094 const TopTools_MapOfShape& theToFind,
4095 const TopAbs_ShapeEnum theType)
4097 bool isShared = false;
4098 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4099 for (; !isShared && anItr.More(); anItr.Next() ) {
4100 const TopoDS_Shape aSubSh = anItr.Key();
4101 // check for case when concurrent dimensions are same
4102 isShared = theToFind.Contains( aSubSh );
4103 // check for subshape with concurrent dimension
4104 TopExp_Explorer anExp( aSubSh, theType );
4105 for ( ; !isShared && anExp.More(); anExp.Next() )
4106 isShared = theToFind.Contains( anExp.Current() );
4111 //! check algorithms
4112 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4113 const SMESHDS_Hypothesis* theA2)
4115 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4116 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4117 return false; // one of the hypothesis is not algorithm
4118 // check algorithm names (should be equal)
4119 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4123 //! Check if subshape hypotheses are concurrent
4124 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4126 if ( _subMesh == theOther->_subMesh )
4127 return false; // same subshape - should not be
4129 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4130 // any of the two submeshes is not on COMPOUND shape )
4131 // -> no concurrency
4132 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4133 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4134 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4137 // bool checkSubShape = ( _dim >= theOther->_dim )
4138 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4139 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4140 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4141 if ( !checkSubShape )
4144 // check algorithms to be same
4145 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
4146 return true; // different algorithms
4148 // check hypothesises for concurrence (skip first as algorithm)
4150 // pointers should be same, becase it is referenes from mesh hypothesis partition
4151 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
4152 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
4153 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
4154 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
4156 // the submeshes are concurrent if their algorithms has different parameters
4157 return nbSame != theOther->_hypothesises.size() - 1;
4160 }; // end of SMESH_DimHyp
4162 typedef list<SMESH_DimHyp*> TDimHypList;
4164 static void addDimHypInstance(const int theDim,
4165 const TopoDS_Shape& theShape,
4166 const SMESH_Algo* theAlgo,
4167 const SMESH_subMesh* theSubMesh,
4168 const list <const SMESHDS_Hypothesis*>& theHypList,
4169 TDimHypList* theDimHypListArr )
4171 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4172 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4173 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4174 listOfdimHyp.push_back( dimHyp );
4177 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
4178 dimHyp->_hypothesises.push_front(theAlgo);
4179 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
4180 for( ; hypIt != theHypList.end(); hypIt++ )
4181 dimHyp->_hypothesises.push_back( *hypIt );
4184 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
4185 const TDimHypList& theListOfDimHyp,
4186 TListOfInt& theListOfConcurr )
4188 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4189 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
4190 const SMESH_DimHyp* curDimHyp = *rIt;
4191 if ( curDimHyp == theDimHyp )
4192 break; // meet own dimHyp pointer in same dimension
4193 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
4194 if ( find( theListOfConcurr.begin(),
4195 theListOfConcurr.end(),
4196 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
4197 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
4201 static void unionLists(TListOfInt& theListOfId,
4202 TListOfListOfInt& theListOfListOfId,
4205 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4206 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4208 continue; //skip already treated lists
4209 // check if other list has any same submesh object
4210 TListOfInt& otherListOfId = *it;
4211 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4212 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4215 // union two lists (from source into target)
4216 TListOfInt::iterator it2 = otherListOfId.begin();
4217 for ( ; it2 != otherListOfId.end(); it2++ ) {
4218 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4219 theListOfId.push_back(*it2);
4221 // clear source list
4222 otherListOfId.clear();
4226 //! free memory allocated for dimension-hypothesis objects
4227 static void removeDimHyps( TDimHypList* theArrOfList )
4229 for (int i = 0; i < 4; i++ ) {
4230 TDimHypList& listOfdimHyp = theArrOfList[i];
4231 TDimHypList::const_iterator it = listOfdimHyp.begin();
4232 for ( ; it != listOfdimHyp.end(); it++ )
4237 //=============================================================================
4239 * \brief Return submesh objects list in meshing order
4241 //=============================================================================
4243 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4245 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4247 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4249 return aResult._retn();
4251 ::SMESH_Mesh& mesh = GetImpl();
4252 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4253 if ( !anOrder.size() ) {
4255 // collect submeshes detecting concurrent algorithms and hypothesises
4256 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4258 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4259 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4260 ::SMESH_subMesh* sm = (*i_sm).second;
4262 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4264 // list of assigned hypothesises
4265 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4266 // Find out dimensions where the submesh can be concurrent.
4267 // We define the dimensions by algo of each of hypotheses in hypList
4268 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4269 for( ; hypIt != hypList.end(); hypIt++ ) {
4270 SMESH_Algo* anAlgo = 0;
4271 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4272 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4273 // hyp it-self is algo
4274 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4276 // try to find algorithm with help of subshapes
4277 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4278 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4279 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4282 continue; // no assigned algorithm to current submesh
4284 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4285 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
4287 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4288 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4289 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4291 } // end iterations on submesh
4293 // iterate on created dimension-hypotheses and check for concurrents
4294 for ( int i = 0; i < 4; i++ ) {
4295 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
4296 // check for concurrents in own and other dimensions (step-by-step)
4297 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4298 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4299 const SMESH_DimHyp* dimHyp = *dhIt;
4300 TListOfInt listOfConcurr;
4301 // looking for concurrents and collect into own list
4302 for ( int j = i; j < 4; j++ )
4303 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
4304 // check if any concurrents found
4305 if ( listOfConcurr.size() > 0 ) {
4306 // add own submesh to list of concurrent
4307 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
4308 anOrder.push_back( listOfConcurr );
4313 removeDimHyps(dimHypListArr);
4315 // now, minimise the number of concurrent groups
4316 // Here we assume that lists of submhes can has same submesh
4317 // in case of multi-dimension algorithms, as result
4318 // list with common submesh have to be union into one list
4320 TListOfListOfInt::iterator listIt = anOrder.begin();
4321 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4322 unionLists( *listIt, anOrder, listIndx + 1 );
4324 // convert submesh ids into interface instances
4325 // and dump command into python
4326 convertMeshOrder( anOrder, aResult, true );
4328 return aResult._retn();
4331 //=============================================================================
4333 * \brief find common submeshes with given submesh
4334 * \param theSubMeshList list of already collected submesh to check
4335 * \param theSubMesh given submesh to intersect with other
4336 * \param theCommonSubMeshes collected common submeshes
4338 //=============================================================================
4340 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4341 const SMESH_subMesh* theSubMesh,
4342 set<const SMESH_subMesh*>& theCommon )
4346 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4347 for ( ; it != theSubMeshList.end(); it++ )
4348 theSubMesh->FindIntersection( *it, theCommon );
4349 theSubMeshList.push_back( theSubMesh );
4350 //theCommon.insert( theSubMesh );
4353 //=============================================================================
4355 * \brief Set submesh object order
4356 * \param theSubMeshArray submesh array order
4358 //=============================================================================
4360 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4363 ::SMESH_Mesh& mesh = GetImpl();
4365 TPythonDump aPythonDump; // prevent dump of called methods
4366 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4368 TListOfListOfInt subMeshOrder;
4369 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4371 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4372 TListOfInt subMeshIds;
4373 aPythonDump << "[ ";
4374 // Collect subMeshes which should be clear
4375 // do it list-by-list, because modification of submesh order
4376 // take effect between concurrent submeshes only
4377 set<const SMESH_subMesh*> subMeshToClear;
4378 list<const SMESH_subMesh*> subMeshList;
4379 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4381 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4383 aPythonDump << ", ";
4384 aPythonDump << subMesh;
4385 subMeshIds.push_back( subMesh->GetId() );
4386 // detect common parts of submeshes
4387 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4388 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4390 aPythonDump << " ]";
4391 subMeshOrder.push_back( subMeshIds );
4393 // clear collected submeshes
4394 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4395 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
4396 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
4398 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4399 // ClearSubMesh( *clrIt );
4402 aPythonDump << " ])";
4404 mesh.SetMeshOrder( subMeshOrder );
4410 //=============================================================================
4412 * \brief Convert submesh ids into submesh interfaces
4414 //=============================================================================
4416 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4417 SMESH::submesh_array_array& theResOrder,
4418 const bool theIsDump)
4420 int nbSet = theIdsOrder.size();
4421 TPythonDump aPythonDump; // prevent dump of called methods
4423 aPythonDump << "[ ";
4424 theResOrder.length(nbSet);
4425 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4427 for( ; it != theIdsOrder.end(); it++ ) {
4428 // translate submesh identificators into submesh objects
4429 // takeing into account real number of concurrent lists
4430 const TListOfInt& aSubOrder = (*it);
4431 if (!aSubOrder.size())
4434 aPythonDump << "[ ";
4435 // convert shape indeces into interfaces
4436 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4437 aResSubSet->length(aSubOrder.size());
4438 TListOfInt::const_iterator subIt = aSubOrder.begin();
4439 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4440 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4442 SMESH::SMESH_subMesh_var subMesh =
4443 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4446 aPythonDump << ", ";
4447 aPythonDump << subMesh;
4449 aResSubSet[ j++ ] = subMesh;
4452 aPythonDump << " ]";
4453 theResOrder[ listIndx++ ] = aResSubSet;
4455 // correct number of lists
4456 theResOrder.length( listIndx );
4459 // finilise python dump
4460 aPythonDump << " ]";
4461 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4465 //================================================================================
4467 // Implementation of SMESH_MeshPartDS
4469 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4470 SMESHDS_Mesh( /*theMeshID=*/-1, /*theIsEmbeddedMode=*/true)
4472 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4473 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4475 _meshDS = mesh_i->GetImpl().GetMeshDS();
4477 SetPersistentId( _meshDS->GetPersistentId() );
4479 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4481 // <meshPart> is the whole mesh
4482 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4484 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
4485 myGroupSet = _meshDS->GetGroups();
4490 SMESH::long_array_var anIDs = meshPart->GetIDs();
4491 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4492 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4494 for (int i=0; i < anIDs->length(); i++)
4495 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4496 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4501 for (int i=0; i < anIDs->length(); i++)
4502 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4503 if ( _elements[ e->GetType() ].insert( e ).second )
4506 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4507 while ( nIt->more() )
4509 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4510 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4517 _meshDS = 0; // to enforce iteration on _elements and _nodes
4520 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
4522 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4523 if ( type == SMDSAbs_All && !_meshDS )
4525 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
4527 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4528 if ( !_elements[i].empty() && i != SMDSAbs_Node )
4530 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
4532 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
4533 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
4535 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
4536 ( new TIter( _elements[type].begin(), _elements[type].end() ));
4538 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
4539 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
4541 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
4542 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
4543 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
4545 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
4546 _GET_ITER_DEFINE( SMDS_0DElementIteratorPtr, elements0dIterator, SMDS_Mesh0DElement, SMDSAbs_0DElement)
4547 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
4548 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
4549 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
4550 #undef _GET_ITER_DEFINE
4552 // END Implementation of SMESH_MeshPartDS
4554 //================================================================================