"Fossies" - the Fresh Open Source Software Archive

Member "mathmod-branches-r508-trunk/pariso/parametric/Model3D.cpp" (8 Mar 2021, 83817 Bytes) of package /linux/misc/mathmod-11.0-source.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "Model3D.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 10.1_vs_11.0.

    1 /***************************************************************************
    2  *   Copyright (C) 2021 by Abderrahman Taha                                *
    3  *                                                                         *
    4  *                                                                         *
    5  *   This program is free software; you can redistribute it and/or modify  *
    6  *   it under the terms of the GNU General Public License as published by  *
    7  *   the Free Software Foundation; either version 2 of the License, or     *
    8  *   (at your option) any later version.                                   *
    9  *                                                                         *
   10  *   This program is distributed in the hope that it will be useful,       *
   11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
   12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
   13  *   GNU General Public License for more details.                          *
   14  *                                                                         *
   15  *   You should have received a copy of the GNU General Public License     *
   16  *   along with this program; if not, write to the                         *
   17  *   Free Software Foundation, Inc.,                                       *
   18  *   51 Franklin Street, Fifth Floor,Boston, MA 02110-1301 USA             *
   19  ***************************************************************************/
   20 #include "Model3D.h"
   21 #include <QElapsedTimer>
   22 
   23 static uint NbVertexTmp = 0;
   24 static std::vector<float>  ExtraDimensionVector;
   25 static CellNoise *NoiseFunction2 = new CellNoise();
   26 static ImprovedNoise *PNoise2 = new ImprovedNoise(4., 4., 4.);
   27 static double ParamComponentId=0;
   28 static double ParamThreadId=0;
   29 static QElapsedTimer ptime;
   30 
   31 double CurrentParamCmpId(const double* p)
   32 {
   33     int pp = int(p[0]);
   34     if(pp==0)
   35         return ParamComponentId;
   36     else
   37         return ParamThreadId;
   38 }
   39 double TurbulenceWorley2(const double* p)
   40 {
   41     return double(NoiseFunction2->CellNoiseFunc(
   42                       float(p[0]),
   43                       float(p[1]),
   44                       float(p[2]),
   45                       int(p[3]),
   46                       int(p[4]),
   47                       int(p[5])));
   48 }
   49 double TurbulencePerlin2(const double* p)
   50 {
   51     return double(PNoise2->FractalNoise3D(
   52                       float(p[0]),
   53                       float(p[1]),
   54                       float(p[2]),
   55                       int(p[3]),
   56                       float(p[4]),
   57                       float(p[5])));
   58 }
   59 Par3D::~Par3D()
   60 {
   61 }
   62 void Par3D::emitUpdateMessageSignal()
   63 {
   64     emit UpdateMessageSignal(message);
   65 }
   66 ParWorkerThread::ParWorkerThread()
   67 {
   68     stepMorph = 0;
   69     pace = 1.0/30.0;
   70     ParsersAllocated = false;
   71 }
   72 ParWorkerThread::~ParWorkerThread()
   73 {
   74 }
   75 ParMasterThread::~ParMasterThread()
   76 {
   77     delete[] UsedFunct;
   78     delete[] UsedFunct2;
   79 
   80     ParamStructs.clear();
   81     SliderValues.clear();
   82     SliderNames.clear();
   83     Rgbts.clear();
   84     RgbtNames.clear();
   85     VRgbts.clear();
   86     VRgbtNames.clear();
   87     Functs.clear();
   88     FunctNames.clear();
   89     Consts.clear();
   90     ConstNames.clear();
   91     ConstValues.clear();
   92 }
   93 
   94 ParMasterThread::ParMasterThread()
   95 {
   96     activeMorph = -1;
   97     ParisoCondition = -1;
   98     Nb_Sliders = 0;
   99     Gain = 1.0;
  100     Octaves = 4;
  101     Lacunarity = 0.5;
  102     UsedFunct    = new bool[0];
  103     UsedFunct2   = new bool[0];
  104 }
  105 
  106 Par3D::Par3D(uint nbThreads, uint nbGrid)
  107 {
  108     initialiser_parametres(nbThreads, nbGrid);
  109 }
  110 
  111 void ParWorkerThread::run()
  112 {
  113     ParCompute(CurrentComponent, CurrentIndex);
  114 }
  115 
  116 void ParWorkerThread::ParCompute(uint fctnb, uint idx)
  117 {
  118     calcul_objet(fctnb, idx);
  119 }
  120 
  121 void Par3D::initialiser_parametres(uint nbThreads, uint nbGrid)
  122 {
  123     Ugrid = nbGrid;
  124     Vgrid = nbGrid;
  125     CutV = CutU = 0;
  126     tetazw = tetaxy =  tetaxz = tetayz = tetaxw = tetayw =  0;
  127     tetazw_ok = tetaxy_ok =  tetaxz_ok = tetayz_ok = tetaxw_ok = tetayw_ok =  param4D = -1;
  128     // initialisation des matrices 4D
  129     mat4D                     = Matrix4D();
  130     mat_rotation4D            = Matrix4D();
  131     mat_rotation_save4D       = Matrix4D();
  132     mat_homothetie4D          = Matrix4D();
  133     mat_translation4D         = Matrix4D();
  134     mat_inversetranslation4D  = Matrix4D();
  135     mat4D.unit();
  136 
  137     WorkerThreadsNumber = nbThreads;
  138     workerthreads = new ParWorkerThread[WorkerThreadsNumber-1];
  139     masterthread  = new ParMasterThread();
  140 
  141     masterthread->Ugrid  = Ugrid;
  142     masterthread->Vgrid = Vgrid;
  143     masterthread->MyIndex   = 0;
  144     masterthread->param4D   = param4D;
  145     masterthread->WorkerThreadsNumber = WorkerThreadsNumber;
  146 
  147     for(uint nbthreads=0; nbthreads+1<WorkerThreadsNumber; nbthreads++)
  148     {
  149         workerthreads[nbthreads].Ugrid  = Ugrid;
  150         workerthreads[nbthreads].Vgrid = Vgrid;
  151         workerthreads[nbthreads].MyIndex   = nbthreads+1;
  152         workerthreads[nbthreads].param4D   = param4D;
  153         workerthreads[nbthreads].WorkerThreadsNumber = WorkerThreadsNumber;
  154     }
  155 }
  156 
  157 void Par3D::initialiser_LineColumn(uint li, uint cl)
  158 {
  159     Ugrid  = li;
  160     Vgrid = cl;
  161     masterthread->Ugrid  = Ugrid;
  162     masterthread->Vgrid = Vgrid;
  163     for(uint nbthreads=0; nbthreads+1<WorkerThreadsNumber; nbthreads++)
  164     {
  165         workerthreads[nbthreads].Ugrid  = Ugrid;
  166         workerthreads[nbthreads].Vgrid = Vgrid;
  167     }
  168 }
  169 
  170 void  Par3D::rotation4()
  171 {
  172     mat_rotation4D.unit();
  173     // Construction de la matrice de trnsformation
  174     if(tetaxy_ok == 1)    mat_rotation4D.xyrot(tetaxy);
  175     if(tetaxz_ok == 1)    mat_rotation4D.xzrot(tetaxz);
  176     if(tetayz_ok == 1)    mat_rotation4D.yzrot(tetayz);
  177     if(param4D == 1)
  178     {
  179         if(tetaxw_ok == 1)    mat_rotation4D.xwrot(tetaxw);
  180         if(tetayw_ok == 1)    mat_rotation4D.ywrot(tetayw);
  181         if(tetazw_ok == 1)    mat_rotation4D.zwrot(tetazw);
  182     }
  183 // On applique cette transformation a la matrice principale "mat"
  184     mat4D.mult(mat_rotation4D);
  185 }
  186 
  187 void  Par3D::boite_englobante4D(uint idx)
  188 {
  189     MINX =1000000000000.0;
  190     MINY =MINX;
  191     MINZ =MINX;
  192     MINW =MINX;
  193 
  194     MAXX =-MINX;
  195     MAXY =-MINX;
  196     MAXZ =-MINX;
  197     MAXW =-MINX;
  198 
  199     uint IDX = 0;
  200     for (uint i=0; i < Ugrid; i++)
  201         for (uint j=0; j < Vgrid; j++)
  202         {
  203             if(MINX > NormVertexTabVector[IDX+idx*10+7] ) MINX = NormVertexTabVector[IDX+idx*10+7];
  204             if(MINY > NormVertexTabVector[IDX+idx*10+8] ) MINY = NormVertexTabVector[IDX+idx*10+8];
  205             if(MINZ > NormVertexTabVector[IDX+idx*10+9] ) MINZ = NormVertexTabVector[IDX+idx*10+9];
  206             if(MINW > ExtraDimensionVector[i*Vgrid + j + idx] ) MINW = ExtraDimensionVector[i*Vgrid + j + idx];
  207 
  208             if(MAXX < NormVertexTabVector[IDX+idx*10+7] ) MAXX = NormVertexTabVector[IDX+idx*10+7];
  209             if(MAXY < NormVertexTabVector[IDX+idx*10+8] ) MAXY = NormVertexTabVector[IDX+idx*10+8];
  210             if(MAXZ < NormVertexTabVector[IDX+idx*10+9] ) MAXZ = NormVertexTabVector[IDX+idx*10+9];
  211             if(MAXW < ExtraDimensionVector[i*Vgrid + j + idx] ) MAXW = ExtraDimensionVector[i*Vgrid + j + idx];
  212             IDX+=10;
  213         }
  214 
  215     DIFX = MAXX - MINX ;
  216     DIFY = MAXY - MINY ;
  217     DIFZ = MAXZ - MINZ ;
  218     DIFW = MAXW - MINW ;
  219 // Recherche du maximum :
  220     DIFMAXIMUM = DIFX;
  221     if (DIFY > DIFMAXIMUM)
  222     {
  223         DIFMAXIMUM = DIFY;
  224     }
  225     if (DIFZ > DIFMAXIMUM)
  226     {
  227         DIFMAXIMUM = DIFZ;
  228     }
  229     if (DIFW > DIFMAXIMUM)
  230     {
  231         DIFMAXIMUM = DIFW;
  232     }
  233 // On va inclure cet objet dans un HperCube de langueur maximum
  234 // egale a "hauteur_fenetre"
  235 
  236     float decalage_xo  = -(MINX +MAXX)/2 ;
  237     float decalage_yo  = -(MINY +MAXY)/2 ;
  238     float decalage_zo  = -(MINZ +MAXZ)/2 ;
  239     float decalage_wo  = -(MINW +MAXW)/2 ;
  240     IDX =0;
  241     for (uint i=0; i < Ugrid   ; i++)
  242         for (uint j=0; j < Vgrid   ; j++)
  243         {
  244             NormVertexTabVector[IDX+idx*10+7] = (NormVertexTabVector[IDX+idx*10+7] + decalage_xo)/DIFMAXIMUM ;
  245             NormVertexTabVector[IDX+idx*10+8] = (NormVertexTabVector[IDX+idx*10+8] + decalage_yo)/DIFMAXIMUM ;
  246             NormVertexTabVector[IDX+idx*10+9] = (NormVertexTabVector[IDX+idx*10+9] + decalage_zo)/DIFMAXIMUM ;
  247             ExtraDimensionVector[i*Vgrid + j + idx] = (ExtraDimensionVector[i*Vgrid + j + idx] + decalage_wo)/DIFMAXIMUM ;
  248             IDX+=10;
  249         }
  250 }
  251 
  252 void  Par3D::Invert_boite_englobante4D(uint idx)
  253 {
  254     float decalage_xo  = -(MINX +MAXX)/2;
  255     float decalage_yo  = -(MINY +MAXY)/2;
  256     float decalage_zo  = -(MINZ +MAXZ)/2;
  257     uint IDX =0;
  258     for (uint i=0; i < Ugrid   ; i++)
  259         for (uint j=0; j < Vgrid   ; j++)
  260         {
  261             NormVertexTabVector[IDX+idx*10+7] = (NormVertexTabVector[IDX+idx*10+7]*DIFMAXIMUM -  decalage_xo);
  262             NormVertexTabVector[IDX+idx*10+8] = (NormVertexTabVector[IDX+idx*10+8]*DIFMAXIMUM -  decalage_yo);
  263             NormVertexTabVector[IDX+idx*10+9] = (NormVertexTabVector[IDX+idx*10+9]*DIFMAXIMUM -  decalage_zo);
  264             IDX+=10;
  265         }
  266 }
  267 
  268 void Par3D::Anim_Rot4D (uint idx)
  269 {
  270     rotation4();
  271     calcul_points4(idx);
  272     if(param4D == 1)// On applique la rotation 4D
  273     {
  274         boite_englobante4D(idx);
  275         project_4D_to_3D(idx);
  276     }
  277     Invert_boite_englobante4D(idx);
  278 }
  279 
  280 void  Par3D::calcul_points4(uint idx)
  281 {
  282     double tp1, tp2, tp3, tp4;
  283     // Changement de coordonnees des points selon les
  284     // angles angex et angley
  285     uint lndex =0;
  286     for (uint i=0; i < Ugrid  ; i++)
  287         for (uint j=0; j < Vgrid   ; j++)
  288         {
  289             tp1 = double(NormVertexTabVector[lndex+idx*10+7]);
  290             tp2 = double(NormVertexTabVector[lndex+idx*10+8]);
  291             tp3 = double(NormVertexTabVector[lndex+idx*10+9]);
  292             tp4 = double(ExtraDimensionVector[i*Vgrid + j + idx]);
  293             if(param4D == 1)
  294             {
  295                 NormVertexTabVector[lndex+idx*10+7] = float(mat4D.xx*tp1 + mat4D.xy*tp2 + mat4D.xz*tp3 + mat4D.xw*tp4 + mat4D.xo);
  296                 NormVertexTabVector[lndex+idx*10+8] = float(mat4D.yx*tp1 + mat4D.yy*tp2 + mat4D.yz*tp3 + mat4D.yw*tp4 + mat4D.yo);
  297                 NormVertexTabVector[lndex+idx*10+9] = float(mat4D.zx*tp1 + mat4D.zy*tp2 + mat4D.zz*tp3 + mat4D.zw*tp4 + mat4D.zo);
  298                 ExtraDimensionVector[i*Vgrid + j + idx] = float(mat4D.wx*tp1 + mat4D.wy*tp2 + mat4D.wz*tp3 + mat4D.ww*tp4 + mat4D.wo);
  299             }
  300             else
  301             {
  302                 NormVertexTabVector[lndex+idx*10+7] = float(mat4D.xx*tp1 + mat4D.xy*tp2 + mat4D.xz*tp3 + mat4D.xo);
  303                 NormVertexTabVector[lndex+idx*10+8] = float(mat4D.yx*tp1 + mat4D.yy*tp2 + mat4D.yz*tp3 + mat4D.yo);
  304                 NormVertexTabVector[lndex+idx*10+9] = float(mat4D.zx*tp1 + mat4D.zy*tp2 + mat4D.zz*tp3 + mat4D.zo);
  305             }
  306             lndex += 10;
  307         }
  308 }
  309 
  310 void  Par3D::project_4D_to_3D(uint idx)
  311 {
  312     double c4;
  313     uint I = 0;
  314     for (uint i=0; i < Ugrid; ++i)
  315         for (uint j=0; j < Vgrid  ; ++j)
  316         {
  317             c4 = 1.0/double(ExtraDimensionVector[i*Vgrid + j + idx] - 2);
  318             NormVertexTabVector[I+idx*10+7] *= float(c4);
  319             NormVertexTabVector[I+idx*10+8] *= float(c4);
  320             NormVertexTabVector[I+idx*10+9] *= float(c4);
  321             I += 10;
  322         }
  323 }
  324 
  325 void ParMasterThread::AllocateParsersForMasterThread()
  326 {
  327     if(!ParsersAllocated)
  328     {
  329         myParserX = new FunctionParser[componentsNumber];
  330         myParserY = new FunctionParser[componentsNumber];
  331         myParserZ = new FunctionParser[componentsNumber];
  332         myParserW = new FunctionParser[componentsNumber];
  333         myParserUmin = new FunctionParser[componentsNumber];
  334         myParserVmin = new FunctionParser[componentsNumber];
  335         myParserUmax = new FunctionParser[componentsNumber];
  336         myParserVmax = new FunctionParser[componentsNumber];
  337         ParisoConditionParser  = new FunctionParser[componentsNumber];
  338         ParamStructs.resize(componentsNumber);
  339         v_inf.resize(componentsNumber);
  340         v_sup.resize(componentsNumber);
  341         u_inf.resize(componentsNumber);
  342         u_sup.resize(componentsNumber);
  343         dif_v.resize(componentsNumber);
  344         dif_u.resize(componentsNumber);
  345         if(!functnotnull)
  346             FunctSize = 0;
  347         Fct          = new FunctionParser[FunctSize];
  348         UsedFunct    = new bool[4*uint(componentsNumber)*FunctSize];
  349         UsedFunct2   = new bool[FunctSize*FunctSize];
  350 
  351         rgbtnotnull ?
  352         RgbtParser = new FunctionParser[(RgbtSize = 4)] :
  353         RgbtParser = new FunctionParser[(RgbtSize = 0)];
  354 
  355         vrgbtnotnull ?
  356         VRgbtParser = new FunctionParser[VRgbtSize] :
  357         VRgbtParser = new FunctionParser[(VRgbtSize = 0)];
  358 
  359         if(constnotnull)
  360             ConstSize=0;
  361 
  362         GradientParser   = new FunctionParser;
  363         NoiseParser      = new FunctionParser;
  364         NoiseShapeParser = new FunctionParser;
  365         ParsersAllocated = true;
  366     }
  367 }
  368 
  369 void ParWorkerThread::AllocateParsersForWorkerThread(uint nbcomposants, uint nbfunct)
  370 {
  371     if(!ParsersAllocated)
  372     {
  373         myParserX = new FunctionParser[nbcomposants];
  374         myParserY = new FunctionParser[nbcomposants];
  375         myParserZ = new FunctionParser[nbcomposants];
  376         myParserW = new FunctionParser[nbcomposants];
  377         Fct       = new FunctionParser[nbfunct];
  378         ParsersAllocated = true;
  379     }
  380 }
  381 
  382 void ParMasterThread::DeleteMasterParsers()
  383 {
  384     if(ParsersAllocated)
  385     {
  386         delete[] myParserX;
  387         delete[] myParserY;
  388         delete[] myParserZ;
  389         delete[] myParserW;
  390         delete[] myParserUmin;
  391         delete[] myParserVmin;
  392         delete[] myParserUmax;
  393         delete[] myParserVmax;
  394         delete[] ParisoConditionParser;
  395         delete[] Fct;
  396         delete[] UsedFunct;
  397         delete[] UsedFunct2;
  398         delete[] RgbtParser;
  399         delete[] VRgbtParser;
  400         delete GradientParser;
  401         delete NoiseParser;
  402         delete NoiseShapeParser;
  403         ParsersAllocated = false;
  404     }
  405 
  406     ParamStructs.clear();
  407     v_inf.clear();
  408     v_sup.clear();
  409     u_inf.clear();
  410     u_sup.clear();
  411     dif_v.clear();
  412     dif_u.clear();
  413     SliderValues.clear();
  414     SliderNames.clear();
  415     Rgbts.clear();
  416     RgbtNames.clear();
  417     VRgbts.clear();
  418     VRgbtNames.clear();
  419     Functs.clear();
  420     FunctNames.clear();
  421     Consts.clear();
  422     ConstNames.clear();
  423     ConstValues.clear();
  424 }
  425 
  426 void ParWorkerThread::DeleteWorkerParsers()
  427 {
  428     if(ParsersAllocated)
  429     {
  430         delete[] myParserX;
  431         delete[] myParserY;
  432         delete[] myParserZ;
  433         delete[] myParserW;
  434         delete[] Fct;
  435         ParsersAllocated = false;
  436     }
  437 }
  438 
  439 void ParMasterThread::InitMasterParsers()
  440 {
  441     DeleteMasterParsers();
  442     AllocateParsersForMasterThread();
  443 
  444     GradientParser->AddConstant("pi", PI);
  445     GradientParser->AddFunction("NoiseW",TurbulenceWorley2, 6);
  446     GradientParser->AddFunction("NoiseP",TurbulencePerlin2, 6);
  447     Cstparser.AddConstant("pi", PI);
  448     NoiseParser->AddConstant("pi", PI);
  449     NoiseParser->AddFunction("NoiseW",TurbulenceWorley2, 6);
  450     NoiseParser->AddFunction("NoiseP",TurbulencePerlin2, 6);
  451     NoiseParser->AddConstant("Lacunarity", Lacunarity);
  452     NoiseParser->AddConstant("Gain", Gain);
  453     NoiseParser->AddConstant("Octaves", Octaves);
  454     NoiseShapeParser->AddConstant("pi", PI);
  455     NoiseShapeParser->AddFunction("NoiseW",TurbulenceWorley2, 6);
  456     NoiseShapeParser->AddFunction("NoiseP",TurbulencePerlin2, 6);
  457 
  458     for(uint i=0; i<componentsNumber; i++)
  459     {
  460         myParserX[i].AddConstant("pi", PI);
  461         myParserY[i].AddConstant("pi", PI);
  462         myParserZ[i].AddConstant("pi", PI);
  463         myParserW[i].AddConstant("pi", PI);
  464         ParisoConditionParser[i].AddConstant("pi", PI);
  465         myParserUmin[i].AddConstant("pi", PI);
  466         myParserVmin[i].AddConstant("pi", PI);
  467         myParserUmax[i].AddConstant("pi", PI);
  468         myParserVmax[i].AddConstant("pi", PI);
  469 
  470         myParserX[i].AddFunction("NoiseW",TurbulenceWorley2, 6);
  471         myParserX[i].AddFunction("NoiseP",TurbulencePerlin2, 6);
  472         myParserY[i].AddFunction("NoiseW",TurbulenceWorley2, 6);
  473         myParserY[i].AddFunction("NoiseP",TurbulencePerlin2, 6);
  474         myParserZ[i].AddFunction("NoiseW",TurbulenceWorley2, 6);
  475         myParserZ[i].AddFunction("NoiseP",TurbulencePerlin2, 6);
  476         myParserW[i].AddFunction("NoiseW",TurbulenceWorley2, 6);
  477         myParserW[i].AddFunction("NoiseP",TurbulencePerlin2, 6);
  478         ParisoConditionParser[i].AddFunction("NoiseW",TurbulenceWorley2, 6);
  479         ParisoConditionParser[i].AddFunction("NoiseP",TurbulencePerlin2, 6);
  480     }
  481     for(uint i=0; i<RgbtSize; i++)
  482     {
  483         RgbtParser[i].AddConstant("pi", PI);
  484     }
  485     for(uint i=0; i<VRgbtSize; i++)
  486     {
  487         VRgbtParser[i].AddConstant("pi", PI);
  488     }
  489     for(uint i=0; i<FunctSize; i++)
  490     {
  491         Fct[i].AddConstant("pi", PI);
  492         Fct[i].AddFunction("CmpId",CurrentParamCmpId, 1);
  493     }
  494 }
  495 
  496 ErrorMessage  Par3D::ParMorph()
  497 {
  498     ErrorMessage err = masterthread->parse_expression();
  499     if(err.iErrorIndex < 0)
  500         ThreadParsersCopy();
  501     return err;
  502 }
  503 
  504 ErrorMessage  ParMasterThread::parse_expression()
  505 {
  506     double vals[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  507     std::string varliste = "x,y,z,t";
  508 
  509     InitMasterParsers();
  510 
  511     if(constnotnull)
  512     {
  513         ConstSize = HowManyVariables(Const, 1);
  514         for(uint j=0; j<ConstSize; j++)
  515         {
  516             if ((stdError.iErrorIndex = Cstparser.Parse(Consts[j],"u")) >= 0)
  517             {
  518                 stdError.strError = Consts[j];
  519                 return stdError;
  520             }
  521             ConstValues.push_back(Cstparser.Eval(vals));
  522             Cstparser.AddConstant(ConstNames[j], ConstValues[j]);
  523         }
  524     }
  525     else
  526     {
  527         ConstSize =0;
  528     }
  529     if(functnotnull)
  530     {
  531         FunctSize = HowManyVariables(Funct, 2);
  532 
  533         for(uint i=0; i<FunctSize; i++)
  534         {
  535             for(uint j=0; j<ConstSize; j++)
  536             {
  537                 Fct[i].AddConstant(ConstNames[j], ConstValues[j]);
  538             }
  539             //Add predefined constatnts:
  540             for(uint k=0; k<Nb_Sliders; k++)
  541             {
  542                 Fct[i].AddConstant(SliderNames[k], SliderValues[k]);
  543             }
  544         }
  545         for(uint i=0; i<FunctSize; i++)
  546         {
  547             for(uint j=0; j<i; j++)
  548                 if( (UsedFunct2[i*FunctSize+j]=(Functs[i].find(FunctNames[j]) != std::string::npos)))
  549                     Fct[i].AddFunction(FunctNames[j], Fct[j]);
  550             if ((stdError.iErrorIndex = Fct[i].Parse(Functs[i],"u,v,t")) >= 0)
  551             {
  552                 stdError.strError = Functs[i];
  553                 return stdError;
  554             }
  555             Fct[i].AllocateStackMemory(Stack_Factor);
  556         }
  557     }
  558     else
  559     {
  560         FunctSize =0;
  561     }
  562     //Colors
  563     if(rgbtnotnull)
  564     {
  565         RgbtSize = HowManyVariables(Rgbt, 3);
  566         for(uint i=0; i<RgbtSize; i++)
  567             for(uint j=0; j<ConstSize; j++)
  568             {
  569                 RgbtParser[i].AddConstant(ConstNames[j], ConstValues[j]);
  570                 for(uint k=0; k<Nb_Sliders; k++)
  571                     RgbtParser[i].AddConstant(SliderNames[k], SliderValues[k]);
  572             }
  573     }
  574     else
  575     {
  576         RgbtSize =0;
  577     }
  578     //Texture:
  579     if(vrgbtnotnull)
  580     {
  581         VRgbtSize = HowManyVariables(VRgbt, 4);
  582 
  583         GradientParser->AddFunction("NoiseW",TurbulenceWorley2, 6);
  584         GradientParser->AddFunction("NoiseP",TurbulencePerlin2, 6);
  585         for(uint j=0; j<ConstSize; j++)
  586         {
  587             GradientParser->AddConstant(ConstNames[j], ConstValues[j]);
  588             //Add predefined constatnts:
  589             for(uint k=0; k<Nb_Sliders; k++)
  590                 GradientParser->AddConstant(SliderNames[k], SliderValues[k]);
  591         }
  592 
  593         for(uint i=0; i<VRgbtSize; i++)
  594             for(uint j=0; j<ConstSize; j++)
  595             {
  596                 VRgbtParser[i].AddConstant(ConstNames[j], ConstValues[j]);
  597                 //Add predefined constatnts:
  598                 for(uint k=0; k<Nb_Sliders; k++)
  599                     VRgbtParser[i].AddConstant(SliderNames[k], SliderValues[k]);
  600             }
  601 
  602     }
  603     else
  604     {
  605         VRgbtSize =0;
  606     }
  607 
  608     if(Noise != "")
  609     {
  610         for(uint j=0; j<ConstSize; j++)
  611             NoiseParser->AddConstant(ConstNames[j], ConstValues[j]);
  612         NoiseParser->AddConstant("Lacunarity", Lacunarity);
  613         NoiseParser->AddConstant("Gain", Gain);
  614         NoiseParser->AddConstant("Octaves", Octaves);
  615         //Add predefined constatnts:
  616         for(uint k=0; k<Nb_Sliders; k++)
  617         {
  618             NoiseParser->AddConstant(SliderNames[k], SliderValues[k]);
  619         }
  620     }
  621 
  622     HowManyParamSurface(expression_X, 0);
  623     HowManyParamSurface(expression_Y, 1);
  624     HowManyParamSurface(expression_Z, 2);
  625     HowManyParamSurface(inf_u, 3);
  626     HowManyParamSurface(sup_u, 4);
  627     HowManyParamSurface(inf_v, 5);
  628     HowManyParamSurface(sup_v, 6);
  629     if(param4D == 1)
  630         HowManyParamSurface(expression_W, 7);
  631     if(cndnotnull)
  632     {
  633         ParisoCondition = 1;
  634         HowManyParamSurface(expression_CND, 8);
  635     }
  636     else
  637         ParisoCondition = -1;
  638 
  639     //Add defined constantes:
  640     for(uint i=0; i<componentsNumber; i++)
  641     {
  642         for(uint j=0; j<ConstSize; j++)
  643         {
  644             if(cndnotnull)
  645                 ParisoConditionParser[i].AddConstant(ConstNames[j], ConstValues[j]);
  646             myParserUmax[i].AddConstant(ConstNames[j], ConstValues[j]);
  647             myParserUmin[i].AddConstant(ConstNames[j], ConstValues[j]);
  648             myParserVmin[i].AddConstant(ConstNames[j], ConstValues[j]);
  649             myParserVmax[i].AddConstant(ConstNames[j], ConstValues[j]);
  650             myParserX[i].AddConstant(ConstNames[j], ConstValues[j]);
  651             myParserY[i].AddConstant(ConstNames[j], ConstValues[j]);
  652             myParserZ[i].AddConstant(ConstNames[j], ConstValues[j]);
  653             myParserW[i].AddConstant(ConstNames[j], ConstValues[j]);
  654         }
  655 
  656         //Add predefined constatnts:
  657         for(uint k=0; k<Nb_Sliders; k++)
  658         {
  659             if(cndnotnull)
  660                 ParisoConditionParser[i].AddConstant(SliderNames[k], SliderValues[k]);
  661             myParserUmin[i].AddConstant(SliderNames[k], SliderValues[k]);
  662             myParserUmax[i].AddConstant(SliderNames[k], SliderValues[k]);
  663             myParserVmin[i].AddConstant(SliderNames[k], SliderValues[k]);
  664             myParserVmax[i].AddConstant(SliderNames[k], SliderValues[k]);
  665             myParserX[i].AddConstant(SliderNames[k], SliderValues[k]);
  666             myParserY[i].AddConstant(SliderNames[k], SliderValues[k]);
  667             myParserZ[i].AddConstant(SliderNames[k], SliderValues[k]);
  668             myParserW[i].AddConstant(SliderNames[k], SliderValues[k]);
  669         }
  670     }
  671     // Add defined functions :
  672     for(uint i=0; i<componentsNumber; i++)
  673     {
  674         for(uint j=0; j<FunctSize; j++)
  675         {
  676             if((UsedFunct[i*4*FunctSize+4*j]=(ParamStructs[i].fx.find(FunctNames[j]) != std::string::npos)))
  677                 myParserX[i].AddFunction(FunctNames[j], Fct[j]);
  678             if((UsedFunct[i*4*FunctSize+4*j+1]=(ParamStructs[i].fy.find(FunctNames[j]) != std::string::npos)))
  679                 myParserY[i].AddFunction(FunctNames[j], Fct[j]);
  680             if((UsedFunct[i*4*FunctSize+4*j+2]=(ParamStructs[i].fz.find(FunctNames[j]) != std::string::npos)))
  681                 myParserZ[i].AddFunction(FunctNames[j], Fct[j]);
  682             if((UsedFunct[i*4*FunctSize+4*j+3]=(ParamStructs[i].fw.find(FunctNames[j]) != std::string::npos)))
  683                 myParserW[i].AddFunction(FunctNames[j], Fct[j]);
  684         }
  685     }
  686 
  687     // Parse
  688     if(rgbtnotnull)
  689         for(uint i=0; i<RgbtSize; i++)
  690             if ((stdError.iErrorIndex = RgbtParser[i].Parse(Rgbts[i],"x,y,z,u,v,i_indx,j_indx,indx,max_i,max_j,cmpId,t")) >= 0)
  691             {
  692                 stdError.strError = Rgbts[i];
  693                 return stdError;
  694             }
  695 
  696     // Parse
  697     if(vrgbtnotnull && (VRgbtSize % 5) ==0)
  698     {
  699         if ((stdError.iErrorIndex = GradientParser->Parse(Gradient,"x,y,z,u,v,i_indx,j_indx,indx,max_i,max_j,cmpId,t")) >= 0)
  700         {
  701             stdError.strError = Gradient;
  702             return stdError;
  703         }
  704 
  705         for(uint i=0; i<VRgbtSize; i++)
  706             if ((stdError.iErrorIndex = VRgbtParser[i].Parse(VRgbts[i],"x,y,z,u,v,i_indx,j_indx,indx,max_i,max_j,cmpId,t")) >= 0)
  707             {
  708                 stdError.strError = VRgbts[i];
  709                 return stdError;
  710             }
  711     }
  712 
  713     if(Noise != "")
  714         if ((stdError.iErrorIndex = NoiseParser->Parse(Noise,"x,y,z,u,v,i_indx,j_indx,indx,max_i,max_j,cmpId,t")) >= 0)
  715         {
  716             stdError.strError = Noise;
  717             return stdError;
  718         }
  719 
  720     for(uint index=0; index< componentsNumber; index++)
  721     {
  722         if ((stdError.iErrorIndex = myParserUmin[index].Parse(ParamStructs[index].umin, "u,v,t")) >= 0)
  723         {
  724             stdError.strError = ParamStructs[index].umin;
  725             return stdError;
  726         }
  727         u_inf[index] = myParserUmin[index].Eval(vals);
  728 
  729         if ((stdError.iErrorIndex = myParserUmax[index].Parse(ParamStructs[index].umax, "u,v,t")) >= 0)
  730         {
  731             stdError.strError = ParamStructs[index].umax;
  732             return stdError;
  733         }
  734         u_sup[index] = myParserUmax[index].Eval(vals);
  735         dif_u[index] = u_sup[index] - u_inf[index];
  736 
  737         if ((stdError.iErrorIndex = myParserVmin[index].Parse(ParamStructs[index].vmin, "u,v,t")) >= 0)
  738         {
  739             stdError.strError = ParamStructs[index].vmin;
  740             return stdError;
  741         }
  742         v_inf[index] = myParserVmin[index].Eval(vals);
  743 
  744         if ((stdError.iErrorIndex = myParserVmax[index].Parse(ParamStructs[index].vmax, "u,v,t")) >= 0)
  745         {
  746             stdError.strError = ParamStructs[index].vmax;
  747             return stdError;
  748         }
  749         v_sup[index] = myParserVmax[index].Eval(vals);
  750         dif_v[index] = v_sup[index] - v_inf[index];
  751 
  752         if ((stdError.iErrorIndex = myParserX[index].Parse(ParamStructs[index].fx, "u,v,t")) >= 0)
  753         {
  754             stdError.strError = ParamStructs[index].fx;
  755             return stdError;
  756         }
  757 
  758         if ((stdError.iErrorIndex = myParserY[index].Parse(ParamStructs[index].fy, "u,v,t")) >= 0)
  759         {
  760             stdError.strError = ParamStructs[index].fy;
  761             return stdError;
  762         }
  763 
  764         if ((stdError.iErrorIndex = myParserZ[index].Parse(ParamStructs[index].fz, "u,v,t")) >= 0)
  765         {
  766             stdError.strError = ParamStructs[index].fz;
  767             return stdError;
  768         }
  769 
  770         if(param4D == 1)
  771             if ((stdError.iErrorIndex = myParserW[index].Parse(ParamStructs[index].fw, "u,v,t")) >= 0)
  772             {
  773                 stdError.strError = ParamStructs[index].fw;
  774                 return stdError;
  775             }
  776 
  777         if(cndnotnull && (ParamStructs[index].cnd!=""))
  778             if ((stdError.iErrorIndex = ParisoConditionParser[index].Parse(ParamStructs[index].cnd, "x,y,z,t")) >= 0)
  779             {
  780                 stdError.strError = ParamStructs[index].cnd;
  781                 return stdError;
  782             }
  783     }
  784     return stdError;
  785 }
  786 ErrorMessage  Par3D::parse_expression2()
  787 {
  788     ErrorMessage NodError;
  789     for(uint nbthreads=0; nbthreads+1<WorkerThreadsNumber; nbthreads++)
  790     {
  791         //Functions:
  792         for(uint ij=0; ij<masterthread->FunctSize; ij++)
  793         {
  794             workerthreads[nbthreads].Fct[ij].AddConstant("pi", PI);
  795             workerthreads[nbthreads].Fct[ij].AddFunction("CmpId",CurrentParamCmpId, 1);
  796         }
  797         for(uint ii=0; ii<masterthread->FunctSize; ii++)
  798         {
  799             for(uint jj=0; jj<masterthread->ConstSize; jj++)
  800             {
  801                 workerthreads[nbthreads].Fct[ii].AddConstant(masterthread->ConstNames[jj], masterthread->ConstValues[jj]);
  802             }
  803 
  804             //Add predefined constatnts:
  805             for(uint kk=0; kk<masterthread->Nb_Sliders; kk++)
  806             {
  807                 workerthreads[nbthreads].Fct[ii].AddConstant(masterthread->SliderNames[kk], masterthread->SliderValues[kk]);
  808             }
  809         }
  810         for(uint ii=0; ii<masterthread->FunctSize; ii++)
  811         {
  812             for(uint jj=0; jj<ii; jj++)
  813                 if(masterthread->UsedFunct2[ii*masterthread->FunctSize+jj])
  814                     workerthreads[nbthreads].Fct[ii].AddFunction(masterthread->FunctNames[jj], workerthreads[nbthreads].Fct[jj]);
  815             if ((masterthread->stdError.iErrorIndex = workerthreads[nbthreads].Fct[ii].Parse(masterthread->Functs[ii],"u,v,t")) >= 0)
  816             {
  817                 masterthread->stdError.strError = masterthread->Functs[ii];
  818                 return masterthread->stdError;
  819             }
  820             workerthreads[nbthreads].Fct[ii].AllocateStackMemory(Stack_Factor);
  821         }
  822     }
  823     for(uint nbthreads=0; nbthreads+1<WorkerThreadsNumber; nbthreads++)
  824     {
  825         //Add defined constantes:
  826         for(uint i=0; i<masterthread->componentsNumber; i++)
  827         {
  828             workerthreads[nbthreads].param4D   = masterthread->param4D;
  829             workerthreads[nbthreads].myParserX[i].AddConstant("pi", PI);
  830             workerthreads[nbthreads].myParserY[i].AddConstant("pi", PI);
  831             workerthreads[nbthreads].myParserZ[i].AddConstant("pi", PI);
  832             workerthreads[nbthreads].myParserW[i].AddConstant("pi", PI);
  833             workerthreads[nbthreads].myParserX[i].AddFunction("NoiseW",TurbulenceWorley2, 6);
  834             workerthreads[nbthreads].myParserX[i].AddFunction("NoiseP",TurbulencePerlin2, 6);
  835             workerthreads[nbthreads].myParserY[i].AddFunction("NoiseW",TurbulenceWorley2, 6);
  836             workerthreads[nbthreads].myParserY[i].AddFunction("NoiseP",TurbulencePerlin2, 6);
  837             workerthreads[nbthreads].myParserZ[i].AddFunction("NoiseW",TurbulenceWorley2, 6);
  838             workerthreads[nbthreads].myParserZ[i].AddFunction("NoiseP",TurbulencePerlin2, 6);
  839             workerthreads[nbthreads].myParserW[i].AddFunction("NoiseW",TurbulenceWorley2, 6);
  840             workerthreads[nbthreads].myParserW[i].AddFunction("NoiseP",TurbulencePerlin2, 6);
  841             for(uint j=0; j<masterthread->ConstSize; j++)
  842             {
  843                 workerthreads[nbthreads].myParserX[i].AddConstant(masterthread->ConstNames[j], masterthread->ConstValues[j]);
  844                 workerthreads[nbthreads].myParserY[i].AddConstant(masterthread->ConstNames[j], masterthread->ConstValues[j]);
  845                 workerthreads[nbthreads].myParserZ[i].AddConstant(masterthread->ConstNames[j], masterthread->ConstValues[j]);
  846                 workerthreads[nbthreads].myParserW[i].AddConstant(masterthread->ConstNames[j], masterthread->ConstValues[j]);
  847             }
  848             //Add predefined sliders constatnts:
  849             for(uint k=0; k<masterthread->Nb_Sliders; k++)
  850             {
  851                 workerthreads[nbthreads].myParserX[i].AddConstant(masterthread->SliderNames[k], masterthread->SliderValues[k]);
  852                 workerthreads[nbthreads].myParserY[i].AddConstant(masterthread->SliderNames[k], masterthread->SliderValues[k]);
  853                 workerthreads[nbthreads].myParserZ[i].AddConstant(masterthread->SliderNames[k], masterthread->SliderValues[k]);
  854                 workerthreads[nbthreads].myParserW[i].AddConstant(masterthread->SliderNames[k], masterthread->SliderValues[k]);
  855             }
  856         }
  857         // Add defined functions :
  858         for(uint i=0; i<masterthread->componentsNumber; i++)
  859         {
  860             for(uint j=0; j<masterthread->FunctSize; j++)
  861             {
  862                 if(masterthread->UsedFunct[i*4*masterthread->FunctSize+4*j])
  863                     workerthreads[nbthreads].myParserX[i].AddFunction(masterthread->FunctNames[j], workerthreads[nbthreads].Fct[j]);
  864                 if(masterthread->UsedFunct[i*4*masterthread->FunctSize+4*j+1])
  865                     workerthreads[nbthreads].myParserY[i].AddFunction(masterthread->FunctNames[j], workerthreads[nbthreads].Fct[j]);
  866                 if(masterthread->UsedFunct[i*4*masterthread->FunctSize+4*j+2])
  867                     workerthreads[nbthreads].myParserZ[i].AddFunction(masterthread->FunctNames[j], workerthreads[nbthreads].Fct[j]);
  868                 if(masterthread->UsedFunct[i*4*masterthread->FunctSize+4*j+3])
  869                     workerthreads[nbthreads].myParserW[i].AddFunction(masterthread->FunctNames[j], workerthreads[nbthreads].Fct[j]);
  870             }
  871 
  872         }
  873     }
  874     for(uint nbthreads=0; nbthreads+1<WorkerThreadsNumber; nbthreads++)
  875     {
  876         for(uint index=0; index< masterthread->componentsNumber; index++)
  877         {
  878             if ((masterthread->stdError.iErrorIndex = workerthreads[nbthreads].myParserX[index].Parse(masterthread->ParamStructs[index].fx, "u,v,t")) >= 0)
  879             {
  880                 masterthread->stdError.strError = masterthread->ParamStructs[index].fx;
  881                 return masterthread->stdError;
  882             }
  883             if ((masterthread->stdError.iErrorIndex = workerthreads[nbthreads].myParserY[index].Parse(masterthread->ParamStructs[index].fy, "u,v,t")) >= 0)
  884             {
  885                 masterthread->stdError.strError = masterthread->ParamStructs[index].fy;
  886                 return masterthread->stdError;
  887             }
  888             if ((masterthread->stdError.iErrorIndex = workerthreads[nbthreads].myParserZ[index].Parse(masterthread->ParamStructs[index].fz, "u,v,t")) >= 0)
  889             {
  890                 masterthread->stdError.strError = masterthread->ParamStructs[index].fz;
  891                 return masterthread->stdError;
  892             }
  893             if(param4D == 1)
  894                 if ((masterthread->stdError.iErrorIndex = workerthreads[nbthreads].myParserW[index].Parse(masterthread->ParamStructs[index].fw, "u,v,t")) >= 0)
  895                 {
  896                     masterthread->stdError.strError = masterthread->ParamStructs[index].fw;
  897                     return masterthread->stdError;
  898                 }
  899         }
  900     }
  901     return NodError;
  902 }
  903 void Par3D::WorkerThreadCopy(ParWorkerThread *WorkerThreadsTmp)
  904 {
  905     for(uint nbthreads=0; nbthreads+1<WorkerThreadsNumber; nbthreads++)
  906     {
  907         WorkerThreadsTmp[nbthreads].Ugrid = masterthread->Ugrid;
  908         WorkerThreadsTmp[nbthreads].Vgrid = masterthread->Vgrid;
  909         WorkerThreadsTmp[nbthreads].MyIndex = nbthreads+1;
  910         WorkerThreadsTmp[nbthreads].param4D   = param4D;
  911         WorkerThreadsTmp[nbthreads].WorkerThreadsNumber = WorkerThreadsNumber;
  912     }
  913 }
  914 ErrorMessage Par3D::ThreadParsersCopy()
  915 {
  916     for(uint nbthreads=0; nbthreads+1<WorkerThreadsNumber; nbthreads++)
  917     {
  918         workerthreads[nbthreads].dif_u.clear();
  919         workerthreads[nbthreads].dif_u = masterthread->dif_u;
  920         workerthreads[nbthreads].dif_v.clear();
  921         workerthreads[nbthreads].dif_v = masterthread->dif_v;
  922         workerthreads[nbthreads].u_inf.clear();
  923         workerthreads[nbthreads].u_inf = masterthread->u_inf;
  924         workerthreads[nbthreads].v_inf.clear();
  925         workerthreads[nbthreads].v_inf = masterthread->v_inf;
  926         workerthreads[nbthreads].param4D  = masterthread->param4D;
  927     }
  928     for(uint nbthreads=0; nbthreads+1<WorkerThreadsNumber; nbthreads++)
  929         workerthreads[nbthreads].DeleteWorkerParsers();
  930     for(uint nbthreads=0; nbthreads+1<WorkerThreadsNumber; nbthreads++)
  931         workerthreads[nbthreads].AllocateParsersForWorkerThread(masterthread->componentsNumber, masterthread->FunctSize);
  932     return(parse_expression2());
  933 }
  934 
  935 uint ParMasterThread::HowManyVariables(std::string NewVariables, int type)
  936 {
  937     std::string tmp, tmp2,tmp3;
  938     size_t position =0, jpos;
  939     uint Nb_variables =0;
  940     while( NewVariables!= "")
  941     {
  942         if((position = NewVariables.find(";")) != string::npos)
  943         {
  944             tmp = NewVariables;
  945             tmp2= tmp3 = (tmp.substr(0,position));
  946             jpos = tmp2.find("=");
  947             if(type == 1)
  948             {
  949                 ConstNames.push_back(tmp2.substr(0,jpos));
  950                 Consts.push_back(tmp3.substr(jpos+1,position-1));
  951             }
  952             else if(type == 2)
  953             {
  954                 FunctNames.push_back(tmp2.substr(0,jpos));
  955                 Functs.push_back(tmp3.substr(jpos+1,position-1));
  956             }
  957             else if(type == 3)
  958             {
  959                 RgbtNames.push_back(tmp2.substr(0,jpos));
  960                 Rgbts.push_back(tmp3.substr(jpos+1,position-1));
  961             }
  962             else if(type == 4)
  963             {
  964                 VRgbtNames.push_back(tmp2.substr(0,jpos));
  965                 VRgbts.push_back(tmp3.substr(jpos+1,position-1));
  966             }
  967             tmp2 = NewVariables.substr(position+1, NewVariables.length()-1);
  968             NewVariables = tmp2;
  969             Nb_variables++;
  970         }
  971         else
  972         {
  973             tmp = tmp2 = tmp3 = NewVariables;
  974             jpos = tmp2.find("=");
  975             if(type == 1)
  976             {
  977                 ConstNames.push_back(tmp2.substr(0, jpos));
  978                 Consts.push_back(tmp3.substr(jpos+1,position-1));
  979             }
  980             else if(type == 2)
  981             {
  982                 FunctNames.push_back(tmp2.substr(0, jpos));
  983                 Functs.push_back(tmp3.substr(jpos+1,position-1));
  984             }
  985             else if(type == 3)
  986             {
  987                 RgbtNames.push_back(tmp2.substr(0, jpos));
  988                 Rgbts.push_back(tmp3.substr(jpos+1,position-1));
  989             }
  990             else if(type == 4)
  991             {
  992                 VRgbtNames.push_back(tmp2.substr(0, jpos));
  993                 VRgbts.push_back(tmp3.substr(jpos+1,position-1));
  994             }
  995             NewVariables = "";
  996             Nb_variables++;
  997         }
  998     }
  999     return Nb_variables;
 1000 }
 1001 
 1002 void ParMasterThread::HowManyParamSurface(std::string ParamFct, int type)
 1003 {
 1004     std::string tmp, tmp2;
 1005     size_t position =0;
 1006     uint Nb_paramfunction =0;
 1007     switch(type)
 1008     {
 1009     case 0:
 1010         ParamStructs[0].fx = ParamFct;
 1011         break;
 1012     case 1:
 1013         ParamStructs[0].fy = ParamFct;
 1014         break;
 1015     case 2:
 1016         ParamStructs[0].fz = ParamFct;
 1017         break;
 1018     case 3:
 1019         ParamStructs[0].umin = ParamFct;
 1020         break;
 1021     case 4:
 1022         ParamStructs[0].umax = ParamFct;
 1023         break;
 1024     case 5:
 1025         ParamStructs[0].vmin = ParamFct;
 1026         break;
 1027     case 6:
 1028         ParamStructs[0].vmax = ParamFct;
 1029         break;
 1030     case 7:
 1031         ParamStructs[0].fw = ParamFct;
 1032         break;
 1033     case 8:
 1034         ParamStructs[0].cnd = ParamFct;
 1035         break;
 1036     }
 1037 
 1038     while( ParamFct!= "")
 1039     {
 1040         if((position = ParamFct.find(";")) != string::npos   )
 1041         {
 1042             tmp = ParamFct;
 1043             switch(type)
 1044             {
 1045             case 0:
 1046                 ParamStructs[Nb_paramfunction].fx = (tmp.substr(0,position));
 1047                 break;
 1048             case 1:
 1049                 ParamStructs[Nb_paramfunction].fy = (tmp.substr(0,position));
 1050                 break;
 1051             case 2:
 1052                 ParamStructs[Nb_paramfunction].fz = (tmp.substr(0,position));
 1053                 break;
 1054             case 7:
 1055                 ParamStructs[Nb_paramfunction].fw = (tmp.substr(0,position));
 1056                 break;
 1057             case 8:
 1058                 ParamStructs[Nb_paramfunction].cnd = (tmp.substr(0,position));
 1059                 break;
 1060             case 3:
 1061                 ParamStructs[Nb_paramfunction].umin = (tmp.substr(0,position));
 1062                 break;
 1063             case 4:
 1064                 ParamStructs[Nb_paramfunction].umax = (tmp.substr(0,position));
 1065                 break;
 1066             case 5:
 1067                 ParamStructs[Nb_paramfunction].vmin = (tmp.substr(0,position));
 1068                 break;
 1069             case 6:
 1070                 ParamStructs[Nb_paramfunction].vmax = (tmp.substr(0,position));
 1071                 break;
 1072             }
 1073             Nb_paramfunction++;
 1074             tmp2 = ParamFct.substr(position+1, ParamFct.length()-1);
 1075             ParamFct = tmp2;
 1076         }
 1077         else
 1078         {
 1079             switch(type)
 1080             {
 1081             case 0:
 1082                 ParamStructs[Nb_paramfunction].fx = ParamFct;
 1083                 break;
 1084             case 1:
 1085                 ParamStructs[Nb_paramfunction].fy = ParamFct;
 1086                 break;
 1087             case 2:
 1088                 ParamStructs[Nb_paramfunction].fz = ParamFct;
 1089                 break;
 1090             case 7:
 1091                 ParamStructs[Nb_paramfunction].fw = ParamFct;
 1092                 break;
 1093             case 8:
 1094                 ParamStructs[Nb_paramfunction].cnd = ParamFct;
 1095                 break;
 1096             case 3:
 1097                 ParamStructs[Nb_paramfunction].umin = ParamFct;
 1098                 break;
 1099             case 4:
 1100                 ParamStructs[Nb_paramfunction].umax = ParamFct;
 1101                 break;
 1102             case 5:
 1103                 ParamStructs[Nb_paramfunction].vmin = ParamFct;
 1104                 break;
 1105             case 6:
 1106                 ParamStructs[Nb_paramfunction].vmax = ParamFct;
 1107                 break;
 1108             }
 1109             ParamFct ="";
 1110         }
 1111     }
 1112 }
 1113 void Par3D::CalculateColorsPoints(struct ComponentInfos *comp, uint index)
 1114 {
 1115     uint Iprime, Jprime,cmpId=0, K=0;
 1116     double tmp, ValCol[masterthread->VRgbtSize], val[12];
 1117     val[11] = masterthread->stepMorph;
 1118     val[0] = val[1] = val[2] = 0.0;
 1119 
 1120     if(comp->ThereisRGBA[index] == true &&  comp->NoiseParam[comp->ParisoCurrentComponentIndex].NoiseType == 0)
 1121     {
 1122         uint idx=0;
 1123         for(uint i=0; i < comp->NbComponentsType.size()-1; i++)
 1124             idx+=comp->NbComponentsType[i];
 1125         for(uint i= comp->ParisoVertex[2*idx]; i < NbVertexTmp; i++)
 1126         {
 1127             if((i >= uint(comp->ParisoVertex[2*(cmpId+idx)])))
 1128             {
 1129                 K = cmpId;
 1130                 if((masterthread->componentsNumber -1)>cmpId)
 1131                 {
 1132                     cmpId++;
 1133                 }
 1134             }
 1135             val[0]= double(NormVertexTabVector[i*10+7]);
 1136             val[1]= double(NormVertexTabVector[i*10+8]);
 1137             val[2]= double(NormVertexTabVector[i*10+9]);
 1138             if(masterthread->gridnotnull)
 1139             {
 1140                 val[7] = double(i);
 1141                 val[8] = double(masterthread->grid[2*K]);
 1142                 val[9] = double(masterthread->grid[2*K+1]);
 1143                 val[10] = double(K);
 1144                 Jprime = (i) %  (masterthread->grid[2*K+1]);
 1145                 Iprime = floor((i-Jprime)/(masterthread->grid[2*K+1]));
 1146                 val[5] = double(Iprime);
 1147                 val[6] = double(Jprime);
 1148                 val[3] = val[5]/double(masterthread->grid[2*K]);
 1149                 val[3] = val[3] * masterthread->dif_u[K]  + masterthread->u_inf[K];
 1150                 val[4] = val[6]/double(masterthread->grid[2*K+1]);
 1151                 val[4] = val[4] * masterthread->dif_v[K]  + masterthread->v_inf[K];
 1152             }
 1153             else
 1154             {
 1155                 val[7] = double(i);
 1156                 val[8] = double(Ugrid);
 1157                 val[9] = double(Vgrid);
 1158                 val[10] = double(K);
 1159                 Jprime = (i) %  (Vgrid);
 1160                 Iprime = floor((i-Jprime)/(Vgrid));
 1161                 val[5] = double(Iprime);
 1162                 val[6] = double(Jprime);
 1163                 val[3] = val[5]/double(Ugrid);
 1164                 val[3] = val[3] * masterthread->dif_u[0]  + masterthread->u_inf[0];
 1165                 val[4] = val[6]/double(Vgrid);
 1166                 val[4] = val[4] * masterthread->dif_v[0]  + masterthread->v_inf[0];
 1167             }
 1168             for(uint li=0; li<masterthread->VRgbtSize; li++)
 1169             {
 1170                 ValCol[li] = masterthread->VRgbtParser[li].Eval(val);
 1171             }
 1172             if(masterthread->Noise != "")
 1173                 tmp  = masterthread->NoiseParser->Eval(val);
 1174             else
 1175                 tmp =1.0;
 1176             val[0]= tmp*double(NormVertexTabVector[i*10+7]);
 1177             val[1]= tmp*double(NormVertexTabVector[i*10+8]);
 1178             val[2]= tmp*double(NormVertexTabVector[i*10+9]);
 1179             tmp  = masterthread->GradientParser->Eval(val);
 1180             tmp  = masterthread->GradientParser->Eval(val);
 1181             for (uint j=0; j < masterthread->VRgbtSize; j+=5)
 1182                 if(tmp < ValCol[j])
 1183                 {
 1184                     float fraction=0;
 1185                     if(j>=5 && (ValCol[j] != ValCol[j-5]))
 1186                     {
 1187                         fraction = (tmp-ValCol[j-5])/(ValCol[j]-ValCol[j-5]);
 1188                         NormVertexTabVector[i*10  ] = float(ValCol[j+1])*(fraction) + (1-fraction)*float(ValCol[(j-5)+1]);
 1189                         NormVertexTabVector[i*10+1] = float(ValCol[j+2])*(fraction) + (1-fraction)*float(ValCol[(j-5)+2]);//float(ValCol[j+2]-ValCol[(j-5)+2])*fraction + float(ValCol[(j-5)+2]);
 1190                         NormVertexTabVector[i*10+2] = float(ValCol[j+3])*(fraction) + (1-fraction)*float(ValCol[(j-5)+3]);//float(ValCol[j+3]-ValCol[(j-5)+3])*fraction + float(ValCol[(j-5)+3]);
 1191                         NormVertexTabVector[i*10+3] = float(ValCol[(j)+4]);
 1192                         j = masterthread->VRgbtSize;
 1193                     }
 1194                 }
 1195                 else if(tmp == ValCol[j])
 1196                 {
 1197                     NormVertexTabVector[i*10  ] = float(ValCol[j+1]);
 1198                     NormVertexTabVector[i*10+1] = float(ValCol[j+2]);
 1199                     NormVertexTabVector[i*10+2] = float(ValCol[j+3]);
 1200                     NormVertexTabVector[i*10+3] = float(ValCol[j+4]);
 1201                     j = masterthread->VRgbtSize;
 1202                 }
 1203         }
 1204     }
 1205     else if(comp->ThereisRGBA[index] == true &&  comp->NoiseParam[comp->ParisoCurrentComponentIndex].NoiseType == 1)
 1206     {
 1207         uint idx=0;
 1208         for(uint i=0; i < comp->NbComponentsType.size()-1; i++)
 1209             idx+=comp->NbComponentsType[i];
 1210         for(uint i= comp->ParisoVertex[2*idx]; i < NbVertexTmp; i++)
 1211         {
 1212             if((i >= uint(comp->ParisoVertex[2*(cmpId+idx)])))
 1213             {
 1214                 K = cmpId;
 1215                 if((masterthread->componentsNumber -1)>cmpId)
 1216                 {
 1217                     cmpId++;
 1218                 }
 1219             }
 1220             val[0]= double(NormVertexTabVector[i*10+7]);
 1221             val[1]= double(NormVertexTabVector[i*10+8]);
 1222             val[2]= double(NormVertexTabVector[i*10+9]);
 1223             if(masterthread->gridnotnull)
 1224             {
 1225                 val[7] = double(i);
 1226                 val[8] = double(masterthread->grid[2*K]);
 1227                 val[9] = double(masterthread->grid[2*K+1]);
 1228                 val[10] = double(K);
 1229                 Jprime = (i) %  (masterthread->grid[2*K+1]);
 1230                 Iprime = floor((i-Jprime)/(masterthread->grid[2*K+1]));
 1231                 val[5] = double(Iprime);
 1232                 val[6] = double(Jprime);
 1233                 val[3] = val[5]/double(masterthread->grid[2*K]);
 1234                 val[3] = val[3] * masterthread->dif_u[K]  + masterthread->u_inf[K];
 1235                 val[4] = val[6]/double(masterthread->grid[2*K+1]);
 1236                 val[4] = val[4] * masterthread->dif_v[K]  + masterthread->v_inf[K];
 1237             }
 1238             else
 1239             {
 1240                 val[7] = double(i);
 1241                 val[8] = double(Ugrid);
 1242                 val[9] = double(Vgrid);
 1243                 val[10] = double(K);
 1244                 Jprime = (i) %  (Vgrid);
 1245                 Iprime = floor((i-Jprime)/(Vgrid));
 1246                 val[5] = double(Iprime);
 1247                 val[6] = double(Jprime);
 1248                 val[3] = val[5]/double(Ugrid);
 1249                 val[3] = val[3] * masterthread->dif_u[0]  + masterthread->u_inf[0];
 1250                 val[4] = val[6]/double(Vgrid);
 1251                 val[4] = val[4] * masterthread->dif_v[0]  + masterthread->v_inf[0];
 1252             }
 1253             if(masterthread->Noise != "")
 1254                 tmp  = masterthread->NoiseParser->Eval(val);
 1255             else
 1256                 tmp =1.0;
 1257             val[0]= tmp*double(NormVertexTabVector[i*10+7]);
 1258             val[1]= tmp*double(NormVertexTabVector[i*10+8]);
 1259             val[2]= tmp*double(NormVertexTabVector[i*10+9]);
 1260             val[3]*= tmp;
 1261             val[4]*= tmp;
 1262             NormVertexTabVector[i*10  ] = float(masterthread->RgbtParser[0].Eval(val));
 1263             NormVertexTabVector[i*10+1] = float(masterthread->RgbtParser[1].Eval(val));
 1264             NormVertexTabVector[i*10+2] = float(masterthread->RgbtParser[2].Eval(val));
 1265             NormVertexTabVector[i*10+3] = float(masterthread->RgbtParser[3].Eval(val));
 1266         }
 1267     }
 1268 }
 1269 uint Par3D::CNDCalculation(uint & NbTriangleIsoSurfaceTmp, struct ComponentInfos *comp)
 1270 {
 1271     uint idmx=0;
 1272     for(uint i=0; i < comp->NbComponentsType.size()-1; i++)
 1273         idmx+=comp->NbComponentsType[i];
 1274     uint startpoint=comp->ParisoVertex[2*idmx];
 1275     //In the case the isosurface part of a Pariso object doesn't have a CND condition
 1276     int sz = (comp->ParisoCondition.size() ==
 1277               comp->NbComponentsType[comp->NbComponentsType.size()-1]) ? 0 : idmx;
 1278     if (masterthread->ParisoCondition == 1)
 1279     {
 1280         double vals[4];
 1281         std::vector<int> PointVerifyCond;
 1282         vals[3] = masterthread->stepMorph;
 1283         for(uint i= startpoint; i < NbVertexTmp; i++)
 1284         {
 1285             vals[0] = double(NormVertexTabVector[i*10+7]);
 1286             vals[1] = double(NormVertexTabVector[i*10+8]);
 1287             vals[2] = double(NormVertexTabVector[i*10+9]);
 1288             uint compid= CNDtoUse(i, comp);
 1289             if(comp->ParisoCondition[compid+sz])
 1290                 PointVerifyCond.push_back(8);
 1291             else
 1292                 PointVerifyCond.push_back(int(masterthread->ParisoConditionParser[compid].Eval(vals)));
 1293 
 1294             if(PointVerifyCond[i-startpoint])
 1295             {
 1296                 NormVertexTabVector[i*10  ] = 0.1f;
 1297                 NormVertexTabVector[i*10+1] = 0.9f;
 1298                 NormVertexTabVector[i*10+2] = 0.0;
 1299                 NormVertexTabVector[i*10+3] = 1.0;
 1300             }
 1301             else
 1302             {
 1303                 NormVertexTabVector[i*10  ] = 0.9f;
 1304                 NormVertexTabVector[i*10+1] = 0.1f;
 1305                 NormVertexTabVector[i*10+2] = 0.9;
 1306                 NormVertexTabVector[i*10+3] = 1.0;
 1307             }
 1308         }
 1309         uint Aindex, Bindex, Cindex;
 1310         uint nbtriangle = NbTriangleIsoSurfaceTmp;
 1311         uint idpx=0;
 1312         for(uint id=0; id < comp->NbComponentsType.size()-1; id++)
 1313             idpx+=comp->NbComponentsType[id];
 1314         uint starttri = uint(comp->ParisoTriangle[2*idpx]/3);
 1315         std::vector<int> TypeIsoSurfaceTriangleListeCNDVector (NbTriangleIsoSurfaceTmp-starttri, 1);
 1316         for(uint i= starttri; i < nbtriangle; i++)
 1317         {
 1318             Aindex = IndexPolyTabVector[3*i    ];
 1319             Bindex = IndexPolyTabVector[3*i + 1];
 1320             Cindex = IndexPolyTabVector[3*i + 2];
 1321             int TypeTriangle = -1;
 1322             if((PointVerifyCond[Aindex-startpoint] == 8) ||
 1323                     (PointVerifyCond[Bindex-startpoint] == 8) ||
 1324                     (PointVerifyCond[Cindex-startpoint] == 8))
 1325             {
 1326                 TypeTriangle = 8;
 1327                 TypeIsoSurfaceTriangleListeCNDVector[i-starttri] = 8;
 1328             }
 1329             else if(PointVerifyCond[Aindex-startpoint] && !PointVerifyCond[Bindex-startpoint] && !PointVerifyCond[Cindex-startpoint])
 1330                 TypeTriangle = 0;
 1331             else if(!PointVerifyCond[Aindex-startpoint] && PointVerifyCond[Bindex-startpoint] && PointVerifyCond[Cindex-startpoint])
 1332                 TypeTriangle = 1;
 1333             else if(!PointVerifyCond[Aindex-startpoint] && PointVerifyCond[Bindex-startpoint] && !PointVerifyCond[Cindex-startpoint])
 1334                 TypeTriangle = 2;
 1335             else if(PointVerifyCond[Aindex-startpoint] && !PointVerifyCond[Bindex-startpoint] && PointVerifyCond[Cindex-startpoint])
 1336                 TypeTriangle = 3;
 1337             else if(!PointVerifyCond[Aindex-startpoint] && !PointVerifyCond[Bindex-startpoint] && PointVerifyCond[Cindex-startpoint])
 1338                 TypeTriangle = 4;
 1339             else if(PointVerifyCond[Aindex-startpoint] && PointVerifyCond[Bindex-startpoint] && !PointVerifyCond[Cindex-startpoint])
 1340                 TypeTriangle = 5;
 1341             else if(!PointVerifyCond[Aindex-startpoint] && !PointVerifyCond[Bindex-startpoint] && !PointVerifyCond[Cindex-startpoint])
 1342             {
 1343                 TypeTriangle = 6;
 1344                 TypeIsoSurfaceTriangleListeCNDVector[i-starttri] = -1;
 1345             }
 1346             else if(PointVerifyCond[Aindex-startpoint] && PointVerifyCond[Bindex-startpoint] && PointVerifyCond[Cindex-startpoint])
 1347             {
 1348                 TypeTriangle = 7;
 1349                 TypeIsoSurfaceTriangleListeCNDVector[i-starttri] = 1;
 1350             }
 1351             if(TypeTriangle == 2 || TypeTriangle == 3)
 1352             {
 1353                 Aindex = IndexPolyTabVector[3*i+1];
 1354                 Bindex = IndexPolyTabVector[3*i+2];
 1355                 Cindex = IndexPolyTabVector[3*i  ];
 1356             }
 1357             else if(TypeTriangle == 4 || TypeTriangle == 5)
 1358             {
 1359                 Aindex = IndexPolyTabVector[3*i+2];
 1360                 Bindex = IndexPolyTabVector[3*i  ];
 1361                 Cindex = IndexPolyTabVector[3*i+1];
 1362             }
 1363             double Bprime[4], Cprime[4], DiffX, DiffY, DiffZ;
 1364             int Alfa;
 1365             uint cnd = CNDtoUse(Aindex, comp);
 1366             if(TypeTriangle >=0 && TypeTriangle <= 5)
 1367             {
 1368                 /// Bprime
 1369                 Bprime[0] = double(NormVertexTabVector[10*Aindex+7]);
 1370                 Bprime[1] = double(NormVertexTabVector[10*Aindex+8]);
 1371                 Bprime[2] = double(NormVertexTabVector[10*Aindex+9]);
 1372                 Bprime[3] = masterthread->stepMorph;
 1373                 DiffX = double(NormVertexTabVector[10*Bindex+7] - NormVertexTabVector[3+10*Aindex  + 4])/20.0;
 1374                 DiffY = double(NormVertexTabVector[10*Bindex+8] - NormVertexTabVector[3+10*Aindex+1+ 4])/20.0;
 1375                 DiffZ = double(NormVertexTabVector[10*Bindex+9] - NormVertexTabVector[3+10*Aindex+2+ 4])/20.0;
 1376                 Alfa = 0;
 1377                 if(TypeTriangle == 0 || TypeTriangle == 2 || TypeTriangle == 4)
 1378                 {
 1379                     while(masterthread->ParisoConditionParser[cnd].Eval(Bprime) == 1.0 && (Alfa < 20))
 1380                     {
 1381                         Bprime[0] += DiffX;
 1382                         Bprime[1] += DiffY;
 1383                         Bprime[2] += DiffZ;
 1384                         Alfa += 1;
 1385                     }
 1386                 }
 1387                 else
 1388                 {
 1389                     while(!(masterthread->ParisoConditionParser[cnd].Eval(Bprime) == 1.0) && (Alfa < 20))
 1390                     {
 1391                         Bprime[0] += DiffX;
 1392                         Bprime[1] += DiffY;
 1393                         Bprime[2] += DiffZ;
 1394                         Alfa += 1;
 1395                     }
 1396                 }
 1397                 /// Cprime
 1398                 Cprime[0] = double(NormVertexTabVector[10*Aindex+7]);
 1399                 Cprime[1] = double(NormVertexTabVector[10*Aindex+8]);
 1400                 Cprime[2] = double(NormVertexTabVector[10*Aindex+9]);
 1401                 Cprime[3] = masterthread->stepMorph;
 1402                 DiffX = double(NormVertexTabVector[3+10*Cindex  + 4] - NormVertexTabVector[3+10*Aindex  + 4])/20;
 1403                 DiffY = double(NormVertexTabVector[3+10*Cindex+1+ 4] - NormVertexTabVector[3+10*Aindex+1+ 4])/20;
 1404                 DiffZ = double(NormVertexTabVector[3+10*Cindex+2+ 4] - NormVertexTabVector[3+10*Aindex+2+ 4])/20;
 1405                 Alfa = 0;
 1406                 if(TypeTriangle == 0 || TypeTriangle == 2 || TypeTriangle == 4)
 1407                 {
 1408                     while(masterthread->ParisoConditionParser[cnd].Eval(Cprime) == 1.0 && (Alfa < 20))
 1409                     {
 1410                         Cprime[0] += DiffX;
 1411                         Cprime[1] += DiffY;
 1412                         Cprime[2] += DiffZ;
 1413                         Alfa += 1;
 1414                     }
 1415                 }
 1416                 else
 1417                 {
 1418                     while(!(masterthread->ParisoConditionParser[cnd].Eval(Cprime) == 1.0) && (Alfa < 20))
 1419                     {
 1420                         Cprime[0] += DiffX;
 1421                         Cprime[1] += DiffY;
 1422                         Cprime[2] += DiffZ;
 1423                         Alfa += 1;
 1424                     }
 1425                 }
 1426                 //***********
 1427                 //Add points:
 1428                 //***********
 1429                 //Add Bprime:
 1430                 NormVertexTabVector.push_back(1.0);
 1431                 NormVertexTabVector.push_back(1.0);
 1432                 NormVertexTabVector.push_back(1.0);
 1433                 NormVertexTabVector.push_back(1.0);
 1434                 NormVertexTabVector.push_back(NormVertexTabVector[10*Bindex + 4]);
 1435                 NormVertexTabVector.push_back(NormVertexTabVector[10*Bindex + 5]);
 1436                 NormVertexTabVector.push_back(NormVertexTabVector[10*Bindex + 6]);
 1437                 NormVertexTabVector.push_back(float(Bprime[0]));
 1438                 NormVertexTabVector.push_back(float(Bprime[1]));
 1439                 NormVertexTabVector.push_back(float(Bprime[2]));
 1440                 //Add Cprime:
 1441                 NormVertexTabVector.push_back(1.0);
 1442                 NormVertexTabVector.push_back(1.0);
 1443                 NormVertexTabVector.push_back(1.0);
 1444                 NormVertexTabVector.push_back(1.0);
 1445                 NormVertexTabVector.push_back(NormVertexTabVector[10*Cindex + 4]);
 1446                 NormVertexTabVector.push_back(NormVertexTabVector[10*Cindex + 5]);
 1447                 NormVertexTabVector.push_back(NormVertexTabVector[10*Cindex + 6]);
 1448                 NormVertexTabVector.push_back(float(Cprime[0]));
 1449                 NormVertexTabVector.push_back(float(Cprime[1]));
 1450                 NormVertexTabVector.push_back(float(Cprime[2]));
 1451                 NbVertexTmp += 2;
 1452                 //***********
 1453                 //Add triangles:
 1454                 //***********
 1455                 /// Add Three new triangles :
 1456                 uint IndexBprime = (NbVertexTmp-2);
 1457                 uint IndexCprime = (NbVertexTmp-1);
 1458                 // The original triangle will be replaced by four other triangles:
 1459                 TypeIsoSurfaceTriangleListeCNDVector[i-starttri]=0;
 1460                 /// (A, Bprime, Cprime)
 1461                 IndexPolyTabVector.push_back(Aindex);
 1462                 IndexPolyTabVector.push_back(IndexBprime);
 1463                 IndexPolyTabVector.push_back(IndexCprime);
 1464                 (TypeTriangle == 0 || TypeTriangle == 2 || TypeTriangle == 4) ?
 1465                 TypeIsoSurfaceTriangleListeCNDVector.push_back(1) : TypeIsoSurfaceTriangleListeCNDVector.push_back(-1);
 1466                 NbTriangleIsoSurfaceTmp++;
 1467                 IndexPolyTabMinVector.push_back(3);
 1468                 IndexPolyTabMinVector.push_back(Aindex);
 1469                 IndexPolyTabMinVector.push_back(IndexBprime);
 1470                 IndexPolyTabMinVector.push_back(IndexCprime);
 1471                 /// (Bprime, B, C)
 1472                 IndexPolyTabVector.push_back(IndexBprime);
 1473                 IndexPolyTabVector.push_back(Bindex);
 1474                 IndexPolyTabVector.push_back(Cindex);
 1475                 (TypeTriangle == 0 || TypeTriangle == 2 || TypeTriangle == 4) ?
 1476                 TypeIsoSurfaceTriangleListeCNDVector.push_back(-1) : TypeIsoSurfaceTriangleListeCNDVector.push_back(1);
 1477                 NbTriangleIsoSurfaceTmp++;
 1478                 IndexPolyTabMinVector.push_back(3);
 1479                 IndexPolyTabMinVector.push_back(IndexBprime);
 1480                 IndexPolyTabMinVector.push_back(Bindex);
 1481                 IndexPolyTabMinVector.push_back(Cindex);
 1482                 /// (Bprime, C, Cprime)
 1483                 IndexPolyTabVector.push_back(IndexBprime);
 1484                 IndexPolyTabVector.push_back(Cindex);
 1485                 IndexPolyTabVector.push_back(IndexCprime);
 1486                 (TypeTriangle == 0 || TypeTriangle == 2 || TypeTriangle == 4) ?
 1487                 TypeIsoSurfaceTriangleListeCNDVector.push_back(-1) : TypeIsoSurfaceTriangleListeCNDVector.push_back(1);
 1488                 NbTriangleIsoSurfaceTmp++;
 1489                 IndexPolyTabMinVector.push_back(3);
 1490                 IndexPolyTabMinVector.push_back(IndexBprime);
 1491                 IndexPolyTabMinVector.push_back(Cindex);
 1492                 IndexPolyTabMinVector.push_back(IndexCprime);
 1493                 /// (Bprime, Cprime) --> the border
 1494                 IndexPolyTabVector.push_back(IndexBprime);
 1495                 IndexPolyTabVector.push_back(IndexCprime);
 1496                 IndexPolyTabVector.push_back(IndexCprime);
 1497                 TypeIsoSurfaceTriangleListeCNDVector.push_back(4); /// Type = 4-->Border
 1498                 NbTriangleIsoSurfaceTmp++;
 1499                 IndexPolyTabMinVector.push_back(3);
 1500                 IndexPolyTabMinVector.push_back(IndexBprime);
 1501                 IndexPolyTabMinVector.push_back(IndexCprime);
 1502                 IndexPolyTabMinVector.push_back(IndexCprime);
 1503             }
 1504         }
 1505         //***********
 1506         //Reorganize the triangles index:
 1507         //***********
 1508         std::vector<uint>NewIndexPolyTabVector;
 1509         uint k, l, M, N;
 1510         k = l = M = N = 0;
 1511         // In case we have a ParIso object, this will save the triangle arrangement for the parametric CND
 1512         for(uint i=0; i<starttri; i++)
 1513         {
 1514             NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i  ]);
 1515             NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i+1]);
 1516             NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i+2]);
 1517         }
 1518         // Now we start sorting the triangles list. We have 3 cases
 1519         for(uint i=starttri; i<NbTriangleIsoSurfaceTmp; i++)
 1520             if(TypeIsoSurfaceTriangleListeCNDVector[i-starttri] == 8)
 1521             {
 1522                 NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i  ]);
 1523                 NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i+1]);
 1524                 NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i+2]);
 1525                 N++;
 1526             }
 1527         for(uint i=starttri; i<NbTriangleIsoSurfaceTmp; i++)
 1528             if(TypeIsoSurfaceTriangleListeCNDVector[i-starttri] == 1)
 1529             {
 1530                 NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i  ]);
 1531                 NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i+1]);
 1532                 NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i+2]);
 1533                 k++;
 1534             }
 1535         for(uint i=starttri; i<NbTriangleIsoSurfaceTmp; i++)
 1536             if(TypeIsoSurfaceTriangleListeCNDVector[i-starttri] == -1)
 1537             {
 1538                 NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i  ]);
 1539                 NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i+1]);
 1540                 NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i+2]);
 1541                 l++;
 1542             }
 1543         for(uint i=starttri; i<NbTriangleIsoSurfaceTmp; i++)
 1544             if(TypeIsoSurfaceTriangleListeCNDVector[i-starttri] == 4)
 1545             {
 1546                 NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i  ]);
 1547                 NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i+1]);
 1548                 NewIndexPolyTabVector.push_back(IndexPolyTabVector[3*i+2]);
 1549                 M++;
 1550             }
 1551         //Copy the new index in the original one:
 1552         IndexPolyTabVector.clear();
 1553         NewIndexPolyTabVector.shrink_to_fit();
 1554         IndexPolyTabVector = NewIndexPolyTabVector;
 1555         NewIndexPolyTabVector.clear();
 1556         NewIndexPolyTabVector.shrink_to_fit();
 1557         NbTriangleIsoSurfaceTmp = M + l + k + N;
 1558         comp->NbTrianglesNoCND.push_back(N);
 1559         comp->NbTrianglesVerifyCND.push_back(k);
 1560         comp->NbTrianglesNotVerifyCND.push_back(l);
 1561         comp->NbTrianglesBorderCND.push_back(M);
 1562         comp->ThereisCND.push_back(true);
 1563         PointVerifyCond.clear();
 1564         PointVerifyCond.shrink_to_fit();
 1565         TypeIsoSurfaceTriangleListeCNDVector.clear();
 1566         TypeIsoSurfaceTriangleListeCNDVector.shrink_to_fit();
 1567     }
 1568     else
 1569     {
 1570         comp->NbTrianglesNoCND.push_back(0);
 1571         comp->NbTrianglesVerifyCND.push_back(0);
 1572         comp->NbTrianglesNotVerifyCND.push_back(0);
 1573         comp->NbTrianglesBorderCND.push_back(0);
 1574         comp->ThereisCND.push_back(false);
 1575         for(uint i= startpoint; i < NbVertexTmp; i++)
 1576         {
 1577             NormVertexTabVector[i*10  ] = 0.5f;
 1578             NormVertexTabVector[i*10+1] = 0.6f;
 1579             NormVertexTabVector[i*10+2] = 0.8f;
 1580             NormVertexTabVector[i*10+3] = 1.0;
 1581         }
 1582     }
 1583     return 1;
 1584 }
 1585 void Par3D::BuildPar()
 1586 {
 1587     ParamBuild(
 1588         &(localScene->ArrayNorVer_localPt),
 1589         &(localScene->PolyIndices_localPt),
 1590         &localScene->PolyNumber,
 1591         &(localScene->VertxNumber),
 1592         &(localScene->componentsinfos),
 1593         &(localScene->PolyIndices_localPtMin),
 1594         &(localScene->NbPolygnNbVertexPtMin),
 1595         &(localScene->NbPolygnNbVertexPtMinSize)
 1596     );
 1597 }
 1598 void Par3D::run()
 1599 {
 1600     BuildPar();
 1601 }
 1602 void Par3D::UpdateThredsNumber(uint NewThreadsNumber)
 1603 {
 1604     uint tmp= WorkerThreadsNumber;
 1605     WorkerThreadsNumber = NewThreadsNumber;
 1606     ParWorkerThread *workerthreadstmp = new ParWorkerThread[WorkerThreadsNumber-1];
 1607     WorkerThreadCopy(workerthreadstmp);
 1608     //Free old memory:
 1609     for(uint i=0; i+1<tmp; i++)
 1610         workerthreads[i].DeleteWorkerParsers();
 1611     delete[] workerthreads;
 1612     //Assigne newly allocated memory
 1613     workerthreads = workerthreadstmp;
 1614     masterthread->WorkerThreadsNumber  = WorkerThreadsNumber;
 1615 }
 1616 void Par3D::stopcalculations(bool calculation)
 1617 {
 1618     StopCalculations = calculation;
 1619     masterthread->StopCalculations = StopCalculations;
 1620     for(uint nbthreads=0; nbthreads+1< WorkerThreadsNumber; nbthreads++)
 1621         workerthreads[nbthreads].StopCalculations = StopCalculations;
 1622 }
 1623 void ParWorkerThread::emitMySignal()
 1624 {
 1625     emit mySignal(signalVal);
 1626 }
 1627 void  ParWorkerThread::calcul_objet(uint cmp, uint idx)
 1628 {
 1629     uint NewPosition =  10*idx, id=0;
 1630     int PreviousSignal=0;
 1631     uint OrignbU=uint (std::sqrt(Stack_Factor));
 1632     uint OrignbV=OrignbU;
 1633     uint nbU=OrignbU, nbV=OrignbV;
 1634     uint nbstack=nbU*nbV;
 1635     uint Iindice=0, Jindice=0;
 1636     double* vals, res;
 1637     double *ResX, *ResY, *ResZ, *ResW;
 1638     uint taille=0;
 1639     vals  = new double[3*nbstack];
 1640     ResX  = new double[nbstack];
 1641     ResY  = new double[nbstack];
 1642     ResZ  = new double[nbstack];
 1643     ResW  = new double[nbstack];
 1644     if(activeMorph == 1)
 1645         stepMorph += pace;
 1646     iStart = 0;
 1647     iFinish = 0;
 1648     for(uint i=0; i<Ugrid; i++)
 1649     {
 1650         if((i% (WorkerThreadsNumber))  == MyIndex )
 1651         {
 1652             taille += 1;
 1653         }
 1654         if(MyIndex <= (i% (WorkerThreadsNumber)))
 1655             iFinish  += 1;
 1656     }
 1657     iStart = iFinish - taille;
 1658     uint remU= (iFinish-iStart)%nbU;
 1659     uint remV= Vgrid%nbV;
 1660     uint Totalpoints=(iFinish-iStart)*Vgrid;
 1661     for(uint l=0; l<nbstack; l++)
 1662         vals[l*3+2]= stepMorph;
 1663     myParserX[cmp].AllocateStackMemory(Stack_Factor);
 1664     myParserY[cmp].AllocateStackMemory(Stack_Factor);
 1665     myParserZ[cmp].AllocateStackMemory(Stack_Factor);
 1666     if(param4D == 1)
 1667         myParserW[cmp].AllocateStackMemory(Stack_Factor);
 1668     for(uint i=iStart; i < iFinish   ; i+=nbU)
 1669     {
 1670         Iindice = i;
 1671         nbV=OrignbV;
 1672         if((remU>0) && ((Iindice+remU)==(iFinish)))
 1673         {
 1674             nbU = remU;
 1675             i= iFinish;
 1676             nbstack = nbU*nbV;
 1677         }
 1678         for (uint j=0; j < Vgrid   ; j+=nbV)
 1679         {
 1680             Jindice = j;
 1681             nbstack = nbU*nbV;
 1682             if((remV>0) && ((Jindice+remV)==(Vgrid)))
 1683             {
 1684                 nbV = remV;
 1685                 j= Vgrid;
 1686                 nbstack = nbU*nbV;
 1687             }
 1688             for(uint l=0; l<nbstack; l++)
 1689             {
 1690                 vals[l*3  ]= double(Iindice+ uint(l/nbV))*dif_u[cmp]/double(Ugrid-1) + u_inf[cmp];
 1691                 vals[l*3+1]= double(Jindice+(l%nbV))*dif_v[cmp]/double(Vgrid-1) + v_inf[cmp];
 1692             }
 1693             if(StopCalculations)
 1694                 return;
 1695             res = myParserX[cmp].Eval2(vals, 3, ResX, nbstack);
 1696             if(int(res) == VAR_OVERFLOW)
 1697             {
 1698                 StopCalculations=true;
 1699                 return;
 1700             }
 1701             if(int(res) == IF_FUNCT_ERROR)
 1702             {
 1703                 for(uint l=0; l<nbstack; l++)
 1704                     ResX[l] = myParserX[cmp].Eval(&(vals[l*3]));
 1705             }
 1706 
 1707             res = myParserY[cmp].Eval2(vals, 3, ResY, nbstack);
 1708             if(int(res) == VAR_OVERFLOW)
 1709             {
 1710                 StopCalculations=true;
 1711                 return;
 1712             }
 1713             if(int(res) == IF_FUNCT_ERROR)
 1714             {
 1715                 for(uint l=0; l<nbstack; l++)
 1716                     ResY[l] = myParserY[cmp].Eval(&(vals[l*3]));
 1717             }
 1718 
 1719             res = myParserZ[cmp].Eval2(vals, 3, ResZ, nbstack);
 1720             if(int(res) == VAR_OVERFLOW)
 1721             {
 1722                 StopCalculations=true;
 1723                 return;
 1724             }
 1725             if(int(res) == IF_FUNCT_ERROR)
 1726             {
 1727                 for(uint l=0; l<nbstack; l++)
 1728                     ResZ[l] = myParserZ[cmp].Eval(&(vals[l*3]));
 1729             }
 1730 
 1731             if(param4D == 1)
 1732             {
 1733                 res = myParserW[cmp].Eval2(vals, 3, ResW, nbstack);
 1734                 if(int(res) == VAR_OVERFLOW)
 1735                 {
 1736                     StopCalculations=true;
 1737                     return;
 1738                 }
 1739                 if(int(res) == IF_FUNCT_ERROR)
 1740                 {
 1741                     for(uint l=0; l<nbstack; l++)
 1742                         ResW[l] = myParserW[cmp].Eval(&(vals[l*3]));
 1743                 }
 1744             }
 1745             //Signal emission:
 1746             id+=nbstack;
 1747             if(MyIndex == 0 && activeMorph != 1)
 1748             {
 1749                 signalVal = int((id*100)/Totalpoints);
 1750                 if((signalVal - PreviousSignal) > 1 || id==Totalpoints)
 1751                 {
 1752                     PreviousSignal = signalVal;
 1753                     emitMySignal();
 1754                 }
 1755             }
 1756             int p=0;
 1757             for(uint ii=0; ii<nbU; ii++)
 1758                 for(uint jj=0; jj<nbV; jj++)
 1759                 {
 1760                     NormVertexTabVector[(Iindice+ii)*10*Vgrid + 10*(Jindice +jj) +7 +NewPosition] = float(ResX[p]);
 1761                     NormVertexTabVector[(Iindice+ii)*10*Vgrid + 10*(Jindice +jj) +8 +NewPosition] = float(ResY[p]);
 1762                     NormVertexTabVector[(Iindice+ii)*10*Vgrid + 10*(Jindice +jj) +9 +NewPosition] = float(ResZ[p]);
 1763                     if(param4D == 1)
 1764                         ExtraDimensionVector[(Iindice+ii)*Vgrid + (Jindice +jj) + idx] = float(ResW[p]);
 1765                     p++;
 1766                 }
 1767         }
 1768     }
 1769     delete[] vals;
 1770     delete[] ResX;
 1771     delete[] ResY;
 1772     delete[] ResZ;
 1773     delete[] ResW;
 1774 }
 1775 
 1776 void Par3D::emitErrorSignal()
 1777 {
 1778     emit ErrorSignal(int(messageerror));
 1779 }
 1780 
 1781 void Par3D::copycomponent(struct ComponentInfos* copy, struct ComponentInfos* origin)
 1782 {
 1783     copy->ParisoTriangle = origin->ParisoTriangle;
 1784     copy->ParisoVertex          = origin->ParisoVertex;
 1785     copy->NbComponentsType    = origin->NbComponentsType;
 1786     copy->ParisoCurrentComponentIndex = origin->ParisoCurrentComponentIndex;
 1787     copy->ParisoNbComponents          = origin->ParisoNbComponents;
 1788     copy->Interleave                  = origin->Interleave;
 1789     copy->pariso                      = origin->pariso;
 1790     copy->updateviewer                = origin->updateviewer;
 1791     copy->ThereisCND                  = origin->ThereisCND;
 1792     copy->ParisoCondition             = origin->ParisoCondition;
 1793     copy->ThereisRGBA                 = origin->ThereisRGBA;
 1794     copy->NbTrianglesVerifyCND        = origin->NbTrianglesVerifyCND;
 1795     copy->NbTrianglesNoCND            = origin->NbTrianglesNoCND;
 1796     copy->NbTrianglesNotVerifyCND     = origin->NbTrianglesNotVerifyCND;
 1797     copy->NbTrianglesBorderCND        = origin->NbTrianglesBorderCND;
 1798     for(int i=0; i<2; i++)
 1799     {
 1800         copy->NoiseParam[i]  = origin->NoiseParam[i];
 1801     }
 1802 }
 1803 
 1804 void  Par3D::ParamBuild(
 1805     float **NormVertexTabPt,
 1806     uint **IndexPolyTabPt,
 1807     uint *PolyNumber,
 1808     uint *VertxNumber,
 1809     ComponentInfos *componentsPt,
 1810     uint **IndexPolyTabMinPt,
 1811     unsigned  int *NbPolyMinPt,
 1812     unsigned  int *MinimPolySize
 1813 )
 1814 {
 1815     uint NbTriangleIsoSurfaceTmp;
 1816     uint nbline_save=Ugrid, nbcolone_save=Vgrid, NextPosition=0;
 1817     NbVertexTmp = NbTriangleIsoSurfaceTmp =  0;
 1818     componentsPt->updateviewer= false;
 1819     clear(components);
 1820     components->ParisoCondition = componentsPt->ParisoCondition;
 1821     if(componentsPt->pariso && componentsPt->ParisoCurrentComponentIndex>0)
 1822     {
 1823         NbVertexTmp = uint(NormVertexTabVector.size()/10);
 1824         NbTriangleIsoSurfaceTmp = uint(IndexPolyTabVector.size()/3);
 1825         copycomponent(components, componentsPt);
 1826     }
 1827     else
 1828     {
 1829         if(componentsPt->pariso)
 1830         {
 1831             components->pariso = true;
 1832             components->ParisoCurrentComponentIndex = componentsPt->ParisoCurrentComponentIndex;
 1833             components->ParisoNbComponents = componentsPt->ParisoNbComponents;
 1834         }
 1835         NormVertexTabVector.clear();
 1836         NormVertexTabVector.shrink_to_fit();
 1837         IndexPolyTabVector.clear();
 1838         IndexPolyTabVector.shrink_to_fit();
 1839         IndexPolyTabMinVector.clear();
 1840         IndexPolyTabMinVector.shrink_to_fit();
 1841     }
 1842     ExtraDimensionVector.clear();
 1843     ExtraDimensionVector.shrink_to_fit();
 1844     components->NbComponentsType.push_back(masterthread->componentsNumber);
 1845     stopcalculations(false);
 1846     if(masterthread->activeMorph != 1)
 1847     {
 1848         ptime.restart();
 1849     }
 1850     for(uint fctnb= 0; fctnb< masterthread->componentsNumber; fctnb++)
 1851     {
 1852         if(masterthread->activeMorph != 1)
 1853         {
 1854             message = QString("1) Cmp:"+QString::number(fctnb+1)+"/"+QString::number(masterthread->componentsNumber)+"==> Math calculation");
 1855             emitUpdateMessageSignal();
 1856         }
 1857         ParamComponentId = fctnb;
 1858         if(masterthread->gridnotnull)
 1859         {
 1860             initialiser_LineColumn(masterthread->grid[2*fctnb], masterthread->grid[2*fctnb+1]);
 1861         }
 1862         masterthread->CurrentComponent   = fctnb;
 1863         masterthread->CurrentIndex = NbVertexTmp;
 1864         // Save Number of Polys and vertex :
 1865         components->ParisoVertex.push_back(NbVertexTmp);
 1866         components->ParisoVertex.push_back(NbVertexTmp + (Ugrid)*(Vgrid)  -1);
 1867 
 1868         NbTriangleIsoSurfaceTmp     += 2*(Ugrid  - CutU -1)*(Vgrid - CutV -1);
 1869         for(uint nbthreads=0; nbthreads+1< WorkerThreadsNumber; nbthreads++)
 1870         {
 1871             workerthreads[nbthreads].CurrentComponent = fctnb;
 1872             workerthreads[nbthreads].CurrentIndex = NbVertexTmp;
 1873         }
 1874         ExtraDimensionVector.resize(ExtraDimensionVector.size()+Ugrid*Vgrid);
 1875         NormVertexTabVector.resize(NormVertexTabVector.size()+10*Ugrid*Vgrid);
 1876         for(uint nbthreads=0; nbthreads+1< WorkerThreadsNumber; nbthreads++)
 1877             workerthreads[nbthreads].stepMorph = masterthread->stepMorph;
 1878         masterthread->start();
 1879         for(uint nbthreads=0; nbthreads+1< WorkerThreadsNumber; nbthreads++)
 1880             workerthreads[nbthreads].start();
 1881         masterthread->wait();
 1882         for(uint nbthreads=0; nbthreads+1< WorkerThreadsNumber; nbthreads++)
 1883             workerthreads[nbthreads].wait();
 1884         if(StopCalculations)
 1885         {
 1886             initialiser_LineColumn(nbline_save, nbcolone_save);
 1887             return;
 1888         }
 1889         if(masterthread->activeMorph != 1)
 1890         {
 1891             message += QString(" ==> Mesh generation");
 1892             emitUpdateMessageSignal();
 1893         }
 1894 
 1895         if(param4D == 1)
 1896         {
 1897             Anim_Rot4D (NbVertexTmp);
 1898         }
 1899         calcul_Norm(10*NbVertexTmp);
 1900         make_PolyIndexMin(NbVertexTmp);
 1901         make_PolyIndexTri(NbVertexTmp);
 1902 
 1903         components->ParisoTriangle.push_back(6*NextPosition); //save the starting position of this component
 1904         components->ParisoTriangle.push_back(2*(Ugrid  - CutU -1)*(Vgrid - CutV -1)); //save the number of Polygones of this component
 1905 
 1906         NextPosition += (Ugrid  - CutU-1)*(Vgrid - CutV-1);
 1907         NbVertexTmp    += (Ugrid)*(Vgrid);
 1908     }
 1909     if(masterthread->activeMorph != 1)
 1910     {
 1911         message = QString("2) Mesh Processing");
 1912         emitUpdateMessageSignal();
 1913     }
 1914     //CND calculation for the triangles results:
 1915     CNDCalculation(NbTriangleIsoSurfaceTmp, components);
 1916     // Pigment, Texture and Noise :
 1917     if(masterthread->vrgbtnotnull)
 1918     {
 1919         components->ThereisRGBA.push_back(true);
 1920         components->NoiseParam[components->ParisoCurrentComponentIndex].NoiseType = 0; //Pigments
 1921         components->NoiseParam[components->ParisoCurrentComponentIndex].VRgbtParser = masterthread->VRgbtParser;
 1922         components->NoiseParam[components->ParisoCurrentComponentIndex].GradientParser = masterthread->GradientParser;
 1923         components->NoiseParam[components->ParisoCurrentComponentIndex].Nb_vrgbts = masterthread->VRgbtSize;
 1924     }
 1925     else if(masterthread->RgbtSize >= 4)
 1926     {
 1927         components->ThereisRGBA.push_back(true);
 1928         components->NoiseParam[components->ParisoCurrentComponentIndex].NoiseType = 1; //Texture
 1929         components->NoiseParam[components->ParisoCurrentComponentIndex].RgbtParser = masterthread->RgbtParser;
 1930     }
 1931     else
 1932     {
 1933         components->ThereisRGBA.push_back(false);
 1934         components->NoiseParam[components->ParisoCurrentComponentIndex].NoiseType = -1; //No Pigments or texture
 1935     }
 1936     if(masterthread->Noise == "")
 1937         components->NoiseParam[components->ParisoCurrentComponentIndex].NoiseShape = 0;
 1938     else
 1939         components->NoiseParam[components->ParisoCurrentComponentIndex].NoiseShape = 1;
 1940     CalculateColorsPoints(components, components->ThereisRGBA.size()-1);
 1941     //revert to their initial values:
 1942     if(masterthread->gridnotnull)
 1943         initialiser_LineColumn(nbline_save, nbcolone_save);
 1944     if(masterthread->activeMorph != 1)
 1945     {
 1946         message = QString("Threads:"+QString::number(WorkerThreadsNumber)+"; Cmp:"+QString::number(masterthread->componentsNumber)+"; T="+QString::number(ptime.elapsed()/1000.0)+"s");
 1947         emitUpdateMessageSignal();
 1948     }
 1949     // 3) Nb Poly & Vertex :
 1950     {
 1951         *PolyNumber      = uint(IndexPolyTabVector.size());//3*NbTriangleIsoSurfaceTmp;
 1952         *VertxNumber     = uint(NormVertexTabVector.size()/10);//NbVertexTmp;
 1953         *NbPolyMinPt     = uint(IndexPolyTabMinVector.size());//NbPolyMinimalTopology;
 1954         NormVertexTabVector.resize(NormVertexTabVector.size()+ (12+60+36)*10); // To add memory space to store the cube 12 vertices (three quads)
 1955         uint startpl = 0;
 1956         uint actualpointindice=0;
 1957         for (uint i = 0; i < *NbPolyMinPt; i++)
 1958         {
 1959             uint polysize = IndexPolyTabMinVector[startpl++];
 1960             for (uint j = 0; j < polysize; j++)
 1961             {
 1962                 actualpointindice = IndexPolyTabMinVector[startpl];
 1963                 IndexPolyTabVector.push_back(actualpointindice);
 1964                 startpl++;
 1965             }
 1966             i += polysize;
 1967         }
 1968 
 1969         IndexPolyTabMinVector2.clear();
 1970         for (uint i = 0; i < *NbPolyMinPt; i++)
 1971         {
 1972             uint polysize = IndexPolyTabMinVector[i];
 1973             IndexPolyTabMinVector2.push_back(polysize);
 1974             i += polysize;
 1975         }
 1976 
 1977         *MinimPolySize = IndexPolyTabVector.size() - *PolyNumber;
 1978         *NbPolyMinPt     = uint(IndexPolyTabMinVector2.size());
 1979         *IndexPolyTabMinPt = IndexPolyTabMinVector2.data();
 1980         *NormVertexTabPt   = NormVertexTabVector.data();
 1981         *IndexPolyTabPt    = IndexPolyTabVector.data();
 1982     }
 1983     copycomponent(componentsPt, components);
 1984     componentsPt->Interleave = true;
 1985     if(componentsPt->ParisoCurrentComponentIndex != (componentsPt->ParisoNbComponents-1))
 1986         componentsPt->ParisoCurrentComponentIndex += 1;
 1987     else
 1988         componentsPt->ParisoCurrentComponentIndex = 0;
 1989     InitShowComponent(componentsPt);
 1990     componentsPt->updateviewer = true;
 1991 }
 1992 
 1993 void Par3D::InitShowComponent(struct ComponentInfos *cpInfos)
 1994 {
 1995     cpInfos->ShowParIsoCmp.clear();
 1996     for(uint i=0; i<cpInfos->NbComponentsType[cpInfos->NbComponentsType.size()-1]; i++)
 1997         cpInfos->ShowParIsoCmp.push_back(true);
 1998 }
 1999 
 2000 void  Par3D::make_PolyIndexMin(uint index)
 2001 {
 2002     uint k=0;
 2003     for (uint i=0; i+CutU+1 < Ugrid ; i++)
 2004         for (uint j=0; j+CutV+1< Vgrid ; j++)
 2005         {
 2006             IndexPolyTabMinVector.push_back(4);
 2007             IndexPolyTabMinVector.push_back(i*Vgrid + j+index);
 2008             IndexPolyTabMinVector.push_back((i+1)*Vgrid + j +index);
 2009             IndexPolyTabMinVector.push_back((i+1)*Vgrid + (j+1)+index);
 2010             IndexPolyTabMinVector.push_back(i*Vgrid + (j+1)+index);
 2011             k+=5;
 2012         }
 2013 }
 2014 
 2015 void  Par3D::make_PolyIndexTri(uint index)
 2016 {
 2017     uint k=0;
 2018     for (uint i=0; i+CutU+1< Ugrid; i++)
 2019         for (uint j=0; j+CutV+1< Vgrid; j++)
 2020         {
 2021             IndexPolyTabVector.push_back(i*Vgrid + j+index);
 2022             IndexPolyTabVector.push_back((i+1)*Vgrid + j +index);
 2023             IndexPolyTabVector.push_back((i+1)*Vgrid + (j+1)+index);
 2024 
 2025             IndexPolyTabVector.push_back(i*Vgrid + j+index);
 2026             IndexPolyTabVector.push_back((i+1)*Vgrid + (j+1)+index);
 2027             IndexPolyTabVector.push_back(i*Vgrid + (j+1)+index);
 2028             k+=6;
 2029         }
 2030 }
 2031 
 2032 void  Par3D::calcul_Norm(uint idx)
 2033 {
 2034 //calculate Normals
 2035     uint  i, j, deplacement = 10*Vgrid;
 2036     float caa, bab, cab, baa, ba, ca, b4;
 2037 
 2038     for (i=0; i+1 < Ugrid  ; i++)
 2039         for (j=0; j+1 < Vgrid  ; j++)
 2040         {
 2041             caa = NormVertexTabVector[(i+1)*deplacement+j*10+idx+8] - NormVertexTabVector[i*deplacement+j*10+idx+8];
 2042             bab = NormVertexTabVector[i*deplacement+(j+1)*10+idx+9] - NormVertexTabVector[i*deplacement+j*10+idx+9];
 2043             cab = NormVertexTabVector[(i+1)*deplacement+j*10+idx+9] - NormVertexTabVector[i*deplacement+j*10+idx+9];
 2044             baa = NormVertexTabVector[i*deplacement+(j+1)*10+idx+8] - NormVertexTabVector[i*deplacement+j*10+idx+8];
 2045             ba  = NormVertexTabVector[i*deplacement+(j+1)*10+idx+7] - NormVertexTabVector[i*deplacement+j*10+idx+7];
 2046             ca  = NormVertexTabVector[(i+1)*deplacement+j*10+idx+7] - NormVertexTabVector[i*deplacement+j*10+idx+7];
 2047             NormVertexTabVector[i*deplacement+j*10+idx+4] = caa*bab - cab*baa;
 2048             NormVertexTabVector[i*deplacement+j*10+idx+5] = cab*ba  - ca*bab;
 2049             NormVertexTabVector[i*deplacement+j*10+idx+6] = ca*baa  - caa*ba;
 2050             b4  = sqrt((NormVertexTabVector[i*deplacement+j*10+idx+4]*NormVertexTabVector[i*deplacement+j*10+idx+4]) +
 2051                        (NormVertexTabVector[i*deplacement+j*10+idx+5]*NormVertexTabVector[i*deplacement+j*10+idx+5]) +
 2052                        (NormVertexTabVector[i*deplacement+j*10+idx+6]*NormVertexTabVector[i*deplacement+j*10+idx+6]));
 2053             if( b4 < float(0.000001))  b4 = float(0.000001);
 2054 //Normalise:
 2055             NormVertexTabVector[i*deplacement +j*10+idx+4]/=b4;
 2056             NormVertexTabVector[i*deplacement +j*10+idx+5]/=b4;
 2057             NormVertexTabVector[i*deplacement +j*10+idx+6]/=b4;
 2058         }
 2059     if(Ugrid>1)
 2060     {
 2061         i = Ugrid -1;
 2062         for (j=0; j+1 < Vgrid   ; j++)
 2063         {
 2064             NormVertexTabVector[i*deplacement+j*10+idx+4] = NormVertexTabVector[(i-1)*deplacement+j*10+idx+4];
 2065             NormVertexTabVector[i*deplacement+j*10+idx+5] = NormVertexTabVector[(i-1)*deplacement+j*10+idx+5];
 2066             NormVertexTabVector[i*deplacement+j*10+idx+6] = NormVertexTabVector[(i-1)*deplacement+j*10+idx+6];
 2067         }
 2068     }
 2069     if(Vgrid>1)
 2070     {
 2071         j =Vgrid -1;
 2072         for (i=0; i+1< Ugrid  ; i++)
 2073         {
 2074             NormVertexTabVector[i*deplacement +j*10  +idx+ 4] = NormVertexTabVector[i*deplacement +(j-1)*10  +idx+ 4];
 2075             NormVertexTabVector[i*deplacement +j*10+1+idx+ 4] = NormVertexTabVector[i*deplacement +(j-1)*10+1+idx+ 4];
 2076             NormVertexTabVector[i*deplacement +j*10+2+idx+ 4] = NormVertexTabVector[i*deplacement +(j-1)*10+2+idx+ 4];
 2077         }
 2078     }
 2079     if(Ugrid>1 && Vgrid>1)
 2080     {
 2081         i = Ugrid -1;
 2082         j =Vgrid -1;
 2083         NormVertexTabVector[i*deplacement +j*10  +idx+ 4]  = NormVertexTabVector[(i-1)*deplacement +(j-1)*10  +idx+ 4];
 2084         NormVertexTabVector[i*deplacement +j*10+1+idx+ 4]  = NormVertexTabVector[(i-1)*deplacement +(j-1)*10+1+idx+ 4];
 2085         NormVertexTabVector[i*deplacement +j*10+2+idx+ 4]  = NormVertexTabVector[(i-1)*deplacement +(j-1)*10+2+idx+ 4];
 2086     }
 2087 }