Logo Search packages:      
Sourcecode: ted version File versions

appRgbCube.c

/************************************************************************/
/*                                                    */
/*  Draw color cubes.                                       */
/*                                                    */
/************************************************************************/

#   include "appFrameConfig.h"

#   include <stdio.h>
#   include <string.h>
#   include <stdlib.h>

#   include <math.h>

#   include <appRgbCube.h>

#   include <appDebugon.h>

/************************************************************************/
/*                                                    */
/*  For scanning the faces of the individual color cubes.         */
/*                                                    */
/************************************************************************/

typedef struct FindColor
    {
    int                 fcFound;
    int                 fcSplitCandidate;
    Point2DI            fcPoint;
    RGB8Color           fcRgbColor;
    } FindColor;

typedef void (*HANDLE_FACE)(        RgbCube *         rc,
                              RgbColorBlock *         rcb,
                              void *                  through,
                              int               square,
                              double                  scale,
                              const double            xo[8],
                              const double            yo[8],
                              int               canSplit,
                              const int         nodes[4] );

/************************************************************************/
/*                                                    */
/*  1/2 the fraction of a block that is opened to show the inside.      */
/*                                                    */
/************************************************************************/

#   define  RGB_K       (18* 256)
#   define  RGB_GAP           80
#   define  RGB_MARG    (-10)

/************************************************************************/
/*                                                    */
/*  Init/Clean an rgb cube.                                 */
/*                                                    */
/************************************************************************/

void appInitRgbCube(    RgbCube *   rc )
    {
    rc->rcRedSteps= 1;
    rc->rcGreenSteps= 1;
    rc->rcBlueSteps= 1;

    appInitColors( &(rc->rcColors) );

    rc->rcColorBlocks= (RgbColorBlock *)0;
    rc->rcColorBlockCount= 0;

    return;
    }

void appCleanRgbCube(   RgbCube *   rc )
    {
    appCleanColors( &(rc->rcColors) );
    }

/************************************************************************/
/*                                                    */
/*  Common geometry calculations.                           */
/*                                                    */
/************************************************************************/

static void appRgbCubeGeometry(     double *          pScale,
                        int *             pSquare,
                        const RgbCube *         rc,
                        int               wide,
                        int               high )
    {
    int                 drsz;
    int                 square;
    double        scale;

    drsz= 256+ 2* RGB_GAP+ 2* RGB_MARG;
    if  ( wide <= high )
      { square= wide;   }
    else{ square= high; }

    scale= ( 1.0* square )/ drsz;

    *pScale= scale;
    *pSquare= square;

    return;
    }

/************************************************************************/
/*                                                    */
/*  See whether a mouse click is in one of the faces of a cube.         */
/*                                                    */
/************************************************************************/

static void appTryRgbColorFace(           RgbCube *         rc,
                              RgbColorBlock *         rcb,
                              void *                  through,
                              int               square,
                              double                  scale,
                              const double            xo[8],
                              const double            yo[8],
                              int               canSplit,
                              const int         nodes[4] )
    {
    FindColor *         fc= (FindColor *)through;

    Point2DI            points[5];

    points[0].p2diX= scale* xo[nodes[0]]+ square/ 2;
    points[1].p2diX= scale* xo[nodes[1]]+ square/ 2;
    points[2].p2diX= scale* xo[nodes[2]]+ square/ 2;
    points[3].p2diX= scale* xo[nodes[3]]+ square/ 2;
    points[4].p2diX= scale* xo[nodes[0]]+ square/ 2;

    points[0].p2diY= square/ 2- scale* yo[nodes[0]];
    points[1].p2diY= square/ 2- scale* yo[nodes[1]];
    points[2].p2diY= square/ 2- scale* yo[nodes[2]];
    points[3].p2diY= square/ 2- scale* yo[nodes[3]];
    points[4].p2diY= square/ 2- scale* yo[nodes[0]];

    if  ( geo2DIPointInPolygon( &(fc->fcPoint), points, 4 ) )
      {
      fc->fcFound= 1;
      fc->fcSplitCandidate= canSplit;
      fc->fcRgbColor= rcb->rcbRgbColor;
      }

    return;
    }

