Salome HOME
Merge from OCC_development_generic_2006
[modules/visu.git] / src / VISU_I / VISU_CutLines_i.cc
1 //  VISU OBJECT : interactive object for VISU entities implementation
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //  File   : VISU_PrsObject_i.cxx
24 //  Author : Alexey PETROV
25 //  Module : VISU
26
27 #include "VISU_CutLines_i.hh"
28 #include "VISU_Result_i.hh"
29
30 #include "VISU_Actor.h"
31 #include "VISU_CutLinesPL.hxx"
32 #include "VISU_Convertor.hxx"
33 #include "VISU_PipeLineUtils.hxx"
34
35 #include <vtkAppendPolyData.h>
36
37 using namespace VISU;
38 using namespace std;
39
40 static float EPS_machine = 1.0E-7;
41
42 #ifdef _DEBUG_
43 static int MYDEBUG = 0;
44 #else
45 static int MYDEBUG = 0;
46 #endif
47
48 int VISU::CutLines_i::IsPossible(Result_i* theResult, const char* theMeshName, VISU::Entity theEntity, 
49                                  const char* theFieldName, int theIteration, int isMemoryCheck)
50 {
51   return VISU::ScalarMap_i::IsPossible(theResult,theMeshName,theEntity,theFieldName,theIteration,isMemoryCheck);
52 }
53
54 int VISU::CutLines_i::myNbPresent = 0;
55 QString VISU::CutLines_i::GenerateName() { return VISU::GenerateName("CutLines",myNbPresent++);}
56
57 const string VISU::CutLines_i::myComment = "CUTLINES";
58 const char* VISU::CutLines_i::GetComment() const { return myComment.c_str();}
59
60
61 VISU::CutLines_i::
62 CutLines_i(Result_i* theResult, 
63            bool theAddToStudy) :
64   PrsObject_i(theResult->GetStudyDocument()), 
65   Prs3d_i(theResult,theAddToStudy),
66   ColoredPrs3d_i(theResult,theAddToStudy),
67   ScalarMap_i(theResult,theAddToStudy),
68   myCutLinesPL(NULL)
69 {}
70
71
72 VISU::CutLines_i::
73 CutLines_i(Result_i* theResult, 
74            SALOMEDS::SObject_ptr theSObject) :
75   PrsObject_i(theResult->GetStudyDocument()), 
76   Prs3d_i(theResult,theSObject),
77   ColoredPrs3d_i(theResult,theSObject),
78   ScalarMap_i(theResult,theSObject),
79   myCutLinesPL(NULL)
80 {
81 }
82
83
84 /*! Copy map to /a myMapCurvesInverted.
85  * \param theCurves - map
86  */
87 void VISU::CutLines_i::CopyCurvesInverted(const TCurvesInv& theCurves){
88   myMapCurvesInverted = theCurves;
89 }
90
91 VISU::Storable* VISU::CutLines_i::Create(const char* theMeshName, VISU::Entity theEntity, 
92                                          const char* theFieldName, int theIteration)
93 {
94   return ScalarMap_i::Create(theMeshName,theEntity,theFieldName,theIteration);
95 }
96
97
98 VISU::Storable* VISU::CutLines_i::Restore(const Storable::TRestoringMap& theMap)
99 {
100   TSuperClass::Restore(theMap);
101
102   SetNbLines(VISU::Storable::FindValue(theMap,"myNbLines").toInt());
103   SetDisplacement(VISU::Storable::FindValue(theMap,"myDisplacement[0]").toDouble());
104   SetDisplacement2(VISU::Storable::FindValue(theMap,"myDisplacement[1]").toDouble());
105   SetOrientation(CutPlanes::Orientation(VISU::Storable::FindValue(theMap,"myBasePlane[0]").toInt()),
106                  Storable::FindValue(theMap,"aRot[0][0]").toDouble(),
107                  Storable::FindValue(theMap,"aRot[0][1]").toDouble());
108   SetOrientation2(CutPlanes::Orientation(VISU::Storable::FindValue(theMap,"myBasePlane[1]").toInt()),
109                   Storable::FindValue(theMap,"aRot[1][0]").toDouble(),
110                   Storable::FindValue(theMap,"aRot[1][1]").toDouble());
111   if (VISU::Storable::FindValue(theMap,"myBasePlaneCondition").toInt())
112     SetDefault();
113   else
114     SetBasePlanePosition(VISU::Storable::FindValue(theMap,"myBasePlanePosition").toDouble());
115   
116   QStringList aPosList = QStringList::split("|",VISU::Storable::FindValue(theMap,"myLinePosition") );
117   QStringList aCondList = QStringList::split("|",VISU::Storable::FindValue(theMap,"myLineCondition") );
118   for(int i = 0, iEnd = GetNbLines(); i < iEnd; i++)
119     if(aCondList[i].toInt() == 0)
120       SetLinePosition(i,aPosList[i].toDouble());
121
122   // Restoring the map - \a myMapCurvesInverted
123   QStringList aMapCurvesInverted = QStringList::split("|",VISU::Storable::FindValue(theMap,"myMapCurvesInverted") );
124   if (aMapCurvesInverted.count() == GetNbLines()){
125     for(int i = 0, iEnd = GetNbLines(); i < iEnd ; i++){
126       if(aMapCurvesInverted[i].toInt())
127         SetCurveInverted(i,true);
128       else
129         SetCurveInverted(i,false);
130     }
131   } else {
132     for(int i = 0, iEnd = GetNbLines(); i < iEnd ; i++)
133       SetCurveInverted(i,false);
134   }
135       
136   return this;
137 }
138
139
140 void VISU::CutLines_i::ToStream(std::ostringstream& theStr){
141   ScalarMap_i::ToStream(theStr);
142
143   int aNbLines = GetNbLines();
144   
145   Storable::DataToStream( theStr, "myNbLines",         aNbLines );
146   Storable::DataToStream( theStr, "myDisplacement[0]", GetDisplacement() );
147   Storable::DataToStream( theStr, "myDisplacement[1]", GetDisplacement2() );
148   Storable::DataToStream( theStr, "myBasePlane[0]",    int(GetOrientationType()) );
149   Storable::DataToStream( theStr, "myBasePlane[1]",    int(GetOrientationType2()) );
150   Storable::DataToStream( theStr, "aRot[0][0]",        GetRotateX() );
151   Storable::DataToStream( theStr, "aRot[0][1]",        GetRotateY() );
152   Storable::DataToStream( theStr, "aRot[1][0]",        GetRotateX2() );
153   Storable::DataToStream( theStr, "aRot[1][1]",        GetRotateY2() );
154   Storable::DataToStream( theStr, "myBasePlanePosition", GetBasePlanePosition() );
155   Storable::DataToStream( theStr, "myBasePlaneCondition", IsDefault() );
156
157   QString aStrPos, aStrCon;
158   for(int i = 0, iEnd = GetNbLines(); i < iEnd; i++){
159     aStrPos.append(QString::number(GetLinePosition(i)) + "|");
160     aStrCon.append(QString::number(IsDefaultPosition(i)) + "|");
161   }
162   Storable::DataToStream( theStr, "myLinePosition",  aStrPos.latin1());
163   Storable::DataToStream( theStr, "myLineCondition", aStrCon.latin1());
164
165   // Storing the map - \a myMapCurvesInverted
166   QString aStrCurvesInverted;
167   for(int i = 0, iEnd = GetNbLines(); i < iEnd; i++) 
168     aStrCurvesInverted.append(QString::number(IsCurveInverted(i)) + "|");
169   Storable::DataToStream( theStr, "myMapCurvesInverted", aStrCurvesInverted.latin1());
170 }
171
172 VISU::CutLines_i::~CutLines_i(){
173   if(MYDEBUG) MESSAGE("CutLines_i::~CutLines_i()");
174 }
175
176
177 void VISU::CutLines_i::SetOrientation(VISU::CutPlanes::Orientation theOrient,
178                                       CORBA::Double theXAngle, CORBA::Double theYAngle)
179 {
180   myCutLinesPL->SetOrientation(VISU_CutPlanesPL::PlaneOrientation(theOrient),
181                                theXAngle,theYAngle);
182 }
183 void VISU::CutLines_i::SetOrientation2(VISU::CutPlanes::Orientation theOrient,
184                                        CORBA::Double theXAngle, CORBA::Double theYAngle)
185 {
186   myCutLinesPL->SetOrientation(VISU_CutPlanesPL::PlaneOrientation(theOrient),
187                                theXAngle,theYAngle,1);
188 }
189
190 VISU::CutPlanes::Orientation VISU::CutLines_i::GetOrientationType() { 
191   return VISU::CutPlanes::Orientation(myCutLinesPL->GetPlaneOrientation());
192 }
193 VISU::CutPlanes::Orientation VISU::CutLines_i::GetOrientationType2() { 
194   return VISU::CutPlanes::Orientation(myCutLinesPL->GetPlaneOrientation(1));
195 }
196
197 CORBA::Double VISU::CutLines_i::GetRotateX(){
198   return myCutLinesPL->GetRotateX();
199 }
200 CORBA::Double VISU::CutLines_i::GetRotateY(){
201   return myCutLinesPL->GetRotateY();
202 }
203
204 CORBA::Double VISU::CutLines_i::GetRotateX2(){
205   return myCutLinesPL->GetRotateX(1);
206 }
207 CORBA::Double VISU::CutLines_i::GetRotateY2(){
208   return myCutLinesPL->GetRotateY(1);
209 }
210
211
212 void VISU::CutLines_i::SetDisplacement(CORBA::Double theDisp) { 
213   myCutLinesPL->SetDisplacement(theDisp);
214 }
215 void VISU::CutLines_i::SetDisplacement2(CORBA::Double theDisp) { 
216   myCutLinesPL->SetDisplacement(theDisp,1);
217 }
218
219 CORBA::Double VISU::CutLines_i::GetDisplacement() { 
220   return myCutLinesPL->GetDisplacement();
221 }
222 CORBA::Double VISU::CutLines_i::GetDisplacement2() { 
223   return myCutLinesPL->GetDisplacement(1);
224 }
225
226
227 void VISU::CutLines_i::SetBasePlanePosition(CORBA::Double thePlanePosition){
228   myCutLinesPL->SetPosition(thePlanePosition);
229 }
230
231 CORBA::Double VISU::CutLines_i::GetBasePlanePosition(){ 
232   return myCutLinesPL->GetPosition();
233 }
234
235 void VISU::CutLines_i::SetLinePosition(CORBA::Long thePlaneNumber, CORBA::Double thePlanePosition){
236   myCutLinesPL->SetPartPosition(thePlaneNumber,thePlanePosition);
237 }
238
239 CORBA::Double VISU::CutLines_i::GetLinePosition(CORBA::Long thePlaneNumber){ 
240   return myCutLinesPL->GetPartPosition(thePlaneNumber,1);
241 }
242
243
244 void VISU::CutLines_i::SetDefault(){
245   myCutLinesPL->SetDefault();
246 }
247
248 CORBA::Boolean VISU::CutLines_i::IsDefault(){ 
249   return myCutLinesPL->IsDefault();
250 }
251
252 void VISU::CutLines_i::SetDefaultPosition(CORBA::Long thePlaneNumber){
253   myCutLinesPL->SetPartDefault(thePlaneNumber);
254 }
255
256 CORBA::Boolean VISU::CutLines_i::IsDefaultPosition(CORBA::Long thePlaneNumber){ 
257   return myCutLinesPL->IsPartDefault(thePlaneNumber);
258 }
259
260 /*! Invert all curves of corresponding table
261  * see void VISU::CutLines_i::SetCurveInverted(CORBA::Long theCurveNumber,CORBA::Boolean theInvert)
262  * \param theInvert - Invert all curves, if value is TRUE, else not.
263  */
264 void VISU::CutLines_i::SetAllCurvesInverted(CORBA::Boolean theInvert){
265   for (int i=0; i<GetNbLines(); i++) SetCurveInverted(i,theInvert);
266 }
267
268 /*! Checks the orientation of all curves
269  * \retval TRUE - if all curves are inverted, else FALSE
270  */
271 CORBA::Boolean VISU::CutLines_i::IsAllCurvesInverted(){
272   for (int i=0; i<GetNbLines(); i++)
273     if (!IsCurveInverted(i)) return false;
274   return true;
275 }
276
277 /*! Sets orientation of curve
278  * \param theCurveNumber - integer value, number of cut line.
279  * \param theInvert      - boolean value, TRUE or false.
280  */
281 void VISU::CutLines_i::SetCurveInverted(CORBA::Long theCurveNumber,CORBA::Boolean theInvert){
282   myMapCurvesInverted[theCurveNumber] = theInvert;
283 }
284
285 /*! Checks orientation of curve.
286  * \param theCurveNumber - integer value, number of cut line.
287  * \retval TRUE - if line in the table is inverted, else FALSE.
288  */
289 CORBA::Boolean VISU::CutLines_i::IsCurveInverted(CORBA::Long theCurveNumber){
290   return myMapCurvesInverted[theCurveNumber];
291 }
292
293 void VISU::CutLines_i::SetNbLines(CORBA::Long theNb) { 
294   myCutLinesPL->SetNbParts(theNb);
295 }
296 CORBA::Long VISU::CutLines_i::GetNbLines() { 
297   return myCutLinesPL->GetNbParts();
298 }
299
300
301 void VISU::CutLines_i::DoHook(){
302   if(!myPipeLine) myPipeLine = VISU_CutLinesPL::New();
303   myCutLinesPL = dynamic_cast<VISU_CutLinesPL*>(myPipeLine);
304
305   ScalarMap_i::DoHook();
306 }
307
308 VISU_Actor* 
309 VISU::CutLines_i
310 ::CreateActor(const Handle(SALOME_InteractiveObject)& theIO)
311 {
312   if(VISU_Actor* anActor = ScalarMap_i::CreateActor(theIO)){
313     anActor->SetVTKMapping(true);
314     return anActor;
315   }
316   return NULL;
317 }
318
319 void VISU::CutLines_i::BuildTableOfReal(SALOMEDS::SObject_ptr theSObject){
320   try{
321     if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal");
322     Update();
323     SALOMEDS::GenericAttribute_var anAttr;
324     SALOMEDS::StudyBuilder_var aStudyBuilder = myStudy->NewBuilder();
325     anAttr = aStudyBuilder->FindOrCreateAttribute(theSObject, "AttributeTableOfReal");
326     SALOMEDS::AttributeTableOfReal_var aTableOfReal = SALOMEDS::AttributeTableOfReal::_narrow(anAttr);
327     
328     typedef set<float> TXCont;
329     typedef map<float,float> TXYMap;
330     typedef map<int,TXYMap> TXYMapCont;
331     typedef map<long,long> TLineIdCont;
332     
333     QString aTitle;
334     aTitle.sprintf("%s",myTitle.c_str());
335     aTitle = aTitle.simplifyWhiteSpace();
336     aTableOfReal->SetTitle(aTitle.latin1());
337     
338     int iLineEnd = myCutLinesPL->GetAppendPolyData()->GetNumberOfInputs();
339     if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal iLineEnd = "<<iLineEnd);
340     TXCont aXCont;
341     TXYMapCont aXYMapCont; 
342     TLineIdCont aLineIdCont;  // Define internal numeration of lines
343     const float *aDirLn = myCutLinesPL->GetDirLn();
344     const float *aBasePnt = myCutLinesPL->GetBasePnt();
345     const float *aBoundPrjLn = myCutLinesPL->GetBoundPrjLn();
346     for(int iLine = 0, jLine = 0; iLine < iLineEnd; iLine++){
347       vtkDataSet *aDataSet = myCutLinesPL->GetAppendPolyData()->GetInput(iLine);
348       aDataSet->Update();
349       int aNbPoints = aDataSet->GetNumberOfPoints();
350       if(!aNbPoints) continue;
351       vtkPointData *aPointData = aDataSet->GetPointData();
352       vtkDataArray *aScalars = aPointData->GetScalars();
353       vtkCellDataToPointData *aFilter = NULL;
354       if(!aScalars) {
355         aFilter = vtkCellDataToPointData::New();
356         aFilter->SetInput(aDataSet);
357         aFilter->PassCellDataOn();
358         aDataSet = aFilter->GetOutput();
359         aDataSet->Update();
360       }
361       aPointData = aDataSet->GetPointData();
362       aScalars = aPointData->GetScalars();
363       if(!aScalars) continue;
364       if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal iLine = "<<iLine<<"; aNbPoints = "<<aNbPoints);
365       aLineIdCont[iLine] = jLine++;
366       TXYMap& aXYMap = aXYMapCont[iLine];
367       float aPnt[3], aVect[3], aDist;
368       for(int i = 0; i < aNbPoints; i++){
369         aDataSet->GetPoint(i,aPnt);
370         Sub(aPnt,aBasePnt,aVect);
371         if ( fabs(aBoundPrjLn[2]) < EPS_machine )
372           aDist = 0.5;
373         else
374           {
375             aDist = vtkMath::Dot(aVect,aDirLn) / aBoundPrjLn[2];
376             // the workaround
377             if(aDist < 0.0) aDist = 0.0; 
378             if(aDist > 1.0) aDist = 1.0;
379           }
380         aXYMap[aDist] = aScalars->GetTuple1(i);
381       }
382       if(aFilter){
383         aFilter->UnRegisterAllOutputs();
384         aFilter->Delete();
385       }
386     }
387     if(aXYMapCont.size() == 0)
388       throw std::runtime_error("CutPlanes_i::BuildTableOfReal aXYMapCont.size() == 0 !!!");
389
390     {
391       // Invertion all curves in the table, which has inversion flag is TRUE (see \a myMapCurvesInverted)
392       for(int iLine=0; iLine < iLineEnd; iLine++){
393         if (!IsCurveInverted(iLine)) continue;
394         TXYMap aNewXYMap;
395         TXYMap& aXYMap = aXYMapCont[iLine];
396         TXYMap::const_iterator aXYMapIter = aXYMap.begin();
397         std::list<float> XKeys;
398         for (;aXYMapIter != aXYMap.end() ; aXYMapIter++) XKeys.push_back(aXYMapIter->first);
399         XKeys.sort();
400         if (XKeys.size() > 1) {
401           float a_first_indx = XKeys.front();
402           float a_last_indx = XKeys.back();
403           if (a_first_indx > a_last_indx){
404             XKeys.reverse();
405             float tmp = a_first_indx;
406             a_first_indx = a_last_indx;
407             a_last_indx = tmp;
408           }
409           std::list<float>::const_iterator aIter = XKeys.begin();
410           for (int k=0;k<XKeys.size() and aIter != XKeys.end();k++,aIter++){
411             // Warning: value '1.0' come from workaround:
412             // see also aDist = vtkMath::Dot(aVect,aDirLn) / aBoundPrjLn[2];
413             // aDist >= 0 and aDist<=1.0
414             aNewXYMap[1.0 - *aIter] = aXYMap[*aIter];
415           }
416           TXYMap::const_iterator aNewXYMapIter = aNewXYMap.begin();
417           aXYMap.clear();
418           for (;aNewXYMapIter != aNewXYMap.end();aNewXYMapIter++) {
419             aXYMap[aNewXYMapIter->first] = aNewXYMapIter->second;
420           }
421         }
422       }
423     }
424     //Resorting of theXYMap
425     TXYMapCont::iterator aXYMapContIter = aXYMapCont.begin();
426     for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
427       TXYMap& aXYMap = aXYMapContIter->second, aNewXYMap;
428       if(aXYMap.size() > 2){  
429         // Try to smooth the values of the line by applying linear approximation
430         TXYMap::const_iterator aXYMapIter[2] = {aXYMap.begin(), ++aXYMap.begin()};
431         aNewXYMap[aXYMapIter[0]->first] = aXYMapIter[0]->second;
432         aXCont.insert(aXYMapIter[0]->first);
433         for(; aXYMapIter[1] != aXYMap.end(); aXYMapIter[0]++, aXYMapIter[1]++){
434           float aY[3] = {aXYMapIter[0]->second, aXYMapIter[1]->second, 0.0};
435           aY[2] = (aY[0] + aY[1])/2.0;
436           float aX[3] = {aXYMapIter[0]->first, aXYMapIter[1]->first, 0.0};
437           aX[2] = (aX[0] + aX[1])/2.0;
438           aNewXYMap[aX[2]] = aY[2];
439           aXCont.insert(aX[2]);
440         }
441         aNewXYMap[aXYMapIter[0]->first] = aXYMapIter[0]->second;
442         aXCont.insert(aXYMapIter[0]->first);
443         aXYMap = aNewXYMap;
444       }else{
445         TXYMap::const_iterator aXYMapIter = aXYMap.begin();
446         for(; aXYMapIter != aXYMap.end(); aXYMapIter++)
447           aXCont.insert(aXYMapIter->first);
448       }
449     }
450     if(aXCont.size() == 0)
451       throw std::runtime_error("CutPlanes_i::BuildTableOfReal aXCont.size() == 0 !!!");
452     QString aString;
453     int iEnd = aXCont.size();
454     aTableOfReal->SetNbColumns(iEnd);
455     TXCont::const_iterator aXContIter = aXCont.begin();
456     for(long i = 0; aXContIter != aXCont.end(); aXContIter++, i++){
457       float aDist = *aXContIter; 
458       aTableOfReal->PutValue(aDist,1,i+1);
459       aString.sprintf("%d",i);
460       aTableOfReal->SetColumnTitle(i+1,aString.latin1());
461       if(MYDEBUG) MESSAGE("CutPlanes_i::BuildTableOfReal aDist = "<<aDist);
462       TXYMapCont::const_iterator aXYMapContIter = aXYMapCont.begin();
463       for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
464         long iLine = aXYMapContIter->first;
465         long iLineId = aLineIdCont[iLine];
466         const TXYMap& aXYMap = aXYMapCont[iLine];
467         TXYMap::const_iterator aXYMapIter = aXYMap.find(aDist);
468         // Can we find some value that belong to the line and have the same X coordinate?
469         if(aXYMapIter == aXYMap.end()) continue;
470         float aVal = aXYMapIter->second;
471         aTableOfReal->PutValue(aVal,iLineId+2,i+1);
472       }
473     }
474     {
475       aTableOfReal->SetRowTitle(1,"X");
476       aTableOfReal->SetRowUnit(1,"-");
477       QString aUnitName = myField->myUnitNames[0].c_str();
478       int aScalarMode = myCutLinesPL->GetScalarMode();
479       if(aScalarMode != 0) 
480         aUnitName = myField->myUnitNames[aScalarMode-1].c_str();
481       aUnitName = aUnitName.simplifyWhiteSpace();
482       if(aUnitName.isEmpty()) aUnitName = "-";
483       TXYMapCont::const_iterator aXYMapContIter = aXYMapCont.begin();
484       for(; aXYMapContIter != aXYMapCont.end(); aXYMapContIter++){
485         long iLine = aXYMapContIter->first;
486         long iLineId = aLineIdCont[iLine];
487         aString.sprintf("Y%d",iLine);
488         if(MYDEBUG) 
489           MESSAGE("CutPlanes_i::BuildTableOfReal - SetRowTitle("<<iLineId+2<<",'"<<aString<<"')");
490         aTableOfReal->SetRowTitle(iLineId+2,aString.latin1());
491         aTableOfReal->SetRowUnit(iLineId+2,aUnitName.latin1());
492       }
493     }
494   }catch(std::exception& exc){
495     INFOS("Follow exception was occured :\n"<<exc.what());
496   }catch (...){
497     INFOS("Unknown exception was occured !!!");
498   }
499 }