1 // Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_SMESHDS_Mesh.h"
30 #include "SMDS_EdgePosition.hxx"
31 #include "SMDS_ElemIterator.hxx"
32 #include "SMDS_FacePosition.hxx"
33 #include "SMDS_IteratorOnIterators.hxx"
34 #include "SMDS_SetIterator.hxx"
35 #include "SMDS_VolumeTool.hxx"
36 #include "SMESHDS_Command.hxx"
37 #include "SMESHDS_CommandType.hxx"
38 #include "SMESHDS_GroupOnGeom.hxx"
39 #include "SMESH_Filter_i.hxx"
40 #include "SMESH_Gen_i.hxx"
41 #include "SMESH_Group.hxx"
42 #include "SMESH_Group_i.hxx"
43 #include "SMESH_MEDMesh_i.hxx"
44 #include "SMESH_MeshEditor.hxx"
45 #include "SMESH_MeshEditor_i.hxx"
46 #include "SMESH_MesherHelper.hxx"
47 #include "SMESH_PythonDump.hxx"
48 #include "SMESH_subMesh_i.hxx"
51 #include <SALOME_NamingService.hxx>
52 #include <Utils_CorbaException.hxx>
53 #include <Utils_ExceptHandlers.hxx>
54 #include <Utils_SINGLETON.hxx>
55 #include <utilities.h>
56 #include <GEOMImpl_Types.hxx>
59 #include <BRep_Builder.hxx>
60 #include <OSD_Directory.hxx>
61 #include <OSD_File.hxx>
62 #include <OSD_Path.hxx>
63 #include <OSD_Protection.hxx>
64 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
65 #include <TColStd_MapOfInteger.hxx>
66 #include <TColStd_SequenceOfInteger.hxx>
67 #include <TCollection_AsciiString.hxx>
69 #include <TopExp_Explorer.hxx>
70 #include <TopoDS_Compound.hxx>
71 #include <TopTools_MapOfShape.hxx>
72 #include <TopTools_MapIteratorOfMapOfShape.hxx>
82 static int MYDEBUG = 0;
84 static int MYDEBUG = 0;
88 using SMESH::TPythonDump;
90 int SMESH_Mesh_i::myIdGenerator = 0;
92 //To disable automatic genericobj management, the following line should be commented.
93 //Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
94 #define WITHGENERICOBJ
96 //=============================================================================
100 //=============================================================================
102 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
104 CORBA::Long studyId )
105 : SALOME::GenericObj_i( thePOA )
107 MESSAGE("SMESH_Mesh_i");
110 _id = myIdGenerator++;
114 //=============================================================================
118 //=============================================================================
120 SMESH_Mesh_i::~SMESH_Mesh_i()
122 MESSAGE("~SMESH_Mesh_i");
124 #ifdef WITHGENERICOBJ
126 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
127 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
128 if ( CORBA::is_nil( itGr->second ))
130 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
132 // this method is called from destructor of group (PAL6331)
133 //_impl->RemoveGroup( aGroup->GetLocalID() );
134 aGroup->myMeshServant = 0;
135 aGroup->UnRegister();
141 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
142 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
143 if ( CORBA::is_nil( itSM->second ))
145 SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
147 aSubMesh->UnRegister();
150 _mapSubMeshIor.clear();
152 // destroy hypotheses
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( CORBA::is_nil( itH->second ))
157 SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
168 //=============================================================================
172 * Associates <this> mesh with <theShape> and puts a reference
173 * to <theShape> into the current study;
174 * the previous shape is substituted by the new one.
176 //=============================================================================
178 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
179 throw (SALOME::SALOME_Exception)
181 Unexpect aCatch(SALOME_SalomeException);
183 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
185 catch(SALOME_Exception & S_ex) {
186 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
188 // to track changes of GEOM groups
189 addGeomGroupData( theShapeObject, _this() );
192 //================================================================================
194 * \brief return true if mesh has a shape to build a shape on
196 //================================================================================
198 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
199 throw (SALOME::SALOME_Exception)
201 Unexpect aCatch(SALOME_SalomeException);
204 res = _impl->HasShapeToMesh();
206 catch(SALOME_Exception & S_ex) {
207 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
212 //=======================================================================
213 //function : GetShapeToMesh
215 //=======================================================================
217 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
218 throw (SALOME::SALOME_Exception)
220 Unexpect aCatch(SALOME_SalomeException);
221 GEOM::GEOM_Object_var aShapeObj;
223 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
225 aShapeObj = _gen_i->ShapeToGeomObject( S );
227 catch(SALOME_Exception & S_ex) {
228 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
230 return aShapeObj._retn();
233 //================================================================================
235 * \brief Remove all nodes and elements
237 //================================================================================
239 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
241 Unexpect aCatch(SALOME_SalomeException);
244 CheckGeomGroupModif(); // issue 20145
246 catch(SALOME_Exception & S_ex) {
247 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
249 TPythonDump() << _this() << ".Clear()";
252 //================================================================================
254 * \brief Remove all nodes and elements for indicated shape
256 //================================================================================
258 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
259 throw (SALOME::SALOME_Exception)
261 Unexpect aCatch(SALOME_SalomeException);
263 _impl->ClearSubMesh( ShapeID );
265 catch(SALOME_Exception & S_ex) {
266 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
270 //=============================================================================
274 //=============================================================================
276 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
278 SMESH::DriverMED_ReadStatus res;
281 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
282 res = SMESH::DRS_OK; break;
283 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
284 res = SMESH::DRS_EMPTY; break;
285 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
286 res = SMESH::DRS_WARN_RENUMBER; break;
287 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
288 res = SMESH::DRS_WARN_SKIP_ELEM; break;
289 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
291 res = SMESH::DRS_FAIL; break;
296 //=============================================================================
300 * Imports mesh data from MED file
302 //=============================================================================
304 SMESH::DriverMED_ReadStatus
305 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
306 throw ( SALOME::SALOME_Exception )
308 Unexpect aCatch(SALOME_SalomeException);
311 status = _impl->MEDToMesh( theFileName, theMeshName );
313 catch( SALOME_Exception& S_ex ) {
314 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
317 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
320 CreateGroupServants();
322 int major, minor, release;
323 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
324 major = minor = release = -1;
325 myFileInfo = new SALOME_MED::MedFileInfo();
326 myFileInfo->fileName = theFileName;
327 myFileInfo->fileSize = 0;
330 if ( ::_stati64( theFileName, &d ) != -1 )
333 if ( ::stat64( theFileName, &d ) != -1 )
335 myFileInfo->fileSize = d.st_size;
336 myFileInfo->major = major;
337 myFileInfo->minor = minor;
338 myFileInfo->release = release;
340 return ConvertDriverMEDReadStatus(status);
343 //================================================================================
345 * \brief Imports mesh data from the CGNS file
347 //================================================================================
349 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
350 const int theMeshIndex,
351 std::string& theMeshName )
352 throw ( SALOME::SALOME_Exception )
354 Unexpect aCatch(SALOME_SalomeException);
357 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
359 catch( SALOME_Exception& S_ex ) {
360 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
363 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
366 CreateGroupServants();
368 return ConvertDriverMEDReadStatus(status);
371 //================================================================================
373 * \brief Return string representation of a MED file version comprising nbDigits
375 //================================================================================
377 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
379 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
381 return CORBA::string_dup( ver.c_str() );
384 //=============================================================================
388 * Imports mesh data from MED file
390 //=============================================================================
392 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
393 throw ( SALOME::SALOME_Exception )
395 // Read mesh with name = <theMeshName> into SMESH_Mesh
396 _impl->UNVToMesh( theFileName );
398 CreateGroupServants();
403 //=============================================================================
407 * Imports mesh data from STL file
409 //=============================================================================
410 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
411 throw ( SALOME::SALOME_Exception )
413 // Read mesh with name = <theMeshName> into SMESH_Mesh
414 _impl->STLToMesh( theFileName );
419 //=============================================================================
423 * Imports mesh data from MED file
425 //=============================================================================
427 // int SMESH_Mesh_i::importMEDFile( const char* theFileName, const char* theMeshName )
429 // // Read mesh with name = <theMeshName> and all its groups into SMESH_Mesh
430 // int status = _impl->MEDToMesh( theFileName, theMeshName );
431 // CreateGroupServants();
436 //=============================================================================
440 //=============================================================================
442 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
444 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
445 (SMESH_Hypothesis::Hypothesis_Status theStatus)
448 RETURNCASE( HYP_OK );
449 RETURNCASE( HYP_MISSING );
450 RETURNCASE( HYP_CONCURENT );
451 RETURNCASE( HYP_BAD_PARAMETER );
452 RETURNCASE( HYP_HIDDEN_ALGO );
453 RETURNCASE( HYP_HIDING_ALGO );
454 RETURNCASE( HYP_UNKNOWN_FATAL );
455 RETURNCASE( HYP_INCOMPATIBLE );
456 RETURNCASE( HYP_NOTCONFORM );
457 RETURNCASE( HYP_ALREADY_EXIST );
458 RETURNCASE( HYP_BAD_DIM );
459 RETURNCASE( HYP_BAD_SUBSHAPE );
460 RETURNCASE( HYP_BAD_GEOMETRY );
461 RETURNCASE( HYP_NEED_SHAPE );
464 return SMESH::HYP_UNKNOWN_FATAL;
467 //=============================================================================
471 * calls internal addHypothesis() and then adds a reference to <anHyp> under
472 * the SObject actually having a reference to <aSubShape>.
473 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
475 //=============================================================================
477 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
478 SMESH::SMESH_Hypothesis_ptr anHyp)
479 throw(SALOME::SALOME_Exception)
481 Unexpect aCatch(SALOME_SalomeException);
482 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
484 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
485 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
486 aSubShapeObject, anHyp );
488 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
490 // Update Python script
491 if(_impl->HasShapeToMesh()) {
492 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
493 << aSubShapeObject << ", " << anHyp << " )";
496 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
499 return ConvertHypothesisStatus(status);
502 //=============================================================================
506 //=============================================================================
508 SMESH_Hypothesis::Hypothesis_Status
509 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
510 SMESH::SMESH_Hypothesis_ptr anHyp)
512 if(MYDEBUG) MESSAGE("addHypothesis");
514 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
515 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
518 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
519 if (CORBA::is_nil(myHyp))
520 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
523 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
526 TopoDS_Shape myLocSubShape;
527 //use PseudoShape in case if mesh has no shape
529 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
531 myLocSubShape = _impl->GetShapeToMesh();
533 int hypId = myHyp->GetId();
534 status = _impl->AddHypothesis(myLocSubShape, hypId);
535 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
536 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
537 #ifdef WITHGENERICOBJ
538 _mapHypo[hypId]->Register();
540 // assure there is a corresponding submesh
541 if ( !_impl->IsMainShape( myLocSubShape )) {
542 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
543 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
544 createSubMesh( aSubShapeObject );
548 catch(SALOME_Exception & S_ex)
550 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
555 //=============================================================================
559 //=============================================================================
561 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
562 SMESH::SMESH_Hypothesis_ptr anHyp)
563 throw(SALOME::SALOME_Exception)
565 Unexpect aCatch(SALOME_SalomeException);
566 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
568 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
569 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
570 aSubShapeObject, anHyp );
572 // Update Python script
573 // Update Python script
574 if(_impl->HasShapeToMesh()) {
575 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
576 << aSubShapeObject << ", " << anHyp << " )";
579 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
583 return ConvertHypothesisStatus(status);
586 //=============================================================================
590 //=============================================================================
592 SMESH_Hypothesis::Hypothesis_Status
593 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
594 SMESH::SMESH_Hypothesis_ptr anHyp)
596 if(MYDEBUG) MESSAGE("removeHypothesis()");
597 // **** proposer liste de subShape (selection multiple)
599 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
600 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
602 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
603 if (CORBA::is_nil(myHyp))
604 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
606 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
609 TopoDS_Shape myLocSubShape;
610 //use PseudoShape in case if mesh has no shape
612 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
614 myLocSubShape = _impl->GetShapeToMesh();
616 int hypId = myHyp->GetId();
617 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
618 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many subshapes
619 // _mapHypo.erase( hypId );
621 catch(SALOME_Exception & S_ex)
623 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
628 //=============================================================================
632 //=============================================================================
634 SMESH::ListOfHypothesis *
635 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
636 throw(SALOME::SALOME_Exception)
638 Unexpect aCatch(SALOME_SalomeException);
639 if (MYDEBUG) MESSAGE("GetHypothesisList");
640 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
641 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference", SALOME::BAD_PARAM);
643 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
646 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
647 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
648 myLocSubShape = _impl->GetShapeToMesh();
649 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
650 int i = 0, n = aLocalList.size();
653 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
654 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
655 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
656 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
661 catch(SALOME_Exception & S_ex) {
662 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
665 return aList._retn();
668 //=============================================================================
672 //=============================================================================
673 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
674 const char* theName )
675 throw(SALOME::SALOME_Exception)
677 Unexpect aCatch(SALOME_SalomeException);
678 MESSAGE("SMESH_Mesh_i::GetSubMesh");
679 if (CORBA::is_nil(aSubShapeObject))
680 THROW_SALOME_CORBA_EXCEPTION("bad subShape reference",
683 SMESH::SMESH_subMesh_var subMesh;
684 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
686 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
688 //Get or Create the SMESH_subMesh object implementation
690 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
692 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
694 TopoDS_Iterator it( myLocSubShape );
696 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
698 subMesh = getSubMesh( subMeshId );
700 // create a new subMesh object servant if there is none for the shape
701 if ( subMesh->_is_nil() )
702 subMesh = createSubMesh( aSubShapeObject );
703 if ( _gen_i->CanPublishInStudy( subMesh )) {
704 SALOMEDS::SObject_var aSO =
705 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
706 subMesh, aSubShapeObject, theName );
707 if ( !aSO->_is_nil()) {
708 // Update Python script
709 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
710 << aSubShapeObject << ", '" << theName << "' )";
714 catch(SALOME_Exception & S_ex) {
715 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
717 return subMesh._retn();
720 //=============================================================================
724 //=============================================================================
726 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
727 throw (SALOME::SALOME_Exception)
729 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
730 if ( theSubMesh->_is_nil() )
733 GEOM::GEOM_Object_var aSubShapeObject;
734 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
735 if ( !aStudy->_is_nil() ) {
736 // Remove submesh's SObject
737 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
738 if ( !anSO->_is_nil() ) {
739 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
740 SALOMEDS::SObject_var anObj, aRef;
741 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
742 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
744 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
745 // aSubShapeObject = theSubMesh->GetSubShape();
747 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
749 // Update Python script
750 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
754 removeSubMesh( theSubMesh, aSubShapeObject.in() );
757 //=============================================================================
761 //=============================================================================
763 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
764 const char* theName )
765 throw(SALOME::SALOME_Exception)
767 Unexpect aCatch(SALOME_SalomeException);
768 SMESH::SMESH_Group_var aNewGroup =
769 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
771 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
772 SALOMEDS::SObject_var aSO =
773 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
774 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
775 if ( !aSO->_is_nil()) {
776 // Update Python script
777 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
778 << theElemType << ", '" << theName << "' )";
781 return aNewGroup._retn();
785 //=============================================================================
789 //=============================================================================
790 SMESH::SMESH_GroupOnGeom_ptr
791 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
793 GEOM::GEOM_Object_ptr theGeomObj)
794 throw(SALOME::SALOME_Exception)
796 Unexpect aCatch(SALOME_SalomeException);
797 SMESH::SMESH_GroupOnGeom_var aNewGroup;
799 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
800 if ( !aShape.IsNull() )
802 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
803 ( createGroup( theElemType, theName, aShape ));
805 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
806 SALOMEDS::SObject_var aSO =
807 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
808 aNewGroup, theGeomObj, theName);
809 if ( !aSO->_is_nil()) {
810 // Update Python script
811 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
812 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
817 return aNewGroup._retn();
820 //================================================================================
822 * \brief Creates a group whose contents is defined by filter
823 * \param theElemType - group type
824 * \param theName - group name
825 * \param theFilter - the filter
826 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
828 //================================================================================
830 SMESH::SMESH_GroupOnFilter_ptr
831 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
833 SMESH::Filter_ptr theFilter )
834 throw (SALOME::SALOME_Exception)
836 Unexpect aCatch(SALOME_SalomeException);
838 if ( CORBA::is_nil( theFilter ))
839 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
841 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
843 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
845 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
846 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
849 if ( !aNewGroup->_is_nil() )
850 aNewGroup->SetFilter( theFilter );
852 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
854 SALOMEDS::SObject_var aSO =
855 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
856 GEOM::GEOM_Object::_nil(), theName);
857 if ( !aSO->_is_nil()) {
858 // Update Python script
859 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
860 << theElemType << ", '" << theName << "', " << theFilter << " )";
864 return aNewGroup._retn();
867 //=============================================================================
871 //=============================================================================
873 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
874 throw (SALOME::SALOME_Exception)
876 if ( theGroup->_is_nil() )
879 SMESH_GroupBase_i* aGroup =
880 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
884 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
885 if ( !aStudy->_is_nil() ) {
886 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
888 if ( !aGroupSO->_is_nil() ) {
889 // Update Python script
890 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
892 // Remove group's SObject
893 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
897 // Remove the group from SMESH data structures
898 removeGroup( aGroup->GetLocalID() );
901 //=============================================================================
902 /*! RemoveGroupWithContents
903 * Remove group with its contents
905 //=============================================================================
906 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
907 throw (SALOME::SALOME_Exception)
909 if ( theGroup->_is_nil() )
912 SMESH_GroupBase_i* aGroup =
913 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
917 SMESH::long_array_var anIds = aGroup->GetListOfID();
918 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
920 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
923 if ( aGroup->GetType() == SMESH::NODE )
924 aMeshEditor->RemoveNodes( anIds );
926 aMeshEditor->RemoveElements( anIds );
929 RemoveGroup( theGroup );
931 // Update Python script
932 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
935 //================================================================================
937 * \brief Get the list of groups existing in the mesh
938 * \retval SMESH::ListOfGroups * - list of groups
940 //================================================================================
942 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
944 Unexpect aCatch(SALOME_SalomeException);
945 if (MYDEBUG) MESSAGE("GetGroups");
947 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
950 TPythonDump aPythonDump;
951 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
955 aList->length( _mapGroups.size() );
957 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
958 for ( ; it != _mapGroups.end(); it++ ) {
959 if ( CORBA::is_nil( it->second )) continue;
960 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
962 if (i > 1) aPythonDump << ", ";
963 aPythonDump << it->second;
967 catch(SALOME_Exception & S_ex) {
968 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
971 // Update Python script
972 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
973 aPythonDump << " ] = " << _this() << ".GetGroups()";
975 return aList._retn();
978 //=============================================================================
980 * Get number of groups existing in the mesh
982 //=============================================================================
984 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
986 Unexpect aCatch(SALOME_SalomeException);
987 return _mapGroups.size();
990 //=============================================================================
992 * New group is created. All mesh elements that are
993 * present in initial groups are added to the new one
995 //=============================================================================
996 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
997 SMESH::SMESH_GroupBase_ptr theGroup2,
998 const char* theName )
999 throw (SALOME::SALOME_Exception)
1003 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1004 theGroup1->GetType() != theGroup2->GetType() )
1005 return SMESH::SMESH_Group::_nil();
1008 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1009 if ( aResGrp->_is_nil() )
1010 return SMESH::SMESH_Group::_nil();
1012 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1013 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1015 TColStd_MapOfInteger aResMap;
1017 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1018 aResMap.Add( anIds1[ i1 ] );
1020 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1021 aResMap.Add( anIds2[ i2 ] );
1023 SMESH::long_array_var aResIds = new SMESH::long_array;
1024 aResIds->length( aResMap.Extent() );
1027 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1028 for( ; anIter.More(); anIter.Next() )
1029 aResIds[ resI++ ] = anIter.Key();
1031 aResGrp->Add( aResIds );
1033 // Clear python lines, created by CreateGroup() and Add()
1034 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1035 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1036 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1038 // Update Python script
1039 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
1040 << theGroup1 << ", " << theGroup2 << ", '"
1041 << theName << "' )";
1043 return aResGrp._retn();
1047 return SMESH::SMESH_Group::_nil();
1051 //=============================================================================
1053 \brief Union list of groups. New group is created. All mesh elements that are
1054 present in initial groups are added to the new one.
1055 \param theGroups list of groups
1056 \param theName name of group to be created
1057 \return pointer on the group
1059 //=============================================================================
1060 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1061 const char* theName )
1062 throw (SALOME::SALOME_Exception)
1065 return SMESH::SMESH_Group::_nil();
1069 vector< int > anIds;
1070 SMESH::ElementType aType = SMESH::ALL;
1071 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1073 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1074 if ( CORBA::is_nil( aGrp ) )
1078 SMESH::ElementType aCurrType = aGrp->GetType();
1079 if ( aType == SMESH::ALL )
1083 if ( aType != aCurrType )
1084 return SMESH::SMESH_Group::_nil();
1088 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1089 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1091 int aCurrId = aCurrIds[ i ];
1092 anIds.push_back( aCurrId );
1097 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1098 if ( aResGrp->_is_nil() )
1099 return SMESH::SMESH_Group::_nil();
1101 // Create array of identifiers
1102 SMESH::long_array_var aResIds = new SMESH::long_array;
1103 aResIds->length( anIds.size() );
1105 //NCollection_Map< int >::Iterator anIter( anIds );
1106 for ( int i = 0; i<anIds.size(); i++ )
1108 aResIds[ i ] = anIds[i];
1110 aResGrp->Add( aResIds );
1112 // Clear python lines, created by CreateGroup() and Add()
1113 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1114 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1115 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1117 // Update Python script
1119 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1120 << &theGroups << ", '" << theName << "' )";
1122 return aResGrp._retn();
1126 return SMESH::SMESH_Group::_nil();
1130 //=============================================================================
1132 * New group is created. All mesh elements that are
1133 * present in both initial groups are added to the new one.
1135 //=============================================================================
1136 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1137 SMESH::SMESH_GroupBase_ptr theGroup2,
1138 const char* theName )
1139 throw (SALOME::SALOME_Exception)
1141 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1142 theGroup1->GetType() != theGroup2->GetType() )
1143 return SMESH::SMESH_Group::_nil();
1145 // Create Intersection
1146 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1147 if ( aResGrp->_is_nil() )
1150 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1151 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1153 TColStd_MapOfInteger aMap1;
1155 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1156 aMap1.Add( anIds1[ i1 ] );
1158 TColStd_SequenceOfInteger aSeq;
1160 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1161 if ( aMap1.Contains( anIds2[ i2 ] ) )
1162 aSeq.Append( anIds2[ i2 ] );
1164 SMESH::long_array_var aResIds = new SMESH::long_array;
1165 aResIds->length( aSeq.Length() );
1167 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1168 aResIds[ resI ] = aSeq( resI + 1 );
1170 aResGrp->Add( aResIds );
1172 // Clear python lines, created by CreateGroup() and Add()
1173 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1174 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1175 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1177 // Update Python script
1178 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1179 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1181 return aResGrp._retn();
1184 //=============================================================================
1186 \brief Intersect list of groups. New group is created. All mesh elements that
1187 are present in all initial groups simultaneously are added to the new one.
1188 \param theGroups list of groups
1189 \param theName name of group to be created
1190 \return pointer on the group
1192 //=============================================================================
1193 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectListOfGroups(
1194 const SMESH::ListOfGroups& theGroups, const char* theName )
1195 throw (SALOME::SALOME_Exception)
1198 return SMESH::SMESH_Group::_nil();
1202 NCollection_DataMap< int, int > anIdToCount;
1203 SMESH::ElementType aType = SMESH::ALL;
1204 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1206 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1207 if ( CORBA::is_nil( aGrp ) )
1211 SMESH::ElementType aCurrType = aGrp->GetType();
1212 if ( aType == SMESH::ALL )
1216 if ( aType != aCurrType )
1217 return SMESH::SMESH_Group::_nil();
1220 // calculates number of occurance ids in groups
1221 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1222 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1224 int aCurrId = aCurrIds[ i ];
1225 if ( !anIdToCount.IsBound( aCurrId ) )
1226 anIdToCount.Bind( aCurrId, 1 );
1228 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1232 // create map of ids
1233 int nbGrp = theGroups.length();
1234 vector< int > anIds;
1235 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1236 for ( ; anIter.More(); anIter.Next() )
1238 int aCurrId = anIter.Key();
1239 int aCurrNb = anIter.Value();
1240 if ( aCurrNb == nbGrp )
1241 anIds.push_back( aCurrId );
1245 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1246 if ( aResGrp->_is_nil() )
1247 return SMESH::SMESH_Group::_nil();
1249 // Create array of identifiers
1250 SMESH::long_array_var aResIds = new SMESH::long_array;
1251 aResIds->length( anIds.size() );
1253 //NCollection_Map< int >::Iterator aListIter( anIds );
1254 for ( int i = 0; i<anIds.size(); i++ )
1256 aResIds[ i ] = anIds[i];
1258 aResGrp->Add( aResIds );
1260 // Clear python lines, created by CreateGroup() and Add()
1261 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1262 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1263 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1265 // Update Python script
1267 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1268 << &theGroups << ", '" << theName << "' )";
1270 return aResGrp._retn();
1274 return SMESH::SMESH_Group::_nil();
1278 //=============================================================================
1280 * New group is created. All mesh elements that are present in
1281 * main group but do not present in tool group are added to the new one
1283 //=============================================================================
1284 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1285 SMESH::SMESH_GroupBase_ptr theGroup2,
1286 const char* theName )
1287 throw (SALOME::SALOME_Exception)
1289 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1290 theGroup1->GetType() != theGroup2->GetType() )
1291 return SMESH::SMESH_Group::_nil();
1294 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1295 if ( aResGrp->_is_nil() )
1298 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1299 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1301 TColStd_MapOfInteger aMap2;
1303 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1304 aMap2.Add( anIds2[ i2 ] );
1306 TColStd_SequenceOfInteger aSeq;
1307 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1308 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1309 aSeq.Append( anIds1[ i1 ] );
1311 SMESH::long_array_var aResIds = new SMESH::long_array;
1312 aResIds->length( aSeq.Length() );
1314 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1315 aResIds[ resI ] = aSeq( resI + 1 );
1317 aResGrp->Add( aResIds );
1319 // Clear python lines, created by CreateGroup() and Add()
1320 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1321 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1322 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1324 // Update Python script
1325 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1326 << theGroup1 << ", " << theGroup2 << ", '"
1327 << theName << "' )";
1329 return aResGrp._retn();
1332 //=============================================================================
1334 \brief Cut lists of groups. New group is created. All mesh elements that are
1335 present in main groups but do not present in tool groups are added to the new one
1336 \param theMainGroups list of main groups
1337 \param theToolGroups list of tool groups
1338 \param theName name of group to be created
1339 \return pointer on the group
1341 //=============================================================================
1342 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutListOfGroups(
1343 const SMESH::ListOfGroups& theMainGroups,
1344 const SMESH::ListOfGroups& theToolGroups,
1345 const char* theName )
1346 throw (SALOME::SALOME_Exception)
1349 return SMESH::SMESH_Group::_nil();
1353 set< int > aToolIds;
1354 SMESH::ElementType aType = SMESH::ALL;
1356 // iterate through tool groups
1357 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1359 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1360 if ( CORBA::is_nil( aGrp ) )
1364 SMESH::ElementType aCurrType = aGrp->GetType();
1365 if ( aType == SMESH::ALL )
1369 if ( aType != aCurrType )
1370 return SMESH::SMESH_Group::_nil();
1374 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1375 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1377 int aCurrId = aCurrIds[ i ];
1378 aToolIds.insert( aCurrId );
1382 vector< int > anIds; // result
1384 // Iterate through main group
1385 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1387 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1388 if ( CORBA::is_nil( aGrp ) )
1392 SMESH::ElementType aCurrType = aGrp->GetType();
1393 if ( aType == SMESH::ALL )
1397 if ( aType != aCurrType )
1398 return SMESH::SMESH_Group::_nil();
1402 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1403 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1405 int aCurrId = aCurrIds[ i ];
1406 if ( !aToolIds.count( aCurrId ) )
1407 anIds.push_back( aCurrId );
1412 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1413 if ( aResGrp->_is_nil() )
1414 return SMESH::SMESH_Group::_nil();
1416 // Create array of identifiers
1417 SMESH::long_array_var aResIds = new SMESH::long_array;
1418 aResIds->length( anIds.size() );
1420 for (int i=0; i<anIds.size(); i++ )
1422 aResIds[ i ] = anIds[i];
1424 aResGrp->Add( aResIds );
1426 // Clear python lines, created by CreateGroup() and Add()
1427 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1428 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1429 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1431 // Update Python script
1433 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1434 << &theMainGroups << ", " << &theToolGroups << ", '"
1435 << theName << "' )";
1437 return aResGrp._retn();
1441 return SMESH::SMESH_Group::_nil();
1445 //=============================================================================
1447 \brief Create groups of entities from existing groups of superior dimensions
1449 1) extract all nodes from each group,
1450 2) combine all elements of specified dimension laying on these nodes.
1451 \param theGroups list of source groups
1452 \param theElemType dimension of elements
1453 \param theName name of new group
1454 \return pointer on new group
1456 //=============================================================================
1457 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateDimGroup(
1458 const SMESH::ListOfGroups& theGroups,
1459 SMESH::ElementType theElemType,
1460 const char* theName )
1461 throw (SALOME::SALOME_Exception)
1463 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1465 if ( !theName || !aMeshDS )
1466 return SMESH::SMESH_Group::_nil();
1468 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1472 // Create map of nodes from all groups
1474 set< int > aNodeMap;
1476 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1478 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1479 if ( CORBA::is_nil( aGrp ) )
1482 SMESH::ElementType aType = aGrp->GetType();
1483 if ( aType == SMESH::ALL )
1485 else if ( aType == SMESH::NODE )
1487 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1488 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1490 int aCurrId = aCurrIds[ i ];
1491 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1493 aNodeMap.insert( aNode->GetID() );
1498 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1499 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1501 int aCurrId = aCurrIds[ i ];
1502 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1505 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1506 while( aNodeIter->more() )
1508 const SMDS_MeshNode* aNode =
1509 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1511 aNodeMap.insert( aNode->GetID() );
1517 // Get result identifiers
1519 vector< int > aResultIds;
1520 if ( theElemType == SMESH::NODE )
1522 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1523 set<int>::iterator iter = aNodeMap.begin();
1524 for ( ; iter != aNodeMap.end(); iter++ )
1525 aResultIds.push_back( *iter);
1529 // Create list of elements of given dimension constructed on the nodes
1530 vector< int > anElemList;
1531 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1532 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1533 set<int>::iterator iter = aNodeMap.begin();
1534 for ( ; iter != aNodeMap.end(); iter++ )
1536 const SMDS_MeshElement* aNode =
1537 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1541 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1542 while( anElemIter->more() )
1544 const SMDS_MeshElement* anElem =
1545 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1546 if ( anElem && anElem->GetType() == anElemType )
1547 anElemList.push_back( anElem->GetID() );
1551 // check whether all nodes of elements are present in nodes map
1552 //NCollection_Map< int >::Iterator anIter( anElemList );
1553 //for ( ; anIter.More(); anIter.Next() )
1554 for (int i=0; i< anElemList.size(); i++)
1556 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1561 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1562 while( aNodeIter->more() )
1564 const SMDS_MeshNode* aNode =
1565 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1566 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1573 aResultIds.push_back( anElem->GetID() );
1579 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1580 if ( aResGrp->_is_nil() )
1581 return SMESH::SMESH_Group::_nil();
1583 // Create array of identifiers
1584 SMESH::long_array_var aResIds = new SMESH::long_array;
1585 aResIds->length( aResultIds.size() );
1587 //NCollection_Map< int >::Iterator aResIter( aResultIds );
1588 //for ( int i = 0; aResIter.More(); aResIter.Next(), i++ )
1589 for (int i=0; i< aResultIds.size(); i++)
1590 aResIds[ i ] = aResultIds[i];
1591 aResGrp->Add( aResIds );
1593 // Remove strings corresponding to group creation
1594 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1595 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1596 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1598 // Update Python script
1600 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1601 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1603 return aResGrp._retn();
1607 return SMESH::SMESH_Group::_nil();
1611 //================================================================================
1613 * \brief Remember GEOM group data
1615 //================================================================================
1617 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1618 CORBA::Object_ptr theSmeshObj)
1620 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1623 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1624 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1625 if ( groupSO->_is_nil() )
1628 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1629 GEOM::GEOM_IGroupOperations_var groupOp =
1630 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1631 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1634 _geomGroupData.push_back( TGeomGroupData() );
1635 TGeomGroupData & groupData = _geomGroupData.back();
1637 CORBA::String_var entry = groupSO->GetID();
1638 groupData._groupEntry = entry.in();
1640 for ( int i = 0; i < ids->length(); ++i )
1641 groupData._indices.insert( ids[i] );
1643 groupData._smeshObject = theSmeshObj;
1646 //================================================================================
1648 * Remove GEOM group data relating to removed smesh object
1650 //================================================================================
1652 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1654 list<TGeomGroupData>::iterator
1655 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1656 for ( ; data != dataEnd; ++data ) {
1657 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1658 _geomGroupData.erase( data );
1664 //================================================================================
1666 * \brief Return new group contents if it has been changed and update group data
1668 //================================================================================
1670 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1672 TopoDS_Shape newShape;
1675 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1676 if ( study->_is_nil() ) return newShape; // means "not changed"
1677 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1678 if ( !groupSO->_is_nil() )
1680 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1681 if ( CORBA::is_nil( groupObj )) return newShape;
1682 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1684 // get indices of group items
1685 set<int> curIndices;
1686 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1687 GEOM::GEOM_IGroupOperations_var groupOp =
1688 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1689 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1690 for ( int i = 0; i < ids->length(); ++i )
1691 curIndices.insert( ids[i] );
1693 if ( groupData._indices == curIndices )
1694 return newShape; // group not changed
1697 groupData._indices = curIndices;
1699 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1700 if ( !geomClient ) return newShape;
1701 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1702 geomClient->RemoveShapeFromBuffer( groupIOR );
1703 newShape = _gen_i->GeomObjectToShape( geomGroup );
1706 if ( newShape.IsNull() ) {
1707 // geom group becomes empty - return empty compound
1708 TopoDS_Compound compound;
1709 BRep_Builder().MakeCompound(compound);
1710 newShape = compound;
1716 //=============================================================================
1718 * \brief Storage of shape and index used in CheckGeomGroupModif()
1720 //=============================================================================
1721 struct TIndexedShape {
1723 TopoDS_Shape _shape;
1724 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1727 //=============================================================================
1729 * \brief Update objects depending on changed geom groups
1731 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1732 * issue 0020210: Update of a smesh group after modification of the associated geom group
1734 //=============================================================================
1736 void SMESH_Mesh_i::CheckGeomGroupModif()
1738 if ( !_impl->HasShapeToMesh() ) return;
1740 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1741 if ( study->_is_nil() ) return;
1743 CORBA::Long nbEntities = NbNodes() + NbElements();
1745 // Check if group contents changed
1747 typedef map< string, TopoDS_Shape > TEntry2Geom;
1748 TEntry2Geom newGroupContents;
1750 list<TGeomGroupData>::iterator
1751 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1752 for ( ; data != dataEnd; ++data )
1754 pair< TEntry2Geom::iterator, bool > it_new =
1755 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1756 bool processedGroup = !it_new.second;
1757 TopoDS_Shape& newShape = it_new.first->second;
1758 if ( !processedGroup )
1759 newShape = newGroupShape( *data );
1760 if ( newShape.IsNull() )
1761 continue; // no changes
1763 if ( processedGroup ) { // update group indices
1764 list<TGeomGroupData>::iterator data2 = data;
1765 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1766 data->_indices = data2->_indices;
1769 // Update SMESH objects according to new GEOM group contents
1771 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1772 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1774 int oldID = submesh->GetId();
1775 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1777 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1779 // update hypotheses
1780 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1781 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1782 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1784 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1785 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1787 // care of submeshes
1788 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1789 int newID = newSubmesh->GetId();
1790 if ( newID != oldID ) {
1791 _mapSubMesh [ newID ] = newSubmesh;
1792 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1793 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1794 _mapSubMesh. erase(oldID);
1795 _mapSubMesh_i. erase(oldID);
1796 _mapSubMeshIor.erase(oldID);
1797 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1802 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1803 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1804 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1806 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1808 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1809 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1810 ds->SetShape( newShape );
1815 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1816 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1818 // Remove groups and submeshes basing on removed sub-shapes
1820 TopTools_MapOfShape newShapeMap;
1821 TopoDS_Iterator shapeIt( newShape );
1822 for ( ; shapeIt.More(); shapeIt.Next() )
1823 newShapeMap.Add( shapeIt.Value() );
1825 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1826 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1828 if ( newShapeMap.Contains( shapeIt.Value() ))
1830 TopTools_IndexedMapOfShape oldShapeMap;
1831 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1832 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1834 const TopoDS_Shape& oldShape = oldShapeMap(i);
1835 int oldInd = meshDS->ShapeToIndex( oldShape );
1837 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1838 if ( i_smIor != _mapSubMeshIor.end() ) {
1839 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1842 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1843 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1845 // check if a group bases on oldInd shape
1846 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1847 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1848 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1849 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1851 RemoveGroup( i_grp->second ); // several groups can base on same shape
1852 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1857 // Reassign hypotheses and update groups after setting the new shape to mesh
1859 // collect anassigned hypotheses
1860 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1861 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1862 TShapeHypList assignedHyps;
1863 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1865 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1866 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1867 if ( !hyps.empty() ) {
1868 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1869 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1870 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1873 // collect shapes supporting groups
1874 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1875 TShapeTypeList groupData;
1876 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1877 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1878 for ( ; grIt != groups.end(); ++grIt )
1880 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1882 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1884 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1885 _impl->ShapeToMesh( newShape );
1887 // reassign hypotheses
1888 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1889 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1891 TIndexedShape& geom = indS_hyps->first;
1892 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1893 int oldID = geom._index;
1894 int newID = meshDS->ShapeToIndex( geom._shape );
1897 if ( oldID == 1 ) { // main shape
1899 geom._shape = newShape;
1901 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1902 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1903 // care of submeshes
1904 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1905 if ( newID != oldID ) {
1906 _mapSubMesh [ newID ] = newSubmesh;
1907 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1908 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1909 _mapSubMesh. erase(oldID);
1910 _mapSubMesh_i. erase(oldID);
1911 _mapSubMeshIor.erase(oldID);
1912 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1916 TShapeTypeList::iterator geomType = groupData.begin();
1917 for ( ; geomType != groupData.end(); ++geomType )
1919 const TIndexedShape& geom = geomType->first;
1920 int oldID = geom._index;
1921 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1924 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1925 CORBA::String_var name = groupSO->GetName();
1927 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1929 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1930 group_i->changeLocalId( newID );
1933 break; // everything has been updated
1936 } // loop on group data
1940 CORBA::Long newNbEntities = NbNodes() + NbElements();
1941 list< SALOMEDS::SObject_var > soToUpdateIcons;
1942 if ( newNbEntities != nbEntities )
1944 // Add all SObjects with icons
1945 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
1947 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
1948 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
1949 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
1951 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
1952 i_gr != _mapGroups.end(); ++i_gr ) // groups
1953 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
1956 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
1957 for ( ; so != soToUpdateIcons.end(); ++so )
1958 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
1961 //=============================================================================
1963 * \brief Create standalone group from a group on geometry or filter
1965 //=============================================================================
1967 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
1969 SMESH::SMESH_Group_var aGroup;
1970 if ( theGroup->_is_nil() )
1971 return aGroup._retn();
1973 Unexpect aCatch(SALOME_SalomeException);
1975 SMESH_GroupBase_i* aGroupToRem =
1976 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1978 return aGroup._retn();
1980 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
1982 int anId = aGroupToRem->GetLocalID();
1983 if ( !_impl->ConvertToStandalone( anId ) )
1984 return aGroup._retn();
1985 removeGeomGroupData( theGroup );
1987 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
1989 // remove old instance of group from own map
1990 _mapGroups.erase( anId );
1992 SALOMEDS::StudyBuilder_var builder;
1993 SALOMEDS::SObject_var aGroupSO;
1994 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1995 if ( !aStudy->_is_nil() ) {
1996 builder = aStudy->NewBuilder();
1997 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1998 if ( !aGroupSO->_is_nil() ) {
2000 // remove reference to geometry
2001 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
2002 for ( ; chItr->More(); chItr->Next() )
2003 // Remove group's child SObject
2004 builder->RemoveObject( chItr->Value() );
2006 // Update Python script
2007 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2008 << aGroupSO << " )";
2010 // change icon of Group on Filter
2013 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2014 const int isEmpty = ( elemTypes->length() == 0 );
2017 SALOMEDS::GenericAttribute_var anAttr =
2018 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2019 SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
2020 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2026 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2027 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2028 aGroupImpl->Register();
2029 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2031 // remember new group in own map
2032 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2033 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2035 // register CORBA object for persistence
2036 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
2038 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
2040 return aGroup._retn();
2043 //=============================================================================
2047 //=============================================================================
2049 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2051 if(MYDEBUG) MESSAGE( "createSubMesh" );
2052 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2054 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2055 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2056 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2057 SMESH::SMESH_subMesh_var subMesh
2058 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2060 _mapSubMesh[subMeshId] = mySubMesh;
2061 _mapSubMesh_i[subMeshId] = subMeshServant;
2062 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2064 // register CORBA object for persistence
2065 int nextId = _gen_i->RegisterObject( subMesh );
2066 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2068 // to track changes of GEOM groups
2069 addGeomGroupData( theSubShapeObject, subMesh );
2071 return subMesh._retn();
2074 //=======================================================================
2075 //function : getSubMesh
2077 //=======================================================================
2079 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2081 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2082 if ( it == _mapSubMeshIor.end() )
2083 return SMESH::SMESH_subMesh::_nil();
2085 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2089 //=============================================================================
2093 //=============================================================================
2095 void SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2096 GEOM::GEOM_Object_ptr theSubShapeObject )
2098 MESSAGE("SMESH_Mesh_i::removeSubMesh()");
2099 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2102 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2104 CORBA::Long shapeId = theSubMesh->GetId();
2105 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2107 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2110 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2111 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2112 for ( ; hyp != hyps.end(); ++hyp )
2113 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2120 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2121 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2122 removeHypothesis( theSubShapeObject, aHypList[i] );
2125 catch( const SALOME::SALOME_Exception& ) {
2126 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2128 removeGeomGroupData( theSubShapeObject );
2130 int subMeshId = theSubMesh->GetId();
2132 _mapSubMesh.erase(subMeshId);
2133 _mapSubMesh_i.erase(subMeshId);
2134 _mapSubMeshIor.erase(subMeshId);
2135 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeSubMesh() completed");
2138 //=============================================================================
2142 //=============================================================================
2144 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2145 const char* theName,
2146 const TopoDS_Shape& theShape,
2147 const SMESH_PredicatePtr& thePredicate )
2149 std::string newName;
2150 if ( !theName || strlen( theName ) == 0 )
2152 std::set< std::string > presentNames;
2153 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2154 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2155 presentNames.insert( i_gr->second->GetName() );
2157 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2158 } while ( !presentNames.insert( newName ).second );
2159 theName = newName.c_str();
2162 SMESH::SMESH_GroupBase_var aGroup;
2163 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2165 SMESH_GroupBase_i* aGroupImpl;
2166 if ( !theShape.IsNull() )
2167 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2168 else if ( thePredicate )
2169 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2171 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2173 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2174 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2175 aGroupImpl->Register();
2176 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2178 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2179 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2181 // register CORBA object for persistence
2182 int nextId = _gen_i->RegisterObject( aGroup );
2183 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2185 // to track changes of GEOM groups
2186 if ( !theShape.IsNull() ) {
2187 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2188 addGeomGroupData( geom, aGroup );
2191 return aGroup._retn();
2194 //=============================================================================
2196 * SMESH_Mesh_i::removeGroup
2198 * Should be called by ~SMESH_Group_i()
2200 //=============================================================================
2202 void SMESH_Mesh_i::removeGroup( const int theId )
2204 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2205 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2206 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2207 _mapGroups.erase( theId );
2208 removeGeomGroupData( group );
2209 if (! _impl->RemoveGroup( theId ))
2211 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2212 RemoveGroup( group );
2217 //=============================================================================
2221 //=============================================================================
2223 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2224 throw(SALOME::SALOME_Exception)
2226 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetLog");
2228 SMESH::log_array_var aLog;
2230 list < SMESHDS_Command * >logDS = _impl->GetLog();
2231 aLog = new SMESH::log_array;
2233 int lg = logDS.size();
2236 list < SMESHDS_Command * >::iterator its = logDS.begin();
2237 while(its != logDS.end()){
2238 SMESHDS_Command *com = *its;
2239 int comType = com->GetType();
2241 int lgcom = com->GetNumber();
2243 const list < int >&intList = com->GetIndexes();
2244 int inum = intList.size();
2246 list < int >::const_iterator ii = intList.begin();
2247 const list < double >&coordList = com->GetCoords();
2248 int rnum = coordList.size();
2250 list < double >::const_iterator ir = coordList.begin();
2251 aLog[indexLog].commandType = comType;
2252 aLog[indexLog].number = lgcom;
2253 aLog[indexLog].coords.length(rnum);
2254 aLog[indexLog].indexes.length(inum);
2255 for(int i = 0; i < rnum; i++){
2256 aLog[indexLog].coords[i] = *ir;
2257 //MESSAGE(" "<<i<<" "<<ir.Value());
2260 for(int i = 0; i < inum; i++){
2261 aLog[indexLog].indexes[i] = *ii;
2262 //MESSAGE(" "<<i<<" "<<ii.Value());
2271 catch(SALOME_Exception & S_ex){
2272 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2274 return aLog._retn();
2278 //=============================================================================
2282 //=============================================================================
2284 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2286 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2290 //=============================================================================
2294 //=============================================================================
2296 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2298 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2302 //=============================================================================
2306 //=============================================================================
2308 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2313 //=============================================================================
2316 //!< implementation of struct used to call SMESH_Mesh_i::removeGroup() from
2317 // SMESH_Mesh::RemoveGroup() (issue 0020918)
2318 struct TRmGroupCallUp_i : public SMESH_Mesh::TRmGroupCallUp
2320 SMESH_Mesh_i* _mesh;
2321 TRmGroupCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2322 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2326 //=============================================================================
2330 //=============================================================================
2332 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2334 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2337 _impl->SetRemoveGroupCallUp( new TRmGroupCallUp_i(this));
2340 //=============================================================================
2344 //=============================================================================
2346 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2348 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2352 //=============================================================================
2354 * Return mesh editor
2356 //=============================================================================
2358 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2360 // Create MeshEditor
2361 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2362 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2364 // Update Python script
2365 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2367 return aMesh._retn();
2370 //=============================================================================
2372 * Return mesh edition previewer
2374 //=============================================================================
2376 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2378 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2379 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2380 return aMesh._retn();
2383 //================================================================================
2385 * \brief Return true if the mesh has been edited since a last total re-compute
2386 * and those modifications may prevent successful partial re-compute
2388 //================================================================================
2390 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2392 Unexpect aCatch(SALOME_SalomeException);
2393 return _impl->HasModificationsToDiscard();
2396 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2398 const int MAX_ATTEMPTS = 100;
2400 double tolerance = 0.5;
2401 SALOMEDS::Color col;
2405 // generate random color
2406 double red = (double)rand() / RAND_MAX;
2407 double green = (double)rand() / RAND_MAX;
2408 double blue = (double)rand() / RAND_MAX;
2409 // check existence in the list of the existing colors
2410 bool matched = false;
2411 std::list<SALOMEDS::Color>::const_iterator it;
2412 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2413 SALOMEDS::Color color = *it;
2414 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2415 matched = tol < tolerance;
2417 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2418 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2426 //=============================================================================
2430 //=============================================================================
2431 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2433 Unexpect aCatch(SALOME_SalomeException);
2434 _impl->SetAutoColor(theAutoColor);
2436 TPythonDump pyDump; // not to dump group->SetColor() from below code
2437 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2439 std::list<SALOMEDS::Color> aReservedColors;
2440 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2441 for ( ; it != _mapGroups.end(); it++ ) {
2442 if ( CORBA::is_nil( it->second )) continue;
2443 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2444 it->second->SetColor( aColor );
2445 aReservedColors.push_back( aColor );
2449 //=============================================================================
2453 //=============================================================================
2454 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2456 Unexpect aCatch(SALOME_SalomeException);
2457 return _impl->GetAutoColor();
2461 //=============================================================================
2463 * Export in different formats
2465 //=============================================================================
2467 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2469 return _impl->HasDuplicatedGroupNamesMED();
2472 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2474 TCollection_AsciiString aFullName ((char*)file);
2475 OSD_Path aPath (aFullName);
2476 OSD_File aFile (aPath);
2477 if (aFile.Exists()) {
2478 // existing filesystem node
2479 if (aFile.KindOfFile() == OSD_FILE) {
2480 if (aFile.IsWriteable()) {
2485 if (aFile.Failed()) {
2486 TCollection_AsciiString msg ("File ");
2487 msg += aFullName + " cannot be replaced.";
2488 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2491 TCollection_AsciiString msg ("File ");
2492 msg += aFullName + " cannot be overwritten.";
2493 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2496 TCollection_AsciiString msg ("Location ");
2497 msg += aFullName + " is not a file.";
2498 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2501 // nonexisting file; check if it can be created
2503 aFile.Build(OSD_WriteOnly, OSD_Protection());
2504 if (aFile.Failed()) {
2505 TCollection_AsciiString msg ("You cannot create the file ");
2506 msg += aFullName + ". Check the directory existance and access rights.";
2507 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2515 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2516 CORBA::Boolean auto_groups,
2517 SMESH::MED_VERSION theVersion,
2518 CORBA::Boolean overwrite)
2519 throw(SALOME::SALOME_Exception)
2521 Unexpect aCatch(SALOME_SalomeException);
2524 PrepareForWriting(file, overwrite);
2525 string aMeshName = "Mesh";
2526 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2527 if ( !aStudy->_is_nil() ) {
2528 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2529 if ( !aMeshSO->_is_nil() ) {
2530 CORBA::String_var name = aMeshSO->GetName();
2532 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2533 if ( !aStudy->GetProperties()->IsLocked() )
2535 SALOMEDS::GenericAttribute_var anAttr;
2536 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2537 SALOMEDS::AttributeExternalFileDef_var aFileName;
2538 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2539 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2540 ASSERT(!aFileName->_is_nil());
2541 aFileName->SetValue(file);
2542 SALOMEDS::AttributeFileType_var aFileType;
2543 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2544 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2545 ASSERT(!aFileType->_is_nil());
2546 aFileType->SetValue("FICHIERMED");
2550 // Update Python script
2551 // set name of mesh before export
2552 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2554 // check names of groups
2557 TPythonDump() << _this() << ".ExportToMEDX( r'"
2558 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2560 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2563 //================================================================================
2565 * \brief Export a mesh to a med file
2567 //================================================================================
2569 void SMESH_Mesh_i::ExportToMED (const char* file,
2570 CORBA::Boolean auto_groups,
2571 SMESH::MED_VERSION theVersion)
2572 throw(SALOME::SALOME_Exception)
2574 ExportToMEDX(file,auto_groups,theVersion,true);
2577 //================================================================================
2579 * \brief Export a mesh to a med file
2581 //================================================================================
2583 void SMESH_Mesh_i::ExportMED (const char* file,
2584 CORBA::Boolean auto_groups)
2585 throw(SALOME::SALOME_Exception)
2587 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2590 //================================================================================
2592 * \brief Export a mesh to a DAT file
2594 //================================================================================
2596 void SMESH_Mesh_i::ExportDAT (const char *file)
2597 throw(SALOME::SALOME_Exception)
2599 Unexpect aCatch(SALOME_SalomeException);
2601 // Update Python script
2602 // check names of groups
2604 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2607 PrepareForWriting(file);
2608 _impl->ExportDAT(file);
2611 //================================================================================
2613 * \brief Export a mesh to an UNV file
2615 //================================================================================
2617 void SMESH_Mesh_i::ExportUNV (const char *file)
2618 throw(SALOME::SALOME_Exception)
2620 Unexpect aCatch(SALOME_SalomeException);
2622 // Update Python script
2623 // check names of groups
2625 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2628 PrepareForWriting(file);
2629 _impl->ExportUNV(file);
2632 //================================================================================
2634 * \brief Export a mesh to an STL file
2636 //================================================================================
2638 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2639 throw(SALOME::SALOME_Exception)
2641 Unexpect aCatch(SALOME_SalomeException);
2643 // Update Python script
2644 // check names of groups
2646 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2649 PrepareForWriting(file);
2650 _impl->ExportSTL(file, isascii);
2653 //=============================================================================
2655 * \brief Class providing SMESHDS_Mesh API to SMESH_IDSource.
2656 * It is used to export a part of mesh as a whole mesh.
2658 class SMESH_MeshPartDS : public SMESHDS_Mesh
2661 SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart);
2663 virtual SMDS_NodeIteratorPtr nodesIterator (bool idInceasingOrder=false) const;
2664 virtual SMDS_0DElementIteratorPtr elements0dIterator(bool idInceasingOrder=false) const;
2665 virtual SMDS_EdgeIteratorPtr edgesIterator (bool idInceasingOrder=false) const;
2666 virtual SMDS_FaceIteratorPtr facesIterator (bool idInceasingOrder=false) const;
2667 virtual SMDS_VolumeIteratorPtr volumesIterator (bool idInceasingOrder=false) const;
2669 virtual SMDS_ElemIteratorPtr elementsIterator(SMDSAbs_ElementType type=SMDSAbs_All) const;
2672 TIDSortedElemSet _elements[ SMDSAbs_NbElementTypes ];
2673 SMESHDS_Mesh* _meshDS;
2675 * \brief Class used to access to protected data of SMDS_MeshInfo
2677 struct TMeshInfo : public SMDS_MeshInfo
2679 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
2683 //================================================================================
2685 * \brief Export a part of mesh to a med file
2687 //================================================================================
2689 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2691 CORBA::Boolean auto_groups,
2692 ::SMESH::MED_VERSION version,
2693 ::CORBA::Boolean overwrite)
2694 throw (SALOME::SALOME_Exception)
2696 Unexpect aCatch(SALOME_SalomeException);
2698 PrepareForWriting(file, overwrite);
2700 string aMeshName = "Mesh";
2701 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2702 if ( !aStudy->_is_nil() ) {
2703 SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2704 if ( !SO->_is_nil() ) {
2705 CORBA::String_var name = SO->GetName();
2709 SMESH_MeshPartDS partDS( meshPart );
2710 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2712 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2713 << auto_groups << ", " << version << ", " << overwrite << " )";
2716 //================================================================================
2718 * \brief Export a part of mesh to a DAT file
2720 //================================================================================
2722 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2724 throw (SALOME::SALOME_Exception)
2726 Unexpect aCatch(SALOME_SalomeException);
2728 PrepareForWriting(file);
2730 SMESH_MeshPartDS partDS( meshPart );
2731 _impl->ExportDAT(file,&partDS);
2733 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2735 //================================================================================
2737 * \brief Export a part of mesh to an UNV file
2739 //================================================================================
2741 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2743 throw (SALOME::SALOME_Exception)
2745 Unexpect aCatch(SALOME_SalomeException);
2747 PrepareForWriting(file);
2749 SMESH_MeshPartDS partDS( meshPart );
2750 _impl->ExportUNV(file, &partDS);
2752 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2754 //================================================================================
2756 * \brief Export a part of mesh to an STL file
2758 //================================================================================
2760 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2762 ::CORBA::Boolean isascii)
2763 throw (SALOME::SALOME_Exception)
2765 Unexpect aCatch(SALOME_SalomeException);
2767 PrepareForWriting(file);
2769 SMESH_MeshPartDS partDS( meshPart );
2770 _impl->ExportSTL(file, isascii, &partDS);
2772 TPythonDump() << _this() << ".ExportPartToSTL( "
2773 << meshPart<< ", r'" << file << "', " << isascii << ")";
2776 //================================================================================
2778 * \brief Export a part of mesh to an STL file
2780 //================================================================================
2782 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2784 CORBA::Boolean overwrite)
2785 throw (SALOME::SALOME_Exception)
2787 Unexpect aCatch(SALOME_SalomeException);
2789 PrepareForWriting(file,overwrite);
2791 SMESH_MeshPartDS partDS( meshPart );
2792 _impl->ExportCGNS(file, &partDS);
2794 TPythonDump() << _this() << ".ExportCGNS( "
2795 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2798 //=============================================================================
2802 //=============================================================================
2804 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2806 Unexpect aCatch(SALOME_SalomeException);
2807 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2808 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2809 return aMesh._retn();
2812 //=============================================================================
2816 //=============================================================================
2817 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2819 Unexpect aCatch(SALOME_SalomeException);
2820 return _impl->NbNodes();
2823 //=============================================================================
2827 //=============================================================================
2828 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2830 Unexpect aCatch(SALOME_SalomeException);
2831 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2834 //=============================================================================
2838 //=============================================================================
2839 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2841 Unexpect aCatch(SALOME_SalomeException);
2842 return _impl->Nb0DElements();
2845 //=============================================================================
2849 //=============================================================================
2850 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2852 Unexpect aCatch(SALOME_SalomeException);
2853 return _impl->NbEdges();
2856 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2857 throw(SALOME::SALOME_Exception)
2859 Unexpect aCatch(SALOME_SalomeException);
2860 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2863 //=============================================================================
2867 //=============================================================================
2868 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2870 Unexpect aCatch(SALOME_SalomeException);
2871 return _impl->NbFaces();
2874 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2876 Unexpect aCatch(SALOME_SalomeException);
2877 return _impl->NbTriangles();
2880 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2882 Unexpect aCatch(SALOME_SalomeException);
2883 return _impl->NbQuadrangles();
2886 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2888 Unexpect aCatch(SALOME_SalomeException);
2889 return _impl->NbPolygons();
2892 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2893 throw(SALOME::SALOME_Exception)
2895 Unexpect aCatch(SALOME_SalomeException);
2896 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2899 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2900 throw(SALOME::SALOME_Exception)
2902 Unexpect aCatch(SALOME_SalomeException);
2903 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2906 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2907 throw(SALOME::SALOME_Exception)
2909 Unexpect aCatch(SALOME_SalomeException);
2910 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2913 //=============================================================================
2917 //=============================================================================
2918 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2920 Unexpect aCatch(SALOME_SalomeException);
2921 return _impl->NbVolumes();
2924 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2926 Unexpect aCatch(SALOME_SalomeException);
2927 return _impl->NbTetras();
2930 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2932 Unexpect aCatch(SALOME_SalomeException);
2933 return _impl->NbHexas();
2936 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2938 Unexpect aCatch(SALOME_SalomeException);
2939 return _impl->NbPyramids();
2942 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2944 Unexpect aCatch(SALOME_SalomeException);
2945 return _impl->NbPrisms();
2948 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2950 Unexpect aCatch(SALOME_SalomeException);
2951 return _impl->NbPolyhedrons();
2954 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2955 throw(SALOME::SALOME_Exception)
2957 Unexpect aCatch(SALOME_SalomeException);
2958 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2961 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2962 throw(SALOME::SALOME_Exception)
2964 Unexpect aCatch(SALOME_SalomeException);
2965 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2968 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2969 throw(SALOME::SALOME_Exception)
2971 Unexpect aCatch(SALOME_SalomeException);
2972 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2975 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2976 throw(SALOME::SALOME_Exception)
2978 Unexpect aCatch(SALOME_SalomeException);
2979 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2982 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2983 throw(SALOME::SALOME_Exception)
2985 Unexpect aCatch(SALOME_SalomeException);
2986 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2989 //=============================================================================
2993 //=============================================================================
2994 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
2996 Unexpect aCatch(SALOME_SalomeException);
2997 return _mapSubMesh_i.size();
3000 //=============================================================================
3004 //=============================================================================
3005 char* SMESH_Mesh_i::Dump()
3009 return CORBA::string_dup( os.str().c_str() );
3012 //=============================================================================
3016 //=============================================================================
3017 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3019 // SMESH::long_array_var aResult = new SMESH::long_array();
3020 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3021 // int aMinId = aSMESHDS_Mesh->MinElementID();
3022 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
3024 // aResult->length(aMaxId - aMinId + 1);
3026 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
3027 // aResult[i++] = id;
3029 // return aResult._retn();
3031 return GetElementsId();
3034 //=============================================================================
3038 //=============================================================================
3040 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3041 throw (SALOME::SALOME_Exception)
3043 Unexpect aCatch(SALOME_SalomeException);
3044 MESSAGE("SMESH_Mesh_i::GetElementsId");
3045 SMESH::long_array_var aResult = new SMESH::long_array();
3046 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3048 if ( aSMESHDS_Mesh == NULL )
3049 return aResult._retn();
3051 long nbElements = NbElements();
3052 aResult->length( nbElements );
3053 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3054 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3055 aResult[i] = anIt->next()->GetID();
3057 return aResult._retn();
3061 //=============================================================================
3065 //=============================================================================
3067 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3068 throw (SALOME::SALOME_Exception)
3070 Unexpect aCatch(SALOME_SalomeException);
3071 MESSAGE("SMESH_subMesh_i::GetElementsByType");
3072 SMESH::long_array_var aResult = new SMESH::long_array();
3073 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3075 if ( aSMESHDS_Mesh == NULL )
3076 return aResult._retn();
3078 long nbElements = NbElements();
3080 // No sense in returning ids of elements along with ids of nodes:
3081 // when theElemType == SMESH::ALL, return node ids only if
3082 // there are no elements
3083 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3084 return GetNodesId();
3086 aResult->length( nbElements );
3090 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3091 while ( i < nbElements && anIt->more() ) {
3092 const SMDS_MeshElement* anElem = anIt->next();
3093 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3094 aResult[i++] = anElem->GetID();
3097 aResult->length( i );
3099 return aResult._retn();
3102 //=============================================================================
3106 //=============================================================================
3108 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3109 throw (SALOME::SALOME_Exception)
3111 Unexpect aCatch(SALOME_SalomeException);
3112 MESSAGE("SMESH_subMesh_i::GetNodesId");
3113 SMESH::long_array_var aResult = new SMESH::long_array();
3114 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3116 if ( aSMESHDS_Mesh == NULL )
3117 return aResult._retn();
3119 long nbNodes = NbNodes();
3120 aResult->length( nbNodes );
3121 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3122 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3123 aResult[i] = anIt->next()->GetID();
3125 return aResult._retn();
3128 //=============================================================================
3132 //=============================================================================
3134 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3135 throw (SALOME::SALOME_Exception)
3137 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3140 //=============================================================================
3144 //=============================================================================
3146 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3147 throw (SALOME::SALOME_Exception)
3149 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3151 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3153 return ( SMESH::EntityType ) e->GetEntityType();
3156 //=============================================================================
3158 * Returns ID of elements for given submesh
3160 //=============================================================================
3161 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3162 throw (SALOME::SALOME_Exception)
3164 SMESH::long_array_var aResult = new SMESH::long_array();
3166 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3167 if(!SM) return aResult._retn();
3169 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3170 if(!SDSM) return aResult._retn();
3172 aResult->length(SDSM->NbElements());
3174 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3176 while ( eIt->more() ) {
3177 aResult[i++] = eIt->next()->GetID();
3180 return aResult._retn();
3184 //=============================================================================
3186 * Returns ID of nodes for given submesh
3187 * If param all==true - returns all nodes, else -
3188 * returns only nodes on shapes.
3190 //=============================================================================
3191 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
3192 throw (SALOME::SALOME_Exception)
3194 SMESH::long_array_var aResult = new SMESH::long_array();
3196 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3197 if(!SM) return aResult._retn();
3199 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3200 if(!SDSM) return aResult._retn();
3203 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3204 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3205 while ( nIt->more() ) {
3206 const SMDS_MeshNode* elem = nIt->next();
3207 theElems.insert( elem->GetID() );
3210 else { // all nodes of submesh elements
3211 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3212 while ( eIt->more() ) {
3213 const SMDS_MeshElement* anElem = eIt->next();
3214 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3215 while ( nIt->more() ) {
3216 const SMDS_MeshElement* elem = nIt->next();
3217 theElems.insert( elem->GetID() );
3222 aResult->length(theElems.size());
3223 set<int>::iterator itElem;
3225 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3226 aResult[i++] = *itElem;
3228 return aResult._retn();
3232 //=============================================================================
3234 * Returns type of elements for given submesh
3236 //=============================================================================
3237 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3238 throw (SALOME::SALOME_Exception)
3240 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3241 if(!SM) return SMESH::ALL;
3243 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3244 if(!SDSM) return SMESH::ALL;
3246 if(SDSM->NbElements()==0)
3247 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3249 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3250 const SMDS_MeshElement* anElem = eIt->next();
3251 return ( SMESH::ElementType ) anElem->GetType();
3255 //=============================================================================
3259 //=============================================================================
3261 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3263 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3265 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3270 //=============================================================================
3272 * Get XYZ coordinates of node as list of double
3273 * If there is not node for given ID - returns empty list
3275 //=============================================================================
3277 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3279 SMESH::double_array_var aResult = new SMESH::double_array();
3280 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3281 if ( aSMESHDS_Mesh == NULL )
3282 return aResult._retn();
3285 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3287 return aResult._retn();
3291 aResult[0] = aNode->X();
3292 aResult[1] = aNode->Y();
3293 aResult[2] = aNode->Z();
3294 return aResult._retn();
3298 //=============================================================================
3300 * For given node returns list of IDs of inverse elements
3301 * If there is not node for given ID - returns empty list
3303 //=============================================================================
3305 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3307 SMESH::long_array_var aResult = new SMESH::long_array();
3308 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3309 if ( aSMESHDS_Mesh == NULL )
3310 return aResult._retn();
3313 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3315 return aResult._retn();
3317 // find inverse elements
3318 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3319 TColStd_SequenceOfInteger IDs;
3320 while(eIt->more()) {
3321 const SMDS_MeshElement* elem = eIt->next();
3322 IDs.Append(elem->GetID());
3324 if(IDs.Length()>0) {
3325 aResult->length(IDs.Length());
3327 for(; i<=IDs.Length(); i++) {
3328 aResult[i-1] = IDs.Value(i);
3331 return aResult._retn();
3334 //=============================================================================
3336 * \brief Return position of a node on shape
3338 //=============================================================================
3340 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3342 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3343 aNodePosition->shapeID = 0;
3344 aNodePosition->shapeType = GEOM::SHAPE;
3346 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3347 if ( !mesh ) return aNodePosition;
3349 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3351 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3353 aNodePosition->shapeID = aNode->getshapeId();
3354 switch ( pos->GetTypeOfPosition() ) {
3356 aNodePosition->shapeType = GEOM::EDGE;
3357 aNodePosition->params.length(1);
3358 aNodePosition->params[0] =
3359 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3362 aNodePosition->shapeType = GEOM::FACE;
3363 aNodePosition->params.length(2);
3364 aNodePosition->params[0] =
3365 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3366 aNodePosition->params[1] =
3367 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3369 case SMDS_TOP_VERTEX:
3370 aNodePosition->shapeType = GEOM::VERTEX;
3372 case SMDS_TOP_3DSPACE:
3373 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3374 aNodePosition->shapeType = GEOM::SOLID;
3375 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3376 aNodePosition->shapeType = GEOM::SHELL;
3382 return aNodePosition;
3385 //=============================================================================
3387 * If given element is node returns IDs of shape from position
3388 * If there is not node for given ID - returns -1
3390 //=============================================================================
3392 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3394 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3395 if ( aSMESHDS_Mesh == NULL )
3399 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3401 return aNode->getshapeId();
3408 //=============================================================================
3410 * For given element returns ID of result shape after
3411 * ::FindShape() from SMESH_MeshEditor
3412 * If there is not element for given ID - returns -1
3414 //=============================================================================
3416 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3418 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3419 if ( aSMESHDS_Mesh == NULL )
3422 // try to find element
3423 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3427 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3428 ::SMESH_MeshEditor aMeshEditor(_impl);
3429 int index = aMeshEditor.FindShape( elem );
3437 //=============================================================================
3439 * Returns number of nodes for given element
3440 * If there is not element for given ID - returns -1
3442 //=============================================================================
3444 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3446 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3447 if ( aSMESHDS_Mesh == NULL ) return -1;
3448 // try to find element
3449 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3450 if(!elem) return -1;
3451 return elem->NbNodes();
3455 //=============================================================================
3457 * Returns ID of node by given index for given element
3458 * If there is not element for given ID - returns -1
3459 * If there is not node for given index - returns -2
3461 //=============================================================================
3463 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3465 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3466 if ( aSMESHDS_Mesh == NULL ) return -1;
3467 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3468 if(!elem) return -1;
3469 if( index>=elem->NbNodes() || index<0 ) return -1;
3470 return elem->GetNode(index)->GetID();
3473 //=============================================================================
3475 * Returns IDs of nodes of given element
3477 //=============================================================================
3479 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3481 SMESH::long_array_var aResult = new SMESH::long_array();
3482 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3484 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3486 aResult->length( elem->NbNodes() );
3487 for ( int i = 0; i < elem->NbNodes(); ++i )
3488 aResult[ i ] = elem->GetNode( i )->GetID();
3491 return aResult._retn();
3494 //=============================================================================
3496 * Returns true if given node is medium node
3497 * in given quadratic element
3499 //=============================================================================
3501 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3503 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3504 if ( aSMESHDS_Mesh == NULL ) return false;
3506 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3507 if(!aNode) return false;
3508 // try to find element
3509 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3510 if(!elem) return false;
3512 return elem->IsMediumNode(aNode);
3516 //=============================================================================
3518 * Returns true if given node is medium node
3519 * in one of quadratic elements
3521 //=============================================================================
3523 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3524 SMESH::ElementType theElemType)
3526 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3527 if ( aSMESHDS_Mesh == NULL ) return false;
3530 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3531 if(!aNode) return false;
3533 SMESH_MesherHelper aHelper( *(_impl) );
3535 SMDSAbs_ElementType aType;
3536 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3537 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3538 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3539 else aType = SMDSAbs_All;
3541 return aHelper.IsMedium(aNode,aType);
3545 //=============================================================================
3547 * Returns number of edges for given element
3549 //=============================================================================
3551 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3553 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3554 if ( aSMESHDS_Mesh == NULL ) return -1;
3555 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3556 if(!elem) return -1;
3557 return elem->NbEdges();
3561 //=============================================================================
3563 * Returns number of faces for given element
3565 //=============================================================================
3567 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3569 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3570 if ( aSMESHDS_Mesh == NULL ) return -1;
3571 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3572 if(!elem) return -1;
3573 return elem->NbFaces();
3576 //=======================================================================
3577 //function : GetElemFaceNodes
3578 //purpose : Returns nodes of given face (counted from zero) for given element.
3579 //=======================================================================
3581 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3582 CORBA::Short faceIndex)
3584 SMESH::long_array_var aResult = new SMESH::long_array();
3585 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3587 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3589 SMDS_VolumeTool vtool( elem );
3590 if ( faceIndex < vtool.NbFaces() )
3592 aResult->length( vtool.NbFaceNodes( faceIndex ));
3593 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3594 for ( int i = 0; i < aResult->length(); ++i )
3595 aResult[ i ] = nn[ i ]->GetID();
3599 return aResult._retn();
3602 //=======================================================================
3603 //function : FindElementByNodes
3604 //purpose : Returns an element based on all given nodes.
3605 //=======================================================================
3607 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3609 CORBA::Long elemID(0);
3610 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3612 vector< const SMDS_MeshNode * > nn( nodes.length() );
3613 for ( int i = 0; i < nodes.length(); ++i )
3614 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3617 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3618 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3619 _impl->NbFaces( ORDER_QUADRATIC ) ||
3620 _impl->NbVolumes( ORDER_QUADRATIC )))
3621 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3623 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3628 //=============================================================================
3630 * Returns true if given element is polygon
3632 //=============================================================================
3634 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3636 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3637 if ( aSMESHDS_Mesh == NULL ) return false;
3638 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3639 if(!elem) return false;
3640 return elem->IsPoly();
3644 //=============================================================================
3646 * Returns true if given element is quadratic
3648 //=============================================================================
3650 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3652 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3653 if ( aSMESHDS_Mesh == NULL ) return false;
3654 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3655 if(!elem) return false;
3656 return elem->IsQuadratic();
3660 //=============================================================================
3662 * Returns bary center for given element
3664 //=============================================================================
3666 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3668 SMESH::double_array_var aResult = new SMESH::double_array();
3669 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3670 if ( aSMESHDS_Mesh == NULL )
3671 return aResult._retn();
3673 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3675 return aResult._retn();
3677 if(elem->GetType()==SMDSAbs_Volume) {
3678 SMDS_VolumeTool aTool;
3679 if(aTool.Set(elem)) {
3681 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3686 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3688 double x=0., y=0., z=0.;
3689 for(; anIt->more(); ) {
3691 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3705 return aResult._retn();
3709 //=============================================================================
3711 * Create and publish group servants if any groups were imported or created anyhow
3713 //=============================================================================
3715 void SMESH_Mesh_i::CreateGroupServants()
3717 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3720 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3721 while ( groupIt->more() )
3723 ::SMESH_Group* group = groupIt->next();
3724 int anId = group->GetGroupDS()->GetID();
3726 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3727 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3729 addedIDs.insert( anId );
3731 SMESH_GroupBase_i* aGroupImpl;
3733 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3734 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3736 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3737 shape = groupOnGeom->GetShape();
3740 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3743 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3744 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3745 aGroupImpl->Register();
3747 SMESH::SMESH_GroupBase_var groupVar =
3748 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3749 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3751 // register CORBA object for persistence
3752 int nextId = _gen_i->RegisterObject( groupVar );
3753 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3755 // publishing the groups in the study
3756 if ( !aStudy->_is_nil() ) {
3757 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3758 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3761 if ( !addedIDs.empty() )
3764 set<int>::iterator id = addedIDs.begin();
3765 for ( ; id != addedIDs.end(); ++id )
3767 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
3768 int i = std::distance( _mapGroups.begin(), it );
3769 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
3774 //=============================================================================
3776 * \brief Return groups cantained in _mapGroups by their IDs
3778 //=============================================================================
3780 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3782 int nbGroups = groupIDs.size();
3783 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3784 aList->length( nbGroups );
3786 list<int>::const_iterator ids = groupIDs.begin();
3787 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3789 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3790 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3791 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3793 aList->length( nbGroups );
3794 return aList._retn();
3797 //=============================================================================
3799 * \brief Return information about imported file
3801 //=============================================================================
3803 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3805 SALOME_MED::MedFileInfo_var res( myFileInfo );
3806 if ( !res.operator->() ) {
3807 res = new SALOME_MED::MedFileInfo;
3809 res->fileSize = res->major = res->minor = res->release = -1;
3814 //=============================================================================
3816 * \brief Check and correct names of mesh groups
3818 //=============================================================================
3820 void SMESH_Mesh_i::checkGroupNames()
3822 int nbGrp = NbGroups();
3826 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3827 if ( aStudy->_is_nil() )
3828 return; // nothing to do
3830 SMESH::ListOfGroups* grpList = 0;
3831 // avoid dump of "GetGroups"
3833 // store python dump into a local variable inside local scope
3834 SMESH::TPythonDump pDump; // do not delete this line of code
3835 grpList = GetGroups();
3838 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3839 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3842 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3843 if ( aGrpSO->_is_nil() )
3845 // correct name of the mesh group if necessary
3846 const char* guiName = aGrpSO->GetName();
3847 if ( strcmp(guiName, aGrp->GetName()) )
3848 aGrp->SetName( guiName );
3852 //=============================================================================
3854 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3856 //=============================================================================
3857 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3859 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3860 CORBA::string_dup(theParameters));
3863 //=============================================================================
3865 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3867 //=============================================================================
3868 char* SMESH_Mesh_i::GetParameters()
3870 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3871 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3874 //=============================================================================
3876 * \brief Returns list of notebook variables used for last Mesh operation
3878 //=============================================================================
3879 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3881 SMESH::string_array_var aResult = new SMESH::string_array();
3882 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3884 char *aParameters = GetParameters();
3885 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3886 if(!aStudy->_is_nil()) {
3887 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3888 if(aSections->length() > 0) {
3889 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3890 aResult->length(aVars.length());
3891 for(int i = 0;i < aVars.length();i++)
3892 aResult[i] = CORBA::string_dup( aVars[i]);
3896 return aResult._retn();
3899 //=======================================================================
3900 //function : GetTypes
3901 //purpose : Returns types of elements it contains
3902 //=======================================================================
3904 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3906 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3910 if (_impl->NbEdges())
3911 types[nbTypes++] = SMESH::EDGE;
3912 if (_impl->NbFaces())
3913 types[nbTypes++] = SMESH::FACE;
3914 if (_impl->NbVolumes())
3915 types[nbTypes++] = SMESH::VOLUME;
3916 if (_impl->Nb0DElements())
3917 types[nbTypes++] = SMESH::ELEM0D;
3918 types->length( nbTypes );
3920 return types._retn();
3923 //=======================================================================
3924 //function : GetMesh
3925 //purpose : Returns self
3926 //=======================================================================
3928 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
3930 return SMESH::SMESH_Mesh::_duplicate( _this() );
3933 //=============================================================================
3935 * \brief Returns statistic of mesh elements
3937 //=============================================================================
3938 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3940 SMESH::long_array_var aRes = new SMESH::long_array();
3941 aRes->length(SMESH::Entity_Last);
3942 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3944 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3946 return aRes._retn();
3947 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3948 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3949 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3950 return aRes._retn();
3953 //=============================================================================
3955 * \brief Collect statistic of mesh elements given by iterator
3957 //=============================================================================
3958 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3959 SMESH::long_array& theInfo)
3961 if (!theItr) return;
3962 while (theItr->more())
3963 theInfo[ theItr->next()->GetEntityType() ]++;
3966 //=============================================================================
3968 * \brief mapping of mesh dimension into shape type
3970 //=============================================================================
3971 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3973 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3975 case 0: aType = TopAbs_VERTEX; break;
3976 case 1: aType = TopAbs_EDGE; break;
3977 case 2: aType = TopAbs_FACE; break;
3979 default:aType = TopAbs_SOLID; break;
3984 //=============================================================================
3986 * \brief Internal structure used to find concurent submeshes
3988 * It represents a pair < submesh, concurent dimension >, where
3989 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3990 * with another submesh. In other words, it is dimension of a hypothesis assigned
3993 //=============================================================================
3999 int _dim; //!< a dimension the algo can build (concurrent dimension)
4000 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4001 TopTools_MapOfShape _shapeMap;
4002 SMESH_subMesh* _subMesh;
4003 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
4006 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4008 const TopoDS_Shape& theShape)
4010 _subMesh = (SMESH_subMesh*)theSubMesh;
4011 SetShape( theDim, theShape );
4015 void SetShape(const int theDim,
4016 const TopoDS_Shape& theShape)
4019 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4020 if (_dim >= _ownDim)
4021 _shapeMap.Add( theShape );
4023 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4024 for( ; anExp.More(); anExp.Next() )
4025 _shapeMap.Add( anExp.Current() );
4029 //! Check sharing of sub shapes
4030 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4031 const TopTools_MapOfShape& theToFind,
4032 const TopAbs_ShapeEnum theType)
4034 bool isShared = false;
4035 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4036 for (; !isShared && anItr.More(); anItr.Next() ) {
4037 const TopoDS_Shape aSubSh = anItr.Key();
4038 // check for case when concurrent dimensions are same
4039 isShared = theToFind.Contains( aSubSh );
4040 // check for subshape with concurrent dimension
4041 TopExp_Explorer anExp( aSubSh, theType );
4042 for ( ; !isShared && anExp.More(); anExp.Next() )
4043 isShared = theToFind.Contains( anExp.Current() );
4048 //! check algorithms
4049 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4050 const SMESHDS_Hypothesis* theA2)
4052 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4053 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4054 return false; // one of the hypothesis is not algorithm
4055 // check algorithm names (should be equal)
4056 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4060 //! Check if subshape hypotheses are concurrent
4061 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4063 if ( _subMesh == theOther->_subMesh )
4064 return false; // same subshape - should not be
4066 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4067 // any of the two submeshes is not on COMPOUND shape )
4068 // -> no concurrency
4069 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4070 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4071 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4074 // bool checkSubShape = ( _dim >= theOther->_dim )
4075 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4076 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4077 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4078 if ( !checkSubShape )
4081 // check algorithms to be same
4082 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
4083 return true; // different algorithms
4085 // check hypothesises for concurrence (skip first as algorithm)
4087 // pointers should be same, becase it is referenes from mesh hypothesis partition
4088 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
4089 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
4090 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
4091 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
4093 // the submeshes are concurrent if their algorithms has different parameters
4094 return nbSame != theOther->_hypothesises.size() - 1;
4097 }; // end of SMESH_DimHyp
4099 typedef list<SMESH_DimHyp*> TDimHypList;
4101 static void addDimHypInstance(const int theDim,
4102 const TopoDS_Shape& theShape,
4103 const SMESH_Algo* theAlgo,
4104 const SMESH_subMesh* theSubMesh,
4105 const list <const SMESHDS_Hypothesis*>& theHypList,
4106 TDimHypList* theDimHypListArr )
4108 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4109 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4110 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4111 listOfdimHyp.push_back( dimHyp );
4114 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
4115 dimHyp->_hypothesises.push_front(theAlgo);
4116 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
4117 for( ; hypIt != theHypList.end(); hypIt++ )
4118 dimHyp->_hypothesises.push_back( *hypIt );
4121 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
4122 const TDimHypList& theListOfDimHyp,
4123 TListOfInt& theListOfConcurr )
4125 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4126 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
4127 const SMESH_DimHyp* curDimHyp = *rIt;
4128 if ( curDimHyp == theDimHyp )
4129 break; // meet own dimHyp pointer in same dimension
4130 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
4131 if ( find( theListOfConcurr.begin(),
4132 theListOfConcurr.end(),
4133 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
4134 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
4138 static void unionLists(TListOfInt& theListOfId,
4139 TListOfListOfInt& theListOfListOfId,
4142 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4143 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4145 continue; //skip already treated lists
4146 // check if other list has any same submesh object
4147 TListOfInt& otherListOfId = *it;
4148 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4149 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4152 // union two lists (from source into target)
4153 TListOfInt::iterator it2 = otherListOfId.begin();
4154 for ( ; it2 != otherListOfId.end(); it2++ ) {
4155 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4156 theListOfId.push_back(*it2);
4158 // clear source list
4159 otherListOfId.clear();
4163 //! free memory allocated for dimension-hypothesis objects
4164 static void removeDimHyps( TDimHypList* theArrOfList )
4166 for (int i = 0; i < 4; i++ ) {
4167 TDimHypList& listOfdimHyp = theArrOfList[i];
4168 TDimHypList::const_iterator it = listOfdimHyp.begin();
4169 for ( ; it != listOfdimHyp.end(); it++ )
4174 //=============================================================================
4176 * \brief Return submesh objects list in meshing order
4178 //=============================================================================
4180 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4182 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4184 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4186 return aResult._retn();
4188 ::SMESH_Mesh& mesh = GetImpl();
4189 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4190 if ( !anOrder.size() ) {
4192 // collect submeshes detecting concurrent algorithms and hypothesises
4193 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4195 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4196 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4197 ::SMESH_subMesh* sm = (*i_sm).second;
4199 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4201 // list of assigned hypothesises
4202 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4203 // Find out dimensions where the submesh can be concurrent.
4204 // We define the dimensions by algo of each of hypotheses in hypList
4205 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4206 for( ; hypIt != hypList.end(); hypIt++ ) {
4207 SMESH_Algo* anAlgo = 0;
4208 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4209 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4210 // hyp it-self is algo
4211 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4213 // try to find algorithm with help of subshapes
4214 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4215 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4216 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4219 continue; // no assigned algorithm to current submesh
4221 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4222 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
4224 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4225 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4226 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4228 } // end iterations on submesh
4230 // iterate on created dimension-hypotheses and check for concurrents
4231 for ( int i = 0; i < 4; i++ ) {
4232 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
4233 // check for concurrents in own and other dimensions (step-by-step)
4234 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4235 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4236 const SMESH_DimHyp* dimHyp = *dhIt;
4237 TListOfInt listOfConcurr;
4238 // looking for concurrents and collect into own list
4239 for ( int j = i; j < 4; j++ )
4240 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
4241 // check if any concurrents found
4242 if ( listOfConcurr.size() > 0 ) {
4243 // add own submesh to list of concurrent
4244 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
4245 anOrder.push_back( listOfConcurr );
4250 removeDimHyps(dimHypListArr);
4252 // now, minimise the number of concurrent groups
4253 // Here we assume that lists of submhes can has same submesh
4254 // in case of multi-dimension algorithms, as result
4255 // list with common submesh have to be union into one list
4257 TListOfListOfInt::iterator listIt = anOrder.begin();
4258 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4259 unionLists( *listIt, anOrder, listIndx + 1 );
4261 // convert submesh ids into interface instances
4262 // and dump command into python
4263 convertMeshOrder( anOrder, aResult, true );
4265 return aResult._retn();
4268 //=============================================================================
4270 * \brief find common submeshes with given submesh
4271 * \param theSubMeshList list of already collected submesh to check
4272 * \param theSubMesh given submesh to intersect with other
4273 * \param theCommonSubMeshes collected common submeshes
4275 //=============================================================================
4277 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4278 const SMESH_subMesh* theSubMesh,
4279 set<const SMESH_subMesh*>& theCommon )
4283 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4284 for ( ; it != theSubMeshList.end(); it++ )
4285 theSubMesh->FindIntersection( *it, theCommon );
4286 theSubMeshList.push_back( theSubMesh );
4287 //theCommon.insert( theSubMesh );
4290 //=============================================================================
4292 * \brief Set submesh object order
4293 * \param theSubMeshArray submesh array order
4295 //=============================================================================
4297 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4300 ::SMESH_Mesh& mesh = GetImpl();
4302 TPythonDump aPythonDump; // prevent dump of called methods
4303 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4305 TListOfListOfInt subMeshOrder;
4306 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4308 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4309 TListOfInt subMeshIds;
4310 aPythonDump << "[ ";
4311 // Collect subMeshes which should be clear
4312 // do it list-by-list, because modification of submesh order
4313 // take effect between concurrent submeshes only
4314 set<const SMESH_subMesh*> subMeshToClear;
4315 list<const SMESH_subMesh*> subMeshList;
4316 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4318 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4320 aPythonDump << ", ";
4321 aPythonDump << subMesh;
4322 subMeshIds.push_back( subMesh->GetId() );
4323 // detect common parts of submeshes
4324 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4325 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4327 aPythonDump << " ]";
4328 subMeshOrder.push_back( subMeshIds );
4330 // clear collected submeshes
4331 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4332 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
4333 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
4335 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4336 // ClearSubMesh( *clrIt );
4339 aPythonDump << " ])";
4341 mesh.SetMeshOrder( subMeshOrder );
4347 //=============================================================================
4349 * \brief Convert submesh ids into submesh interfaces
4351 //=============================================================================
4353 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4354 SMESH::submesh_array_array& theResOrder,
4355 const bool theIsDump)
4357 int nbSet = theIdsOrder.size();
4358 TPythonDump aPythonDump; // prevent dump of called methods
4360 aPythonDump << "[ ";
4361 theResOrder.length(nbSet);
4362 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4364 for( ; it != theIdsOrder.end(); it++ ) {
4365 // translate submesh identificators into submesh objects
4366 // takeing into account real number of concurrent lists
4367 const TListOfInt& aSubOrder = (*it);
4368 if (!aSubOrder.size())
4371 aPythonDump << "[ ";
4372 // convert shape indeces into interfaces
4373 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4374 aResSubSet->length(aSubOrder.size());
4375 TListOfInt::const_iterator subIt = aSubOrder.begin();
4376 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4377 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4379 SMESH::SMESH_subMesh_var subMesh =
4380 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4383 aPythonDump << ", ";
4384 aPythonDump << subMesh;
4386 aResSubSet[ j++ ] = subMesh;
4389 aPythonDump << " ]";
4390 theResOrder[ listIndx++ ] = aResSubSet;
4392 // correct number of lists
4393 theResOrder.length( listIndx );
4396 // finilise python dump
4397 aPythonDump << " ]";
4398 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4402 //================================================================================
4404 // Implementation of SMESH_MeshPartDS
4406 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4407 SMESHDS_Mesh( /*theMeshID=*/-1, /*theIsEmbeddedMode=*/true)
4409 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4410 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4412 _meshDS = mesh_i->GetImpl().GetMeshDS();
4414 SetPersistentId( _meshDS->GetPersistentId() );
4416 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4418 // <meshPart> is the whole mesh
4419 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4421 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
4422 myGroupSet = _meshDS->GetGroups();
4427 SMESH::long_array_var anIDs = meshPart->GetIDs();
4428 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4429 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4431 for (int i=0; i < anIDs->length(); i++)
4432 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4433 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4438 for (int i=0; i < anIDs->length(); i++)
4439 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4440 if ( _elements[ e->GetType() ].insert( e ).second )
4443 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4444 while ( nIt->more() )
4446 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4447 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4454 _meshDS = 0; // to enforce iteration on _elements and _nodes
4457 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
4459 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4460 if ( type == SMDSAbs_All && !_meshDS )
4462 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
4464 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4465 if ( !_elements[i].empty() && i != SMDSAbs_Node )
4467 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
4469 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
4470 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
4472 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
4473 ( new TIter( _elements[type].begin(), _elements[type].end() ));
4475 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
4476 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
4478 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
4479 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
4480 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
4482 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
4483 _GET_ITER_DEFINE( SMDS_0DElementIteratorPtr, elements0dIterator, SMDS_Mesh0DElement, SMDSAbs_0DElement)
4484 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
4485 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
4486 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
4487 #undef _GET_ITER_DEFINE
4489 // END Implementation of SMESH_MeshPartDS
4491 //================================================================================