/************************************************************************/
/*                                                    */
/*  Redraw an RGB cube.                                     */
/*                                                    */
/************************************************************************/

static void appDrawRgbColorFace(    RgbCube *         rc,
                              RgbColorBlock *         rcb,
                              void *                  through,
                              int               square,
                              double                  scale,
                              const double            xo[8],
                              const double            yo[8],
                              int               canSplit,
                              const int         nodes[4] )
    {
    AppDrawingData *    add= (AppDrawingData *)through;

    APP_POINT           points[5];

    points[0].x= scale* xo[nodes[0]]+ square/ 2;
    points[1].x= scale* xo[nodes[1]]+ square/ 2;
    points[2].x= scale* xo[nodes[2]]+ square/ 2;
    points[3].x= scale* xo[nodes[3]]+ square/ 2;
    points[4].x= scale* xo[nodes[0]]+ square/ 2;

    points[0].y= square/ 2- scale* yo[nodes[0]];
    points[1].y= square/ 2- scale* yo[nodes[1]];
    points[2].y= square/ 2- scale* yo[nodes[2]];
    points[3].y= square/ 2- scale* yo[nodes[3]];
    points[4].y= square/ 2- scale* yo[nodes[0]];

    if  ( ! rcb->rcbColorAllocated )
      {
      if  ( appColorRgb( &(rcb->rcbAllocatorColor), &(rc->rcColors),
                                    rcb->rcbRgbColor.rgb8Red,
                                    rcb->rcbRgbColor.rgb8Green,
                                    rcb->rcbRgbColor.rgb8Blue ) )
          { LDEB(1); return;  }

      rcb->rcbColorAllocated= 1;
      }

    appDrawSetForegroundColor( add, &(rcb->rcbAllocatorColor) );

    appDrawFillPolygon( add, points, 4 );

    appDrawSetForegroundBlack( add );

    appDrawDrawLines( add, points, 4 );

    return;
    }

typedef struct BlockFace
    {
    const int *         bfNodes;
    int                 bfOnOutside;
    int                 bfDrawCandidate;
    int                 bfSplitCandidate;
    } BlockFace;

