Back to index

salome-smesh  6.5.0
SMESH_Gen_i_1.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 //  File      : SMESH_Gen_i_1.cxx
00023 //  Created   : Thu Oct 21 17:24:06 2004
00024 //  Author    : Edward AGAPOV (eap)
00025 //  Module    : SMESH
00026 
00027 #include "SMESH_Gen_i.hxx"
00028 
00029 #include "SMESH_Mesh_i.hxx"
00030 #include "SMESH_Hypothesis_i.hxx"
00031 #include "SMESH_Algo_i.hxx"
00032 #include "SMESH_Group_i.hxx"
00033 #include "SMESH_subMesh_i.hxx"
00034 
00035 #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog)
00036 
00037 #include "utilities.h"
00038 #include "Utils_ExceptHandlers.hxx"
00039 
00040 #include <TCollection_AsciiString.hxx>
00041 
00042 #ifdef _DEBUG_
00043 static int MYDEBUG = 0;
00044 //static int VARIABLE_DEBUG = 0;
00045 #else
00046 static int MYDEBUG = 0;
00047 //static int VARIABLE_DEBUG = 0;
00048 #endif
00049 
00050 //=============================================================================
00056 //=============================================================================
00057 
00058 long SMESH_Gen_i::GetHypothesisRootTag()
00059 {
00060   return SMESH::Tag_HypothesisRoot;
00061 }
00062 
00063 long SMESH_Gen_i::GetAlgorithmsRootTag()
00064 {
00065   return SMESH::Tag_AlgorithmsRoot;
00066 }
00067 
00068 long SMESH_Gen_i::GetRefOnShapeTag()
00069 {
00070   return SMESH::Tag_RefOnShape;
00071 }
00072 
00073 long SMESH_Gen_i::GetRefOnAppliedHypothesisTag()
00074 {
00075   return SMESH::Tag_RefOnAppliedHypothesis;
00076 }
00077 
00078 long SMESH_Gen_i::GetRefOnAppliedAlgorithmsTag()
00079 {
00080   return SMESH::Tag_RefOnAppliedAlgorithms;
00081 }
00082 
00083 long SMESH_Gen_i::GetSubMeshOnVertexTag()
00084 {
00085   return SMESH::Tag_SubMeshOnVertex;
00086 }
00087 
00088 long SMESH_Gen_i::GetSubMeshOnEdgeTag()
00089 {
00090   return SMESH::Tag_SubMeshOnEdge;
00091 }
00092 
00093 long SMESH_Gen_i::GetSubMeshOnFaceTag()
00094 {
00095   return SMESH::Tag_SubMeshOnFace;
00096 }
00097 
00098 long SMESH_Gen_i::GetSubMeshOnSolidTag()
00099 {
00100   return SMESH::Tag_SubMeshOnSolid;
00101 }
00102 
00103 long SMESH_Gen_i::GetSubMeshOnCompoundTag()
00104 {
00105   return SMESH::Tag_SubMeshOnCompound;
00106 }
00107 
00108 long SMESH_Gen_i::GetSubMeshOnWireTag()
00109 {
00110   return SMESH::Tag_SubMeshOnWire;
00111 }
00112 
00113 long SMESH_Gen_i::GetSubMeshOnShellTag()
00114 {
00115   return SMESH::Tag_SubMeshOnShell;
00116 }
00117 
00118 long SMESH_Gen_i::GetNodeGroupsTag()
00119 {
00120   return SMESH::Tag_NodeGroups;
00121 }
00122 
00123 long SMESH_Gen_i::GetEdgeGroupsTag()
00124 {
00125   return SMESH::Tag_EdgeGroups;
00126 }
00127 
00128 long SMESH_Gen_i::GetFaceGroupsTag()
00129 {
00130   return SMESH::Tag_FaceGroups;
00131 }
00132 
00133 long SMESH_Gen_i::GetVolumeGroupsTag()
00134 {
00135   return SMESH::Tag_VolumeGroups;
00136 }
00137 
00138 long SMESH_Gen_i::Get0DElementsGroupsTag()
00139 {
00140   return SMESH::Tag_0DElementsGroups;
00141 }
00142 
00143 //=============================================================================
00149 //=============================================================================
00150 
00151 bool SMESH_Gen_i::CanPublishInStudy(CORBA::Object_ptr theIOR)
00152 {
00153   if(MYDEBUG) MESSAGE("CanPublishInStudy - "<<!CORBA::is_nil(myCurrentStudy));
00154   if(CORBA::is_nil(myCurrentStudy))
00155     return false;
00156   
00157   SMESH::SMESH_Mesh_var aMesh       = SMESH::SMESH_Mesh::_narrow(theIOR);
00158   if( !aMesh->_is_nil() )
00159     return true;
00160 
00161   SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow(theIOR);
00162   if( !aSubMesh->_is_nil() )
00163     return true;
00164 
00165   SMESH::SMESH_Hypothesis_var aHyp  = SMESH::SMESH_Hypothesis::_narrow(theIOR);
00166   if( !aHyp->_is_nil() )
00167     return true;
00168 
00169   SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(theIOR);
00170   if( !aGroup->_is_nil() )
00171     return true;
00172 
00173   if(MYDEBUG) MESSAGE("CanPublishInStudy--CANT");
00174   return false;
00175 }
00176 
00177 //=======================================================================
00178 //function : ObjectToSObject
00179 //purpose  : 
00180 //=======================================================================
00181 
00182 SALOMEDS::SObject_ptr SMESH_Gen_i::ObjectToSObject(SALOMEDS::Study_ptr theStudy,
00183                                                    CORBA::Object_ptr   theObject)
00184 {
00185   SALOMEDS::SObject_var aSO;
00186   if ( !CORBA::is_nil( theStudy ) && !CORBA::is_nil( theObject ))
00187   {
00188     CORBA::String_var objStr = SMESH_Gen_i::GetORB()->object_to_string( theObject );
00189     aSO = theStudy->FindObjectIOR( objStr.in() );
00190   }
00191   return aSO._retn();
00192 }
00193 
00194 //=======================================================================
00195 //function : objectToServant
00196 //purpose  : 
00197 //=======================================================================
00198 
00199 template<typename T> static inline T* objectToServant( CORBA::Object_ptr theIOR )
00200 {
00201   return dynamic_cast<T*>( SMESH_Gen_i::GetServant( theIOR ).in() );
00202 }
00203 
00204 //=======================================================================
00205 //function : ShapeToGeomObject
00206 //purpose  : 
00207 //=======================================================================
00208 
00209 GEOM::GEOM_Object_ptr SMESH_Gen_i::ShapeToGeomObject (const TopoDS_Shape& theShape )
00210 {
00211   GEOM::GEOM_Object_var aShapeObj;
00212   if ( !theShape.IsNull() ) {
00213     GEOM_Client* aClient = GetShapeReader();
00214     TCollection_AsciiString IOR;
00215     if ( aClient && aClient->Find( theShape, IOR ))
00216     {
00217       CORBA::Object_var obj = GetORB()->string_to_object( IOR.ToCString() );
00218       aShapeObj = GEOM::GEOM_Object::_narrow ( obj );
00219     }
00220   }
00221   return aShapeObj._retn();
00222 }
00223 
00224 //=======================================================================
00225 //function : GeomObjectToShape
00226 //purpose  : 
00227 //=======================================================================
00228 
00229 TopoDS_Shape SMESH_Gen_i::GeomObjectToShape(GEOM::GEOM_Object_ptr theGeomObject)
00230 {
00231   TopoDS_Shape S;
00232   if ( !theGeomObject->_is_nil() ) {
00233     GEOM_Client* aClient = GetShapeReader();
00234     GEOM::GEOM_Gen_ptr aGeomEngine = GetGeomEngine();
00235     if ( aClient && !aGeomEngine->_is_nil () )
00236       S = aClient->GetShape( aGeomEngine, theGeomObject );
00237   }
00238   return S;
00239 }
00240 
00241 //=======================================================================
00242 //function : publish
00243 //purpose  : 
00244 //=======================================================================
00245 
00246 static SALOMEDS::SObject_ptr publish(SALOMEDS::Study_ptr   theStudy,
00247                                      CORBA::Object_ptr     theIOR,
00248                                      SALOMEDS::SObject_ptr theFatherObject,
00249                                      const int             theTag = 0,
00250                                      const char*           thePixMap = 0,
00251                                      const bool            theSelectable = true)
00252 {
00253   SALOMEDS::SObject_var SO = SMESH_Gen_i::ObjectToSObject( theStudy, theIOR );
00254   SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
00255   if ( SO->_is_nil() ) {
00256     if ( theTag == 0 )
00257       SO = aStudyBuilder->NewObject( theFatherObject );
00258     else if ( !theFatherObject->FindSubObject( theTag, SO ))
00259       SO = aStudyBuilder->NewObjectToTag( theFatherObject, theTag );
00260   }
00261 
00262   SALOMEDS::GenericAttribute_var anAttr;
00263   if ( !CORBA::is_nil( theIOR )) {
00264     anAttr = aStudyBuilder->FindOrCreateAttribute( SO, "AttributeIOR" );
00265     CORBA::String_var objStr = SMESH_Gen_i::GetORB()->object_to_string( theIOR );
00266     SALOMEDS::AttributeIOR::_narrow(anAttr)->SetValue( objStr.in() );
00267   }
00268   if ( thePixMap ) {
00269     anAttr  = aStudyBuilder->FindOrCreateAttribute( SO, "AttributePixMap" );
00270     SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
00271     pm->SetPixMap( thePixMap );
00272   }
00273   if ( !theSelectable ) {
00274     anAttr   = aStudyBuilder->FindOrCreateAttribute( SO, "AttributeSelectable" );
00275     SALOMEDS::AttributeSelectable::_narrow( anAttr )->SetSelectable( false );
00276   }
00277   return SO._retn();
00278 }
00279 
00280 //=======================================================================
00281 //function : setName
00282 //purpose  : 
00283 //=======================================================================
00284 
00285 void SMESH_Gen_i::SetName(SALOMEDS::SObject_ptr theSObject,
00286                           const char*           theName,
00287                           const char*           theDefaultName)
00288 {
00289   if ( !theSObject->_is_nil() ) {
00290     SALOMEDS::StudyBuilder_var aStudyBuilder = theSObject->GetStudy()->NewBuilder();
00291     SALOMEDS::GenericAttribute_var anAttr =
00292       aStudyBuilder->FindOrCreateAttribute( theSObject, "AttributeName" );
00293     SALOMEDS::AttributeName_var aNameAttr = SALOMEDS::AttributeName::_narrow( anAttr );
00294     if ( theName && strlen( theName ) != 0 )
00295       aNameAttr->SetValue( theName );
00296     else {
00297       CORBA::String_var curName = CORBA::string_dup( aNameAttr->Value() );
00298       if ( strlen( curName ) == 0 ) {
00299         TCollection_AsciiString aName( (char*) theDefaultName );
00300         aName += TCollection_AsciiString("_") + TCollection_AsciiString( theSObject->Tag() );
00301         aNameAttr->SetValue( aName.ToCString() );
00302       }
00303     }
00304   }
00305 }
00306 
00307 //=======================================================================
00308 //function : SetPixMap
00309 //purpose  : 
00310 //=======================================================================
00311 
00312 void SMESH_Gen_i::SetPixMap(SALOMEDS::SObject_ptr theSObject,
00313                             const char*           thePixMap)
00314 {
00315   if ( !theSObject->_is_nil() && thePixMap && strlen( thePixMap ))
00316   {
00317     SALOMEDS::Study_var aStudy = theSObject->GetStudy();
00318     SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
00319     SALOMEDS::GenericAttribute_var anAttr =
00320       aStudyBuilder->FindOrCreateAttribute( theSObject, "AttributePixMap" );
00321     SALOMEDS::AttributePixMap_var aPMAttr = SALOMEDS::AttributePixMap::_narrow( anAttr );
00322     aPMAttr->SetPixMap( thePixMap );
00323   }
00324 }
00325 
00326 //=======================================================================
00327 //function : addReference
00328 //purpose  : 
00329 //=======================================================================
00330 
00331 static void addReference (SALOMEDS::Study_ptr   theStudy,
00332                           SALOMEDS::SObject_ptr theSObject,
00333                           CORBA::Object_ptr     theToObject,
00334                           int                   theTag = 0)
00335 {
00336   SALOMEDS::SObject_var aToObjSO = SMESH_Gen_i::ObjectToSObject( theStudy, theToObject );
00337   if ( !aToObjSO->_is_nil() && !theSObject->_is_nil() ) {
00338     SALOMEDS::StudyBuilder_var aStudyBuilder = theStudy->NewBuilder();
00339     SALOMEDS::SObject_var aReferenceSO;
00340     if ( !theTag ) {
00341       // check if the reference to theToObject already exists
00342       // and find a free label for the reference object
00343       bool isReferred = false;
00344       int tag = 1;
00345       SALOMEDS::ChildIterator_var anIter = theStudy->NewChildIterator( theSObject );
00346       for ( ; !isReferred && anIter->More(); anIter->Next(), ++tag ) {
00347         if ( anIter->Value()->ReferencedObject( aReferenceSO )) {
00348           if ( strcmp( aReferenceSO->GetID(), aToObjSO->GetID() ) == 0 )
00349             isReferred = true;
00350         }
00351         else if ( !theTag ) {
00352           SALOMEDS::GenericAttribute_var anAttr;
00353           if ( !anIter->Value()->FindAttribute( anAttr, "AttributeIOR" ))
00354             theTag = tag;
00355         }
00356       }
00357       if ( isReferred )
00358         return;
00359       if ( !theTag )
00360         theTag = tag;
00361     }
00362     if ( !theSObject->FindSubObject( theTag, aReferenceSO ))
00363       aReferenceSO = aStudyBuilder->NewObjectToTag( theSObject, theTag );
00364     aStudyBuilder->Addreference( aReferenceSO, aToObjSO );
00365   }
00366 }
00367 
00368 //=============================================================================
00374 //=============================================================================
00375 
00376 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishInStudy(SALOMEDS::Study_ptr   theStudy,
00377                                                   SALOMEDS::SObject_ptr theSObject,
00378                                                   CORBA::Object_ptr     theIOR,
00379                                                   const char*           theName)
00380      throw (SALOME::SALOME_Exception)
00381 {
00382   Unexpect aCatch(SALOME_SalomeException);
00383   SALOMEDS::SObject_var aSO;
00384   if ( CORBA::is_nil( theStudy ) || CORBA::is_nil( theIOR ))
00385     return aSO._retn();
00386   if(MYDEBUG) MESSAGE("PublishInStudy");
00387 
00388   // Publishing a mesh
00389   SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow( theIOR );
00390   if( !aMesh->_is_nil() )
00391     aSO = PublishMesh( theStudy, aMesh, theName );
00392 
00393   // Publishing a sub-mesh
00394   SMESH::SMESH_subMesh_var aSubMesh = SMESH::SMESH_subMesh::_narrow( theIOR );
00395   if( aSO->_is_nil() && !aSubMesh->_is_nil() ) {
00396     GEOM::GEOM_Object_var aShapeObject = aSubMesh->GetSubShape();
00397     aMesh = aSubMesh->GetFather();
00398     aSO = PublishSubMesh( theStudy, aMesh, aSubMesh, aShapeObject, theName );
00399   }
00400 
00401   // Publishing a hypothesis or algorithm
00402   SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( theIOR );
00403   if ( aSO->_is_nil() && !aHyp->_is_nil() )
00404     aSO = PublishHypothesis( theStudy, aHyp );
00405 
00406   // Publishing a group
00407   SMESH::SMESH_GroupBase_var aGroup = SMESH::SMESH_GroupBase::_narrow(theIOR);
00408   if ( aSO->_is_nil() && !aGroup->_is_nil() ) {
00409     GEOM::GEOM_Object_var aShapeObject;
00410     aMesh = aGroup->GetMesh();
00411     aSO = PublishGroup( theStudy, aMesh, aGroup, aShapeObject, theName );
00412   }
00413   if(MYDEBUG) MESSAGE("PublishInStudy_END");
00414 
00415   return aSO._retn();
00416 }
00417 
00418 //=======================================================================
00419 //function : PublishComponent
00420 //purpose  : 
00421 //=======================================================================
00422 
00423 SALOMEDS::SComponent_ptr SMESH_Gen_i::PublishComponent(SALOMEDS::Study_ptr theStudy)
00424 {
00425   if ( CORBA::is_nil( theStudy ))
00426     return SALOMEDS::SComponent::_nil();
00427   if(MYDEBUG) MESSAGE("PublishComponent");
00428 
00429   SALOMEDS::SComponent_var father =
00430     SALOMEDS::SComponent::_narrow( theStudy->FindComponent( ComponentDataType() ) );
00431   if ( !CORBA::is_nil( father ) )
00432     return father._retn();
00433 
00434   SALOME_ModuleCatalog::ModuleCatalog_var aCat =
00435     SALOME_ModuleCatalog::ModuleCatalog::_narrow( GetNS()->Resolve("/Kernel/ModulCatalog") );
00436   if ( CORBA::is_nil( aCat ) )
00437     return father._retn();
00438 
00439   SALOME_ModuleCatalog::Acomponent_var aComp = aCat->GetComponent( ComponentDataType() );
00440   if ( CORBA::is_nil( aComp ) )
00441     return father._retn();
00442 
00443   SALOMEDS::StudyBuilder_var     aStudyBuilder = theStudy->NewBuilder(); 
00444   SALOMEDS::GenericAttribute_var anAttr;
00445   SALOMEDS::AttributePixMap_var  aPixmap;
00446 
00447   father  = aStudyBuilder->NewComponent( ComponentDataType() );
00448   aStudyBuilder->DefineComponentInstance( father, SMESH_Gen::_this() );
00449   anAttr  = aStudyBuilder->FindOrCreateAttribute( father, "AttributePixMap" );
00450   aPixmap = SALOMEDS::AttributePixMap::_narrow( anAttr );
00451   aPixmap ->SetPixMap( "ICON_OBJBROWSER_SMESH" );
00452   SetName( father, aComp->componentusername(), "MESH" );
00453   if(MYDEBUG) MESSAGE("PublishComponent--END");
00454 
00455   return father._retn();
00456 }
00457 
00458 //=============================================================================
00464 //=============================================================================
00465 
00466 static long findMaxChildTag( SALOMEDS::SObject_ptr theSObject )
00467 {
00468   long aTag = 0;
00469   if ( !theSObject->_is_nil() ) {
00470     SALOMEDS::Study_var aStudy = theSObject->GetStudy();
00471     if ( !aStudy->_is_nil() ) {
00472       SALOMEDS::ChildIterator_var anIter = aStudy->NewChildIterator( theSObject );
00473       for ( ; anIter->More(); anIter->Next() ) {
00474         long nTag = anIter->Value()->Tag();
00475         if ( nTag > aTag )
00476           aTag = nTag;
00477       }
00478     }
00479   }
00480   return aTag;
00481 }
00482 
00483 //=======================================================================
00484 //function : PublishMesh
00485 //purpose  : 
00486 //=======================================================================
00487 
00488 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishMesh (SALOMEDS::Study_ptr   theStudy,
00489                                                 SMESH::SMESH_Mesh_ptr theMesh,
00490                                                 const char*           theName)
00491 {
00492   if ( CORBA::is_nil( theStudy ) ||
00493        CORBA::is_nil( theMesh ))
00494     return SALOMEDS::SComponent::_nil();
00495   if(MYDEBUG) MESSAGE("PublishMesh--IN");
00496 
00497   // find or publish a mesh
00498 
00499   SALOMEDS::SObject_var aMeshSO = ObjectToSObject( theStudy, theMesh );
00500   if ( aMeshSO->_is_nil() )
00501   {
00502     SALOMEDS::SComponent_var father = PublishComponent( theStudy );
00503     if ( father->_is_nil() )
00504       return aMeshSO._retn();
00505 
00506     // Find correct free tag
00507     long aTag = findMaxChildTag( father.in() );
00508     if ( aTag <= GetAlgorithmsRootTag() )
00509       aTag = GetAlgorithmsRootTag() + 1;
00510     else
00511       aTag++;
00512 
00513     aMeshSO = publish (theStudy, theMesh, father, aTag, "ICON_SMESH_TREE_MESH_WARN" );
00514     if ( aMeshSO->_is_nil() )
00515       return aMeshSO._retn();
00516   }
00517   SetName( aMeshSO, theName, "Mesh" );
00518 
00519   // Add shape reference
00520 
00521   GEOM::GEOM_Object_var aShapeObject = theMesh->GetShapeToMesh();
00522   if ( !CORBA::is_nil( aShapeObject )) {
00523     addReference( theStudy, aMeshSO, aShapeObject, GetRefOnShapeTag() );
00524 
00525     // Publish global hypotheses
00526 
00527     SMESH::ListOfHypothesis_var hypList = theMesh->GetHypothesisList( aShapeObject );
00528     for ( int i = 0; i < hypList->length(); i++ ) {
00529       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( hypList[ i ]);
00530       PublishHypothesis( theStudy, aHyp );
00531       AddHypothesisToShape( theStudy, theMesh, aShapeObject, aHyp );
00532     }
00533   }
00534 
00535   // Publish submeshes
00536 
00537   SMESH_Mesh_i* mesh_i = objectToServant<SMESH_Mesh_i>( theMesh );
00538   if ( !mesh_i )
00539     return aMeshSO._retn();
00540   map<int, SMESH_subMesh_i*>& subMap = mesh_i->_mapSubMesh_i;
00541   map<int, SMESH_subMesh_i*>::iterator subIt = subMap.begin();
00542   for ( ; subIt != subMap.end(); subIt++ ) {
00543     SMESH::SMESH_subMesh_ptr aSubMesh = (*subIt).second->_this();
00544     if ( !CORBA::is_nil( aSubMesh )) {
00545       aShapeObject = aSubMesh->GetSubShape();
00546       PublishSubMesh( theStudy, theMesh, aSubMesh, aShapeObject );
00547     }
00548   }
00549 
00550   // Publish groups
00551   const map<int, SMESH::SMESH_GroupBase_ptr>& grMap = mesh_i->getGroups();
00552   map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = grMap.begin();
00553   for ( ; it != grMap.end(); it++ )
00554   {
00555     SMESH::SMESH_GroupBase_ptr aGroup = (*it).second;
00556     if ( !aGroup->_is_nil() ) {
00557       GEOM::GEOM_Object_var  aShapeObj;
00558       SMESH::SMESH_GroupOnGeom_var aGeomGroup =
00559         SMESH::SMESH_GroupOnGeom::_narrow( aGroup );
00560       if ( !aGeomGroup->_is_nil() )
00561         aShapeObj = aGeomGroup->GetShape();
00562       PublishGroup( theStudy, theMesh, aGroup, aShapeObj );
00563     }
00564   }
00565 
00566   if(MYDEBUG) MESSAGE("PublishMesh_END");
00567   return aMeshSO._retn();
00568 }
00569 
00570 //=======================================================================
00571 //function : PublishSubMesh
00572 //purpose  : 
00573 //=======================================================================
00574 
00575 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishSubMesh (SALOMEDS::Study_ptr      theStudy,
00576                                                    SMESH::SMESH_Mesh_ptr    theMesh,
00577                                                    SMESH::SMESH_subMesh_ptr theSubMesh,
00578                                                    GEOM::GEOM_Object_ptr    theShapeObject,
00579                                                    const char*              theName)
00580 {
00581   if (theStudy->_is_nil() || theMesh->_is_nil() ||
00582       theSubMesh->_is_nil() || theShapeObject->_is_nil() )
00583     return SALOMEDS::SObject::_nil();
00584 
00585   SALOMEDS::SObject_var aSubMeshSO = ObjectToSObject( theStudy, theSubMesh );
00586   if ( aSubMeshSO->_is_nil() )
00587   {
00588     SALOMEDS::SObject_var aMeshSO = ObjectToSObject( theStudy, theMesh );
00589     if ( aMeshSO->_is_nil() ) {
00590       aMeshSO = PublishMesh( theStudy, theMesh );
00591       if ( aMeshSO->_is_nil())
00592         return SALOMEDS::SObject::_nil();
00593     }
00594     // Find submesh sub-tree tag
00595     long aRootTag;
00596     const char* aRootName = "";
00597     switch ( theShapeObject->GetShapeType() ) {
00598     case GEOM::VERTEX:
00599       aRootTag  = GetSubMeshOnVertexTag();
00600       aRootName = "SubMeshes on Vertex";
00601       break;
00602     case GEOM::EDGE:
00603       aRootTag  = GetSubMeshOnEdgeTag();
00604       aRootName = "SubMeshes on Edge";
00605       break;
00606     case GEOM::WIRE:
00607       aRootTag  = GetSubMeshOnWireTag();
00608       aRootName = "SubMeshes on Wire";
00609       break;
00610     case GEOM::FACE:
00611       aRootTag  = GetSubMeshOnFaceTag();
00612       aRootName = "SubMeshes on Face";    
00613       break;
00614     case GEOM::SHELL:
00615       aRootTag  = GetSubMeshOnShellTag();
00616       aRootName = "SubMeshes on Shell";   
00617       break;
00618     case GEOM::SOLID:
00619       aRootTag  = GetSubMeshOnSolidTag();
00620       aRootName = "SubMeshes on Solid";
00621       break;
00622     default:
00623       aRootTag  = GetSubMeshOnCompoundTag();
00624       aRootName = "SubMeshes on Compound";
00625       break;
00626     }
00627 
00628     // Find or create submesh root
00629     SALOMEDS::SObject_var aRootSO = publish (theStudy, CORBA::Object::_nil(),
00630                                              aMeshSO, aRootTag, 0, false );
00631     SetName( aRootSO, aRootName );
00632 
00633     // Add new submesh to corresponding sub-tree
00634     SMESH::array_of_ElementType_var elemTypes = theSubMesh->GetTypes();
00635     const int isEmpty = ( elemTypes->length() == 0 );
00636     const char* pm[2] = { "ICON_SMESH_TREE_MESH", "ICON_SMESH_TREE_MESH_WARN" };
00637     aSubMeshSO = publish (theStudy, theSubMesh, aRootSO, 0, pm[isEmpty] );
00638     if ( aSubMeshSO->_is_nil() )
00639       return aSubMeshSO._retn();
00640   }
00641   SetName( aSubMeshSO, theName, "SubMesh" );
00642 
00643   // Add reference to theShapeObject
00644 
00645   addReference( theStudy, aSubMeshSO, theShapeObject, 1 );
00646 
00647   // Publish hypothesis
00648 
00649   SMESH::ListOfHypothesis * hypList = theMesh->GetHypothesisList( theShapeObject );
00650   if ( hypList )
00651     for ( int i = 0; i < hypList->length(); i++ ) {
00652       SMESH::SMESH_Hypothesis_var aHyp = SMESH::SMESH_Hypothesis::_narrow( (*hypList)[ i ]);
00653       PublishHypothesis( theStudy, aHyp );
00654       AddHypothesisToShape( theStudy, theMesh, theShapeObject, aHyp );
00655     }
00656 
00657   return aSubMeshSO._retn();
00658 }
00659 
00660 //=======================================================================
00661 //function : PublishGroup
00662 //purpose  : 
00663 //=======================================================================
00664 
00665 SALOMEDS::SObject_ptr SMESH_Gen_i::PublishGroup (SALOMEDS::Study_ptr    theStudy,
00666                                                  SMESH::SMESH_Mesh_ptr  theMesh,
00667                                                  SMESH::SMESH_GroupBase_ptr theGroup,
00668                                                  GEOM::GEOM_Object_ptr  theShapeObject,
00669                                                  const char*            theName)
00670 {
00671   if (theStudy->_is_nil() || theMesh->_is_nil() || theGroup->_is_nil() )
00672     return SALOMEDS::SObject::_nil();
00673 
00674   SALOMEDS::SObject_var aGroupSO = ObjectToSObject( theStudy, theGroup );
00675   if ( aGroupSO->_is_nil() )
00676   {
00677     SALOMEDS::SObject_var aMeshSO = ObjectToSObject( theStudy, theMesh );
00678     if ( aMeshSO->_is_nil() ) {
00679       aMeshSO = PublishInStudy( theStudy, SALOMEDS::SObject::_nil(), theMesh, "");
00680       if ( aMeshSO->_is_nil())
00681         return SALOMEDS::SObject::_nil();
00682     }
00683     int aType = (int)theGroup->GetType();
00684     const char* aRootNames[] = {
00685       "Compound Groups", "Groups of Nodes", "Groups of Edges",
00686       "Groups of Faces", "Groups of Volumes", "Groups of 0D Elements" };
00687 
00688     // Currently, groups with heterogenous content are not supported
00689     if ( aType != SMESH::ALL ) {
00690       long aRootTag = GetNodeGroupsTag() + aType - 1;
00691 
00692       // Find or create groups root
00693       SALOMEDS::SObject_var aRootSO = publish (theStudy, CORBA::Object::_nil(),
00694                                                aMeshSO, aRootTag, 0, false );
00695       if ( aType < 6 )
00696         SetName( aRootSO, aRootNames[aType] );
00697 
00698       // Add new group to corresponding sub-tree
00699       SMESH::array_of_ElementType_var elemTypes = theGroup->GetTypes();
00700       int isEmpty = ( elemTypes->length() == 0 );
00701       std::string pm[2] = { "ICON_SMESH_TREE_GROUP", "ICON_SMESH_TREE_MESH_WARN" };
00702       if ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ))
00703       {
00704         pm[0] = "ICON_SMESH_TREE_GROUP_ON_FILTER";
00705       }
00706       else if ( SMESH::DownCast< SMESH_Group_i* > ( theGroup ))
00707       {
00708         SMESH::array_of_ElementType_var allElemTypes = theMesh->GetTypes();
00709         for ( size_t i =0; i < allElemTypes->length() && isEmpty; ++i )
00710           isEmpty = ( allElemTypes[i] != theGroup->GetType() );
00711       }
00712       aGroupSO = publish (theStudy, theGroup, aRootSO, 0, pm[isEmpty].c_str() );
00713     }
00714     if ( aGroupSO->_is_nil() )
00715       return aGroupSO._retn();
00716   }
00717 
00718   SetName( aGroupSO, theName, "Group" );
00719 
00720   //Add reference to geometry
00721   if ( !theShapeObject->_is_nil() )
00722     addReference( theStudy, aGroupSO, theShapeObject, 1 );
00723 
00724   return aGroupSO._retn();
00725 }
00726 
00727 //=======================================================================
00728 //function : PublishHypothesis
00729 //purpose  : 
00730 //=======================================================================
00731 
00732 SALOMEDS::SObject_ptr
00733   SMESH_Gen_i::PublishHypothesis (SALOMEDS::Study_ptr         theStudy,
00734                                   SMESH::SMESH_Hypothesis_ptr theHyp,
00735                                   const char*                 theName)
00736 {
00737   if(MYDEBUG) MESSAGE("PublishHypothesis")
00738   if (theStudy->_is_nil() || theHyp->_is_nil())
00739     return SALOMEDS::SObject::_nil();
00740 
00741   SALOMEDS::SObject_var aHypSO = ObjectToSObject( theStudy, theHyp );
00742   if ( aHypSO->_is_nil() )
00743   {
00744     SALOMEDS::SComponent_var father = PublishComponent( theStudy );
00745     if ( father->_is_nil() )
00746       return aHypSO._retn();
00747 
00748     //Find or Create Hypothesis root
00749     bool isAlgo = ( !SMESH::SMESH_Algo::_narrow( theHyp )->_is_nil() );
00750     int aRootTag = isAlgo ? GetAlgorithmsRootTag() : GetHypothesisRootTag();
00751     SALOMEDS::SObject_var aRootSO =
00752       publish (theStudy, CORBA::Object::_nil(),father, aRootTag,
00753                isAlgo ? "ICON_SMESH_TREE_ALGO" : "ICON_SMESH_TREE_HYPO", false);
00754     SetName( aRootSO, isAlgo ?  "Algorithms" : "Hypotheses" );
00755 
00756     // Add New Hypothesis
00757     string aPmName = isAlgo ? "ICON_SMESH_TREE_ALGO_" : "ICON_SMESH_TREE_HYPO_";
00758     aPmName += theHyp->GetName();
00759     // prepend plugin name to pixmap name
00760     string pluginName = myHypCreatorMap[string(theHyp->GetName())]->GetModuleName();
00761     if ( pluginName != "StdMeshers" )
00762       aPmName = pluginName + "::" + aPmName;
00763     aHypSO = publish( theStudy, theHyp, aRootSO, 0, aPmName.c_str() );
00764   }
00765 
00766   if ( !aHypSO->_is_nil() ) {
00767     CORBA::String_var aHypName = CORBA::string_dup( theHyp->GetName() );
00768     SetName( aHypSO, theName, aHypName );
00769   }
00770 
00771   if(MYDEBUG) MESSAGE("PublishHypothesis--END")
00772   return aHypSO._retn();
00773 }
00774 
00775 //=======================================================================
00776 //function : GetMeshOrSubmeshByShape
00777 //purpose  : 
00778 //=======================================================================
00779 
00780 SALOMEDS::SObject_ptr
00781   SMESH_Gen_i::GetMeshOrSubmeshByShape (SALOMEDS::Study_ptr   theStudy,
00782                                         SMESH::SMESH_Mesh_ptr theMesh,
00783                                         GEOM::GEOM_Object_ptr theShape)
00784 {
00785   if(MYDEBUG) MESSAGE("GetMeshOrSubmeshByShape")
00786   SALOMEDS::SObject_var aMeshOrSubMesh;
00787   if (theMesh->_is_nil() || ( theShape->_is_nil() && theMesh->HasShapeToMesh()))
00788     return aMeshOrSubMesh._retn();
00789   
00790   TopoDS_Shape aShape;
00791   if(theMesh->HasShapeToMesh())
00792     aShape = GeomObjectToShape( theShape );
00793   else
00794     aShape = SMESH_Mesh::PseudoShape();
00795 
00796   SMESH_Mesh_i* mesh_i = objectToServant<SMESH_Mesh_i>( theMesh );
00797 
00798   if ( !aShape.IsNull() && mesh_i && mesh_i->GetImpl().GetMeshDS() ) {
00799     SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
00800     if ( aShape.IsSame( meshDS->ShapeToMesh() ))
00801       aMeshOrSubMesh = ObjectToSObject( theStudy, theMesh );
00802     else {
00803       int shapeID = meshDS->ShapeToIndex( aShape );
00804       SMESH::SMESH_subMesh_var aSubMesh = mesh_i->getSubMesh(shapeID);
00805       if ( !aSubMesh->_is_nil() )
00806         aMeshOrSubMesh = ObjectToSObject( theStudy, aSubMesh );
00807     }
00808   }
00809   if(MYDEBUG) MESSAGE("GetMeshOrSubmeshByShape--END")
00810   return aMeshOrSubMesh._retn();
00811 }
00812 
00813 //=======================================================================
00814 //function : AddHypothesisToShape
00815 //purpose  : 
00816 //=======================================================================
00817 
00818 bool SMESH_Gen_i::AddHypothesisToShape(SALOMEDS::Study_ptr         theStudy,
00819                                        SMESH::SMESH_Mesh_ptr       theMesh,
00820                                        GEOM::GEOM_Object_ptr       theShape,
00821                                        SMESH::SMESH_Hypothesis_ptr theHyp)
00822 {
00823   if(MYDEBUG) MESSAGE("AddHypothesisToShape")
00824   if (theStudy->_is_nil() || theMesh->_is_nil() ||
00825       theHyp->_is_nil() || (theShape->_is_nil()
00826                             && theMesh->HasShapeToMesh()) )
00827     return false;
00828 
00829   SALOMEDS::SObject_var aMeshSO = ObjectToSObject( theStudy, theMesh );
00830   if ( aMeshSO->_is_nil() )
00831     aMeshSO = PublishMesh( theStudy, theMesh );
00832   SALOMEDS::SObject_var aHypSO = PublishHypothesis( theStudy, theHyp );
00833   if ( aMeshSO->_is_nil() || aHypSO->_is_nil())
00834     return false;
00835 
00836   // Find a mesh or submesh refering to theShape
00837   SALOMEDS::SObject_var aMeshOrSubMesh =
00838     GetMeshOrSubmeshByShape( theStudy, theMesh, theShape );
00839   if ( aMeshOrSubMesh->_is_nil() )
00840   {
00841     // publish submesh
00842     TopoDS_Shape aShape = GeomObjectToShape( theShape );
00843     SMESH_Mesh_i* mesh_i = objectToServant<SMESH_Mesh_i>( theMesh );
00844     if ( !aShape.IsNull() && mesh_i && mesh_i->GetImpl().GetMeshDS() ) {
00845       SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
00846       int shapeID = meshDS->ShapeToIndex( aShape );
00847       SMESH::SMESH_subMesh_var aSubMesh = mesh_i->getSubMesh(shapeID);
00848       aMeshOrSubMesh = PublishSubMesh( theStudy, theMesh, aSubMesh, theShape );
00849     }
00850     if ( aMeshOrSubMesh->_is_nil() )
00851       return false;
00852   }
00853 
00854   //Find or Create Applied Hypothesis root
00855   bool aIsAlgo = !SMESH::SMESH_Algo::_narrow( theHyp )->_is_nil();
00856   SALOMEDS::SObject_var AHR =
00857     publish (theStudy, CORBA::Object::_nil(), aMeshOrSubMesh,
00858              aIsAlgo ? GetRefOnAppliedAlgorithmsTag() : GetRefOnAppliedHypothesisTag(),
00859              aIsAlgo ? "ICON_SMESH_TREE_ALGO" : "ICON_SMESH_TREE_HYPO", false);
00860   SetName( AHR, aIsAlgo ? "Applied algorithms" : "Applied hypotheses" );
00861   if ( AHR->_is_nil() )
00862     return false;
00863 
00864   addReference( theStudy, AHR, theHyp );
00865   if(MYDEBUG) MESSAGE("AddHypothesisToShape--END")
00866   return true;
00867 }
00868 
00869 //=======================================================================
00870 //function : RemoveHypothesisFromShape
00871 //purpose  : 
00872 //=======================================================================
00873 
00874 bool SMESH_Gen_i::RemoveHypothesisFromShape(SALOMEDS::Study_ptr         theStudy,
00875                                             SMESH::SMESH_Mesh_ptr       theMesh,
00876                                             GEOM::GEOM_Object_ptr       theShape,
00877                                             SMESH::SMESH_Hypothesis_ptr theHyp)
00878 {
00879   if (theStudy->_is_nil() || theMesh->_is_nil() ||
00880       theHyp->_is_nil() || (theShape->_is_nil()
00881                             && theMesh->HasShapeToMesh()))
00882     return false;
00883 
00884   SALOMEDS::SObject_var aHypSO = ObjectToSObject( theStudy, theHyp );
00885   if ( aHypSO->_is_nil() )
00886     return false;
00887 
00888   // Find a mesh or submesh refering to theShape
00889   SALOMEDS::SObject_var aMeshOrSubMesh =
00890     GetMeshOrSubmeshByShape( theStudy, theMesh, theShape );
00891   if ( aMeshOrSubMesh->_is_nil() )
00892     return false;
00893 
00894   // Find and remove a reference to aHypSO
00895   SALOMEDS::SObject_var aRef, anObj;
00896   CORBA::String_var     anID = CORBA::string_dup( aHypSO->GetID() );
00897   SALOMEDS::ChildIterator_var it = theStudy->NewChildIterator( aMeshOrSubMesh );
00898   for ( it->InitEx( true ); it->More(); it->Next() ) {
00899     anObj = it->Value();
00900     if (anObj->ReferencedObject( aRef ) && strcmp( aRef->GetID(), anID ) == 0 ) {
00901       theStudy->NewBuilder()->RemoveObject( anObj );
00902       break;
00903     }
00904   }
00905   return true;
00906 }
00907 
00908 //=======================================================================
00909 //function : UpdateParameters
00910 //purpose  : 
00911 //=======================================================================
00912 void SMESH_Gen_i::UpdateParameters(/*CORBA::Object_ptr theObject,*/ const char* theParameters)
00913 {
00914   SALOMEDS::Study_ptr aStudy = GetCurrentStudy();
00915   if ( aStudy->_is_nil() )
00916     return;
00917   myLastParameters.clear();
00918   int pos = 0, prevPos = 0, len = strlen( theParameters );
00919   if ( len == 0 ) return;
00920   while ( pos <= len )
00921   {
00922     if ( pos == len || theParameters[pos] == ':' )
00923     {
00924       if ( prevPos < pos )
00925       {
00926         string val(theParameters + prevPos, theParameters + pos );
00927         if ( !aStudy->IsVariable( val.c_str() ))
00928           val.clear();
00929         myLastParameters.push_back( val );
00930       }
00931       else
00932       {
00933         myLastParameters.push_back("");
00934       }
00935       prevPos = pos+1;
00936     }
00937     ++pos;
00938   }
00939   return;
00940 
00941   // OLD VARIANT
00942 
00943   // if(VARIABLE_DEBUG)
00944   //   cout<<"UpdateParameters : "<<theParameters<<endl;
00945   // //SALOMEDS::Study_ptr aStudy = GetCurrentStudy();
00946   // if(aStudy->_is_nil() || CORBA::is_nil(theObject)) 
00947   //   return;
00948 
00949   // SALOMEDS::SObject_var aSObj =  ObjectToSObject(aStudy,theObject);
00950   // if(aSObj->_is_nil())  
00951   //   return;
00952 
00953   // SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
00954 
00955   // SALOMEDS::GenericAttribute_var aFindAttr;
00956   // bool hasAttr = aSObj->FindAttribute(aFindAttr, "AttributeString");
00957   // if(VARIABLE_DEBUG)
00958   //   cout<<"Find Attribute "<<hasAttr<<endl;
00959 
00960   // SALOMEDS::GenericAttribute_var anAttr;
00961   // anAttr = aStudyBuilder->FindOrCreateAttribute( aSObj, "AttributeString");
00962   // SALOMEDS::AttributeString_var aStringAttr = SALOMEDS::AttributeString::_narrow(anAttr);
00963 
00964   // CORBA::String_var oldparVar = aStringAttr->Value();
00965   // CORBA::String_var inpparVar = ParseParameters(theParameters);
00966   // TCollection_AsciiString aNewParams;
00967   // TCollection_AsciiString aOldParameters(oldparVar.inout());
00968   // TCollection_AsciiString anInputParams(inpparVar.inout());
00969   // if(!hasAttr)
00970   //   aNewParams = anInputParams;
00971   // else 
00972   //   {
00973   //     int pos = aOldParameters.SearchFromEnd("|");
00974   //     if(pos==-1) pos = 0;
00975   //     TCollection_AsciiString previousParamFull(aOldParameters.Split(pos));
00976   //     TCollection_AsciiString previousParam(previousParamFull);
00977   //     TCollection_AsciiString theRepet("1");
00978   //     pos = previousParam.SearchFromEnd(";*=");
00979   //     if(pos >= 0)
00980   //       {
00981   //         theRepet = previousParam.Split(pos+2);
00982   //         pos = pos-1;
00983   //         if(pos==-1) pos = 0;
00984   //         previousParam.Split(pos);
00985   //       }
00986   //     if(previousParam == anInputParams)
00987   //       {
00988   //         theRepet = theRepet.IntegerValue()+1;
00989   //         aNewParams = aOldParameters + previousParam + ";*=" + theRepet;
00990   //       }
00991   //     else
00992   //       {
00993   //         aNewParams = aOldParameters + previousParamFull + "|" + anInputParams;
00994   //       }
00995   //   }
00996 
00997   // if(VARIABLE_DEBUG)
00998   // {
00999   //   cout<<"Input Parameters : "<<anInputParams<<endl;
01000   //   cout<<"Old Parameters : "<<aOldParameters<<endl;
01001   //   cout<<"New Parameters : "<<aNewParams<<endl;
01002   // }
01003 
01004   // aStringAttr->SetValue( aNewParams.ToCString() );
01005 }
01006 
01007 //=======================================================================
01008 //function : ParseParameters
01009 //purpose  : Replace variables by their values
01010 //=======================================================================
01011 char* SMESH_Gen_i::ParseParameters(const char* theParameters)
01012 {
01013   //const char* aParameters = theParameters;
01014 //   const char* aParameters = CORBA::string_dup(theParameters);
01015   TCollection_AsciiString anInputParams;
01016   SALOMEDS::Study_var aStudy = GetCurrentStudy();
01017   if( !aStudy->_is_nil() ) {
01018 //     SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(theParameters);
01019 //     for(int j=0;j<aSections->length();j++) {
01020 //       SALOMEDS::ListOfStrings aVars= aSections[j];
01021 //       for(int i=0;i<aVars.length();i++ ) {
01022 //         anInputParams += aStudy->IsVariable(aVars[i].in()) ? 
01023 //           TCollection_AsciiString(aVars[i].in()) : TCollection_AsciiString("");
01024 //         if(i != aVars.length()-1)
01025 //           anInputParams+=":";
01026 //       }
01027 //       if(j!=aSections->length()-1)
01028 //         anInputParams+="|";
01029 //     }
01030     TCollection_AsciiString paramStr( theParameters );
01031     static TCollection_AsciiString separators(":|");
01032     int beg = 0, end;
01033     char sep, *pParams = (char*)paramStr.ToCString();
01034     while ( beg < paramStr.Length() )
01035     {
01036       end = beg-1;
01037       while ( ++end < paramStr.Length() )
01038         if ( pParams[end] == ':' || pParams[end] == '|')
01039           break;
01040       if ( end < paramStr.Length())
01041       {
01042         sep = pParams[end];
01043         pParams[end] = '\0';
01044       }
01045       if ( aStudy->IsVariable( pParams+beg ))
01046         anInputParams += pParams+beg;
01047       if ( end < paramStr.Length() )
01048         anInputParams += sep;
01049       else
01050         break;
01051       beg = end + 1;
01052     }
01053   }
01054   return CORBA::string_dup(anInputParams.ToCString());
01055 }
01056 
01057 //=======================================================================
01058 //function : GetParameters
01059 //purpose  : 
01060 //=======================================================================
01061 char* SMESH_Gen_i::GetParameters(CORBA::Object_ptr theObject)
01062 {
01063   TCollection_AsciiString aResult;
01064 
01065   SALOMEDS::Study_ptr aStudy = GetCurrentStudy();
01066   SALOMEDS::SObject_var aSObj =  ObjectToSObject(aStudy,theObject);
01067 
01068   if(!aStudy->_is_nil() && 
01069      !CORBA::is_nil(theObject) && 
01070      !aSObj->_is_nil()){
01071     
01072     SALOMEDS::GenericAttribute_var anAttr;
01073     if ( aSObj->FindAttribute(anAttr, "AttributeString")) {
01074       aResult = TCollection_AsciiString(SALOMEDS::AttributeString::_narrow(anAttr)->Value());
01075     }
01076   }
01077   
01078   return CORBA::string_dup( aResult.ToCString() );
01079 }