CCommandExecutor.cpp

Go to the documentation of this file.
00001 
00013 #include <cmath>
00014 #include <iostream>
00015 #include <string>
00016 #include <sstream>
00017 #include <vector>
00018 
00019 #include "popassert.h"
00020 #include "CVector3f.h"
00021 #include "CColor.h"
00022 #include "CImage.h"
00023 #include "CVectBase.h"
00024 #include "compute.h"
00025 #include "CMathExpression.h"
00026 #include "CRenderObj.h"
00027 #include "CCommand.h"
00028 #include "CCommandParser.h"
00029 #include "CCommandExecutor.h"
00030 
00031 
00032 // Static members
00033 const std::string HelpMessages[CCommand::PARAMETER_END+1] =
00034   {
00035     // PARAMETER_FORMULASTRING
00036     "The implicit equation of the surface to render.",
00037     // PARAMETER_SIGNINCREMENT
00038     "The step taken at each iteration in the signed mode.\n"
00039     "Lowering that value causes the rendering to be slower\n"
00040     "but more precise.\n"
00041     "\"help Sign\" for more info on the signed mode.",
00042     // PARAMETER_NOSIGNINCREMENT
00043     "The step taken at each iteration in the no signed mode.\n"
00044     "Lowering that value cause the rendering to be slower\n"
00045     "but more precise.\n"
00046     "\"help Sign\" for more info on the no signed mode.",
00047     // PARAMETER_NOSIGNPRECISION
00048     "The limit under which a floating point value is considered\n"
00049     "to be equal to zero.  It is used as the criterium to know\n"
00050     "if a point is on the surface in the no signed mode.\n"
00051     "\"help Sign\" for more info on the no signed mode.",
00052     // PARAMETER_ZOOM
00053     "The zoom factor of the camera.  If that value is set to 0,\n"
00054     "the camera is left in its position.  If the zoom is set to 1,\n"
00055     "the camera is placed so that all the viewing volume is seen.",
00056     // PARAMETER_MINVECTOR
00057     "The vector holding the minimum x, y and z value of the\n"
00058     "bouding box of the surface to be rendered.",
00059     // PARAMETER_MAXVECTOR
00060     "The vector holding the maximum x, y and z value of the\n"
00061     "bouding box of the surface to be rendered.",
00062     // PARAMETER_VIEWERPOS
00063     "The vector holding the position of the camera viewing\n"
00064     "the surface to be rendered.",
00065     // PARAMETER_LIGHTDIRECTION
00066     "The vector holding the direction of the directional light\n"
00067     "that is lightening the surface.",
00068     // PARAMETER_SURFACEAMBIENTCOLOR
00069     "The ambient color component of the surface.\n"
00070     "The color is in RGB with each component between 0 and 1.",
00071     // PARAMETER_SURFACEDIFFUSECOLOR
00072     "The diffuse color component of the surface.\n"
00073     "The color is in RGB with each component between 0 and 1.",
00074     // PARAMETER_SURFACESPECULARCOLOR
00075     "The specular color component of the surface.\n"
00076     "The color is in RGB with each component between 0 and 1.",
00077     // PARAMETER_SURFACESPECULAREXPONENT
00078     "The specular color exponent of the surface.\n"
00079     "It influences the specular highlights.",
00080     // PARAMETER_BOXAMBIENTCOLOR
00081     "The ambient color component of the bounding box.\n"
00082     "The color is in RGB with each component between 0 and 1.",
00083     // PARAMETER_BOXDIFFUSECOLOR
00084     "The diffuse color component of the bounding box.\n"
00085     "The color is in RGB with each component between 0 and 1.",
00086     // PARAMETER_BOXSPECULARCOLOR
00087     "The specular color component of the bounding box.\n"
00088     "The color is in RGB with each component between 0 and 1.",
00089     // PARAMETER_BOXSPECULAREXPONENT
00090     "The specular color exponent of the box.\n"
00091     "It influences the specular highlights.",
00092     // PARAMETER_BACKGROUNDCOLOR
00093     "The background color of the scene.\n"
00094     "The color is in RGB with each component between 0 and 1.",
00095     // PARAMETER_WIDTH
00096     "The width of the picture that will be rendering, in pixels.",
00097     // PARAMETER_HEIGHT
00098     "The height of the picture that will be rendering, in pixels.",
00099     // PARAMETER_PERSPECTIVE
00100     "Option to choose to use perspective or orthonormal projection.\n"
00101     "usage: set Perspective {on,off}",
00102     // PARAMETER_BOUNDINGBOX
00103     "Option to choose to draw the bounding box or not.\n"
00104     "usage: set BoundingBox {on,off}",
00105     // PARAMETER_SIGN
00106     "Option to choose between the signed mode and the no signed mode.\n"
00107     "The signed mode uses the signed of the expression f(x,y,z )to\n"
00108     "know if the ray hit the surface.  When the sign changes, there\n"
00109     "is a hit.  The no signed mode uses a threshold under which\n"
00110     "f(x,y,z) is considered to be equal to zero, so that the ray hit\n"
00111     "the surface.\n"
00112     "usage: set Sign {on,off}",
00113     // PARAMETER_OPENGLSPECULAR
00114     "Option to choose between OpenGL specular lighting calculation\n"
00115     "and normal ray-tracing specular lighting."
00116     "usage: set OpenGLSpecular {on,off}",
00117     // PARAMETER_END
00118     "Commands: help  : help on a topic\n"
00119     "          run   : launches the tracing\n"
00120     "          set   : sets a parameter\n"
00121     "          print : prints the value of a parameter\n"
00122     "          quit  : exit the program\n"
00123     "\n"
00124     "Parameters: FormulaString\n"
00125     "            SignIncrement\n"
00126     "            NoSignIncrement\n"
00127     "            NoSignPrecision\n"
00128     "            Zoom\n"
00129     "            MinVector\n"
00130     "            MaxVector\n"
00131     "            ViewerPos\n"
00132     "            LightDirection\n"
00133     "            SurfaceAmbientColor\n"
00134     "            SurfaceDiffuseColor\n"
00135     "            SurfaceSpecularColor\n"
00136     "            SurfaceSpecularExponent\n"
00137     "            BoxAmbientColor\n"
00138     "            BoxDiffuseColor\n"
00139     "            BoxSpecularColor\n"
00140     "            SurfaceSpecularExponent\n"
00141     "            BackgroundColor\n"
00142     "            Width\n"
00143     "            Height\n"
00144     "\n"
00145     "            Perspective\n"
00146     "            BoundingBox\n"
00147     "            Sign\n"
00148     "            OpenGLSpecular"
00149   };
00150 
00151 
00152 CCommandExecutor* CCommandExecutor::s_pInstance = NULL;
00153 
00158 #ifdef WIN32
00159 
00160 #include <fstream>
00161 
00162 bool CCommandExecutor::FileExist(const std::string& FileName)
00163 {
00164   std::ifstream File;
00165   bool Exist;
00166 
00167   File.open(FileName.c_str());
00168   Exist = !(File.fail());
00169   File.close();
00170 
00171   return(Exist);
00172 }
00173 
00174 #elif defined(LINUX)
00175 
00176 #include <sys/types.h>
00177 #include <sys/stat.h>
00178 
00179 bool CCommandExecutor::FileExist(const std::string& FileName)
00180 {
00181   struct stat TempStruct;
00182   return (!stat(FileName.c_str(), &TempStruct));
00183 }
00184 
00185 #else
00186 #error "OS not supported"
00187 #endif
00188 
00189 
00190 
00191 
00196 void CCommandExecutor::Execute(const CCommand& command,
00197                                CRenderObj& surfaceobj) const
00198 {
00199   switch (command.m_CommandID)
00200     {
00202       //                  //
00203       //  "help" command  //
00204       //                  //
00206     case CCommand::COMMAND_HELP:
00207       {
00208         std::cout << HelpMessages[command.m_ParameterID] << std::endl;
00209         break;
00210       }
00211 
00213       //                 //
00214       //  "run" command  //
00215       //                 //
00217     case CCommand::COMMAND_RUN:
00218       {
00219         std::string strParameterCheck = surfaceobj.Validate();
00220 
00221         if (strParameterCheck != "")
00222           {
00223             std::cout << "Ray tracing not started." << std::endl
00224                       << strParameterCheck << std::endl;
00225             break;
00226           }
00227 
00228         bool ReadyToGo = false;
00229         std::string Answer_1, Answer_2;
00230 
00231           while(!ReadyToGo)
00232             {
00233               std::cout << "Enter the name of the BMP file to create."
00234                         << std::endl;
00235               GetLine(std::cin, Answer_1);
00236 
00237               if (Answer_1 == "")
00238                 {
00239                   std::cout << "Please write a non empty name." << std::endl;
00240                   continue;
00241                 }
00242               else
00243                 {
00244                   if (FileExist(Answer_1))
00245                     {
00246                       std::cout << "This file exists.  Overwrite? (yes, no, cancel)"
00247                                 << std::endl;
00248                       GetLine(std::cin, Answer_2);
00249 
00250                       if ( Answer_2 == "y"  ||
00251                            Answer_2 == "ye" || 
00252                            Answer_2 == "yes"  )
00253                         {
00254                           ReadyToGo = true;
00255                         }
00256                       else if ( Answer_2 == "n" ||
00257                                 Answer_2 == "no"  )
00258                         {
00259                           continue;
00260                         }
00261                       else
00262                         {
00263                           std::cout << "Canceled" << std::endl;
00264                           break;
00265                         }
00266                     }
00267                   else
00268                     {
00269                       ReadyToGo = true;
00270                     }
00271                 }
00272             }
00273 
00274           if (ReadyToGo)
00275             {
00276               surfaceobj.Update();
00277               CColor TempColor;
00278               CImage image(surfaceobj.m_Width, surfaceobj.m_Height);
00279 
00280               std::cout << "Ray tracing started" << std::endl;
00281               for (int j = surfaceobj.m_Height - 1; j >= 0; --j)
00282                 for (int i = surfaceobj.m_Width - 1; i >= 0; --i)
00283                   {
00284                     TempColor = surfaceobj.GetPixelColor(i, j);
00285                     TempColor.Clamp();
00286 
00287                     image(i,j,0) = TempColor[0];
00288                     image(i,j,1) = TempColor[1];
00289                     image(i,j,2) = TempColor[2];
00290                   }
00291               std::cout << "Ray tracing completed" << std::endl;
00292 
00293               std::cout << "File writing started" << std::endl;
00294 
00295               switch( image.WriteBmpFile(Answer_1) )
00296                 {
00297                 case 0:
00298                   {
00299                     std::cout << "File writing completed" << std::endl
00300                               << "Job done" << std::endl;
00301                     break;
00302                   }
00303                 case -1:
00304                   {
00305                     std::cout << "Error: unable to open file '"
00306                               << Answer_1 << "'" << std::endl;
00307                     break;
00308                   }
00309                 default:
00310                   {
00311                     std::cout << "Error occured while writing to file"
00312                               << std::endl;
00313                     break;
00314                   }
00315                 }
00316             }
00317 
00318           break;
00319       }
00320 
00322       //                 //
00323       //  "set" command  //
00324       //                 //
00326     case CCommand::COMMAND_SET:
00327       {
00328         switch (command.m_ParameterID)
00329           {
00330           case CCommand::PARAMETER_FORMULASTRING:
00331             {
00332               surfaceobj.m_FormulaString = *command.m_pData.String;
00333               delete command.m_pData.String;
00334               break;
00335             }
00336           case CCommand::PARAMETER_SIGNINCREMENT:
00337             {
00338               surfaceobj.m_SignIncrement = *command.m_pData.Float;
00339               delete command.m_pData.Float;
00340               break;
00341             }
00342           case CCommand::PARAMETER_NOSIGNINCREMENT:
00343             {
00344               surfaceobj.m_NoSignIncrement = *command.m_pData.Float;
00345               delete command.m_pData.Float;
00346               break;
00347             }
00348           case CCommand::PARAMETER_NOSIGNPRECISION:
00349             {
00350               surfaceobj.m_NoSignPrecision = *command.m_pData.Float;
00351               delete command.m_pData.Float;
00352               break;
00353             }
00354           case CCommand::PARAMETER_ZOOM:
00355             {
00356               surfaceobj.m_Zoom = *command.m_pData.Float;
00357               delete command.m_pData.Float;
00358               break;
00359             }
00360           case CCommand::PARAMETER_MINVECTOR:
00361             {
00362               surfaceobj.m_MinVector = *command.m_pData.Vector;
00363               delete command.m_pData.Vector;
00364               break;
00365             }
00366           case CCommand::PARAMETER_MAXVECTOR:
00367             {
00368               surfaceobj.m_MaxVector = *command.m_pData.Vector;
00369               delete command.m_pData.Vector;
00370               break;
00371             }
00372           case CCommand::PARAMETER_VIEWERPOS:
00373             {
00374               surfaceobj.m_ViewerPos = *command.m_pData.Vector;
00375               delete command.m_pData.Vector;
00376               break;
00377             }
00378           case CCommand::PARAMETER_LIGHTDIRECTION:
00379             {
00380               surfaceobj.m_LightDirection = *command.m_pData.Vector;
00381               delete command.m_pData.Vector;
00382               break;
00383             }
00384           case CCommand::PARAMETER_SURFACEAMBIENTCOLOR:
00385             {
00386               surfaceobj.m_SurfaceAmbientColor = *command.m_pData.Color;
00387               delete command.m_pData.Color;
00388               break;
00389             }
00390           case CCommand::PARAMETER_SURFACEDIFFUSECOLOR:
00391             {
00392               surfaceobj.m_SurfaceDiffuseColor = *command.m_pData.Color;
00393               delete command.m_pData.Color;
00394               break;
00395             }
00396           case CCommand::PARAMETER_SURFACESPECULARCOLOR:
00397             {
00398               surfaceobj.m_SurfaceSpecularColor = *command.m_pData.Color;
00399               delete command.m_pData.Color;
00400               break;
00401             }
00402           case CCommand::PARAMETER_SURFACESPECULAREXPONENT:
00403             {
00404               surfaceobj.m_SurfaceSpecularExponent = *command.m_pData.Float;
00405               delete command.m_pData.Float;
00406               break;
00407             }
00408           case CCommand::PARAMETER_BOXAMBIENTCOLOR:
00409             {
00410               surfaceobj.m_BoxAmbientColor = *command.m_pData.Color;
00411               delete command.m_pData.Color;
00412               break;
00413             }
00414           case CCommand::PARAMETER_BOXDIFFUSECOLOR:
00415             {
00416               surfaceobj.m_BoxDiffuseColor = *command.m_pData.Color;
00417               delete command.m_pData.Color;
00418               break;
00419             }
00420           case CCommand::PARAMETER_BOXSPECULARCOLOR:
00421             {
00422               surfaceobj.m_BoxSpecularColor = *command.m_pData.Color;
00423               delete command.m_pData.Color;
00424               break;
00425             }
00426           case CCommand::PARAMETER_BOXSPECULAREXPONENT:
00427             {
00428               surfaceobj.m_BoxSpecularExponent = *command.m_pData.Float;
00429               delete command.m_pData.Float;
00430               break;
00431             }
00432           case CCommand::PARAMETER_BACKGROUNDCOLOR:
00433             {
00434               surfaceobj.m_BackgroundColor = *command.m_pData.Color;
00435               delete command.m_pData.Color;
00436               break;
00437             }
00438           case CCommand::PARAMETER_WIDTH:
00439             {
00440               surfaceobj.m_Width = *command.m_pData.Int;
00441               delete command.m_pData.Int;
00442               break;
00443             }
00444           case CCommand::PARAMETER_HEIGHT:
00445             {
00446               surfaceobj.m_Height = *command.m_pData.Int;
00447               delete command.m_pData.Int;
00448               break;
00449             }
00450           case CCommand::PARAMETER_PERSPECTIVE:
00451             {
00452               if (*command.m_pData.String == "on")
00453                 {
00454                   surfaceobj.m_Options = surfaceobj.m_Options | OPTION_PERSPECTIVE;
00455                 }
00456               else if (*command.m_pData.String == "off")
00457                 {
00458                   surfaceobj.m_Options = surfaceobj.m_Options & ~OPTION_PERSPECTIVE;
00459                 }
00460               else
00461                 {
00462                   std::cout << "Parameter error: usage: set Perspective {on,off}"
00463                             << std::endl;
00464                 }
00465 
00466               delete command.m_pData.String;
00467               break;
00468             }
00469           case CCommand::PARAMETER_BOUNDINGBOX:
00470             {
00471               if (*command.m_pData.String == "on")
00472                 {
00473                   surfaceobj.m_Options = surfaceobj.m_Options | OPTION_BOUNDINGBOX;
00474                 }
00475               else if (*command.m_pData.String == "off")
00476                 {
00477                   surfaceobj.m_Options = surfaceobj.m_Options & ~OPTION_BOUNDINGBOX;
00478                 }
00479               else
00480                 {
00481                   std::cout << "Parameter error: usage: set BoundingBox {on,off}"
00482                             << std::endl;
00483                 }
00484 
00485               delete command.m_pData.String;
00486               break;
00487             }
00488           case CCommand::PARAMETER_SIGN:
00489             {
00490               if (*command.m_pData.String == "on")
00491                 {
00492                   surfaceobj.m_Options = surfaceobj.m_Options | OPTION_SIGN;
00493                 }
00494               else if (*command.m_pData.String == "off")
00495                 {
00496                   surfaceobj.m_Options = surfaceobj.m_Options & ~OPTION_SIGN;
00497                 }
00498               else
00499                 {
00500                   std::cout << "Parameter error: usage: set Sign {on,off}"
00501                             << std::endl;
00502                 }
00503 
00504               delete command.m_pData.String;
00505               break;
00506             }
00507           case CCommand::PARAMETER_OPENGLSPECULAR:
00508             {
00509               if (*command.m_pData.String == "on")
00510                 {
00511                   surfaceobj.m_Options = surfaceobj.m_Options | OPTION_OPENGLSPECULAR;
00512                 }
00513               else if (*command.m_pData.String == "off")
00514                 {
00515                   surfaceobj.m_Options = surfaceobj.m_Options & ~OPTION_OPENGLSPECULAR;
00516                 }
00517               else
00518                 {
00519                   std::cout << "Parameter error: usage: set OpenGLSpecular {on,off}"
00520                             << std::endl;
00521                 }
00522 
00523               delete command.m_pData.String;
00524               break;
00525             }
00526           default:
00527             {
00528               POP_ILLEGAL("Not supposed to get here");
00529             }
00530           }
00531 
00532         break;
00533       }
00534 
00536       //                   //
00537       //  "print" command  //
00538       //                   //
00540     case CCommand::COMMAND_PRINT:
00541       {
00542         switch (command.m_ParameterID)
00543           {
00544           case CCommand::PARAMETER_FORMULASTRING:
00545             {
00546               std::cout << surfaceobj.m_FormulaString << std::endl;
00547               break;
00548             }
00549           case CCommand::PARAMETER_SIGNINCREMENT:
00550             {
00551               std::cout << surfaceobj.m_SignIncrement << std::endl;
00552               break;
00553             }
00554           case CCommand::PARAMETER_NOSIGNINCREMENT:
00555             {
00556               std::cout << surfaceobj.m_NoSignIncrement << std::endl;
00557               break;
00558             }
00559           case CCommand::PARAMETER_NOSIGNPRECISION:
00560             {
00561               std::cout << surfaceobj.m_NoSignPrecision << std::endl;
00562               break;
00563             }
00564           case CCommand::PARAMETER_ZOOM:
00565             {
00566               std::cout << surfaceobj.m_Zoom << std::endl;
00567               break;
00568             }
00569           case CCommand::PARAMETER_MINVECTOR:
00570             {
00571               std::cout << surfaceobj.m_MinVector << std::endl;
00572               break;
00573             }
00574           case CCommand::PARAMETER_MAXVECTOR:
00575             {
00576               std::cout << surfaceobj.m_MaxVector << std::endl;
00577               break;
00578             }
00579           case CCommand::PARAMETER_VIEWERPOS:
00580             {
00581               std::cout << surfaceobj.m_ViewerPos << std::endl;
00582               break;
00583             }
00584           case CCommand::PARAMETER_LIGHTDIRECTION:
00585             {
00586               std::cout << surfaceobj.m_LightDirection << std::endl;
00587               break;
00588             }
00589           case CCommand::PARAMETER_SURFACEAMBIENTCOLOR:
00590             {
00591               std::cout << surfaceobj.m_SurfaceAmbientColor << std::endl;
00592               break;
00593             }
00594           case CCommand::PARAMETER_SURFACEDIFFUSECOLOR:
00595             {
00596               std::cout << surfaceobj.m_SurfaceDiffuseColor << std::endl;
00597               break;
00598             }
00599           case CCommand::PARAMETER_SURFACESPECULARCOLOR:
00600             {
00601               std::cout << surfaceobj.m_SurfaceSpecularColor << std::endl;
00602               break;
00603             }
00604           case CCommand::PARAMETER_SURFACESPECULAREXPONENT:
00605             {
00606               std::cout << surfaceobj.m_SurfaceSpecularExponent << std::endl;
00607               break;
00608             }
00609           case CCommand::PARAMETER_BOXAMBIENTCOLOR:
00610             {
00611               std::cout << surfaceobj.m_BoxAmbientColor << std::endl;
00612               break;
00613             }
00614           case CCommand::PARAMETER_BOXDIFFUSECOLOR:
00615             {
00616               std::cout << surfaceobj.m_BoxDiffuseColor << std::endl;
00617               break;
00618             }
00619           case CCommand::PARAMETER_BOXSPECULARCOLOR:
00620             {
00621               std::cout << surfaceobj.m_BoxSpecularColor << std::endl;
00622               break;
00623             }
00624           case CCommand::PARAMETER_BOXSPECULAREXPONENT:
00625             {
00626               std::cout << surfaceobj.m_BoxSpecularExponent << std::endl;
00627               break;
00628             }
00629           case CCommand::PARAMETER_BACKGROUNDCOLOR:
00630             {
00631               std::cout << surfaceobj.m_BackgroundColor << std::endl;
00632               break;
00633             }
00634           case CCommand::PARAMETER_WIDTH:
00635             {
00636               std::cout << surfaceobj.m_Width << std::endl;
00637               break;
00638             }
00639           case CCommand::PARAMETER_HEIGHT:
00640             {
00641               std::cout << surfaceobj.m_Height << std::endl;
00642               break;
00643             }
00644           case CCommand::PARAMETER_PERSPECTIVE:
00645             {
00646               std::cout << ((surfaceobj.m_Options & OPTION_PERSPECTIVE) ? "on" : "off")
00647                         << std::endl;
00648               break;
00649             }
00650           case CCommand::PARAMETER_BOUNDINGBOX:
00651             {
00652               std::cout << ((surfaceobj.m_Options & OPTION_BOUNDINGBOX) ? "on" : "off")
00653                         << std::endl;
00654               break;
00655             }
00656           case CCommand::PARAMETER_SIGN:
00657             {
00658               std::cout << ((surfaceobj.m_Options & OPTION_SIGN) ? "on" : "off")
00659                         << std::endl;
00660               break;
00661             }
00662           case CCommand::PARAMETER_OPENGLSPECULAR:
00663             {
00664               std::cout << ((surfaceobj.m_Options & OPTION_OPENGLSPECULAR) ? "on" : "off")
00665                         << std::endl;
00666               break;
00667             }
00668           case CCommand::PARAMETER_END:
00669             {
00670               // print all
00671               CCommand FakeCommand;
00672               FakeCommand.m_CommandID = CCommand::COMMAND_PRINT;
00673 
00674               for (int i = 0; i < CCommand::PARAMETER_END; ++i)
00675                 {
00676                   std::cout << CCommand::s_ParameterString[i] << ": ";
00677                   FakeCommand.m_ParameterID = (CCommand::TYPE_PARAMETER) i;
00678                   Execute(FakeCommand, surfaceobj);
00679                 }
00680 
00681               break;
00682             }
00683           default:
00684             {
00685               POP_ILLEGAL("Not supposed to get here");
00686             }
00687           }
00688 
00689         break;
00690       }
00691 
00693       //                  //
00694       //  "quit" command  //
00695       //                  //
00697     case CCommand::COMMAND_QUIT:
00698       {
00699         std::cout << "Thanks for using MathRay." << std::endl;
00700         exit(0);
00701         break;
00702       }
00703 
00704     case CCommand::COMMAND_END:
00705       {
00706         std::cout << "type 'help' for more info" << std::endl;
00707         break;
00708       }
00709 
00710     default:
00711       {
00712         POP_ILLEGAL("Not supposed to get here");
00713       }
00714     }
00715 }
00716 
00717 

Generated on Fri Dec 5 03:20:33 2008 for Mathematical Ray-tracer by  doxygen 1.5.4