static void appHandleRgbColorBlock( double                  k,
                              int               square,
                              double                  scale,
                              RgbCube *         rc,
                              void *                  through,
                              HANDLE_FACE       handleFace,
                              RgbColorBlock *         rcb )
    {
    /*
        6----7
       /:   /|
      4-+--5 |
      | 2..|.3
      |/   |/
      0----1

    Counter clockwise, seen from the outside:
    */

    static const int front [4]=     { 0, 1, 5, 4 };
    static const int back  [4]=     { 3, 2, 6, 7 };
    static const int left  [4]=     { 2, 0, 4, 6 };
    static const int right [4]=     { 1, 3, 7, 5 };
    static const int bottom[4]=     { 2, 3, 1, 0 };
    static const int top   [4]=     { 4, 5, 7, 6 };

    BlockFace     faces[6]=
                {
                   { front,         },
                   { back,          },
                   { left,          },
                   { right,         },
                   { bottom,  },
                   { top,           },
                };

    double  xi[8];
    double  yi[8];
    double  zi[8];

    double  xp[8];
    double  yp[8];
    double  zp[8];

    double  xo[8];
    double  yo[8];

    int           i;

    for ( i= 0; i < 4; i++ )
      {
      zi[front [i]]= rcb->rcbZ0;
      zi[back  [i]]= rcb->rcbZ1;
      xi[left  [i]]= rcb->rcbX0;
      xi[right [i]]= rcb->rcbX1;
      yi[bottom[i]]= rcb->rcbY0;
      yi[top   [i]]= rcb->rcbY1;
      }

    faces[0].bfOnOutside= rcb->rcbRgbColor.rgb8Blue == 0;   /*  front */
    faces[1].bfOnOutside= rcb->rcbRgbColor.rgb8Blue == 255; /*  back */
    faces[2].bfOnOutside= rcb->rcbRgbColor.rgb8Red == 0;    /*  left */
    faces[3].bfOnOutside= rcb->rcbRgbColor.rgb8Red == 255;  /*  right */
    faces[4].bfOnOutside= rcb->rcbRgbColor.rgb8Green == 0;  /*  bottom */
    faces[5].bfOnOutside= rcb->rcbRgbColor.rgb8Green == 255;      /*  top */

    for ( i= 0; i < 6; i++ )
      {
      faces[i].bfDrawCandidate= faces[i].bfOnOutside;
      faces[i].bfSplitCandidate=
                  faces[i].bfOnOutside &&
                  ( rc->rcSplitColor != RCsplitNONE );
      }

    if  ( rc->rcSplitColor == RCsplitRED )
      {
      /*  left  */
      if  ( rcb->rcbRgbColor.rgb8Red == rc->rcSplitValues.rgb8Red )
          { faces[2].bfDrawCandidate= 1;  }

      if  ( rcb->rcbRgbColor.rgb8Red == 0 )
          { faces[2].bfSplitCandidate= 0; }

      /*  right  */
      if  ( rcb->rcbRgbColor.rgb8Red == rc->rcBSplitValues.rgb8Red )
          { faces[3].bfDrawCandidate= 1;  }

      if  ( rcb->rcbRgbColor.rgb8Red == 255     )
          { faces[3].bfSplitCandidate= 0; }
      }

    if  ( rc->rcSplitColor == RCsplitGREEN )
      {
      /*  bottom  */
      if  ( rcb->rcbRgbColor.rgb8Green == rc->rcSplitValues.rgb8Green )
          { faces[4].bfDrawCandidate= 1;  }

      if  ( rcb->rcbRgbColor.rgb8Green == 0     )
          { faces[4].bfSplitCandidate= 0; }

      /*  top  */
      if  ( rcb->rcbRgbColor.rgb8Green == rc->rcBSplitValues.rgb8Green )
          { faces[5].bfDrawCandidate= 1;  }

      if  ( rcb->rcbRgbColor.rgb8Green == 255   )
          { faces[5].bfSplitCandidate= 0; }
      }

    if  ( rc->rcSplitColor == RCsplitBLUE )
      {
      /*  front  */
      if  ( rcb->rcbRgbColor.rgb8Blue == rc->rcSplitValues.rgb8Blue )
          { faces[0].bfDrawCandidate= 1;  }

      if  ( rcb->rcbRgbColor.rgb8Blue == 0      )
          { faces[0].bfSplitCandidate= 0; }

      /*  back  */
      if  ( rcb->rcbRgbColor.rgb8Blue == rc->rcBSplitValues.rgb8Blue )
          { faces[1].bfDrawCandidate= 1;  }

      if  ( rcb->rcbRgbColor.rgb8Blue == 255    )
          { faces[1].bfSplitCandidate= 0; }
      }

    for ( i= 0; i < 8; i++ )
      {
      xp[i]= AT3_X( xi[i], yi[i], zi[i], &(rc->rcAt) );
      yp[i]= AT3_Y( xi[i], yi[i], zi[i], &(rc->rcAt) );
      zp[i]= AT3_Z( xi[i], yi[i], zi[i], &(rc->rcAt) );
      }

    for ( i= 0; i < 8; i++ )
      {
      /*
      xo[i]= xp[i]/ ( zp[i]/ k+ 1.0 );
      yo[i]= yp[i]/ ( zp[i]/ k+ 1.0 );
      */
      xo[i]= xp[i]/ ( ( k- zp[i] )/ k+ 1.0 );
      yo[i]= yp[i]/ ( ( k- zp[i] )/ k+ 1.0 );
      }

    for ( i= 0; i < 6; i++ )
      {
      const int * nodes= faces[i].bfNodes;

      double            ax, bx, nx;
      double            ay, by, ny;
      double            az, bz, nz;

      if  ( ! faces[i].bfDrawCandidate )
          { continue;   }

      ax= xp[nodes[3]]- xp[nodes[0]];
      ay= yp[nodes[3]]- yp[nodes[0]];
      az= zp[nodes[3]]- zp[nodes[0]];

      bx= xp[nodes[1]]- xp[nodes[0]];
      by= yp[nodes[1]]- yp[nodes[0]];
      bz= zp[nodes[1]]- zp[nodes[0]];

      nx= ax* bz- az* bx;
      ny= az* bx- ax* bz;
      nz= ax* by- ay* bx;

      if  ( nz > 0 )
          {
          (*handleFace)( rc, rcb,
                      through, square, scale, xo, yo,
                      faces[i].bfSplitCandidate, nodes );
          }
      }

    return;
    }

