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)
2788 Unexpect aCatch(SALOME_SalomeException);
2790 PrepareForWriting(file,overwrite);
2792 SMESH_MeshPartDS partDS( meshPart );
2793 _impl->ExportCGNS(file, &partDS);
2795 TPythonDump() << _this() << ".ExportCGNS( "
2796 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2798 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2802 //=============================================================================
2806 //=============================================================================
2808 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2810 Unexpect aCatch(SALOME_SalomeException);
2811 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2812 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2813 return aMesh._retn();
2816 //=============================================================================
2820 //=============================================================================
2821 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2823 Unexpect aCatch(SALOME_SalomeException);
2824 return _impl->NbNodes();
2827 //=============================================================================
2831 //=============================================================================
2832 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2834 Unexpect aCatch(SALOME_SalomeException);
2835 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes();
2838 //=============================================================================
2842 //=============================================================================
2843 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2845 Unexpect aCatch(SALOME_SalomeException);
2846 return _impl->Nb0DElements();
2849 //=============================================================================
2853 //=============================================================================
2854 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
2856 Unexpect aCatch(SALOME_SalomeException);
2857 return _impl->NbEdges();
2860 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
2861 throw(SALOME::SALOME_Exception)
2863 Unexpect aCatch(SALOME_SalomeException);
2864 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
2867 //=============================================================================
2871 //=============================================================================
2872 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
2874 Unexpect aCatch(SALOME_SalomeException);
2875 return _impl->NbFaces();
2878 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
2880 Unexpect aCatch(SALOME_SalomeException);
2881 return _impl->NbTriangles();
2884 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
2886 Unexpect aCatch(SALOME_SalomeException);
2887 return _impl->NbQuadrangles();
2890 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
2892 Unexpect aCatch(SALOME_SalomeException);
2893 return _impl->NbPolygons();
2896 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
2897 throw(SALOME::SALOME_Exception)
2899 Unexpect aCatch(SALOME_SalomeException);
2900 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
2903 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
2904 throw(SALOME::SALOME_Exception)
2906 Unexpect aCatch(SALOME_SalomeException);
2907 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
2910 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
2911 throw(SALOME::SALOME_Exception)
2913 Unexpect aCatch(SALOME_SalomeException);
2914 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
2917 //=============================================================================
2921 //=============================================================================
2922 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
2924 Unexpect aCatch(SALOME_SalomeException);
2925 return _impl->NbVolumes();
2928 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
2930 Unexpect aCatch(SALOME_SalomeException);
2931 return _impl->NbTetras();
2934 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
2936 Unexpect aCatch(SALOME_SalomeException);
2937 return _impl->NbHexas();
2940 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
2942 Unexpect aCatch(SALOME_SalomeException);
2943 return _impl->NbPyramids();
2946 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
2948 Unexpect aCatch(SALOME_SalomeException);
2949 return _impl->NbPrisms();
2952 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
2954 Unexpect aCatch(SALOME_SalomeException);
2955 return _impl->NbPolyhedrons();
2958 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
2959 throw(SALOME::SALOME_Exception)
2961 Unexpect aCatch(SALOME_SalomeException);
2962 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
2965 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
2966 throw(SALOME::SALOME_Exception)
2968 Unexpect aCatch(SALOME_SalomeException);
2969 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
2972 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
2973 throw(SALOME::SALOME_Exception)
2975 Unexpect aCatch(SALOME_SalomeException);
2976 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
2979 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
2980 throw(SALOME::SALOME_Exception)
2982 Unexpect aCatch(SALOME_SalomeException);
2983 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
2986 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
2987 throw(SALOME::SALOME_Exception)
2989 Unexpect aCatch(SALOME_SalomeException);
2990 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
2993 //=============================================================================
2997 //=============================================================================
2998 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3000 Unexpect aCatch(SALOME_SalomeException);
3001 return _mapSubMesh_i.size();
3004 //=============================================================================
3008 //=============================================================================
3009 char* SMESH_Mesh_i::Dump()
3013 return CORBA::string_dup( os.str().c_str() );
3016 //=============================================================================
3020 //=============================================================================
3021 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3023 // SMESH::long_array_var aResult = new SMESH::long_array();
3024 // SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3025 // int aMinId = aSMESHDS_Mesh->MinElementID();
3026 // int aMaxId = aSMESHDS_Mesh->MaxElementID();
3028 // aResult->length(aMaxId - aMinId + 1);
3030 // for (int i = 0, id = aMinId; id <= aMaxId; id++ )
3031 // aResult[i++] = id;
3033 // return aResult._retn();
3035 return GetElementsId();
3038 //=============================================================================
3042 //=============================================================================
3044 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3045 throw (SALOME::SALOME_Exception)
3047 Unexpect aCatch(SALOME_SalomeException);
3048 MESSAGE("SMESH_Mesh_i::GetElementsId");
3049 SMESH::long_array_var aResult = new SMESH::long_array();
3050 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3052 if ( aSMESHDS_Mesh == NULL )
3053 return aResult._retn();
3055 long nbElements = NbElements();
3056 aResult->length( nbElements );
3057 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3058 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3059 aResult[i] = anIt->next()->GetID();
3061 return aResult._retn();
3065 //=============================================================================
3069 //=============================================================================
3071 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3072 throw (SALOME::SALOME_Exception)
3074 Unexpect aCatch(SALOME_SalomeException);
3075 MESSAGE("SMESH_subMesh_i::GetElementsByType");
3076 SMESH::long_array_var aResult = new SMESH::long_array();
3077 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3079 if ( aSMESHDS_Mesh == NULL )
3080 return aResult._retn();
3082 long nbElements = NbElements();
3084 // No sense in returning ids of elements along with ids of nodes:
3085 // when theElemType == SMESH::ALL, return node ids only if
3086 // there are no elements
3087 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3088 return GetNodesId();
3090 aResult->length( nbElements );
3094 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3095 while ( i < nbElements && anIt->more() ) {
3096 const SMDS_MeshElement* anElem = anIt->next();
3097 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3098 aResult[i++] = anElem->GetID();
3101 aResult->length( i );
3103 return aResult._retn();
3106 //=============================================================================
3110 //=============================================================================
3112 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3113 throw (SALOME::SALOME_Exception)
3115 Unexpect aCatch(SALOME_SalomeException);
3116 MESSAGE("SMESH_subMesh_i::GetNodesId");
3117 SMESH::long_array_var aResult = new SMESH::long_array();
3118 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3120 if ( aSMESHDS_Mesh == NULL )
3121 return aResult._retn();
3123 long nbNodes = NbNodes();
3124 aResult->length( nbNodes );
3125 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3126 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3127 aResult[i] = anIt->next()->GetID();
3129 return aResult._retn();
3132 //=============================================================================
3136 //=============================================================================
3138 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3139 throw (SALOME::SALOME_Exception)
3141 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3144 //=============================================================================
3148 //=============================================================================
3150 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3151 throw (SALOME::SALOME_Exception)
3153 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3155 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3157 return ( SMESH::EntityType ) e->GetEntityType();
3160 //=============================================================================
3162 * Returns ID of elements for given submesh
3164 //=============================================================================
3165 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3166 throw (SALOME::SALOME_Exception)
3168 SMESH::long_array_var aResult = new SMESH::long_array();
3170 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3171 if(!SM) return aResult._retn();
3173 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3174 if(!SDSM) return aResult._retn();
3176 aResult->length(SDSM->NbElements());
3178 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3180 while ( eIt->more() ) {
3181 aResult[i++] = eIt->next()->GetID();
3184 return aResult._retn();
3188 //=============================================================================
3190 * Returns ID of nodes for given submesh
3191 * If param all==true - returns all nodes, else -
3192 * returns only nodes on shapes.
3194 //=============================================================================
3195 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID, CORBA::Boolean all)
3196 throw (SALOME::SALOME_Exception)
3198 SMESH::long_array_var aResult = new SMESH::long_array();
3200 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3201 if(!SM) return aResult._retn();
3203 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3204 if(!SDSM) return aResult._retn();
3207 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3208 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3209 while ( nIt->more() ) {
3210 const SMDS_MeshNode* elem = nIt->next();
3211 theElems.insert( elem->GetID() );
3214 else { // all nodes of submesh elements
3215 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3216 while ( eIt->more() ) {
3217 const SMDS_MeshElement* anElem = eIt->next();
3218 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3219 while ( nIt->more() ) {
3220 const SMDS_MeshElement* elem = nIt->next();
3221 theElems.insert( elem->GetID() );
3226 aResult->length(theElems.size());
3227 set<int>::iterator itElem;
3229 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3230 aResult[i++] = *itElem;
3232 return aResult._retn();
3236 //=============================================================================
3238 * Returns type of elements for given submesh
3240 //=============================================================================
3241 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3242 throw (SALOME::SALOME_Exception)
3244 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3245 if(!SM) return SMESH::ALL;
3247 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3248 if(!SDSM) return SMESH::ALL;
3250 if(SDSM->NbElements()==0)
3251 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3253 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3254 const SMDS_MeshElement* anElem = eIt->next();
3255 return ( SMESH::ElementType ) anElem->GetType();
3259 //=============================================================================
3263 //=============================================================================
3265 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3267 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3269 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3274 //=============================================================================
3276 * Get XYZ coordinates of node as list of double
3277 * If there is not node for given ID - returns empty list
3279 //=============================================================================
3281 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3283 SMESH::double_array_var aResult = new SMESH::double_array();
3284 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3285 if ( aSMESHDS_Mesh == NULL )
3286 return aResult._retn();
3289 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3291 return aResult._retn();
3295 aResult[0] = aNode->X();
3296 aResult[1] = aNode->Y();
3297 aResult[2] = aNode->Z();
3298 return aResult._retn();
3302 //=============================================================================
3304 * For given node returns list of IDs of inverse elements
3305 * If there is not node for given ID - returns empty list
3307 //=============================================================================
3309 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3311 SMESH::long_array_var aResult = new SMESH::long_array();
3312 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3313 if ( aSMESHDS_Mesh == NULL )
3314 return aResult._retn();
3317 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3319 return aResult._retn();
3321 // find inverse elements
3322 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3323 TColStd_SequenceOfInteger IDs;
3324 while(eIt->more()) {
3325 const SMDS_MeshElement* elem = eIt->next();
3326 IDs.Append(elem->GetID());
3328 if(IDs.Length()>0) {
3329 aResult->length(IDs.Length());
3331 for(; i<=IDs.Length(); i++) {
3332 aResult[i-1] = IDs.Value(i);
3335 return aResult._retn();
3338 //=============================================================================
3340 * \brief Return position of a node on shape
3342 //=============================================================================
3344 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3346 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3347 aNodePosition->shapeID = 0;
3348 aNodePosition->shapeType = GEOM::SHAPE;
3350 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3351 if ( !mesh ) return aNodePosition;
3353 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3355 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3357 aNodePosition->shapeID = aNode->getshapeId();
3358 switch ( pos->GetTypeOfPosition() ) {
3360 aNodePosition->shapeType = GEOM::EDGE;
3361 aNodePosition->params.length(1);
3362 aNodePosition->params[0] =
3363 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3366 aNodePosition->shapeType = GEOM::FACE;
3367 aNodePosition->params.length(2);
3368 aNodePosition->params[0] =
3369 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3370 aNodePosition->params[1] =
3371 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3373 case SMDS_TOP_VERTEX:
3374 aNodePosition->shapeType = GEOM::VERTEX;
3376 case SMDS_TOP_3DSPACE:
3377 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3378 aNodePosition->shapeType = GEOM::SOLID;
3379 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3380 aNodePosition->shapeType = GEOM::SHELL;
3386 return aNodePosition;
3389 //=============================================================================
3391 * If given element is node returns IDs of shape from position
3392 * If there is not node for given ID - returns -1
3394 //=============================================================================
3396 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3398 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3399 if ( aSMESHDS_Mesh == NULL )
3403 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3405 return aNode->getshapeId();
3412 //=============================================================================
3414 * For given element returns ID of result shape after
3415 * ::FindShape() from SMESH_MeshEditor
3416 * If there is not element for given ID - returns -1
3418 //=============================================================================
3420 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3422 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3423 if ( aSMESHDS_Mesh == NULL )
3426 // try to find element
3427 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3431 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3432 ::SMESH_MeshEditor aMeshEditor(_impl);
3433 int index = aMeshEditor.FindShape( elem );
3441 //=============================================================================
3443 * Returns number of nodes for given element
3444 * If there is not element for given ID - returns -1
3446 //=============================================================================
3448 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3450 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3451 if ( aSMESHDS_Mesh == NULL ) return -1;
3452 // try to find element
3453 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3454 if(!elem) return -1;
3455 return elem->NbNodes();
3459 //=============================================================================
3461 * Returns ID of node by given index for given element
3462 * If there is not element for given ID - returns -1
3463 * If there is not node for given index - returns -2
3465 //=============================================================================
3467 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3469 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3470 if ( aSMESHDS_Mesh == NULL ) return -1;
3471 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3472 if(!elem) return -1;
3473 if( index>=elem->NbNodes() || index<0 ) return -1;
3474 return elem->GetNode(index)->GetID();
3477 //=============================================================================
3479 * Returns IDs of nodes of given element
3481 //=============================================================================
3483 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3485 SMESH::long_array_var aResult = new SMESH::long_array();
3486 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3488 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3490 aResult->length( elem->NbNodes() );
3491 for ( int i = 0; i < elem->NbNodes(); ++i )
3492 aResult[ i ] = elem->GetNode( i )->GetID();
3495 return aResult._retn();
3498 //=============================================================================
3500 * Returns true if given node is medium node
3501 * in given quadratic element
3503 //=============================================================================
3505 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3507 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3508 if ( aSMESHDS_Mesh == NULL ) return false;
3510 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3511 if(!aNode) return false;
3512 // try to find element
3513 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3514 if(!elem) return false;
3516 return elem->IsMediumNode(aNode);
3520 //=============================================================================
3522 * Returns true if given node is medium node
3523 * in one of quadratic elements
3525 //=============================================================================
3527 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3528 SMESH::ElementType theElemType)
3530 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3531 if ( aSMESHDS_Mesh == NULL ) return false;
3534 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3535 if(!aNode) return false;
3537 SMESH_MesherHelper aHelper( *(_impl) );
3539 SMDSAbs_ElementType aType;
3540 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3541 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3542 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3543 else aType = SMDSAbs_All;
3545 return aHelper.IsMedium(aNode,aType);
3549 //=============================================================================
3551 * Returns number of edges for given element
3553 //=============================================================================
3555 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3557 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3558 if ( aSMESHDS_Mesh == NULL ) return -1;
3559 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3560 if(!elem) return -1;
3561 return elem->NbEdges();
3565 //=============================================================================
3567 * Returns number of faces for given element
3569 //=============================================================================
3571 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3573 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3574 if ( aSMESHDS_Mesh == NULL ) return -1;
3575 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3576 if(!elem) return -1;
3577 return elem->NbFaces();
3580 //=======================================================================
3581 //function : GetElemFaceNodes
3582 //purpose : Returns nodes of given face (counted from zero) for given element.
3583 //=======================================================================
3585 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3586 CORBA::Short faceIndex)
3588 SMESH::long_array_var aResult = new SMESH::long_array();
3589 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3591 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3593 SMDS_VolumeTool vtool( elem );
3594 if ( faceIndex < vtool.NbFaces() )
3596 aResult->length( vtool.NbFaceNodes( faceIndex ));
3597 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3598 for ( int i = 0; i < aResult->length(); ++i )
3599 aResult[ i ] = nn[ i ]->GetID();
3603 return aResult._retn();
3606 //=======================================================================
3607 //function : FindElementByNodes
3608 //purpose : Returns an element based on all given nodes.
3609 //=======================================================================
3611 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3613 CORBA::Long elemID(0);
3614 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3616 vector< const SMDS_MeshNode * > nn( nodes.length() );
3617 for ( int i = 0; i < nodes.length(); ++i )
3618 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3621 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3622 if ( !elem && ( _impl->NbEdges( ORDER_QUADRATIC ) ||
3623 _impl->NbFaces( ORDER_QUADRATIC ) ||
3624 _impl->NbVolumes( ORDER_QUADRATIC )))
3625 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3627 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3632 //=============================================================================
3634 * Returns true if given element is polygon
3636 //=============================================================================
3638 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3640 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3641 if ( aSMESHDS_Mesh == NULL ) return false;
3642 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3643 if(!elem) return false;
3644 return elem->IsPoly();
3648 //=============================================================================
3650 * Returns true if given element is quadratic
3652 //=============================================================================
3654 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3656 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3657 if ( aSMESHDS_Mesh == NULL ) return false;
3658 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3659 if(!elem) return false;
3660 return elem->IsQuadratic();
3664 //=============================================================================
3666 * Returns bary center for given element
3668 //=============================================================================
3670 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3672 SMESH::double_array_var aResult = new SMESH::double_array();
3673 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3674 if ( aSMESHDS_Mesh == NULL )
3675 return aResult._retn();
3677 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3679 return aResult._retn();
3681 if(elem->GetType()==SMDSAbs_Volume) {
3682 SMDS_VolumeTool aTool;
3683 if(aTool.Set(elem)) {
3685 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
3690 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
3692 double x=0., y=0., z=0.;
3693 for(; anIt->more(); ) {
3695 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
3709 return aResult._retn();
3713 //=============================================================================
3715 * Create and publish group servants if any groups were imported or created anyhow
3717 //=============================================================================
3719 void SMESH_Mesh_i::CreateGroupServants()
3721 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3724 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
3725 while ( groupIt->more() )
3727 ::SMESH_Group* group = groupIt->next();
3728 int anId = group->GetGroupDS()->GetID();
3730 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
3731 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3733 addedIDs.insert( anId );
3735 SMESH_GroupBase_i* aGroupImpl;
3737 if ( SMESHDS_GroupOnGeom* groupOnGeom =
3738 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
3740 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3741 shape = groupOnGeom->GetShape();
3744 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3747 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
3748 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
3749 aGroupImpl->Register();
3751 SMESH::SMESH_GroupBase_var groupVar =
3752 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
3753 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
3755 // register CORBA object for persistence
3756 int nextId = _gen_i->RegisterObject( groupVar );
3757 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
3759 // publishing the groups in the study
3760 if ( !aStudy->_is_nil() ) {
3761 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
3762 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
3765 if ( !addedIDs.empty() )
3768 set<int>::iterator id = addedIDs.begin();
3769 for ( ; id != addedIDs.end(); ++id )
3771 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
3772 int i = std::distance( _mapGroups.begin(), it );
3773 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
3778 //=============================================================================
3780 * \brief Return groups cantained in _mapGroups by their IDs
3782 //=============================================================================
3784 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
3786 int nbGroups = groupIDs.size();
3787 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
3788 aList->length( nbGroups );
3790 list<int>::const_iterator ids = groupIDs.begin();
3791 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
3793 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
3794 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
3795 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
3797 aList->length( nbGroups );
3798 return aList._retn();
3801 //=============================================================================
3803 * \brief Return information about imported file
3805 //=============================================================================
3807 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
3809 SALOME_MED::MedFileInfo_var res( myFileInfo );
3810 if ( !res.operator->() ) {
3811 res = new SALOME_MED::MedFileInfo;
3813 res->fileSize = res->major = res->minor = res->release = -1;
3818 //=============================================================================
3820 * \brief Check and correct names of mesh groups
3822 //=============================================================================
3824 void SMESH_Mesh_i::checkGroupNames()
3826 int nbGrp = NbGroups();
3830 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
3831 if ( aStudy->_is_nil() )
3832 return; // nothing to do
3834 SMESH::ListOfGroups* grpList = 0;
3835 // avoid dump of "GetGroups"
3837 // store python dump into a local variable inside local scope
3838 SMESH::TPythonDump pDump; // do not delete this line of code
3839 grpList = GetGroups();
3842 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
3843 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
3846 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
3847 if ( aGrpSO->_is_nil() )
3849 // correct name of the mesh group if necessary
3850 const char* guiName = aGrpSO->GetName();
3851 if ( strcmp(guiName, aGrp->GetName()) )
3852 aGrp->SetName( guiName );
3856 //=============================================================================
3858 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
3860 //=============================================================================
3861 void SMESH_Mesh_i::SetParameters(const char* theParameters)
3863 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
3864 CORBA::string_dup(theParameters));
3867 //=============================================================================
3869 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
3871 //=============================================================================
3872 char* SMESH_Mesh_i::GetParameters()
3874 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3875 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
3878 //=============================================================================
3880 * \brief Returns list of notebook variables used for last Mesh operation
3882 //=============================================================================
3883 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
3885 SMESH::string_array_var aResult = new SMESH::string_array();
3886 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
3888 char *aParameters = GetParameters();
3889 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
3890 if(!aStudy->_is_nil()) {
3891 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
3892 if(aSections->length() > 0) {
3893 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
3894 aResult->length(aVars.length());
3895 for(int i = 0;i < aVars.length();i++)
3896 aResult[i] = CORBA::string_dup( aVars[i]);
3900 return aResult._retn();
3903 //=======================================================================
3904 //function : GetTypes
3905 //purpose : Returns types of elements it contains
3906 //=======================================================================
3908 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
3910 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
3914 if (_impl->NbEdges())
3915 types[nbTypes++] = SMESH::EDGE;
3916 if (_impl->NbFaces())
3917 types[nbTypes++] = SMESH::FACE;
3918 if (_impl->NbVolumes())
3919 types[nbTypes++] = SMESH::VOLUME;
3920 if (_impl->Nb0DElements())
3921 types[nbTypes++] = SMESH::ELEM0D;
3922 types->length( nbTypes );
3924 return types._retn();
3927 //=======================================================================
3928 //function : GetMesh
3929 //purpose : Returns self
3930 //=======================================================================
3932 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
3934 return SMESH::SMESH_Mesh::_duplicate( _this() );
3937 //=============================================================================
3939 * \brief Returns statistic of mesh elements
3941 //=============================================================================
3942 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
3944 SMESH::long_array_var aRes = new SMESH::long_array();
3945 aRes->length(SMESH::Entity_Last);
3946 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3948 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
3950 return aRes._retn();
3951 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
3952 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
3953 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
3954 return aRes._retn();
3957 //=============================================================================
3959 * \brief Collect statistic of mesh elements given by iterator
3961 //=============================================================================
3962 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
3963 SMESH::long_array& theInfo)
3965 if (!theItr) return;
3966 while (theItr->more())
3967 theInfo[ theItr->next()->GetEntityType() ]++;
3970 //=============================================================================
3972 * \brief mapping of mesh dimension into shape type
3974 //=============================================================================
3975 static TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
3977 TopAbs_ShapeEnum aType = TopAbs_SOLID;
3979 case 0: aType = TopAbs_VERTEX; break;
3980 case 1: aType = TopAbs_EDGE; break;
3981 case 2: aType = TopAbs_FACE; break;
3983 default:aType = TopAbs_SOLID; break;
3988 //=============================================================================
3990 * \brief Internal structure used to find concurent submeshes
3992 * It represents a pair < submesh, concurent dimension >, where
3993 * 'concurrent dimension' is dimension of shape where the submesh can concurent
3994 * with another submesh. In other words, it is dimension of a hypothesis assigned
3997 //=============================================================================
4003 int _dim; //!< a dimension the algo can build (concurrent dimension)
4004 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4005 TopTools_MapOfShape _shapeMap;
4006 SMESH_subMesh* _subMesh;
4007 list<const SMESHDS_Hypothesis*> _hypothesises; //!< algo is first, then its parameters
4010 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4012 const TopoDS_Shape& theShape)
4014 _subMesh = (SMESH_subMesh*)theSubMesh;
4015 SetShape( theDim, theShape );
4019 void SetShape(const int theDim,
4020 const TopoDS_Shape& theShape)
4023 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4024 if (_dim >= _ownDim)
4025 _shapeMap.Add( theShape );
4027 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4028 for( ; anExp.More(); anExp.Next() )
4029 _shapeMap.Add( anExp.Current() );
4033 //! Check sharing of sub shapes
4034 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4035 const TopTools_MapOfShape& theToFind,
4036 const TopAbs_ShapeEnum theType)
4038 bool isShared = false;
4039 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4040 for (; !isShared && anItr.More(); anItr.Next() ) {
4041 const TopoDS_Shape aSubSh = anItr.Key();
4042 // check for case when concurrent dimensions are same
4043 isShared = theToFind.Contains( aSubSh );
4044 // check for subshape with concurrent dimension
4045 TopExp_Explorer anExp( aSubSh, theType );
4046 for ( ; !isShared && anExp.More(); anExp.Next() )
4047 isShared = theToFind.Contains( anExp.Current() );
4052 //! check algorithms
4053 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4054 const SMESHDS_Hypothesis* theA2)
4056 if ( theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4057 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4058 return false; // one of the hypothesis is not algorithm
4059 // check algorithm names (should be equal)
4060 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4064 //! Check if subshape hypotheses are concurrent
4065 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4067 if ( _subMesh == theOther->_subMesh )
4068 return false; // same subshape - should not be
4070 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4071 // any of the two submeshes is not on COMPOUND shape )
4072 // -> no concurrency
4073 bool meIsCompound = (_subMesh->GetSubMeshDS() && _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4074 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() && theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4075 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4078 // bool checkSubShape = ( _dim >= theOther->_dim )
4079 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4080 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4081 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4082 if ( !checkSubShape )
4085 // check algorithms to be same
4086 if (!checkAlgo( _hypothesises.front(), theOther->_hypothesises.front() ))
4087 return true; // different algorithms
4089 // check hypothesises for concurrence (skip first as algorithm)
4091 // pointers should be same, becase it is referenes from mesh hypothesis partition
4092 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypothesises.begin();
4093 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypothesises.end();
4094 for ( hypIt++ /*skip first as algo*/; hypIt != _hypothesises.end(); hypIt++ )
4095 if ( find( theOther->_hypothesises.begin(), otheEndIt, *hypIt ) != otheEndIt )
4097 // the submeshes are concurrent if their algorithms has different parameters
4098 return nbSame != theOther->_hypothesises.size() - 1;
4101 }; // end of SMESH_DimHyp
4103 typedef list<SMESH_DimHyp*> TDimHypList;
4105 static void addDimHypInstance(const int theDim,
4106 const TopoDS_Shape& theShape,
4107 const SMESH_Algo* theAlgo,
4108 const SMESH_subMesh* theSubMesh,
4109 const list <const SMESHDS_Hypothesis*>& theHypList,
4110 TDimHypList* theDimHypListArr )
4112 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4113 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4114 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4115 listOfdimHyp.push_back( dimHyp );
4118 SMESH_DimHyp* dimHyp = listOfdimHyp.back();
4119 dimHyp->_hypothesises.push_front(theAlgo);
4120 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = theHypList.begin();
4121 for( ; hypIt != theHypList.end(); hypIt++ )
4122 dimHyp->_hypothesises.push_back( *hypIt );
4125 static void findConcurrents(const SMESH_DimHyp* theDimHyp,
4126 const TDimHypList& theListOfDimHyp,
4127 TListOfInt& theListOfConcurr )
4129 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4130 for ( ; rIt != theListOfDimHyp.rend(); rIt++ ) {
4131 const SMESH_DimHyp* curDimHyp = *rIt;
4132 if ( curDimHyp == theDimHyp )
4133 break; // meet own dimHyp pointer in same dimension
4134 else if ( theDimHyp->IsConcurrent( curDimHyp ) )
4135 if ( find( theListOfConcurr.begin(),
4136 theListOfConcurr.end(),
4137 curDimHyp->_subMesh->GetId() ) == theListOfConcurr.end() )
4138 theListOfConcurr.push_back( curDimHyp->_subMesh->GetId() );
4142 static void unionLists(TListOfInt& theListOfId,
4143 TListOfListOfInt& theListOfListOfId,
4146 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4147 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4149 continue; //skip already treated lists
4150 // check if other list has any same submesh object
4151 TListOfInt& otherListOfId = *it;
4152 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4153 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4156 // union two lists (from source into target)
4157 TListOfInt::iterator it2 = otherListOfId.begin();
4158 for ( ; it2 != otherListOfId.end(); it2++ ) {
4159 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4160 theListOfId.push_back(*it2);
4162 // clear source list
4163 otherListOfId.clear();
4167 //! free memory allocated for dimension-hypothesis objects
4168 static void removeDimHyps( TDimHypList* theArrOfList )
4170 for (int i = 0; i < 4; i++ ) {
4171 TDimHypList& listOfdimHyp = theArrOfList[i];
4172 TDimHypList::const_iterator it = listOfdimHyp.begin();
4173 for ( ; it != listOfdimHyp.end(); it++ )
4178 //=============================================================================
4180 * \brief Return submesh objects list in meshing order
4182 //=============================================================================
4184 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4186 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4188 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4190 return aResult._retn();
4192 ::SMESH_Mesh& mesh = GetImpl();
4193 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4194 if ( !anOrder.size() ) {
4196 // collect submeshes detecting concurrent algorithms and hypothesises
4197 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4199 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4200 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4201 ::SMESH_subMesh* sm = (*i_sm).second;
4203 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4205 // list of assigned hypothesises
4206 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4207 // Find out dimensions where the submesh can be concurrent.
4208 // We define the dimensions by algo of each of hypotheses in hypList
4209 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4210 for( ; hypIt != hypList.end(); hypIt++ ) {
4211 SMESH_Algo* anAlgo = 0;
4212 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4213 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4214 // hyp it-self is algo
4215 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4217 // try to find algorithm with help of subshapes
4218 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4219 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4220 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4223 continue; // no assigned algorithm to current submesh
4225 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4226 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDescretBoundary())
4228 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4229 for ( int j = anAlgo->NeedDescretBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4230 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4232 } // end iterations on submesh
4234 // iterate on created dimension-hypotheses and check for concurrents
4235 for ( int i = 0; i < 4; i++ ) {
4236 const list<SMESH_DimHyp*>& listOfDimHyp = dimHypListArr[i];
4237 // check for concurrents in own and other dimensions (step-by-step)
4238 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4239 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4240 const SMESH_DimHyp* dimHyp = *dhIt;
4241 TListOfInt listOfConcurr;
4242 // looking for concurrents and collect into own list
4243 for ( int j = i; j < 4; j++ )
4244 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr );
4245 // check if any concurrents found
4246 if ( listOfConcurr.size() > 0 ) {
4247 // add own submesh to list of concurrent
4248 listOfConcurr.push_front( dimHyp->_subMesh->GetId() );
4249 anOrder.push_back( listOfConcurr );
4254 removeDimHyps(dimHypListArr);
4256 // now, minimise the number of concurrent groups
4257 // Here we assume that lists of submhes can has same submesh
4258 // in case of multi-dimension algorithms, as result
4259 // list with common submesh have to be union into one list
4261 TListOfListOfInt::iterator listIt = anOrder.begin();
4262 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4263 unionLists( *listIt, anOrder, listIndx + 1 );
4265 // convert submesh ids into interface instances
4266 // and dump command into python
4267 convertMeshOrder( anOrder, aResult, true );
4269 return aResult._retn();
4272 //=============================================================================
4274 * \brief find common submeshes with given submesh
4275 * \param theSubMeshList list of already collected submesh to check
4276 * \param theSubMesh given submesh to intersect with other
4277 * \param theCommonSubMeshes collected common submeshes
4279 //=============================================================================
4281 static void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4282 const SMESH_subMesh* theSubMesh,
4283 set<const SMESH_subMesh*>& theCommon )
4287 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4288 for ( ; it != theSubMeshList.end(); it++ )
4289 theSubMesh->FindIntersection( *it, theCommon );
4290 theSubMeshList.push_back( theSubMesh );
4291 //theCommon.insert( theSubMesh );
4294 //=============================================================================
4296 * \brief Set submesh object order
4297 * \param theSubMeshArray submesh array order
4299 //=============================================================================
4301 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4304 ::SMESH_Mesh& mesh = GetImpl();
4306 TPythonDump aPythonDump; // prevent dump of called methods
4307 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4309 TListOfListOfInt subMeshOrder;
4310 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4312 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4313 TListOfInt subMeshIds;
4314 aPythonDump << "[ ";
4315 // Collect subMeshes which should be clear
4316 // do it list-by-list, because modification of submesh order
4317 // take effect between concurrent submeshes only
4318 set<const SMESH_subMesh*> subMeshToClear;
4319 list<const SMESH_subMesh*> subMeshList;
4320 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4322 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4324 aPythonDump << ", ";
4325 aPythonDump << subMesh;
4326 subMeshIds.push_back( subMesh->GetId() );
4327 // detect common parts of submeshes
4328 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4329 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4331 aPythonDump << " ]";
4332 subMeshOrder.push_back( subMeshIds );
4334 // clear collected submeshes
4335 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4336 for ( ; clrIt != subMeshToClear.end(); clrIt++ ) {
4337 SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt;
4339 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4340 // ClearSubMesh( *clrIt );
4343 aPythonDump << " ])";
4345 mesh.SetMeshOrder( subMeshOrder );
4351 //=============================================================================
4353 * \brief Convert submesh ids into submesh interfaces
4355 //=============================================================================
4357 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4358 SMESH::submesh_array_array& theResOrder,
4359 const bool theIsDump)
4361 int nbSet = theIdsOrder.size();
4362 TPythonDump aPythonDump; // prevent dump of called methods
4364 aPythonDump << "[ ";
4365 theResOrder.length(nbSet);
4366 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4368 for( ; it != theIdsOrder.end(); it++ ) {
4369 // translate submesh identificators into submesh objects
4370 // takeing into account real number of concurrent lists
4371 const TListOfInt& aSubOrder = (*it);
4372 if (!aSubOrder.size())
4375 aPythonDump << "[ ";
4376 // convert shape indeces into interfaces
4377 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4378 aResSubSet->length(aSubOrder.size());
4379 TListOfInt::const_iterator subIt = aSubOrder.begin();
4380 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4381 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4383 SMESH::SMESH_subMesh_var subMesh =
4384 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4387 aPythonDump << ", ";
4388 aPythonDump << subMesh;
4390 aResSubSet[ j++ ] = subMesh;
4393 aPythonDump << " ]";
4394 theResOrder[ listIndx++ ] = aResSubSet;
4396 // correct number of lists
4397 theResOrder.length( listIndx );
4400 // finilise python dump
4401 aPythonDump << " ]";
4402 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4406 //================================================================================
4408 // Implementation of SMESH_MeshPartDS
4410 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4411 SMESHDS_Mesh( /*theMeshID=*/-1, /*theIsEmbeddedMode=*/true)
4413 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4414 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4416 _meshDS = mesh_i->GetImpl().GetMeshDS();
4418 SetPersistentId( _meshDS->GetPersistentId() );
4420 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4422 // <meshPart> is the whole mesh
4423 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4425 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
4426 myGroupSet = _meshDS->GetGroups();
4431 SMESH::long_array_var anIDs = meshPart->GetIDs();
4432 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4433 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4435 for (int i=0; i < anIDs->length(); i++)
4436 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4437 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4442 for (int i=0; i < anIDs->length(); i++)
4443 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4444 if ( _elements[ e->GetType() ].insert( e ).second )
4447 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4448 while ( nIt->more() )
4450 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4451 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4458 _meshDS = 0; // to enforce iteration on _elements and _nodes
4461 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
4463 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4464 if ( type == SMDSAbs_All && !_meshDS )
4466 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
4468 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4469 if ( !_elements[i].empty() && i != SMDSAbs_Node )
4471 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
4473 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
4474 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
4476 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
4477 ( new TIter( _elements[type].begin(), _elements[type].end() ));
4479 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
4480 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
4482 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
4483 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
4484 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
4486 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
4487 _GET_ITER_DEFINE( SMDS_0DElementIteratorPtr, elements0dIterator, SMDS_Mesh0DElement, SMDSAbs_0DElement)
4488 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
4489 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
4490 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
4491 #undef _GET_ITER_DEFINE
4493 // END Implementation of SMESH_MeshPartDS
4495 //================================================================================