1 // Copyright (C) 2007-2010 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 // SMESH SMESH_I : idl implementation based on 'SMESH' unit's calsses
23 // File : SMESH_Mesh_i.cxx
24 // Author : Paul RASCLE, EDF
27 #include "SMESH_Mesh_i.hxx"
29 #include "SMESH_Filter_i.hxx"
30 #include "SMESH_Gen_i.hxx"
31 #include "SMESH_Group_i.hxx"
32 #include "SMESH_MEDMesh_i.hxx"
33 #include "SMESH_MeshEditor_i.hxx"
34 #include "SMESH_PythonDump.hxx"
35 #include "SMESH_subMesh_i.hxx"
37 #include "DriverMED_R_SMESHDS_Mesh.h"
38 #include "DriverMED_W_SMESHDS_Mesh.h"
39 #include "SMDS_VolumeTool.hxx"
40 #include "SMDS_ElemIterator.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_GroupOnGeom.hxx"
44 #include "SMESH_Group.hxx"
45 #include "SMESH_MeshEditor.hxx"
46 #include "SMESH_MesherHelper.hxx"
47 #include "SMDS_EdgePosition.hxx"
48 #include "SMDS_FacePosition.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 INFOS("~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;
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());
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 Return string representation of a MED file version comprising nbDigits
347 //================================================================================
349 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
351 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
353 return CORBA::string_dup( ver.c_str() );
356 //=============================================================================
360 * Imports mesh data from MED file
362 //=============================================================================
364 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
365 throw ( SALOME::SALOME_Exception )
367 // Read mesh with name = <theMeshName> into SMESH_Mesh
368 _impl->UNVToMesh( theFileName );
370 CreateGroupServants();
375 //=============================================================================
379 * Imports mesh data from STL file
381 //=============================================================================
382 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
383 throw ( SALOME::SALOME_Exception )
385 // Read mesh with name = <theMeshName> into SMESH_Mesh
386 _impl->STLToMesh( theFileName );
391 //=============================================================================
395 * Imports mesh data from MED file
397 //=============================================================================
399 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
401 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
402 // int status = _impl->MEDToMesh( theFileName, theMeshName );
403 // CreateGroupServants();
408 //=============================================================================
412 //=============================================================================
414 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
416 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
417 (SMESH_Hypothesis::Hypothesis_Status theStatus)
420 RETURNCASE( HYP_OK );
421 RETURNCASE( HYP_MISSING );
422 RETURNCASE( HYP_CONCURENT );
423 RETURNCASE( HYP_BAD_PARAMETER );
424 RETURNCASE( HYP_HIDDEN_ALGO );
425 RETURNCASE( HYP_HIDING_ALGO );
426 RETURNCASE( HYP_UNKNOWN_FATAL );
427 RETURNCASE( HYP_INCOMPATIBLE );
428 RETURNCASE( HYP_NOTCONFORM );
429 RETURNCASE( HYP_ALREADY_EXIST );
430 RETURNCASE( HYP_BAD_DIM );
431 RETURNCASE( HYP_BAD_SUBSHAPE );
432 RETURNCASE( HYP_BAD_GEOMETRY );
433 RETURNCASE( HYP_NEED_SHAPE );
436 return SMESH::HYP_UNKNOWN_FATAL;
439 //=============================================================================
443 * calls internal addHypothesis() and then adds a reference to <anHyp> under
444 * the SObject actually having a reference to <aSubShape>.
445 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
447 //=============================================================================
449 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
450 SMESH::SMESH_Hypothesis_ptr anHyp)
451 throw(SALOME::SALOME_Exception)
453 Unexpect aCatch(SALOME_SalomeException);
454 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
456 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
457 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
458 aSubShapeObject, anHyp );
460 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
462 // Update Python script
463 if(_impl->HasShapeToMesh()) {
464 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
465 << aSubShapeObject << ", " << anHyp << " )";
468 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
471 return ConvertHypothesisStatus(status);
474 //=============================================================================
478 //=============================================================================
480 SMESH_Hypothesis::Hypothesis_Status
481 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
482 SMESH::SMESH_Hypothesis_ptr anHyp)
484 if(MYDEBUG) MESSAGE("addHypothesis");
486 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
487 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
490 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
491 if (CORBA::is_nil(myHyp))
492 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
495 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
498 TopoDS_Shape myLocSubShape;
499 //use PseudoShape in case if mesh has no shape
501 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
503 myLocSubShape = _impl->GetShapeToMesh();
505 int hypId = myHyp->GetId();
506 status = _impl->AddHypothesis(myLocSubShape, hypId);
507 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
508 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
509 #ifdef WITHGENERICOBJ
510 _mapHypo[hypId]->Register();
512 // assure there is a corresponding submesh
513 if ( !_impl->IsMainShape( myLocSubShape )) {
514 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
515 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
516 createSubMesh( aSubShapeObject );
520 catch(SALOME_Exception & S_ex)
522 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
527 //=============================================================================
531 //=============================================================================
533 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
534 SMESH::SMESH_Hypothesis_ptr anHyp)
535 throw(SALOME::SALOME_Exception)
537 Unexpect aCatch(SALOME_SalomeException);
538 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
540 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
541 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
542 aSubShapeObject, anHyp );
544 // Update Python script
545 // Update Python script
546 if(_impl->HasShapeToMesh()) {
547 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
548 << aSubShapeObject << ", " << anHyp << " )";
551 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
555 return ConvertHypothesisStatus(status);
558 //=============================================================================
562 //=============================================================================
564 SMESH_Hypothesis::Hypothesis_Status
565 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
566 SMESH::SMESH_Hypothesis_ptr anHyp)
568 if(MYDEBUG) MESSAGE("removeHypothesis()");
569 // **** proposer liste de subShape (selection multiple)
571 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
572 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
574 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
575 if (CORBA::is_nil(myHyp))
576 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
578 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
581 TopoDS_Shape myLocSubShape;
582 //use PseudoShape in case if mesh has no shape
584 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
586 myLocSubShape = _impl->GetShapeToMesh();
588 int hypId = myHyp->GetId();
589 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
590 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
591 // _mapHypo.erase( hypId );
593 catch(SALOME_Exception & S_ex)
595 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
600 //=============================================================================
604 //=============================================================================
606 SMESH::ListOfHypothesis *
607 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
608 throw(SALOME::SALOME_Exception)
610 Unexpect aCatch(SALOME_SalomeException);
611 if (MYDEBUG) MESSAGE("GetHypothesisList");
612 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
613 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
615 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
618 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
619 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
620 myLocSubShape = _impl->GetShapeToMesh();
621 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
622 int i = 0, n = aLocalList.size();
625 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
626 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
627 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
628 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
633 catch(SALOME_Exception & S_ex) {
634 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
637 return aList._retn();
640 //=============================================================================
644 //=============================================================================
645 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
646 const char* theName )
647 throw(SALOME::SALOME_Exception)
649 Unexpect aCatch(SALOME_SalomeException);
650 MESSAGE("SMESH_Mesh_i::GetSubMesh");
651 if (CORBA::is_nil(aSubShapeObject))
652 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
655 SMESH::SMESH_subMesh_var subMesh;
656 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
658 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
660 //Get or Create the SMESH_subMesh object implementation
662 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
663 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
664 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
666 subMesh = getSubMesh( subMeshId );
668 // create a new subMesh object servant if there is none for the shape
669 if ( subMesh->_is_nil() )
670 subMesh = createSubMesh( aSubShapeObject );
671 if ( _gen_i->CanPublishInStudy( subMesh )) {
672 SALOMEDS::SObject_var aSO =
673 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
674 subMesh, aSubShapeObject, theName );
675 if ( !aSO->_is_nil()) {
676 // Update Python script
677 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
678 << aSubShapeObject << ", '" << theName << "' )";
682 catch(SALOME_Exception & S_ex) {
683 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
685 return subMesh._retn();
688 //=============================================================================
692 //=============================================================================
694 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
695 throw (SALOME::SALOME_Exception)
697 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
698 if ( theSubMesh->_is_nil() )
701 GEOM::GEOM_Object_var aSubShapeObject;
702 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
703 if ( !aStudy->_is_nil() ) {
704 // Remove submesh's SObject
705 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
706 if ( !anSO->_is_nil() ) {
707 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
708 SALOMEDS::SObject_var anObj, aRef;
709 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
710 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
712 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
713 // aSubShapeObject = theSubMesh->GetSubShape();
715 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
717 // Update Python script
718 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
722 removeSubMesh( theSubMesh, aSubShapeObject.in() );
725 //=============================================================================
729 //=============================================================================
730 #define CASE2STRING(enum) case SMESH::enum: return "SMESH."#enum;
731 inline TCollection_AsciiString ElementTypeString (SMESH::ElementType theElemType)
733 switch (theElemType) {
738 CASE2STRING( VOLUME );
739 CASE2STRING( ELEM0D );
745 //=============================================================================
749 //=============================================================================
751 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
752 const char* theName )
753 throw(SALOME::SALOME_Exception)
755 Unexpect aCatch(SALOME_SalomeException);
756 SMESH::SMESH_Group_var aNewGroup =
757 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
759 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
760 SALOMEDS::SObject_var aSO =
761 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
762 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
763 if ( !aSO->_is_nil()) {
764 // Update Python script
765 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
766 << ElementTypeString(theElemType) << ", '" << theName << "' )";
769 return aNewGroup._retn();
773 //=============================================================================
777 //=============================================================================
778 SMESH::SMESH_GroupOnGeom_ptr SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
780 GEOM::GEOM_Object_ptr theGeomObj)
781 throw(SALOME::SALOME_Exception)
783 Unexpect aCatch(SALOME_SalomeException);
784 SMESH::SMESH_GroupOnGeom_var aNewGroup;
786 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
787 if ( !aShape.IsNull() )
789 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
790 ( createGroup( theElemType, theName, aShape ));
792 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
793 SALOMEDS::SObject_var aSO =
794 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
795 aNewGroup, theGeomObj, theName);
796 if ( !aSO->_is_nil()) {
797 // Update Python script
798 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
799 << ElementTypeString(theElemType) << ", '" << theName << "', "
800 << theGeomObj << " )";
805 return aNewGroup._retn();
808 //=============================================================================
812 //=============================================================================
814 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
815 throw (SALOME::SALOME_Exception)
817 if ( theGroup->_is_nil() )
820 SMESH_GroupBase_i* aGroup =
821 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
825 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
826 if ( !aStudy->_is_nil() ) {
827 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
829 if ( !aGroupSO->_is_nil() ) {
830 // Update Python script
831 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
833 // Remove group's SObject
834 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
838 // Remove the group from SMESH data structures
839 removeGroup( aGroup->GetLocalID() );
842 //=============================================================================
843 /*! RemoveGroupWithContents
844 * Remove group with its contents
846 //=============================================================================
847 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
848 throw (SALOME::SALOME_Exception)
850 if ( theGroup->_is_nil() )
853 SMESH_GroupBase_i* aGroup =
854 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
858 SMESH::long_array_var anIds = aGroup->GetListOfID();
859 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
861 // Update Python script
862 TPythonDump() << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
865 if ( aGroup->GetType() == SMESH::NODE )
866 aMeshEditor->RemoveNodes( anIds );
868 aMeshEditor->RemoveElements( anIds );
871 RemoveGroup( theGroup );
873 // Clear python lines, created by RemoveNodes/Elements() and RemoveGroup()
874 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
875 _gen_i->RemoveLastFromPythonScript(_gen_i->GetCurrentStudy()->StudyId());
879 //================================================================================
881 * \brief Get the list of groups existing in the mesh
882 * \retval SMESH::ListOfGroups * - list of groups
884 //================================================================================
886 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
888 Unexpect aCatch(SALOME_SalomeException);
889 if (MYDEBUG) MESSAGE("GetGroups");
891 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
894 TPythonDump aPythonDump;
895 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
899 aList->length( _mapGroups.size() );
901 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
902 for ( ; it != _mapGroups.end(); it++ ) {
903 if ( CORBA::is_nil( it->second )) continue;
904 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
906 if (i > 1) aPythonDump << ", ";
907 aPythonDump << it->second;
911 catch(SALOME_Exception & S_ex) {
912 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
915 // Update Python script
916 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
917 aPythonDump << " ] = " << _this() << ".GetGroups()";
919 return aList._retn();
921 //=============================================================================
923 * Get number of groups existing in the mesh
925 //=============================================================================
927 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
929 Unexpect aCatch(SALOME_SalomeException);
930 return _mapGroups.size();
933 //=============================================================================
935 * New group is created. All mesh elements that are
936 * present in initial groups are added to the new one
938 //=============================================================================
939 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
940 SMESH::SMESH_GroupBase_ptr theGroup2,
941 const char* theName )
942 throw (SALOME::SALOME_Exception)
946 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
947 theGroup1->GetType() != theGroup2->GetType() )
948 return SMESH::SMESH_Group::_nil();
951 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
952 if ( aResGrp->_is_nil() )
953 return SMESH::SMESH_Group::_nil();
955 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
956 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
958 TColStd_MapOfInteger aResMap;
960 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
961 aResMap.Add( anIds1[ i1 ] );
963 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
964 aResMap.Add( anIds2[ i2 ] );
966 SMESH::long_array_var aResIds = new SMESH::long_array;
967 aResIds->length( aResMap.Extent() );
970 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
971 for( ; anIter.More(); anIter.Next() )
972 aResIds[ resI++ ] = anIter.Key();
974 aResGrp->Add( aResIds );
976 // Clear python lines, created by CreateGroup() and Add()
977 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
978 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
979 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
981 // Update Python script
982 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
983 << theGroup1 << ", " << theGroup2 << ", '"
986 return aResGrp._retn();
990 return SMESH::SMESH_Group::_nil();
994 //=============================================================================
996 \brief Union list of groups. New group is created. All mesh elements that are
997 present in initial groups are added to the new one.
998 \param theGroups list of groups
999 \param theName name of group to be created
1000 \return pointer on the group
1002 //=============================================================================
1003 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1004 const char* theName )
1005 throw (SALOME::SALOME_Exception)
1008 return SMESH::SMESH_Group::_nil();
1012 NCollection_Map< int > anIds;
1013 SMESH::ElementType aType = SMESH::ALL;
1014 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1016 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1017 if ( CORBA::is_nil( aGrp ) )
1021 SMESH::ElementType aCurrType = aGrp->GetType();
1022 if ( aType == SMESH::ALL )
1026 if ( aType != aCurrType )
1027 return SMESH::SMESH_Group::_nil();
1031 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1032 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1034 int aCurrId = aCurrIds[ i ];
1035 anIds.Add( aCurrId );
1040 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1041 if ( aResGrp->_is_nil() )
1042 return SMESH::SMESH_Group::_nil();
1044 // Create array of identifiers
1045 SMESH::long_array_var aResIds = new SMESH::long_array;
1046 aResIds->length( anIds.Extent() );
1048 NCollection_Map< int >::Iterator anIter( anIds );
1049 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1051 aResIds[ i ] = anIter.Value();
1053 aResGrp->Add( aResIds );
1055 // Clear python lines, created by CreateGroup() and Add()
1056 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1057 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1058 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1060 // Update Python script
1062 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1063 << &theGroups << ", '" << theName << "' )";
1065 return aResGrp._retn();
1069 return SMESH::SMESH_Group::_nil();
1073 //=============================================================================
1075 * New group is created. All mesh elements that are
1076 * present in both initial groups are added to the new one.
1078 //=============================================================================
1079 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1080 SMESH::SMESH_GroupBase_ptr theGroup2,
1081 const char* theName )
1082 throw (SALOME::SALOME_Exception)
1084 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1085 theGroup1->GetType() != theGroup2->GetType() )
1086 return SMESH::SMESH_Group::_nil();
1088 // Create Intersection
1089 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1090 if ( aResGrp->_is_nil() )
1093 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1094 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1096 TColStd_MapOfInteger aMap1;
1098 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1099 aMap1.Add( anIds1[ i1 ] );
1101 TColStd_SequenceOfInteger aSeq;
1103 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1104 if ( aMap1.Contains( anIds2[ i2 ] ) )
1105 aSeq.Append( anIds2[ i2 ] );
1107 SMESH::long_array_var aResIds = new SMESH::long_array;
1108 aResIds->length( aSeq.Length() );
1110 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1111 aResIds[ resI ] = aSeq( resI + 1 );
1113 aResGrp->Add( aResIds );
1115 // Clear python lines, created by CreateGroup() and Add()
1116 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1117 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1118 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1120 // Update Python script
1121 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1122 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1124 return aResGrp._retn();
1127 //=============================================================================
1129 \brief Intersect list of groups. New group is created. All mesh elements that
1130 are present in all initial groups simultaneously are added to the new one.
1131 \param theGroups list of groups
1132 \param theName name of group to be created
1133 \return pointer on the group
1135 //=============================================================================
1136 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1137 const SMESH::ListOfGroups& theGroups, const char* theName )
1138 throw (SALOME::SALOME_Exception)
1141 return SMESH::SMESH_Group::_nil();
1145 NCollection_DataMap< int, int > anIdToCount;
1146 SMESH::ElementType aType = SMESH::ALL;
1147 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1149 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1150 if ( CORBA::is_nil( aGrp ) )
1154 SMESH::ElementType aCurrType = aGrp->GetType();
1155 if ( aType == SMESH::ALL )
1159 if ( aType != aCurrType )
1160 return SMESH::SMESH_Group::_nil();
1163 // calculates number of occurance ids in groups
1164 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1165 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1167 int aCurrId = aCurrIds[ i ];
1168 if ( !anIdToCount.IsBound( aCurrId ) )
1169 anIdToCount.Bind( aCurrId, 1 );
1171 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1175 // create map of ids
1176 int nbGrp = theGroups.length();
1177 NCollection_Map< int > anIds;
1178 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1179 for ( ; anIter.More(); anIter.Next() )
1181 int aCurrId = anIter.Key();
1182 int aCurrNb = anIter.Value();
1183 if ( aCurrNb == nbGrp )
1184 anIds.Add( aCurrId );
1188 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1189 if ( aResGrp->_is_nil() )
1190 return SMESH::SMESH_Group::_nil();
1192 // Create array of identifiers
1193 SMESH::long_array_var aResIds = new SMESH::long_array;
1194 aResIds->length( anIds.Extent() );
1196 NCollection_Map< int >::Iterator aListIter( anIds );
1197 for ( int i = 0; aListIter.More(); aListIter.Next(), i++ )
1199 aResIds[ i ] = aListIter.Value();
1201 aResGrp->Add( aResIds );
1203 // Clear python lines, created by CreateGroup() and Add()
1204 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1205 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1206 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1208 // Update Python script
1210 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1211 << &theGroups << ", '" << theName << "' )";
1213 return aResGrp._retn();
1217 return SMESH::SMESH_Group::_nil();
1221 //=============================================================================
1223 * New group is created. All mesh elements that are present in
1224 * main group but do not present in tool group are added to the new one
1226 //=============================================================================
1227 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1228 SMESH::SMESH_GroupBase_ptr theGroup2,
1229 const char* theName )
1230 throw (SALOME::SALOME_Exception)
1232 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1233 theGroup1->GetType() != theGroup2->GetType() )
1234 return SMESH::SMESH_Group::_nil();
1237 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1238 if ( aResGrp->_is_nil() )
1241 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1242 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1244 TColStd_MapOfInteger aMap2;
1246 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1247 aMap2.Add( anIds2[ i2 ] );
1249 TColStd_SequenceOfInteger aSeq;
1250 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1251 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1252 aSeq.Append( anIds1[ i1 ] );
1254 SMESH::long_array_var aResIds = new SMESH::long_array;
1255 aResIds->length( aSeq.Length() );
1257 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1258 aResIds[ resI ] = aSeq( resI + 1 );
1260 aResGrp->Add( aResIds );
1262 // Clear python lines, created by CreateGroup() and Add()
1263 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1264 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1265 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1267 // Update Python script
1268 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1269 << theGroup1 << ", " << theGroup2 << ", '"
1270 << theName << "' )";
1272 return aResGrp._retn();
1275 //=============================================================================
1277 \brief Cut lists of groups. New group is created. All mesh elements that are
1278 present in main groups but do not present in tool groups are added to the new one
1279 \param theMainGroups list of main groups
1280 \param theToolGroups list of tool groups
1281 \param theName name of group to be created
1282 \return pointer on the group
1284 //=============================================================================
1285 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1286 const SMESH::ListOfGroups& theMainGroups,
1287 const SMESH::ListOfGroups& theToolGroups,
1288 const char* theName )
1289 throw (SALOME::SALOME_Exception)
1292 return SMESH::SMESH_Group::_nil();
1296 NCollection_Map< int > aToolIds;
1297 SMESH::ElementType aType = SMESH::ALL;
1299 // iterate through tool groups
1300 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1302 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1303 if ( CORBA::is_nil( aGrp ) )
1307 SMESH::ElementType aCurrType = aGrp->GetType();
1308 if ( aType == SMESH::ALL )
1312 if ( aType != aCurrType )
1313 return SMESH::SMESH_Group::_nil();
1317 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1318 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1320 int aCurrId = aCurrIds[ i ];
1321 aToolIds.Add( aCurrId );
1325 NCollection_Map< int > anIds; // result
1327 // Iterate through main group
1328 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1330 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1331 if ( CORBA::is_nil( aGrp ) )
1335 SMESH::ElementType aCurrType = aGrp->GetType();
1336 if ( aType == SMESH::ALL )
1340 if ( aType != aCurrType )
1341 return SMESH::SMESH_Group::_nil();
1345 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1346 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1348 int aCurrId = aCurrIds[ i ];
1349 if ( !aToolIds.Contains( aCurrId ) )
1350 anIds.Add( aCurrId );
1355 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1356 if ( aResGrp->_is_nil() )
1357 return SMESH::SMESH_Group::_nil();
1359 // Create array of identifiers
1360 SMESH::long_array_var aResIds = new SMESH::long_array;
1361 aResIds->length( anIds.Extent() );
1363 NCollection_Map< int >::Iterator anIter( anIds );
1364 for ( int i = 0; anIter.More(); anIter.Next(), i++ )
1366 aResIds[ i ] = anIter.Value();
1368 aResGrp->Add( aResIds );
1370 // Clear python lines, created by CreateGroup() and Add()
1371 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1372 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1373 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1375 // Update Python script
1377 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1378 << &theMainGroups << ", " << &theToolGroups << ", '"
1379 << theName << "' )";
1381 return aResGrp._retn();
1385 return SMESH::SMESH_Group::_nil();
1389 //=============================================================================
1391 \brief Create groups of entities from existing groups of superior dimensions
1393 1) extract all nodes from each group,
1394 2) combine all elements of specified dimension laying on these nodes.
1395 \param theGroups list of source groups
1396 \param theElemType dimension of elements
1397 \param theName name of new group
1398 \return pointer on new group
1400 //=============================================================================
1401 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1402 const SMESH::ListOfGroups& theGroups,
1403 SMESH::ElementType theElemType,
1404 const char* theName )
1405 throw (SALOME::SALOME_Exception)
1407 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1409 if ( !theName || !aMeshDS )
1410 return SMESH::SMESH_Group::_nil();
1412 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1416 // Create map of nodes from all groups
1418 NCollection_Map< int > aNodeMap;
1420 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1422 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1423 if ( CORBA::is_nil( aGrp ) )
1426 SMESH::ElementType aType = aGrp->GetType();
1427 if ( aType == SMESH::ALL )
1429 else if ( aType == SMESH::NODE )
1431 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1432 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1434 int aCurrId = aCurrIds[ i ];
1435 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1437 aNodeMap.Add( aNode->GetID() );
1442 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1443 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1445 int aCurrId = aCurrIds[ i ];
1446 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1449 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1450 while( aNodeIter->more() )
1452 const SMDS_MeshNode* aNode =
1453 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1455 aNodeMap.Add( aNode->GetID() );
1461 // Get result identifiers
1463 NCollection_Map< int > aResultIds;
1464 if ( theElemType == SMESH::NODE )
1466 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1467 for ( ; aNodeIter.More(); aNodeIter.Next() )
1468 aResultIds.Add( aNodeIter.Value() );
1472 // Create list of elements of given dimension constructed on the nodes
1473 NCollection_Map< int > anElemList;
1474 NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1475 for ( ; aNodeIter.More(); aNodeIter.Next() )
1477 const SMDS_MeshElement* aNode =
1478 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( aNodeIter.Value() ) );
1482 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1483 while( anElemIter->more() )
1485 const SMDS_MeshElement* anElem =
1486 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1487 if ( anElem && anElem->GetType() == anElemType )
1488 anElemList.Add( anElem->GetID() );
1492 // check whether all nodes of elements are present in nodes map
1493 NCollection_Map< int >::Iterator anIter( anElemList );
1494 for ( ; anIter.More(); anIter.Next() )
1496 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anIter.Value() );
1501 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1502 while( aNodeIter->more() )
1504 const SMDS_MeshNode* aNode =
1505 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1506 if ( !aNode || !aNodeMap.Contains( aNode->GetID() ) )
1513 aResultIds.Add( anElem->GetID() );
1519 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1520 if ( aResGrp->_is_nil() )
1521 return SMESH::SMESH_Group::_nil();
1523 // Create array of identifiers
1524 SMESH::long_array_var aResIds = new SMESH::long_array;
1525 aResIds->length( aResultIds.Extent() );
1527 NCollection_Map< int >::Iterator aResIter( aResultIds );
1528 for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1529 aResIds[ i ] = aResIter.Value();
1530 aResGrp->Add( aResIds );
1532 // Remove strings corresponding to group creation
1533 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1534 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1535 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1537 // Update Python script
1539 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1540 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1542 return aResGrp._retn();
1546 return SMESH::SMESH_Group::_nil();
1550 //================================================================================
1552 * \brief Remember GEOM group data
1554 //================================================================================
1556 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1557 CORBA::Object_ptr theSmeshObj)
1559 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1562 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1563 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1564 if ( groupSO->_is_nil() )
1567 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1568 GEOM::GEOM_IGroupOperations_var groupOp =
1569 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1570 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1573 _geomGroupData.push_back( TGeomGroupData() );
1574 TGeomGroupData & groupData = _geomGroupData.back();
1576 CORBA::String_var entry = groupSO->GetID();
1577 groupData._groupEntry = entry.in();
1579 for ( int i = 0; i < ids->length(); ++i )
1580 groupData._indices.insert( ids[i] );
1582 groupData._smeshObject = theSmeshObj;
1585 //================================================================================
1587 * Remove GEOM group data relating to removed smesh object
1589 //================================================================================
1591 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1593 list<TGeomGroupData>::iterator
1594 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1595 for ( ; data != dataEnd; ++data ) {
1596 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1597 _geomGroupData.erase( data );
1603 //================================================================================
1605 * \brief Return new group contents if it has been changed and update group data
1607 //================================================================================
1609 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1611 TopoDS_Shape newShape;
1614 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1615 if ( study->_is_nil() ) return newShape; // means "not changed"
1616 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1617 if ( !groupSO->_is_nil() )
1619 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1620 if ( CORBA::is_nil( groupObj )) return newShape;
1621 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1623 // get indices of group items
1624 set<int> curIndices;
1625 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1626 GEOM::GEOM_IGroupOperations_var groupOp =
1627 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1628 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1629 for ( int i = 0; i < ids->length(); ++i )
1630 curIndices.insert( ids[i] );
1632 if ( groupData._indices == curIndices )
1633 return newShape; // group not changed
1636 groupData._indices = curIndices;
1638 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1639 if ( !geomClient ) return newShape;
1640 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1641 geomClient->RemoveShapeFromBuffer( groupIOR );
1642 newShape = _gen_i->GeomObjectToShape( geomGroup );
1645 if ( newShape.IsNull() ) {
1646 // geom group becomes empty - return empty compound
1647 TopoDS_Compound compound;
1648 BRep_Builder().MakeCompound(compound);
1649 newShape = compound;
1655 //=============================================================================
1657 * \brief Storage of shape and index used in CheckGeomGroupModif()
1659 //=============================================================================
1660 struct TIndexedShape {
1662 TopoDS_Shape _shape;
1663 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1666 //=============================================================================
1668 * \brief Update objects depending on changed geom groups
1670 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1671 * issue 0020210: Update of a smesh group after modification of the associated geom group
1673 //=============================================================================
1675 void SMESH_Mesh_i::CheckGeomGroupModif()
1677 if ( !_impl->HasShapeToMesh() ) return;
1679 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1680 if ( study->_is_nil() ) return;
1682 CORBA::Long nbEntities = NbNodes() + NbElements();
1684 // Check if group contents changed
1686 typedef map< string, TopoDS_Shape > TEntry2Geom;
1687 TEntry2Geom newGroupContents;
1689 list<TGeomGroupData>::iterator
1690 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1691 for ( ; data != dataEnd; ++data )
1693 pair< TEntry2Geom::iterator, bool > it_new =
1694 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1695 bool processedGroup = !it_new.second;
1696 TopoDS_Shape& newShape = it_new.first->second;
1697 if ( !processedGroup )
1698 newShape = newGroupShape( *data );
1699 if ( newShape.IsNull() )
1700 continue; // no changes
1702 if ( processedGroup ) { // update group indices
1703 list<TGeomGroupData>::iterator data2 = data;
1704 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1705 data->_indices = data2->_indices;
1708 // Update SMESH objects according to new GEOM group contents
1710 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1711 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1713 int oldID = submesh->GetId();
1714 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1716 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1718 // update hypotheses
1719 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1720 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1721 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1723 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1724 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1726 // care of submeshes
1727 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1728 int newID = newSubmesh->GetId();
1729 if ( newID != oldID ) {
1730 _mapSubMesh [ newID ] = newSubmesh;
1731 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1732 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1733 _mapSubMesh. erase(oldID);
1734 _mapSubMesh_i. erase(oldID);
1735 _mapSubMeshIor.erase(oldID);
1736 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1741 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1742 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1743 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1745 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1747 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1748 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1749 ds->SetShape( newShape );
1754 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1755 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1757 // Remove groups and submeshes basing on removed sub-shapes
1759 TopTools_MapOfShape newShapeMap;
1760 TopoDS_Iterator shapeIt( newShape );
1761 for ( ; shapeIt.More(); shapeIt.Next() )
1762 newShapeMap.Add( shapeIt.Value() );
1764 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1765 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1767 if ( newShapeMap.Contains( shapeIt.Value() ))
1769 TopTools_IndexedMapOfShape oldShapeMap;
1770 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1771 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1773 const TopoDS_Shape& oldShape = oldShapeMap(i);
1774 int oldInd = meshDS->ShapeToIndex( oldShape );
1776 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1777 if ( i_smIor != _mapSubMeshIor.end() ) {
1778 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1781 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1782 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1784 // check if a group bases on oldInd shape
1785 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1786 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1787 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1788 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1790 RemoveGroup( i_grp->second ); // several groups can base on same shape
1791 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1796 // Reassign hypotheses and update groups after setting the new shape to mesh
1798 // collect anassigned hypotheses
1799 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1800 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1801 TShapeHypList assignedHyps;
1802 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1804 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1805 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1806 if ( !hyps.empty() ) {
1807 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1808 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1809 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1812 // collect shapes supporting groups
1813 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1814 TShapeTypeList groupData;
1815 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1816 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1817 for ( ; grIt != groups.end(); ++grIt )
1819 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1821 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1823 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1824 _impl->ShapeToMesh( newShape );
1826 // reassign hypotheses
1827 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1828 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1830 TIndexedShape& geom = indS_hyps->first;
1831 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1832 int oldID = geom._index;
1833 int newID = meshDS->ShapeToIndex( geom._shape );
1836 if ( oldID == 1 ) { // main shape
1838 geom._shape = newShape;
1840 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1841 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1842 // care of submeshes
1843 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1844 if ( newID != oldID ) {
1845 _mapSubMesh [ newID ] = newSubmesh;
1846 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1847 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1848 _mapSubMesh. erase(oldID);
1849 _mapSubMesh_i. erase(oldID);
1850 _mapSubMeshIor.erase(oldID);
1851 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1855 TShapeTypeList::iterator geomType = groupData.begin();
1856 for ( ; geomType != groupData.end(); ++geomType )
1858 const TIndexedShape& geom = geomType->first;
1859 int oldID = geom._index;
1860 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1863 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1864 CORBA::String_var name = groupSO->GetName();
1866 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1868 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1869 group_i->changeLocalId( newID );
1872 break; // everything has been updated
1875 } // loop on group data
1879 CORBA::Long newNbEntities = NbNodes() + NbElements();
1880 list< SALOMEDS::SObject_var > soToUpdateIcons;
1881 if ( newNbEntities != nbEntities )
1883 // Add all SObjects with icons
1884 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1886 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1887 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1888 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1890 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1891 i_gr != _mapGroups.end(); ++i_gr ) // groups
1892 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1895 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1896 for ( ; so != soToUpdateIcons.end(); ++so )
1897 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1900 //=============================================================================
1902 * \brief Create standalone group instead if group on geometry
1904 //=============================================================================
1906 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupOnGeom_ptr theGroup )
1908 SMESH::SMESH_Group_var aGroup;
1909 if ( theGroup->_is_nil() )
1910 return aGroup._retn();
1912 Unexpect aCatch(SALOME_SalomeException);
1914 SMESH_GroupBase_i* aGroupToRem =
1915 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1917 return aGroup._retn();
1919 int anId = aGroupToRem->GetLocalID();
1920 if ( !_impl->ConvertToStandalone( anId ) )
1921 return aGroup._retn();
1922 removeGeomGroupData( theGroup );
1924 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1926 // remove old instance of group from own map
1927 _mapGroups.erase( anId );
1929 SALOMEDS::StudyBuilder_var builder;
1930 SALOMEDS::SObject_var aGroupSO;
1931 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1932 if ( !aStudy->_is_nil() ) {
1933 builder = aStudy->NewBuilder();
1934 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1935 if ( !aGroupSO->_is_nil() ) {
1937 // remove reference to geometry
1938 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
1939 for ( ; chItr->More(); chItr->Next() )
1940 // Remove group's child SObject
1941 builder->RemoveObject( chItr->Value() );
1943 // Update Python script
1944 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
1945 << aGroupSO << " )";
1949 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1950 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
1951 aGroupImpl->Register();
1952 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
1954 // remember new group in own map
1955 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
1956 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
1958 // register CORBA object for persistence
1959 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
1961 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
1963 return aGroup._retn();
1966 //=============================================================================
1970 //=============================================================================
1972 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
1974 if(MYDEBUG) MESSAGE( "createSubMesh" );
1975 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
1977 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
1978 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
1979 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
1980 SMESH::SMESH_subMesh_var subMesh
1981 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
1983 _mapSubMesh[subMeshId] = mySubMesh;
1984 _mapSubMesh_i[subMeshId] = subMeshServant;
1985 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
1987 // register CORBA object for persistence
1988 int nextId = _gen_i->RegisterObject( subMesh );
1989 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
1991 // to track changes of GEOM groups
1992 addGeomGroupData( theSubShapeObject, subMesh );
1994 return subMesh._retn();
1997 //=======================================================================
1998 //function : getSubMesh
2000 //=======================================================================
2002 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2004 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2005 if ( it == _mapSubMeshIor.end() )
2006 return SMESH::SMESH_subMesh::_nil();
2008 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2012 //=============================================================================
2016 //=============================================================================
2018 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2019 GEOM::GEOM_Object_ptr theSubShapeObject )
2021 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2022 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2025 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2027 CORBA::Long shapeId = theSubMesh->GetId();
2028 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2030 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2033 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2034 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2035 for ( ; hyp != hyps.end(); ++hyp )
2036 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2043 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2044 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2045 removeHypothesis( theSubShapeObject, aHypList[i] );
2048 catch( const SALOME::SALOME_Exception& ) {
2049 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2051 removeGeomGroupData( theSubShapeObject );
2053 int subMeshId = theSubMesh->GetId();
2055 _mapSubMesh.erase(subMeshId);
2056 _mapSubMesh_i.erase(subMeshId);
2057 _mapSubMeshIor.erase(subMeshId);
2058 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2061 //=============================================================================
2065 //=============================================================================
2067 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2068 const char* theName,
2069 const TopoDS_Shape& theShape )
2072 SMESH::SMESH_GroupBase_var aGroup;
2073 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape )) {
2074 SMESH_GroupBase_i* aGroupImpl;
2075 if ( !theShape.IsNull() )
2076 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2078 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2080 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2081 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2082 aGroupImpl->Register();
2083 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2085 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2086 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2088 // register CORBA object for persistence
2089 int nextId = _gen_i->RegisterObject( aGroup );
2090 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2092 // to track changes of GEOM groups
2093 if ( !theShape.IsNull() ) {
2094 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2095 addGeomGroupData( geom, aGroup );
2098 return aGroup._retn();
2101 //=============================================================================
2103 * SMESH_Mesh_i::removeGroup
2105 * Should be called by ~SMESH_Group_i()
2107 //=============================================================================
2109 void SMESH_Mesh_i::removeGroup( const int theId )
2111 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2112 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2113 removeGeomGroupData( _mapGroups[theId] );
2114 _mapGroups.erase( theId );
2115 _impl->RemoveGroup( theId );
2120 //=============================================================================
2124 //=============================================================================
2126 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2127 throw(SALOME::SALOME_Exception)
2129 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2131 SMESH::log_array_var aLog;
2133 list < SMESHDS_Command * >logDS = _impl->GetLog();
2134 aLog = new SMESH::log_array;
2136 int lg = logDS.size();
2139 list < SMESHDS_Command * >::iterator its = logDS.begin();
2140 while(its != logDS.end()){
2141 SMESHDS_Command *com = *its;
2142 int comType = com->GetType();
2144 int lgcom = com->GetNumber();
2146 const list < int >&intList = com->GetIndexes();
2147 int inum = intList.size();
2149 list < int >::const_iterator ii = intList.begin();
2150 const list < double >&coordList = com->GetCoords();
2151 int rnum = coordList.size();
2153 list < double >::const_iterator ir = coordList.begin();
2154 aLog[indexLog].commandType = comType;
2155 aLog[indexLog].number = lgcom;
2156 aLog[indexLog].coords.length(rnum);
2157 aLog[indexLog].indexes.length(inum);
2158 for(int i = 0; i < rnum; i++){
2159 aLog[indexLog].coords[i] = *ir;
2160 //MESSAGE(" "<<i<<" "<<ir.Value());
2163 for(int i = 0; i < inum; i++){
2164 aLog[indexLog].indexes[i] = *ii;
2165 //MESSAGE(" "<<i<<" "<<ii.Value());
2174 catch(SALOME_Exception & S_ex){
2175 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2177 return aLog._retn();
2181 //=============================================================================
2185 //=============================================================================
2187 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2189 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2193 //=============================================================================
2197 //=============================================================================
2199 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2201 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2205 //=============================================================================
2209 //=============================================================================
2211 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2216 //=============================================================================
2220 //=============================================================================
2222 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2224 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2228 //=============================================================================
2232 //=============================================================================
2234 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2236 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2240 //=============================================================================
2242 * Return mesh editor
2244 //=============================================================================
2246 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2248 // Create MeshEditor
2249 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2250 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2252 // Update Python script
2253 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2255 return aMesh._retn();
2258 //=============================================================================
2260 * Return mesh edition previewer
2262 //=============================================================================
2264 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2266 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2267 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2268 return aMesh._retn();
2271 //================================================================================
2273 * \brief Return true if the mesh has been edited since a last total re-compute
2274 * and those modifications may prevent successful partial re-compute
2276 //================================================================================
2278 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2280 Unexpect aCatch(SALOME_SalomeException);
2281 return _impl->HasModificationsToDiscard();
2284 //=============================================================================
2288 //=============================================================================
2289 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2291 Unexpect aCatch(SALOME_SalomeException);
2292 _impl->SetAutoColor(theAutoColor);
2295 //=============================================================================
2299 //=============================================================================
2300 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2302 Unexpect aCatch(SALOME_SalomeException);
2303 return _impl->GetAutoColor();
2307 //=============================================================================
2309 * Export in different formats
2311 //=============================================================================
2313 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2315 return _impl->HasDuplicatedGroupNamesMED();
2318 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2320 TCollection_AsciiString aFullName ((char*)file);
2321 OSD_Path aPath (aFullName);
2322 OSD_File aFile (aPath);
2323 if (aFile.Exists()) {
2324 // existing filesystem node
2325 if (aFile.KindOfFile() == OSD_FILE) {
2326 if (aFile.IsWriteable()) {
2331 if (aFile.Failed()) {
2332 TCollection_AsciiString msg ("File ");
2333 msg += aFullName + " cannot be replaced.";
2334 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2337 TCollection_AsciiString msg ("File ");
2338 msg += aFullName + " cannot be overwritten.";
2339 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2342 TCollection_AsciiString msg ("Location ");
2343 msg += aFullName + " is not a file.";
2344 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2347 // nonexisting file; check if it can be created
2349 aFile.Build(OSD_WriteOnly, OSD_Protection());
2350 if (aFile.Failed()) {
2351 TCollection_AsciiString msg ("You cannot create the file ");
2352 msg += aFullName + ". Check the directory existance and access rights.";
2353 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2361 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2362 CORBA::Boolean auto_groups,
2363 SMESH::MED_VERSION theVersion,
2364 CORBA::Boolean overwrite)
2365 throw(SALOME::SALOME_Exception)
2367 Unexpect aCatch(SALOME_SalomeException);
2370 PrepareForWriting(file, overwrite);
2371 const char* aMeshName = "Mesh";
2372 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2373 if ( !aStudy->_is_nil() ) {
2374 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2375 if ( !aMeshSO->_is_nil() ) {
2376 aMeshName = aMeshSO->GetName();
2377 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2378 if ( !aStudy->GetProperties()->IsLocked() )
2380 SALOMEDS::GenericAttribute_var anAttr;
2381 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2382 SALOMEDS::AttributeExternalFileDef_var aFileName;
2383 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2384 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2385 ASSERT(!aFileName->_is_nil());
2386 aFileName->SetValue(file);
2387 SALOMEDS::AttributeFileType_var aFileType;
2388 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2389 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2390 ASSERT(!aFileType->_is_nil());
2391 aFileType->SetValue("FICHIERMED");
2395 // Update Python script
2396 // set name of mesh before export
2397 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName << "')";
2399 // check names of groups
2402 TPythonDump() << _this() << ".ExportToMEDX( r'"
2403 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2405 _impl->ExportMED( file, aMeshName, auto_groups, theVersion );
2408 void SMESH_Mesh_i::ExportToMED (const char* file,
2409 CORBA::Boolean auto_groups,
2410 SMESH::MED_VERSION theVersion)
2411 throw(SALOME::SALOME_Exception)
2413 ExportToMEDX(file,auto_groups,theVersion,true);
2416 void SMESH_Mesh_i::ExportMED (const char* file,
2417 CORBA::Boolean auto_groups)
2418 throw(SALOME::SALOME_Exception)
2420 ExportToMEDX(file,auto_groups,SMESH::MED_V2_1,true);
2423 void SMESH_Mesh_i::ExportDAT (const char *file)
2424 throw(SALOME::SALOME_Exception)
2426 Unexpect aCatch(SALOME_SalomeException);
2428 // Update Python script
2429 // check names of groups
2431 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2434 PrepareForWriting(file);
2435 _impl->ExportDAT(file);
2438 void SMESH_Mesh_i::ExportUNV (const char *file)
2439 throw(SALOME::SALOME_Exception)
2441 Unexpect aCatch(SALOME_SalomeException);
2443 // Update Python script
2444 // check names of groups
2446 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2449 PrepareForWriting(file);
2450 _impl->ExportUNV(file);
2453 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2454 throw(SALOME::SALOME_Exception)
2456 Unexpect aCatch(SALOME_SalomeException);
2458 // Update Python script
2459 // check names of groups
2461 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2464 PrepareForWriting(file);
2465 _impl->ExportSTL(file, isascii);
2468 //=============================================================================
2472 //=============================================================================
2474 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2476 Unexpect aCatch(SALOME_SalomeException);
2477 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2478 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2479 return aMesh._retn();
2482 //=============================================================================
2486 //=============================================================================
2487 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2489 Unexpect aCatch(SALOME_SalomeException);
2490 return _impl->NbNodes();
2493 //=============================================================================
2497 //=============================================================================
2498 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2500 Unexpect aCatch(SALOME_SalomeException);
2501 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2504 //=============================================================================
2508 //=============================================================================
2509 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2511 Unexpect aCatch(SALOME_SalomeException);
2512 return _impl->Nb0DElements();
2515 //=============================================================================
2519 //=============================================================================
2520 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2522 Unexpect aCatch(SALOME_SalomeException);
2523 return _impl->NbEdges();
2526 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2527 throw(SALOME::SALOME_Exception)
2529 Unexpect aCatch(SALOME_SalomeException);
2530 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2533 //=============================================================================
2537 //=============================================================================
2538 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2540 Unexpect aCatch(SALOME_SalomeException);
2541 return _impl->NbFaces();
2544 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2546 Unexpect aCatch(SALOME_SalomeException);
2547 return _impl->NbTriangles();
2550 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2552 Unexpect aCatch(SALOME_SalomeException);
2553 return _impl->NbQuadrangles();
2556 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2558 Unexpect aCatch(SALOME_SalomeException);
2559 return _impl->NbPolygons();
2562 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2563 throw(SALOME::SALOME_Exception)
2565 Unexpect aCatch(SALOME_SalomeException);
2566 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2569 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2570 throw(SALOME::SALOME_Exception)
2572 Unexpect aCatch(SALOME_SalomeException);
2573 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2576 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2577 throw(SALOME::SALOME_Exception)
2579 Unexpect aCatch(SALOME_SalomeException);
2580 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2583 //=============================================================================
2587 //=============================================================================
2588 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2590 Unexpect aCatch(SALOME_SalomeException);
2591 return _impl->NbVolumes();
2594 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2596 Unexpect aCatch(SALOME_SalomeException);
2597 return _impl->NbTetras();
2600 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2602 Unexpect aCatch(SALOME_SalomeException);
2603 return _impl->NbHexas();
2606 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2608 Unexpect aCatch(SALOME_SalomeException);
2609 return _impl->NbPyramids();
2612 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2614 Unexpect aCatch(SALOME_SalomeException);
2615 return _impl->NbPrisms();
2618 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2620 Unexpect aCatch(SALOME_SalomeException);
2621 return _impl->NbPolyhedrons();
2624 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2625 throw(SALOME::SALOME_Exception)
2627 Unexpect aCatch(SALOME_SalomeException);
2628 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2631 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2632 throw(SALOME::SALOME_Exception)
2634 Unexpect aCatch(SALOME_SalomeException);
2635 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2638 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2639 throw(SALOME::SALOME_Exception)
2641 Unexpect aCatch(SALOME_SalomeException);
2642 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2645 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2646 throw(SALOME::SALOME_Exception)
2648 Unexpect aCatch(SALOME_SalomeException);
2649 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2652 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2653 throw(SALOME::SALOME_Exception)
2655 Unexpect aCatch(SALOME_SalomeException);
2656 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2659 //=============================================================================
2663 //=============================================================================
2664 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2666 Unexpect aCatch(SALOME_SalomeException);
2667 return _mapSubMesh_i.size();
2670 //=============================================================================
2674 //=============================================================================
2675 char* SMESH_Mesh_i::Dump()
2679 return CORBA::string_dup( os.str().c_str() );
2682 //=============================================================================
2686 //=============================================================================
2687 SMESH::long_array* SMESH_Mesh_i::GetIDs()
2689 // SMESH::long_array_var aResult = new SMESH::long_array();
2690 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2691 // int aMinId = aSMESHDS_Mesh->MinElementID();
2692 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
2694 // aResult->length(aMaxId - aMinId + 1);
2696 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
2697 // aResult[i++] = id;
2699 // return aResult._retn();
2701 return GetElementsId();
2704 //=============================================================================
2708 //=============================================================================
2710 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
2711 throw (SALOME::SALOME_Exception)
2713 Unexpect aCatch(SALOME_SalomeException);
2714 MESSAGE("SMESH_Mesh_i::GetElementsId");
2715 SMESH::long_array_var aResult = new SMESH::long_array();
2716 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2718 if ( aSMESHDS_Mesh == NULL )
2719 return aResult._retn();
2721 long nbElements = NbElements();
2722 aResult->length( nbElements );
2723 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2724 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
2725 aResult[i] = anIt->next()->GetID();
2727 return aResult._retn();
2731 //=============================================================================
2735 //=============================================================================
2737 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
2738 throw (SALOME::SALOME_Exception)
2740 Unexpect aCatch(SALOME_SalomeException);
2741 MESSAGE("SMESH_subMesh_i::GetElementsByType");
2742 SMESH::long_array_var aResult = new SMESH::long_array();
2743 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2745 if ( aSMESHDS_Mesh == NULL )
2746 return aResult._retn();
2748 long nbElements = NbElements();
2750 // No sense in returning ids of elements along with ids of nodes:
2751 // when theElemType == SMESH::ALL, return node ids only if
2752 // there are no elements
2753 if ( theElemType == SMESH::NODE || theElemType == SMESH::ALL && nbElements == 0 )
2754 return GetNodesId();
2756 aResult->length( nbElements );
2760 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
2761 while ( i < nbElements && anIt->more() ) {
2762 const SMDS_MeshElement* anElem = anIt->next();
2763 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
2764 aResult[i++] = anElem->GetID();
2767 aResult->length( i );
2769 return aResult._retn();
2772 //=============================================================================
2776 //=============================================================================
2778 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
2779 throw (SALOME::SALOME_Exception)
2781 Unexpect aCatch(SALOME_SalomeException);
2782 MESSAGE("SMESH_subMesh_i::GetNodesId");
2783 SMESH::long_array_var aResult = new SMESH::long_array();
2784 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2786 if ( aSMESHDS_Mesh == NULL )
2787 return aResult._retn();
2789 long nbNodes = NbNodes();
2790 aResult->length( nbNodes );
2791 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator();
2792 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
2793 aResult[i] = anIt->next()->GetID();
2795 return aResult._retn();
2798 //=============================================================================
2802 //=============================================================================
2804 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
2805 throw (SALOME::SALOME_Exception)
2807 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
2810 //=============================================================================
2814 //=============================================================================
2816 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
2817 throw (SALOME::SALOME_Exception)
2819 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
2821 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
2823 return ( SMESH::EntityType ) e->GetEntityType();
2826 //=============================================================================
2828 * Returns ID of elements for given submesh
2830 //=============================================================================
2831 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
2832 throw (SALOME::SALOME_Exception)
2834 SMESH::long_array_var aResult = new SMESH::long_array();
2836 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2837 if(!SM) return aResult._retn();
2839 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2840 if(!SDSM) return aResult._retn();
2842 aResult->length(SDSM->NbElements());
2844 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2846 while ( eIt->more() ) {
2847 aResult[i++] = eIt->next()->GetID();
2850 return aResult._retn();
2854 //=============================================================================
2856 * Returns ID of nodes for given submesh
2857 * If param all==true - returns all nodes, else -
2858 * returns only nodes on shapes.
2860 //=============================================================================
2861 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
2862 throw (SALOME::SALOME_Exception)
2864 SMESH::long_array_var aResult = new SMESH::long_array();
2866 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2867 if(!SM) return aResult._retn();
2869 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2870 if(!SDSM) return aResult._retn();
2873 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
2874 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
2875 while ( nIt->more() ) {
2876 const SMDS_MeshNode* elem = nIt->next();
2877 theElems.insert( elem->GetID() );
2880 else { // all nodes of submesh elements
2881 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2882 while ( eIt->more() ) {
2883 const SMDS_MeshElement* anElem = eIt->next();
2884 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
2885 while ( nIt->more() ) {
2886 const SMDS_MeshElement* elem = nIt->next();
2887 theElems.insert( elem->GetID() );
2892 aResult->length(theElems.size());
2893 set<int>::iterator itElem;
2895 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
2896 aResult[i++] = *itElem;
2898 return aResult._retn();
2902 //=============================================================================
2904 * Returns type of elements for given submesh
2906 //=============================================================================
2907 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
2908 throw (SALOME::SALOME_Exception)
2910 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
2911 if(!SM) return SMESH::ALL;
2913 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
2914 if(!SDSM) return SMESH::ALL;
2916 if(SDSM->NbElements()==0)
2917 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
2919 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
2920 const SMDS_MeshElement* anElem = eIt->next();
2921 return ( SMESH::ElementType ) anElem->GetType();
2925 //=============================================================================
2929 //=============================================================================
2931 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
2933 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
2935 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
2940 //=============================================================================
2942 * Get XYZ coordinates of node as list of double
2943 * If there is not node for given ID - returns empty list
2945 //=============================================================================
2947 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
2949 SMESH::double_array_var aResult = new SMESH::double_array();
2950 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2951 if ( aSMESHDS_Mesh == NULL )
2952 return aResult._retn();
2955 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2957 return aResult._retn();
2961 aResult[0] = aNode->X();
2962 aResult[1] = aNode->Y();
2963 aResult[2] = aNode->Z();
2964 return aResult._retn();
2968 //=============================================================================
2970 * For given node returns list of IDs of inverse elements
2971 * If there is not node for given ID - returns empty list
2973 //=============================================================================
2975 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
2977 SMESH::long_array_var aResult = new SMESH::long_array();
2978 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
2979 if ( aSMESHDS_Mesh == NULL )
2980 return aResult._retn();
2983 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
2985 return aResult._retn();
2987 // find inverse elements
2988 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
2989 TColStd_SequenceOfInteger IDs;
2990 while(eIt->more()) {
2991 const SMDS_MeshElement* elem = eIt->next();
2992 IDs.Append(elem->GetID());
2994 if(IDs.Length()>0) {
2995 aResult->length(IDs.Length());
2997 for(; i<=IDs.Length(); i++) {
2998 aResult[i-1] = IDs.Value(i);
3001 return aResult._retn();
3004 //=============================================================================
3006 * \brief Return position of a node on shape
3008 //=============================================================================
3010 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3012 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3013 aNodePosition->shapeID = 0;
3014 aNodePosition->shapeType = GEOM::SHAPE;
3016 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3017 if ( !mesh ) return aNodePosition;
3019 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3021 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3023 aNodePosition->shapeID = pos->GetShapeId();
3024 switch ( pos->GetTypeOfPosition() ) {
3026 aNodePosition->shapeType = GEOM::EDGE;
3027 aNodePosition->params.length(1);
3028 aNodePosition->params[0] =
3029 static_cast<SMDS_EdgePosition*>( pos.get() )->GetUParameter();
3032 aNodePosition->shapeType = GEOM::FACE;
3033 aNodePosition->params.length(2);
3034 aNodePosition->params[0] =
3035 static_cast<SMDS_FacePosition*>( pos.get() )->GetUParameter();
3036 aNodePosition->params[1] =
3037 static_cast<SMDS_FacePosition*>( pos.get() )->GetVParameter();
3039 case SMDS_TOP_VERTEX:
3040 aNodePosition->shapeType = GEOM::VERTEX;
3042 case SMDS_TOP_3DSPACE:
3043 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3044 aNodePosition->shapeType = GEOM::SOLID;
3045 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3046 aNodePosition->shapeType = GEOM::SHELL;
3052 return aNodePosition;
3055 //=============================================================================
3057 * If given element is node returns IDs of shape from position
3058 * If there is not node for given ID - returns -1
3060 //=============================================================================
3062 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3064 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3065 if ( aSMESHDS_Mesh == NULL )
3069 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3071 SMDS_PositionPtr pos = aNode->GetPosition();
3075 return pos->GetShapeId();
3082 //=============================================================================
3084 * For given element returns ID of result shape after
3085 * ::FindShape() from SMESH_MeshEditor
3086 * If there is not element for given ID - returns -1
3088 //=============================================================================
3090 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3092 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3093 if ( aSMESHDS_Mesh == NULL )
3096 // try to find element
3097 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3101 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3102 ::SMESH_MeshEditor aMeshEditor(_impl);
3103 int index = aMeshEditor.FindShape( elem );
3111 //=============================================================================
3113 * Returns number of nodes for given element
3114 * If there is not element for given ID - returns -1
3116 //=============================================================================
3118 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3120 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3121 if ( aSMESHDS_Mesh == NULL ) return -1;
3122 // try to find element
3123 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3124 if(!elem) return -1;
3125 return elem->NbNodes();
3129 //=============================================================================
3131 * Returns ID of node by given index for given element
3132 * If there is not element for given ID - returns -1
3133 * If there is not node for given index - returns -2
3135 //=============================================================================
3137 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3139 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3140 if ( aSMESHDS_Mesh == NULL ) return -1;
3141 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3142 if(!elem) return -1;
3143 if( index>=elem->NbNodes() || index<0 ) return -1;
3144 return elem->GetNode(index)->GetID();
3147 //=============================================================================
3149 * Returns IDs of nodes of given element
3151 //=============================================================================
3153 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3155 SMESH::long_array_var aResult = new SMESH::long_array();
3156 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3158 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3160 aResult->length( elem->NbNodes() );
3161 for ( int i = 0; i < elem->NbNodes(); ++i )
3162 aResult[ i ] = elem->GetNode( i )->GetID();
3165 return aResult._retn();
3168 //=============================================================================
3170 * Returns true if given node is medium node
3171 * in given quadratic element
3173 //=============================================================================
3175 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3177 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3178 if ( aSMESHDS_Mesh == NULL ) return false;
3180 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3181 if(!aNode) return false;
3182 // try to find element
3183 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3184 if(!elem) return false;
3186 return elem->IsMediumNode(aNode);
3190 //=============================================================================
3192 * Returns true if given node is medium node
3193 * in one of quadratic elements
3195 //=============================================================================
3197 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3198 SMESH::ElementType theElemType)
3200 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3201 if ( aSMESHDS_Mesh == NULL ) return false;
3204 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3205 if(!aNode) return false;
3207 SMESH_MesherHelper aHelper( *(_impl) );
3209 SMDSAbs_ElementType aType;
3210 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3211 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3212 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3213 else aType = SMDSAbs_All;
3215 return aHelper.IsMedium(aNode,aType);
3219 //=============================================================================
3221 * Returns number of edges for given element
3223 //=============================================================================
3225 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3227 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3228 if ( aSMESHDS_Mesh == NULL ) return -1;
3229 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3230 if(!elem) return -1;
3231 return elem->NbEdges();
3235 //=============================================================================
3237 * Returns number of faces for given element
3239 //=============================================================================
3241 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3243 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3244 if ( aSMESHDS_Mesh == NULL ) return -1;
3245 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3246 if(!elem) return -1;
3247 return elem->NbFaces();
3250 //=======================================================================
3251 //function : GetElemFaceNodes
3252 //purpose : Returns nodes of given face (counted from zero) for given element.
3253 //=======================================================================
3255 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3256 CORBA::Short faceIndex)
3258 SMESH::long_array_var aResult = new SMESH::long_array();
3259 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3261 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3263 SMDS_VolumeTool vtool( elem );
3264 if ( faceIndex < vtool.NbFaces() )
3266 aResult->length( vtool.NbFaceNodes( faceIndex ));
3267 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3268 for ( int i = 0; i < aResult->length(); ++i )
3269 aResult[ i ] = nn[ i ]->GetID();
3273 return aResult._retn();
3276 //=======================================================================
3277 //function : FindElementByNodes
3278 //purpose : Returns an element based on all given nodes.
3279 //=======================================================================
3281 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3283 CORBA::Long elemID(0);
3284 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3286 vector< const SMDS_MeshNode * > nn( nodes.length() );
3287 for ( int i = 0; i < nodes.length(); ++i )
3288 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3291 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3292 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3293 _impl->NbFaces( ORDER_QUADRATIC ) ||
3294 _impl->NbVolumes( ORDER_QUADRATIC )))
3295 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3297 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3302 //=============================================================================
3304 * Returns true if given element is polygon
3306 //=============================================================================
3308 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3310 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3311 if ( aSMESHDS_Mesh == NULL ) return false;
3312 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3313 if(!elem) return false;
3314 return elem->IsPoly();
3318 //=============================================================================
3320 * Returns true if given element is quadratic
3322 //=============================================================================
3324 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3326 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3327 if ( aSMESHDS_Mesh == NULL ) return false;
3328 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3329 if(!elem) return false;
3330 return elem->IsQuadratic();
3334 //=============================================================================
3336 * Returns bary center for given element
3338 //=============================================================================
3340 SMESH::double_array* SMESH_Mesh_i::BaryCenter(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();
3347 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3349 return aResult._retn();
3351 if(elem->GetType()==SMDSAbs_Volume) {
3352 SMDS_VolumeTool aTool;
3353 if(aTool.Set(elem)) {
3355 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3360 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3362 double x=0., y=0., z=0.;
3363 for(; anIt->more(); ) {
3365 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3379 return aResult._retn();
3383 //=============================================================================
3385 * Create and publish group servants if any groups were imported or created anyhow
3387 //=============================================================================
3389 void SMESH_Mesh_i::CreateGroupServants()
3391 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3393 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3394 while ( groupIt->more() )
3396 ::SMESH_Group* group = groupIt->next();
3397 int anId = group->GetGroupDS()->GetID();
3399 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3400 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3403 SMESH_GroupBase_i* aGroupImpl;
3405 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3406 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3408 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3409 shape = groupOnGeom->GetShape();
3412 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3415 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3416 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3417 aGroupImpl->Register();
3419 SMESH::SMESH_GroupBase_var groupVar =
3420 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3421 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3423 // register CORBA object for persistence
3424 int nextId = _gen_i->RegisterObject( groupVar );
3425 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3427 // publishing of the groups in the study
3428 if ( !aStudy->_is_nil() ) {
3429 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3430 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3435 //=============================================================================
3437 * \brief Return groups cantained in _mapGroups by their IDs
3439 //=============================================================================
3441 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3443 int nbGroups = groupIDs.size();
3444 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3445 aList->length( nbGroups );
3447 list<int>::const_iterator ids = groupIDs.begin();
3448 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3450 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3451 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3452 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3454 aList->length( nbGroups );
3455 return aList._retn();
3458 //=============================================================================
3460 * \brief Return information about imported file
3462 //=============================================================================
3464 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3466 SALOME_MED::MedFileInfo_var res( myFileInfo );
3467 if ( !res.operator->() ) {
3468 res = new SALOME_MED::MedFileInfo;
3470 res->fileSize = res->major = res->minor = res->release = -1;
3475 //=============================================================================
3477 * \brief Check and correct names of mesh groups
3479 //=============================================================================
3481 void SMESH_Mesh_i::checkGroupNames()
3483 int nbGrp = NbGroups();
3487 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3488 if ( aStudy->_is_nil() )
3489 return; // nothing to do
3491 SMESH::ListOfGroups* grpList = 0;
3492 // avoid dump of "GetGroups"
3494 // store python dump into a local variable inside local scope
3495 SMESH::TPythonDump pDump; // do not delete this line of code
3496 grpList = GetGroups();
3499 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3500 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3503 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3504 if ( aGrpSO->_is_nil() )
3506 // correct name of the mesh group if necessary
3507 const char* guiName = aGrpSO->GetName();
3508 if ( strcmp(guiName, aGrp->GetName()) )
3509 aGrp->SetName( guiName );
3513 //=============================================================================
3515 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3517 //=============================================================================
3518 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3520 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3521 CORBA::string_dup(theParameters));
3524 //=============================================================================
3526 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3528 //=============================================================================
3529 char* SMESH_Mesh_i::GetParameters()
3531 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3532 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3535 //=============================================================================
3537 * \brief Returns list of notebook variables used for last Mesh operation
3539 //=============================================================================
3540 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3542 SMESH::string_array_var aResult = new SMESH::string_array();
3543 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3545 char *aParameters = GetParameters();
3546 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3547 if(!aStudy->_is_nil()) {
3548 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3549 if(aSections->length() > 0) {
3550 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3551 aResult->length(aVars.length());
3552 for(int i = 0;i < aVars.length();i++)
3553 aResult[i] = CORBA::string_dup( aVars[i]);
3557 return aResult._retn();
3560 //=======================================================================
3561 //function : GetTypes
3562 //purpose : Returns types of elements it contains
3563 //=======================================================================
3565 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3567 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3571 if (_impl->NbEdges())
3572 types[nbTypes++] = SMESH::EDGE;
3573 if (_impl->NbFaces())
3574 types[nbTypes++] = SMESH::FACE;
3575 if (_impl->NbVolumes())
3576 types[nbTypes++] = SMESH::VOLUME;
3577 if (_impl->Nb0DElements())
3578 types[nbTypes++] = SMESH::ELEM0D;
3579 types->length( nbTypes );
3581 return types._retn();
3584 //=============================================================================
3586 * \brief Returns statistic of mesh elements
3588 //=============================================================================
3589 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3591 SMESH::long_array_var aRes = new SMESH::long_array();
3592 aRes->length(SMESH::Entity_Last);
3593 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3595 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3597 return aRes._retn();
3598 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3599 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3600 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3601 return aRes._retn();
3604 //=============================================================================
3606 * \brief Collect statistic of mesh elements given by iterator
3608 //=============================================================================
3609 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3610 SMESH::long_array& theInfo)
3612 if (!theItr) return;
3613 while (theItr->more())
3614 theInfo[ theItr->next()->GetEntityType() ]++;
3617 //=============================================================================
3619 * \brief mapping of mesh dimension into shape type
3621 //=============================================================================
3622 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3624 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3626 case 0: aType = TopAbs_VERTEX; break;
3627 case 1: aType = TopAbs_EDGE; break;
3628 case 2: aType = TopAbs_FACE; break;
3630 default:aType = TopAbs_SOLID; break;
3635 //=============================================================================
3637 * \brief Internal structure used to find concurent submeshes
3639 * It represents a pair < submesh, concurent dimension >, where
3640 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3641 * with another submesh. In other words, it is dimension of a hypothesis assigned
3644 //=============================================================================
3650 int _dim; //!< a dimension the algo can build (concurrent dimension)
3651 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
3652 TopTools_MapOfShape _shapeMap;
3653 SMESH_subMesh* _subMesh;
3654 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
3657 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
3659 const TopoDS_Shape& theShape)
3661 _subMesh = (SMESH_subMesh*)theSubMesh;
3662 SetShape( theDim, theShape );
3666 void SetShape(const int theDim,
3667 const TopoDS_Shape& theShape)
3670 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
3671 if (_dim >= _ownDim)
3672 _shapeMap.Add( theShape );
3674 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
3675 for( ; anExp.More(); anExp.Next() )
3676 _shapeMap.Add( anExp.Current() );
3680 //! Check sharing of sub shapes
3681 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
3682 const TopTools_MapOfShape& theToFind,
3683 const TopAbs_ShapeEnum theType)
3685 bool isShared = false;
3686 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
3687 for (; !isShared && anItr.More(); anItr.Next() ) {
3688 const TopoDS_Shape aSubSh = anItr.Key();
3689 // check for case when concurrent dimensions are same
3690 isShared = theToFind.Contains( aSubSh );
3691 // check for subshape with concurrent dimension
3692 TopExp_Explorer anExp( aSubSh, theType );
3693 for ( ; !isShared && anExp.More(); anExp.Next() )
3694 isShared = theToFind.Contains( anExp.Current() );
3699 //! check algorithms
3700 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
3701 const SMESHDS_Hypothesis* theA2)
3703 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
3704 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
3705 return false; // one of the hypothesis is not algorithm
3706 // check algorithm names (should be equal)
3707 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
3711 //! Check if subshape hypotheses are concurrent
3712 bool IsConcurrent(const SMESH_DimHyp* theOther) const
3714 if ( _subMesh == theOther->_subMesh )
3715 return false; // same subshape - should not be
3717 // if ( <own dim of either of submeshes> == <concurrent dim> &&
3718 // any of the two submeshes is not on COMPOUND shape )
3719 // -> no concurrency
3720 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
3721 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
3722 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
3725 // bool checkSubShape = ( _dim >= theOther->_dim )
3726 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
3727 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
3728 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
3729 if ( !checkSubShape )
3732 // check algorithms to be same
3733 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
3734 return true; // different algorithms
3736 // check hypothesises for concurrence (skip first as algorithm)
3738 // pointers should be same, becase it is referenes from mesh hypothesis partition
3739 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
3740 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
3741 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
3742 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
3744 // the submeshes are concurrent if their algorithms has different parameters
3745 return nbSame != theOther->_hypothesises.size() - 1;
3748 }; // end of SMESH_DimHyp
3750 typedef list<SMESH_DimHyp*> TDimHypList;
3752 static void addDimHypInstance(const int theDim,
3753 const TopoDS_Shape& theShape,
3754 const SMESH_Algo* theAlgo,
3755 const SMESH_subMesh* theSubMesh,
3756 const list <const SMESHDS_Hypothesis*>& theHypList,
3757 TDimHypList* theDimHypListArr )
3759 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
3760 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
3761 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
3762 listOfdimHyp.push_back( dimHyp );
3765 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
3766 dimHyp->_hypothesises.push_front(theAlgo);
3767 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
3768 for( ; hypIt != theHypList.end(); hypIt++ )
3769 dimHyp->_hypothesises.push_back( *hypIt );
3772 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
3773 const TDimHypList& theListOfDimHyp,
3774 TListOfInt& theListOfConcurr )
3776 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
3777 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
3778 const SMESH_DimHyp* curDimHyp = *rIt;
3779 if ( curDimHyp == theDimHyp )
3780 break; // meet own dimHyp pointer in same dimension
3781 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
3782 if ( find( theListOfConcurr.begin(),
3783 theListOfConcurr.end(),
3784 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
3785 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
3789 static void unionLists(TListOfInt& theListOfId,
3790 TListOfListOfInt& theListOfListOfId,
3793 TListOfListOfInt::iterator it = theListOfListOfId.begin();
3794 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
3796 continue; //skip already treated lists
3797 // check if other list has any same submesh object
3798 TListOfInt& otherListOfId = *it;
3799 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
3800 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
3803 // union two lists (from source into target)
3804 TListOfInt::iterator it2 = otherListOfId.begin();
3805 for ( ; it2 != otherListOfId.end(); it2++ ) {
3806 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
3807 theListOfId.push_back(*it2);
3809 // clear source list
3810 otherListOfId.clear();
3814 //! free memory allocated for dimension-hypothesis objects
3815 static void removeDimHyps( TDimHypList* theArrOfList )
3817 for (int i = 0; i < 4; i++ ) {
3818 TDimHypList& listOfdimHyp = theArrOfList[i];
3819 TDimHypList::const_iterator it = listOfdimHyp.begin();
3820 for ( ; it != listOfdimHyp.end(); it++ )
3825 //=============================================================================
3827 * \brief Return submesh objects list in meshing order
3829 //=============================================================================
3831 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
3833 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
3835 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3837 return aResult._retn();
3839 ::SMESH_Mesh& mesh = GetImpl();
3840 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
3841 if ( !anOrder.size() ) {
3843 // collect submeshes detecting concurrent algorithms and hypothesises
3844 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
3846 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
3847 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
3848 ::SMESH_subMesh* sm = (*i_sm).second;
3850 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
3852 // list of assigned hypothesises
3853 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
3854 // Find out dimensions where the submesh can be concurrent.
3855 // We define the dimensions by algo of each of hypotheses in hypList
3856 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
3857 for( ; hypIt != hypList.end(); hypIt++ ) {
3858 SMESH_Algo* anAlgo = 0;
3859 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
3860 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
3861 // hyp it-self is algo
3862 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
3864 // try to find algorithm with help of subshapes
3865 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
3866 for ( ; !anAlgo && anExp.More(); anExp.Next() )
3867 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
3870 continue; // no assigned algorithm to current submesh
3872 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
3873 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
3875 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
3876 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
3877 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
3879 } // end iterations on submesh
3881 // iterate on created dimension-hypotheses and check for concurrents
3882 for ( int i = 0; i < 4; i++ ) {
3883 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
3884 // check for concurrents in own and other dimensions (step-by-step)
3885 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
3886 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
3887 const SMESH_DimHyp* dimHyp = *dhIt;
3888 TListOfInt listOfConcurr;
3889 // looking for concurrents and collect into own list
3890 for ( int j = i; j < 4; j++ )
3891 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
3892 // check if any concurrents found
3893 if ( listOfConcurr.size() > 0 ) {
3894 // add own submesh to list of concurrent
3895 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
3896 anOrder.push_back( listOfConcurr );
3901 removeDimHyps(dimHypListArr);
3903 // now, minimise the number of concurrent groups
3904 // Here we assume that lists of submhes can has same submesh
3905 // in case of multi-dimension algorithms, as result
3906 // list with common submesh have to be union into one list
3908 TListOfListOfInt::iterator listIt = anOrder.begin();
3909 for(; listIt != anOrder.end(); listIt++, listIndx++ )
3910 unionLists( *listIt, anOrder, listIndx + 1 );
3912 // convert submesh ids into interface instances
3913 // and dump command into python
3914 convertMeshOrder( anOrder, aResult, true );
3916 return aResult._retn();
3919 //=============================================================================
3921 * \brief find common submeshes with given submesh
3922 * \param theSubMeshList list of already collected submesh to check
3923 * \param theSubMesh given submesh to intersect with other
3924 * \param theCommonSubMeshes collected common submeshes
3926 //=============================================================================
3928 static void findCommonSubMesh
3929 (list<const SMESH_subMesh*>& theSubMeshList,
3930 const SMESH_subMesh* theSubMesh,
3931 set<const SMESH_subMesh*>& theCommon )
3935 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
3936 for ( ; it != theSubMeshList.end(); it++ )
3937 theSubMesh->FindIntersection( *it, theCommon );
3938 theSubMeshList.push_back( theSubMesh );
3939 //theCommon.insert( theSubMesh );
3942 //=============================================================================
3944 * \brief Set submesh object order
3945 * \param theSubMeshArray submesh array order
3947 //=============================================================================
3949 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
3952 ::SMESH_Mesh& mesh = GetImpl();
3954 TPythonDump aPythonDump; // prevent dump of called methods
3955 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
3957 TListOfListOfInt subMeshOrder;
3958 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
3960 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
3961 TListOfInt subMeshIds;
3962 aPythonDump << "[ ";
3963 // Collect subMeshes which should be clear
3964 // do it list-by-list, because modification of submesh order
3965 // take effect between concurrent submeshes only
3966 set<const SMESH_subMesh*> subMeshToClear;
3967 list<const SMESH_subMesh*> subMeshList;
3968 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
3970 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
3972 aPythonDump << ", ";
3973 aPythonDump << subMesh;
3974 subMeshIds.push_back( subMesh->GetId() );
3975 // detect common parts of submeshes
3976 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
3977 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
3979 aPythonDump << " ]";
3980 subMeshOrder.push_back( subMeshIds );
3982 // clear collected submeshes
3983 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
3984 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
3985 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
3987 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
3988 // ClearSubMesh( *clrIt );
3991 aPythonDump << " ])";
3993 mesh.SetMeshOrder( subMeshOrder );
3999 //=============================================================================
4001 * \brief Convert submesh ids into submesh interfaces
4003 //=============================================================================
4005 void SMESH_Mesh_i::convertMeshOrder
4006 (const TListOfListOfInt& theIdsOrder,
4007 SMESH::submesh_array_array& theResOrder,
4008 const bool theIsDump)
4010 int nbSet = theIdsOrder.size();
4011 TPythonDump aPythonDump; // prevent dump of called methods
4013 aPythonDump << "[ ";
4014 theResOrder.length(nbSet);
4015 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4017 for( ; it != theIdsOrder.end(); it++ ) {
4018 // translate submesh identificators into submesh objects
4019 // takeing into account real number of concurrent lists
4020 const TListOfInt& aSubOrder = (*it);
4021 if (!aSubOrder.size())
4024 aPythonDump << "[ ";
4025 // convert shape indeces into interfaces
4026 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4027 aResSubSet->length(aSubOrder.size());
4028 TListOfInt::const_iterator subIt = aSubOrder.begin();
4029 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4030 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4032 SMESH::SMESH_subMesh_var subMesh =
4033 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4036 aPythonDump << ", ";
4037 aPythonDump << subMesh;
4039 aResSubSet[ j++ ] = subMesh;
4042 aPythonDump << " ]";
4043 theResOrder[ listIndx++ ] = aResSubSet;
4045 // correct number of lists
4046 theResOrder.length( listIndx );
4049 // finilise python dump
4050 aPythonDump << " ]";
4051 aPythonDump << " = " << _this() << ".GetMeshOrder()";