/************************************************************************/
/*                                                    */
/*  Redraw the whole RGB cube.                                    */
/*                                                    */
/************************************************************************/

void appRedrawRgbCube(  RgbCube *               rc,
                  int                     wide,
                  int                     high,
                  const DocumentRectangle *     drClip,
                  AppDrawingData *        add )
    {
    double        k= RGB_K;

    int                 i;
    RgbColorBlock *     rcb;

    int                 square;
    double        scale;

    appRgbCubeGeometry( &scale, &square, rc, wide, high );

    appDrawSetForegroundColor( add, &(rc->rcBackColor) );

    appDrawFillRectangle( add, drClip->drX0, drClip->drY0,
                                  drClip->drX1- drClip->drX0+ 1,
                                  drClip->drY1- drClip->drY0+ 1 );

    if  ( rc->rcColorSelected )
      {
      DocumentRectangle drSel;

      drSel.drX0= ( 5* wide )/ 6;
      drSel.drY0= ( 5* high )/ 6;
      drSel.drX1= wide- 6;
      drSel.drY1= high- 6;

      if  ( wide > high )
          { drSel.drY0= 6;    }
      else{ drSel.drX0= 6;    }

      if  ( docIntersectRectangle( &drSel, &drSel, drClip ) )
          {
          if  ( ! rc->rcColorAllocated )
            {
            if  ( appColorRgb( &(rc->rcAllocatedColor), &(rc->rcColors),
                                  rc->rcSelectedColor.rgb8Red,
                                  rc->rcSelectedColor.rgb8Green,
                                  rc->rcSelectedColor.rgb8Blue ) )
                { LDEB(1); return;  }

            rc->rcColorAllocated= 1;
            }

          appDrawSetForegroundColor( add, &(rc->rcAllocatedColor) );

          appDrawFillRectangle( add, drSel.drX0, drSel.drY0,
                                    drSel.drX1- drSel.drX0+ 1,
                                    drSel.drY1- drSel.drY0+ 1 );
          }
      }

    rcb= rc->rcColorBlocks;
    for ( i= 0; i < rc->rcColorBlockCount; rcb++, i++ )
      {
      appHandleRgbColorBlock( k, square, scale, rc,
                            (void *)add, appDrawRgbColorFace, rcb );
      }

    return;
    }

/************************************************************************/
/*                                                    */
/*  Find out what color is clicked.                         */
/*                                                    */
/************************************************************************/

int appRgbCubeFindColor(RGB8Color *             rgb8,
                  int *                   pOnOutside,
                  RgbCube *               rc,
                  int                     mouseX,
                  int                     mouseY,
                  int                     wide,
                  int                     high )
    {
    double        k= RGB_K;

    int                 i;
    RgbColorBlock *     rcb;

    int                 square;
    double        scale;

    FindColor           fc;

    appRgbCubeGeometry( &scale, &square, rc, wide, high );

    fc.fcFound= 0;
    fc.fcPoint.p2diX= mouseX;
    fc.fcPoint.p2diY= mouseY;

    rcb= rc->rcColorBlocks;
    for ( i= 0; i < rc->rcColorBlockCount; rcb++, i++ )
      {
      appHandleRgbColorBlock( k, square, scale, rc,
                            (void *)&fc, appTryRgbColorFace, rcb );
      }

    if  ( ! fc.fcFound )
      { return -1;      }

    *rgb8= fc.fcRgbColor;
    *pOnOutside= fc.fcSplitCandidate;

    return 0;
    }

/************************************************************************/
/*                                                    */
/*  Calculate coordinates of an individual cube in the block.           */
/*                                                    */
/************************************************************************/

