Beispiel #1
0
void REORDER::initFront( ELEM* elem )
{
  num = updateFront( elem, &frnt, num, 1 );
  if( num > max )  max = num;
  square += num*num;
  nel--;
  elem->mark = true;
  if( prev_el ) prev_el = elem;
  prev_el = elem;
  elem->link = (ELEM*) 0;
}
Beispiel #2
0
void GLWorld::mousePressEvent(QMouseEvent *event)
{
    last_pos = event->pos();

    if(!(event->buttons() & Qt::RightButton && current_selection.type != TYPE_NOTHING && editable))
        return;

    WorldObject &here = getObject(current_selection.coords);
    bool steve_is_here = current_selection.coords == steve;
    QPoint pos = mapToGlobal(event->pos());

    QMenu menu;
    QAction steve_here(trUtf8("Steve hierher teleportieren"), &menu);
    steve_here.setDisabled(here.has_cube || steve_is_here);
    menu.addAction(&steve_here);

    QAction cube_here(trUtf8("Würfel"), &menu);
    cube_here.setCheckable(true);
    cube_here.setChecked(here.has_cube);
    cube_here.setDisabled(steve_is_here); //No cube into steve
    menu.addAction(&cube_here);

    QAction stack_here(trUtf8("Stapel"), &menu);
    stack_here.setCheckable(true);
    if(here.stack_size > 0)
    {
        stack_here.setChecked(true);
        stack_here.setText(trUtf8("Stapel (%1)").arg(here.stack_size));
    }
    menu.addAction(&stack_here);

    QAction mark_here(trUtf8("Markierung"), &menu);
    mark_here.setCheckable(true);
    mark_here.setChecked(here.has_mark);
    menu.addAction(&mark_here);

    QAction *selected = menu.exec(pos);
    if(selected == &steve_here)
    {
        steve = current_selection.coords;

        //The user can't be really fast, so animations always on
        setSpeed(2000);

        setAnimation(ANIM_STEP);
        updateAnimationTarget();
        updateFront();

        fbo_dirty = true;
    }
    else if(selected == &cube_here)
    {
        here.has_cube = !here.has_cube;
        here.stack_size = 0;
        here.has_mark = false;

        fbo_dirty = true;

        emit changed();
    }
    else if(selected == &stack_here)
    {
        bool ok;
        int s = QInputDialog::getInt(this, trUtf8("Stapelhöhe"), trUtf8("Stapelhöhe auswählen:"), here.stack_size, 0, World::max_height, 1, &ok);
        if(ok)
        {
            if(s > 0)
                here.has_cube = false;

            here.stack_size = s;

            if(steve == current_selection.coords)
            {
                setAnimation(ANIM_STEP);
                updateAnimationTarget();
            }

            fbo_dirty = true;

            emit changed();
        }
    }
    else if(selected == &mark_here)
    {
        here.has_mark = !here.has_mark;
        here.has_cube = false;

        fbo_dirty = true;

        emit changed();
    }

    updateSelection();
}
Beispiel #3
0
int REORDER::frontWidth( REOFRONT **frnt, int num, int depth, double *square )
{
   int       i;
   int       dp, m, size, min;
   double    sqr, min_sqr;
   REOFRONT* fr;
   ELEM**    list;

   if( num == 0  ||  depth == 0 )
      return num;


   // Anzahl der Elemente an der Front bestimmen

   size = 0;
   fr   = *frnt;

   while( fr )
   {
      size += fr->node->noel;
      fr = fr->next;
   }

   list = new ELEM* [size];

   if( !list )
     REPORT::rpt.Error ("Could not allocate memory - frontWidth (1)");

   // Liste der Frontelemente erstellen, die noch nicht erfasst wurden
   size = frontListOfElems( *frnt, list );

   if( size==0 )
   {
      delete[] list;
      REPORT::rpt.Error ("Unexpected error -  frontWidth (2)");
   }

   dp = (minDepth<depth)? (minDepth):(depth-1);

   do
   {
      m       = 0;
      min_sqr = 0.0;

      for( i=0; i<size; i++ )
      {
         int n;

         if( !list[i] )  continue;

         // Front an die Hinzunahme des Elementes list[0] anpassen
         min = updateFront( list[i], frnt, num, 0 );

         // und dann rekursiv weiter
         sqr = *square + min*min;
         n = frontWidth( frnt, min, dp, &sqr );

         removeFront( list[i], frnt, min );

         if( min > n )     n = min;
         if( !m || n < m ) m = n;

         if( min_sqr>0.1 && sqr>min_sqr )
         {
            list[i] = (ELEM *) 0;
         }

         else if( min_sqr<0.1 || sqr<min_sqr )
         {
            register int j;

            // wenn list[i] zu einer guenstigeren Frontweite fuehrt ...
            min_sqr = sqr;

            for( j=0; j<i; j++ )
               list[j] = (ELEM *)0;
         }
      }
      dp++;

   } while( dp<depth );

   delete[] list;

   *square = min_sqr;

   return m;
}
Beispiel #4
0
void REORDER::start()
{
  int       min;             // minimale Anzahl aktiver Knoten
  int       size;            // Anzahl der Elemente an der Front
  REOFRONT* fr;              // Listenzeiger fuer aktiven Knoten
  ELEM**    list;            // Liste der Elemente an der Front
  ELEM*     elem;            // ausgewaehltes Element aus *list


  if( !prev_el )
  {
    REPORT::rpt.Error( "no starting element for reordering (REORDER::start - 1)" );
  }


  for( ;; )
  {
     if( num > max )  max = num;

     if( nel == 0 )
       REPORT::rpt.Error( "unexpected error (nel == 0) (REORDER::start - 2)" );

     if( num == 0 )
     {
       REPORT::rpt.Error( "\nunexpected error (num == 0) (REORDER::start - 3)\n" );
     }


     // find number of elements at actual front

     size = 0;
     fr   = frnt;

     while ( fr )
     {
        size += fr->node->noel;
        fr = fr->next;
     }

     list = new ELEM* [size];

     if ( !list )
       REPORT::rpt.Error( "can not allocate memory (REORDER::start - 4)" );


     // create list of front elements

     size = frontListOfElems (frnt, list);

     if ( size == 0 )
     {
       delete[] list;
       REPORT::rpt.Error ("Unexpected error - reorder (3)");
     }

     elem = list[0];

     if ( nel == 1 )
     {
       prev_el->link = elem;
       elem->link = (ELEM *)0;
       delete[] list;

       REPORT::rpt.Screen( 5, "  element count down %7d;  front width: 0\r", nel );
       break;
     }

     if ( size > 1 )
     {
       register int i;
       int depth, m, found;
       double sqr, min_sqr;     // square sum of front width
       ELEM *el;

       depth = minDepth;

       do
       {
         found   = -1;
         m       = 0;
         min_sqr = 0.0;

         for (i=0; i<size; i++)
         {
           int n;

           if (!list[i])  continue;

           found++;

           // Front an die Hinzunahme des Elementes list[i] anpassen
           min = updateFront (list[i], &frnt, num, 0);

           // maximale Frontweite bis zur Rekursionstiefe depth
           sqr = square + min*min;
           n = frontWidth (&frnt, min, depth, &sqr);

           removeFront (list[i], &frnt, min);

           if (min > n)     n = min;
           if (!m || n < m) m = n;

           if (min_sqr>0.1 && sqr>min_sqr)
           {
             list[i] = (ELEM *)0;
           }

           else if (min_sqr<0.1 || sqr<min_sqr)
           {
             register int j;

             // wenn list[i] zu einer guenstigeren Frontweite fuehrt ...
             min_sqr = sqr;
             elem = list[i];
             for (j=0; j<i; j++)
               list[j] = (ELEM *)0;
           }
         }
         depth++;

       } while ( found > 0  &&  depth <= maxDepth);

       // aus allen guenstigen Frontelementen dasjenige waehlen, das
       // am laengsten in der Liste steht

       if( found > 1 )  el = chooseElem( list, size );

       if( found > 1  &&  el )  elem = el;
     }

     delete[] list;

     prev_el->link = elem;
     elem->link = (ELEM *)0;

     // Front an die Hinzunahme des ausgewaehlten Elementes elem anpassen
     min = updateFront (elem, &frnt, num, 1);

     REPORT::rpt.Screen( 5, "  element count down %7d;  front width: %d \r", nel, min );

     nel--;
     prev_el = elem;
     num     = min;
     square += num*num;


     // und dann weiter im 'reordering'
  }
}