static void appRgbColorBlockSetC(   double *    pC0,
                              double *    pC1,
                              int         c,
                              int         split,
                              int         splitValue,
                              int         step )
    {
    const int           size= 256+ 2* RGB_GAP;

    const double  f= 100;
    const double  f0=  0;
    const double  f1= ( f- f0 );

    double        c0= c;
    double        c1= c +step;

    if  ( split )
      {
      if  ( c0 < splitValue )
          { c0 -= RGB_GAP; c1 -= RGB_GAP; }
      else{ c0 += RGB_GAP; c1 += RGB_GAP; }
      }

    c0 -= size/ 2;
    c1 -= size/ 2;

    *pC0= ( f1* c0+ f0* c1 )/ f;
    *pC1= ( f1* c1+ f0* c0 )/ f;

    return;
    }

static void appPlaceRgbColorBlock(  RgbCube *   rc,
                              RgbColorBlock *   rcb )
    {
    appRgbColorBlockSetC( &(rcb->rcbX0), &(rcb->rcbX1),
                              rcb->rcbRgbColor.rgb8Red,
                              rc->rcSplitColor == RCsplitRED,
                              rc->rcSplitValues.rgb8Red,
                              rc->rcRedStep );

    appRgbColorBlockSetC( &(rcb->rcbY0), &(rcb->rcbY1),
                              rcb->rcbRgbColor.rgb8Green,
                              rc->rcSplitColor == RCsplitGREEN,
                              rc->rcSplitValues.rgb8Green,
                              rc->rcGreenStep );

    appRgbColorBlockSetC( &(rcb->rcbZ0), &(rcb->rcbZ1),
                              rcb->rcbRgbColor.rgb8Blue,
                              rc->rcSplitColor == RCsplitBLUE,
                              rc->rcSplitValues.rgb8Blue,
                              rc->rcBlueStep );

    return;
    }

/************************************************************************/
/*                                                    */
/*  Sort the color blocks in the Z direction. As perspective is not     */
/*  from a point of view very nearby, this works.                 */
/*                                                    */
/************************************************************************/

static int appRgbCubeZCmp(    const void *      vrcb1,
                        const void *      vrcb2 )
    {
    const RgbColorBlock *     rcb1= (const RgbColorBlock *)vrcb1;
    const RgbColorBlock *     rcb2= (const RgbColorBlock *)vrcb2;

    if  ( rcb1->rcbZ < rcb2->rcbZ )
      { return -1;      }
    if  ( rcb1->rcbZ > rcb2->rcbZ )
      { return +1;      }

    return 0;
    }

/************************************************************************/
/*                                                    */
/*  Recalculate the blocks of an RGB Cube.                        */
/*                                                    */
/************************************************************************/

static void appRgbCubeCalculateBlocks(    RgbCube *   rc )
    {
    int                 i;
    RgbColorBlock *     rcb;

    rcb= rc->rcColorBlocks;
    for ( i= 0; i < rc->rcColorBlockCount; rcb++, i++ )
      {
      appPlaceRgbColorBlock( rc, rcb );

      rcb->rcbZ=
          AT3_Z( rcb->rcbX0, rcb->rcbY0, rcb->rcbZ0, &(rc->rcAt) );
      }

    qsort( rc->rcColorBlocks, rc->rcColorBlockCount,
                            sizeof(RgbColorBlock), appRgbCubeZCmp );

    return;
    }

/************************************************************************/
/*                                                    */
/*  Rotate an RGB cube. i.e. Set a new affine transform.          */
/*                                                    */
/************************************************************************/

void appRotateRgbCube(        RgbCube *         rc,
                        int               mouseX,
                        int               mouseY,
                        int               wide,
                        int               high )
    {
    AffineTransform3D   at;
    double        a_yz;
    double        a_xz;

    int                 square;
    double        scale;

    double        d;

    appRgbCubeGeometry( &scale, &square, rc, wide, high );

    mouseX= mouseX- square/ 2;
    mouseY= mouseY- square/ 2;

    d= sqrt( 1.0* mouseX* mouseX+ 1.0* mouseY* mouseY );
    a_xz= -mouseX/ d;
    a_yz= +mouseY/ d;

    a_xz *= M_PI/2.0;
    a_yz *= M_PI/2.0;

    a_xz /= 10;
    a_yz /= 10;

    utilYZRotationAffineTransform3D( &at, a_yz );
    utilAffineTransform3DProduct( &(rc->rcAt), &at, &(rc->rcAt) );

    utilXZRotationAffineTransform3D( &at,  a_xz );
    utilAffineTransform3DProduct( &(rc->rcAt), &at, &(rc->rcAt) );

    appRgbCubeCalculateBlocks( rc );

    return;
    }

void appRgbCubeSetSplit(      RgbCube *         rc,
                        int               splitColor,
                        const RGB8Color * splitValues )
    {
    int           n;

    switch( splitColor )
      {
      case RCsplitNONE:
          rc->rcSplitColor= splitColor;
          break;

      case RCsplitRED:
          n= splitValues->rgb8Red/ rc->rcRedStep;
          if  ( n < 1 )
            { n= 1;     }
          if  ( n >= rc->rcRedSteps )
            { n=   rc->rcRedSteps- 1;     }

          rc->rcSplitColor= splitColor;
          rc->rcSplitValues.rgb8Red= ( 255* n )/ ( rc->rcRedSteps- 1 );
          rc->rcBSplitValues.rgb8Red= ( 255* (n-1) )/ ( rc->rcRedSteps- 1 );
          break;

      case RCsplitGREEN:
          n= splitValues->rgb8Green/ rc->rcGreenStep;
          if  ( n < 1 )
            { n= 1;     }
          if  ( n >= rc->rcGreenSteps )
            { n=   rc->rcGreenSteps- 1;   }

          rc->rcSplitColor= splitColor;
          rc->rcSplitValues.rgb8Green= ( 255* n )/ ( rc->rcGreenSteps- 1 );
          rc->rcBSplitValues.rgb8Green= ( 255* (n-1) )/
                                        ( rc->rcGreenSteps- 1 );
          break;

      case RCsplitBLUE:
          n= splitValues->rgb8Blue/ rc->rcBlueStep;
          if  ( n < 1 )
            { n= 1;     }
          if  ( n >= rc->rcBlueSteps )
            { n=   rc->rcBlueSteps- 1;    }

          rc->rcSplitColor= splitColor;
          rc->rcSplitValues.rgb8Blue= ( 255* n )/ ( rc->rcBlueSteps- 1 );
          rc->rcBSplitValues.rgb8Blue= ( 255* (n-1) )/ ( rc->rcBlueSteps- 1 );
          break;

      default:
          LDEB(splitColor); return;
      }

    appRgbCubeCalculateBlocks( rc );

    return;
    }

void appRgbCubeRefreshSplit(  RgbCube *         rc,
                        const RGB8Color * rgb8 )
    {
    RGB8Color     rgb8Set;

    rgb8Set= *rgb8;

    if  ( rc->rcSplitColor == RCsplitRED )
      {
      if  ( rgb8Set.rgb8Red == rc->rcSplitValues.rgb8Red    &&
            rgb8Set.rgb8Red+ rc->rcRedStep <= 255           )
          { rgb8Set.rgb8Red += rc->rcRedStep; }

      appRgbCubeSetSplit( rc, rc->rcSplitColor, &rgb8Set );
      return;
      }

    if  ( rc->rcSplitColor == RCsplitGREEN )
      {
      if  ( rgb8Set.rgb8Green == rc->rcSplitValues.rgb8Green      &&
            rgb8Set.rgb8Green+ rc->rcGreenStep <= 255       )
          { rgb8Set.rgb8Green += rc->rcGreenStep; }

      appRgbCubeSetSplit( rc, rc->rcSplitColor, &rgb8Set );
      return;
      }

    if  ( rc->rcSplitColor == RCsplitBLUE )
      {
      if  ( rgb8Set.rgb8Blue == rc->rcSplitValues.rgb8Blue  &&
            rgb8Set.rgb8Blue+ rc->rcBlueStep <= 255         )
          { rgb8Set.rgb8Blue += rc->rcBlueStep; }

      appRgbCubeSetSplit( rc, rc->rcSplitColor, &rgb8Set );
      return;
      }

    return;
    }

void appRgbCubeSelectColor(   RgbCube *         rc,
                        const RGB8Color * rgb8 )
    {
    rc->rcSelectedColor= *rgb8;
    rc->rcColorSelected= 1;
    rc->rcColorAllocated= 0;

    return;
    }

/************************************************************************/
/*                                                    */
/*  Prepare an RGB cube for drawing.                              */
/*                                                    */
/************************************************************************/

int appPrepareRgbCube(  RgbCube *               rc,
                  AppDrawingData *        add,
                  int                     redSteps,
                  int                     greenSteps,
                  int                     blueSteps )
    {
    int                 rr;
    int                 gg;
    int                 bb;

    int                 r= 84;
    int                 g= 84;
    int                 b= 84;

    int                 i;

    int                 count;
    RgbColorBlock *     fresh;

    if  ( appAllocateColors( add, &(rc->rcColors) ) )
      { LDEB(1); return -1;   }

    if  ( appColorRgb( &(rc->rcBackColor), &(rc->rcColors), r, g, b ) )
      { LLLDEB(r,g,b); return -1;   }

    rc->rcColorSelected= 0;
    rc->rcColorAllocated= 0;

    count= redSteps* greenSteps* blueSteps;

    fresh= realloc( rc->rcColorBlocks, count* sizeof( RgbColorBlock ) );
    if  ( ! fresh )
      { LXDEB(count,fresh); return -1;    }

    rc->rcColorBlocks= fresh;
    rc->rcColorBlockCount= count;

    rc->rcRedSteps= redSteps;
    rc->rcGreenSteps= greenSteps;
    rc->rcBlueSteps= blueSteps;

    rc->rcRedStep= 255/ ( redSteps- 1 );
    rc->rcGreenStep= 255/ ( greenSteps- 1 );
    rc->rcBlueStep= 255/ ( blueSteps- 1 );

    rc->rcSplitValues.rgb8Red= rc->rcRedStep* ( 128/ rc->rcRedStep );
    rc->rcSplitValues.rgb8Green= rc->rcGreenStep* ( 128/ rc->rcGreenStep );
    rc->rcSplitValues.rgb8Blue= rc->rcBlueStep* ( 128/ rc->rcBlueStep );

    rc->rcSplitColor= RCsplitNONE;

    utilIdentityAffineTransform3D( &(rc->rcAt) );

    /**/
    i= 0; fresh= rc->rcColorBlocks;
    for ( rr= 0; rr < redSteps; rr++ )
      {
      r= ( 255* rr )/ ( redSteps- 1 );

      for ( gg= 0; gg < greenSteps; gg++ )
          {
          g= ( 255* gg )/ ( greenSteps- 1 );

          for ( bb= 0; bb < blueSteps; bb++ )
            {
            b= ( 255* bb )/ ( blueSteps- 1 );

            if  ( i >= rc->rcColorBlockCount )
                { LLDEB(i,rc->rcColorBlockCount); return -1;      }

            fresh->rcbRgbColor.rgb8Red= r;
            fresh->rcbRgbColor.rgb8Green= g;
            fresh->rcbRgbColor.rgb8Blue= b;
            fresh->rcbRgbColor.rgb8Alpha= 255;

            fresh->rcbColorAllocated= 0;

            fresh++; i++;
            }
          }
      }

    /**/
    {
    double        a_yz_0= -asin( 1.0/ sqrt( 3.0 ) );
    AffineTransform3D   at;

    double        angleXZ= ( -3* M_PI )/ 4;
    double        angleYZ= a_yz_0;
    double        angleXY= (  0* M_PI )/ 6;

    utilXZRotationAffineTransform3D( &(rc->rcAt), angleXZ );

    utilYZRotationAffineTransform3D( &at, angleYZ );
    utilAffineTransform3DProduct( &(rc->rcAt), &at, &(rc->rcAt) );

    utilXYRotationAffineTransform3D( &at, angleXY );
    utilAffineTransform3DProduct( &(rc->rcAt), &at, &(rc->rcAt) );
    }

    /**/
    appRgbCubeCalculateBlocks( rc );

    return 0;
    }

Generated by  Doxygen 1.6.0   Back to index