Пример #1
0
void calculate_expr( node_t* node, node_t* parent) {
    // recurse to bottom, and evaluate bottom-up

    if( node == NULL )
        return;
    if( node->type.index != expression_n.index )
        return;

    if(node->n_children > 0)
        for(int i = 0; i < node->n_children; i++)
            calculate_expr(node->children[i], node);

    if(node->n_children == 2 &&
       node->children[0]->type.index == INTEGER &&
       node->children[1]->type.index == INTEGER) {
            doOp(node, parent);
    }

    char* c;
    if(node->data != NULL)
        c = (char*)node->data;
    if(node->n_children==1 && *c == '-' &&
            node->children[0]->type.index == INTEGER) {
        unary_minus(node);
    }
}
double parse(string s){
    stack<char> op;
    stack<double> num;
    map<char,int> pr;

    //setting the priorities, greater values with higher pr
    pr['+'] = 0;
    pr['-'] = 0;
    pr['*'] = 1;
    pr['/'] = 1;

    for (int i = 0; i < s.size(); i++){
        if (s[i] == ')'){
            while(!op.empty() && op.top() != '('){
                doOp(num,op);
            }
            op.pop();
        } else if(s[i] == '('){
			op.push('(');
        } else if(!(s[i] >= '0' && s[i] <= '9')){
            while(!op.empty() && pr[s[i]] <= pr[op.top()] && op.top() != '('){
                doOp(num,op);
            }
            op.push(s[i]);
        } else {
            double ans = 0;
            while(i < s.size() && s[i] >= '0' && s[i] <= '9'){
                ans = ans * 10 + (s[i] - '0');
                i++;
            }
            i--;
            num.push(ans);
        }
    }
    while (op.size()) {
        doOp(num,op);
    }
    return num.top();
}
Пример #3
0
void evalStackPush(Stack *s, token val)
{
	if(prefs.display.postfix)
		printf("\t%s\n", val);

	switch(tokenType(val))
	{
		case function:
			{
				//token res;
				//operand = (token)stackPop(s);
				if (doFunc(s, val) < 0)
					return;
				//stackPush(s, res);
			}
			break;
		case expop:
		case multop:
		case addop:
			{
				if(stackSize(s) >= 2)
				{
					// Pop two operands

					// Evaluate
					if (doOp(s, val) < 0)
						return;

					// Push result
					//stackPush(s, res);
				}
				else
				{
					stackPush(s, val);
				}
			}
			break;
		case value:
			{
				stackPush(s, val);
			}
			break;
		default:
			break;
	}
}
Пример #4
0
char *eval(char	*p, int *valuePtr, bool *refPtr, int *errorPtr)
{
  int	valStack[STACKMAX];
  char	opStack[STACKMAX-1];
  int	valPtr = 0;
  int	opPtr = 0;
  int	t;
  int	prec;
  int	i;
  bool	evaluate, backRef;
  int	status;

  try {
    // Assume that the expression is to be evaluated,
    //   at least until an undefined symbol is found
    evaluate = true;
    // Assume initially that all symbols are backwards references
    *refPtr = true;
    // Loop until terminator character is found (loop is exited via return)
    while (true) {
      /************************************************
       *						*
       *		EXPECT AN OPERAND		*
       *						*
       ************************************************/
      // Use evalNumber to read in a number or symbol
      status = OK;
      p = evalNumber(p, &t, &backRef, &status);
      NEWERROR(*errorPtr, status);
      if (!backRef && status > ERRORN) {        // || status == INCOMPLETE)) {
        // Stop evaluating the expression
        *refPtr = false;
        return p;                       // ck 4-16-2002
      }
      else if (*errorPtr > SEVERE)
        // Pass any other error to the caller
        return NULL;
      else {
        // If OK or WARNING, push the value on the stack
        if (evaluate)
          valStack[valPtr++] = t;
        // Set *refPtr to reflect the symbol just parsed
        *refPtr = (char) (*refPtr && backRef);
      }

      /************************************************
       *						*
       *		EXPECT AN OPERATOR		*
       *						*
       ************************************************/
      // Handle the >> and << operators
      if (*p == '>' || *p == '<') {
        p++;
        if (*p != *(p-1)) {
          NEWERROR(*errorPtr, SYNTAX);
          return NULL;
        }
      }
      prec = precedence(*p);
      // Do all stacked operations that are of higher
      //     precedence than the operator just examined.
      while (opPtr && evaluate && (prec <= precedence(opStack[opPtr-1]))) {
        // Pop operands and operator and do the operation
        t = valStack[--valPtr];
        i = valStack[--valPtr];
        status = doOp(i, t, opStack[--opPtr], &t);
        if (status != OK) {
          // Report error from doOp
          if (pass2) {
            NEWERROR(*errorPtr, status);
          }
          else
            NEWERROR(*errorPtr, INCOMPLETE);
          evaluate = false;
          *refPtr = false;
        }
        else
          // Otherwise push result on the stack
          valStack[valPtr++] = t;
      }
      if (prec) {
        if (evaluate)
          // If operator is valid, push it on the stack
          opStack[opPtr++] = *p;
        p++;
      }
      else if (*p==',' || *p=='(' || *p==')' || !(*p) || isspace(*p) || *p=='.' || *p=='{' || *p==':' || *p=='}') {
        // If the character terminates the expression,
        //     then return the various results needed.
        if (evaluate)
          *valuePtr = valStack[--valPtr];
        else
          *valuePtr = 0;

        return p;
      } else {
        // Otherwise report the syntax error
        NEWERROR(*errorPtr,  SYNTAX);
        return NULL;
      }
    }
  }
  catch( ... ) {
    NEWERROR(*errorPtr, EXCEPTION);
    sprintf(buffer, "ERROR: An exception occurred in routine 'eval'. \n");
    return NULL;
  }

  //return NORMAL;
}
bool mitk::PointSetInteractor::ExecuteAction( Action* action, mitk::StateEvent const* stateEvent )
{
  bool ok = false;//for return type bool

  //checking corresponding Data; has to be a PointSet or a subclass
  mitk::PointSet* pointSet =
    dynamic_cast<mitk::PointSet*>(m_DataNode->GetData());
  if ( pointSet == NULL )
  {
    return false;
  }

  //get the timestep to support 3D+T
  const mitk::Event *theEvent = stateEvent->GetEvent();
  mitk::ScalarType timeInMS = 0.0;

  //check if the current timestep has to be changed
  if ( theEvent )
  {
    if (theEvent->GetSender() != NULL)
    {
      //additionaly to m_TimeStep we need timeInMS to satisfy the execution of the operations
      timeInMS = theEvent->GetSender()->GetTime();
    }
  }

  //for reading on the points, Id's etc
  mitk::PointSet::DataType *itkPointSet = pointSet->GetPointSet( m_TimeStep );
  if ( itkPointSet == NULL )
  {
    return false;
  }

  mitk::PointSet::PointsContainer *points = itkPointSet->GetPoints();

  /*Each case must watch the type of the event!*/
  switch (action->GetActionId())
  {
  case AcDONOTHING:
    ok = true;
    break;
  case AcCHECKOPERATION:
    //to check if the given Event is a DisplayPositionEvent.
    {
      mitk::DisplayPositionEvent const *dispPosEvent =
        dynamic_cast <const mitk::DisplayPositionEvent *> (
          stateEvent->GetEvent());

      if (dispPosEvent != NULL)
      {
        mitk::StateEvent newStateEvent(EIDYES, stateEvent->GetEvent());
        this->HandleEvent( &newStateEvent );
      }
      else
      {
        mitk::StateEvent newStateEvent(EIDNO, stateEvent->GetEvent());
        this->HandleEvent( &newStateEvent );
      }
      ok = true;
      break;
    }

  case AcADDPOINT:
    // Declare two operations: one for the selected state: deselect the last
    // one selected and select the new one the other operation is the add
    // operation: There the first empty place have to be found and the new
    // point inserted into that space
    {
      mitk::DisplayPositionEvent const *posEvent =
        dynamic_cast < const mitk::DisplayPositionEvent * >
          (stateEvent->GetEvent());

      // Check if it is a DisplayEvent thrown in a 3D window. Then the
      // z-information is missing. Returning false might end in the state
      // full, but the last point couldn't be added, so the set wouldn't be
      // full. So a extra Action that checks the operationtype has been added.
      if ( posEvent == NULL )
      {
        return false;
      }

      mitk::Point3D itkPoint;
      itkPoint = posEvent->GetWorldPosition();

      // undo-supported deselect of all points in the DataList; if List is
      // empty, then nothing will be unselected
      this->UnselectAll( m_TimeStep, timeInMS );

      // find the position, the point is to be added to: first entry with
      // empty index. If the Set is empty, then start with 0. if not empty,
      // then take the first index not occupied
      int lastPosition = 0;
      if (!points->empty())
      {
        mitk::PointSet::PointsIterator it, end;
        it = points->Begin();
        end = points->End();
        while( it != end )
        {
          if (!points->IndexExists(lastPosition))
            break;
          ++it;
          ++lastPosition;
        }
      }

      PointOperation* doOp = new mitk::PointOperation(
        OpINSERT, timeInMS, itkPoint, lastPosition);

      if (m_UndoEnabled)
      {
        // difference between OpDELETE and OpREMOVE is, that OpDELETE deletes
        // a point at the end, and OpREMOVE deletes it from the given position
        // remove is better, cause we need the position to add or remove the
        // point anyway. We can get the last position from size()
        PointOperation *undoOp = new mitk::PointOperation(
          OpREMOVE, timeInMS, itkPoint, lastPosition);
        OperationEvent *operationEvent =
          new OperationEvent(pointSet, doOp, undoOp, "Add point");
        m_UndoController->SetOperationEvent(operationEvent);
      }

      //execute the Operation
      pointSet->ExecuteOperation(doOp);

      if ( !m_UndoEnabled )
        delete doOp;

      //the point is added and directly selected in PintSet. So no need to call OpSELECTPOINT

      ok = true;

      // Update the display
      mitk::RenderingManager::GetInstance()->RequestUpdateAll();
      break;
    }
  case AcINITMOVEMENT:
    {
      mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());

      if (posEvent == NULL)
        return false;

      // start of the Movement is stored to calculate the undoKoordinate
      // in FinishMovement
      m_LastPoint = posEvent->GetWorldPosition();

      // initialize a value to calculate the movement through all
      // MouseMoveEvents from MouseClick to MouseRelease
      m_SumVec.Fill(0);

      ok = true;
      break;
    }
  case AcMOVESELECTED://moves all selected Elements
    {
      mitk::PositionEvent const *posEvent = dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());

      if (posEvent == NULL)
        return false;

      mitk::Point3D newPoint, resultPoint;
      newPoint = posEvent->GetWorldPosition();
      // search the elements in the list that are selected then calculate the
      // vector, because only with the vector we can move several elements in
      // the same direction
      //   newPoint - lastPoint = vector
      // then move all selected and set the lastPoint = newPoint.
      // then add all vectors to a summeryVector (to be able to calculate the
      // startpoint for undoOperation)
      mitk::Vector3D dirVector = newPoint - m_LastPoint;

      //sum up all Movement for Undo in FinishMovement
      m_SumVec = m_SumVec + dirVector;

      mitk::PointSet::PointsIterator it, end;
      it = points->Begin();
      end = points->End();
      while( it != end )
      {
        int position = it->Index();
        if ( pointSet->GetSelectInfo(position, m_TimeStep) )//if selected
        {
          PointSet::PointType pt = pointSet->GetPoint(position, m_TimeStep);
          mitk::Point3D sumVec;
          sumVec[0] = pt[0];
          sumVec[1] = pt[1];
          sumVec[2] = pt[2];
          resultPoint = sumVec + dirVector;
          PointOperation doOp(OpMOVE, timeInMS, resultPoint, position);

          //execute the Operation
          //here no undo is stored, because the movement-steps aren't interesting.
          // only the start and the end is interisting to store for undo.
          pointSet->ExecuteOperation(&doOp);
        }
        ++it;
      }
      m_LastPoint = newPoint;//for calculation of the direction vector
      ok = true;

      // Update the display
      mitk::RenderingManager::GetInstance()->RequestUpdateAll();
      break;
    }

  case AcREMOVEPOINT://remove the given Point from the list
    {
      //if the point to be removed is given by the positionEvent:
      mitk::PositionEvent const  *posEvent =
        dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
      if (posEvent != NULL)
      {
        mitk::Point3D itkPoint;
        itkPoint = posEvent->GetWorldPosition();

        //search the point in the list
        int position = pointSet->SearchPoint(itkPoint, 0.0, m_TimeStep);
        //distance set to 0, cause we already got the exact point from last
        //State checkpointbut we also need the position in the list to remove it
        if (position>=0)//found a point
        {
          PointSet::PointType pt = pointSet->GetPoint(position, m_TimeStep);
          itkPoint[0] = pt[0];
          itkPoint[1] = pt[1];
          itkPoint[2] = pt[2];

          //Undo
          PointOperation* doOp = new mitk::PointOperation(OpREMOVE,
            timeInMS, itkPoint, position);
          if (m_UndoEnabled)  //write to UndoMechanism
          {
            PointOperation* undoOp = new mitk::PointOperation(OpINSERT,
              timeInMS, itkPoint, position);
            OperationEvent *operationEvent = new OperationEvent(pointSet,
              doOp, undoOp, "Remove point");
            m_UndoController->SetOperationEvent(operationEvent);
          }
          //execute the Operation
          pointSet->ExecuteOperation(doOp);

          if ( !m_UndoEnabled )
            delete doOp;

          //only then a select of a point is possible!
          if (pointSet->GetSize( m_TimeStep ) > 0)
          {
            this->SelectPoint(pointSet->Begin(m_TimeStep)->Index(), m_TimeStep, timeInMS);
          }

          ok = true;
        }
      }
      else //no position is given so remove all selected elements
      {
        //delete all selected points
        //search for the selected one and then declare the operations!
        mitk::PointSet::PointsContainer::Iterator it, end;
        it = points->Begin();
        end = points->End();
        int position = 0;
        int previousExistingPosition = -1;//to recognize the last existing position; needed because the iterator gets invalid if the point is deleted!
        int lastDelPrevExistPosition = -1; //the previous position of the last deleted point
        while (it != end)
        {
          if (points->IndexExists(it->Index()))
          {
            //if point is selected
            if (  pointSet->GetSelectInfo(it->Index(), m_TimeStep) )
            {
              //get the coordinates of that point to be undoable
              PointSet::PointType selectedPoint = it->Value();
              mitk::Point3D itkPoint;
              itkPoint[0] = selectedPoint[0];
              itkPoint[1] = selectedPoint[1];
              itkPoint[2] = selectedPoint[2];

              position = it->Index();
              PointOperation* doOp = new mitk::PointOperation(OpREMOVE,
                timeInMS, itkPoint, position);
              //Undo
              if (m_UndoEnabled)  //write to UndoMechanism
              {
                PointOperation* undoOp = new mitk::PointOperation(OpINSERT,
                  timeInMS, itkPoint, position);
                OperationEvent *operationEvent = new OperationEvent(pointSet,
                  doOp, undoOp, "Remove point");
                m_UndoController->SetOperationEvent(operationEvent);
              }
              pointSet->ExecuteOperation(doOp);

              if ( !m_UndoEnabled )
                delete doOp;

              //after delete the iterator is undefined, so start again
              //count to the last existing entry
              if (points->Size()>1 && points->IndexExists(previousExistingPosition))
              {
                for (it = points->Begin(); it != points->End(); it++)
                {
                  if (it->Index() == (unsigned int) previousExistingPosition)
                  {
                    lastDelPrevExistPosition = previousExistingPosition;
                    break; //return if the iterator on the last existing position is found
                  }
                }
              }
              else // size <= 1 or no previous existing position set
              {
                //search for the first existing position
                for (it = points->Begin(); it != points->End(); it++)
                  if (points->IndexExists(it->Index()))
                  {
                    previousExistingPosition = it->Index();
                    break;
                  }
              }

              //now that we have set the iterator, lets get sure, that the next it++ will not crash!
              if (it == end) { break; }

            }//if
            else
            {
              previousExistingPosition = it->Index();
            }
          }//if index exists

          it++;
        }//while

        if (lastDelPrevExistPosition < 0)//the var has not been set because the first element was deleted and there was no prev position
          lastDelPrevExistPosition = previousExistingPosition; //go to the end

        /*
        * now select the point before the point/points that was/were deleted
        */
        if (pointSet->GetSize( m_TimeStep ) > 0) //only then a select of a point is possible!
        {
          if (points->IndexExists(lastDelPrevExistPosition))
          {
            this->SelectPoint( lastDelPrevExistPosition, m_TimeStep, timeInMS );
          }
          else
          {
            //select the first existing element
            for (mitk::PointSet::PointsContainer::Iterator it = points->Begin(); it != points->End(); it++)
              if (points->IndexExists(it->Index()))
              {
                this->SelectPoint( it->Index(), m_TimeStep, timeInMS );
                break;
              }
          }
        }//if
        ok = true;
      }//else
    }//case

    // Update the display
    mitk::RenderingManager::GetInstance()->RequestUpdateAll();
    break;

  // Remove all Points that have been set at once.
  // TODO: Undo function not supported yet.
  case AcREMOVEALL:
    {
      if ( !points->empty() )
      {
        PointSet::PointType pt;
        mitk::PointSet::PointsContainer::Iterator it, end;
        it = points->Begin();
        end = points->End();
        int position = 0;
        while ( it != end )
        {
          position = it->Index();
          if ( points->IndexExists( position ) )
          {
            pt = pointSet->GetPoint( position, m_TimeStep );
            PointOperation doOp( OpREMOVE, timeInMS, pt, position );
            ++it;
            pointSet->ExecuteOperation( &doOp );
          }
          else it++;
        }
      }
      ok = true;
      // Update the display
      mitk::RenderingManager::GetInstance()->RequestUpdateAll();
      break;
    }

  //Checking if the Point transmitted is close enough to one point. Then
  //generate a new event with the point and let this statemaschine
  //handle the event.
  case AcCHECKELEMENT:
    {
      mitk::PositionEvent const  *posEvent =
        dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
      if (posEvent != NULL)
      {
        mitk::Point3D worldPoint = posEvent->GetWorldPosition();

        int position = pointSet->SearchPoint( worldPoint, m_Precision, m_TimeStep );
        if (position>=0)//found a point near enough to the given point
        {
          //get that point, the one meant by the user!
          PointSet::PointType pt = pointSet->GetPoint(position, m_TimeStep);
          mitk::Point2D displPoint;
          displPoint[0] = worldPoint[0]; displPoint[1] = worldPoint[1];
          //new Event with information YES and with the correct point
          mitk::PositionEvent newPosEvent(posEvent->GetSender(), Type_None,
            BS_NoButton, BS_NoButton, Key_none, displPoint, pt);
          mitk::StateEvent newStateEvent(EIDYES, &newPosEvent);
          //call HandleEvent to leave the guard-state
          this->HandleEvent( &newStateEvent );
          ok = true;
        }
        else
        {
          //new Event with information NO
          mitk::StateEvent newStateEvent(EIDNO, posEvent);
          this->HandleEvent(&newStateEvent );
          ok = true;
        }
      }
      else
      {
        MITK_DEBUG("OperationError")<<this->GetType()<<" AcCHECKELEMENT expected PointOperation.";

        mitk::DisplayPositionEvent const  *disPosEvent =
          dynamic_cast <const mitk::DisplayPositionEvent *> (
            stateEvent->GetEvent());
        if (disPosEvent != NULL)
        { //2d Koordinates for 3D Interaction; return false to redo
          //the last statechange
          mitk::StateEvent newStateEvent(EIDNO, disPosEvent);
          this->HandleEvent(&newStateEvent);
          ok = true;
        }
      }

      break;
    }
  case AcCHECKONESELECTED:
    //check if there is a point that is selected
    {
      if (pointSet->GetNumberOfSelected(m_TimeStep)>0)
      {
        mitk::StateEvent newStateEvent( EIDYES, theEvent);
        this->HandleEvent( &newStateEvent );
      }
      else //not selected then call event EIDNO
      {
        //new Event with information NO
        mitk::StateEvent newStateEvent( EIDNO, theEvent);
        this->HandleEvent( &newStateEvent );
      }
      ok = true;
      break;
    }
  case AcCHECKSELECTED:
    /*check, if the given point is selected:
    if no, then send EIDNO
    if yes, then send EIDYES*/

    // check, if: because of the need to look up the point again, it is
    // possible, that we grab the wrong point in case there are two same points
    // so maybe we do have to set a global index for further computation,
    // as long, as the mouse is moved...
    {
      int position = -1;
      mitk::PositionEvent const  *posEvent =
        dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
      if (posEvent == NULL)
        return false;
      mitk::Point3D worldPoint = posEvent->GetWorldPosition();

      position = pointSet->SearchPoint(worldPoint, m_Precision, m_TimeStep);

      if (position>=0)
      {
        mitk::PositionEvent const  *newPosEvent =
          new mitk::PositionEvent(posEvent->GetSender(),
          posEvent->GetType(), posEvent->GetButton(),
          posEvent->GetButtonState(), posEvent->GetKey(),
          posEvent->GetDisplayPosition(), posEvent->GetWorldPosition());

        //if selected on true, then call Event EIDYES
        if (pointSet->GetSelectInfo(position, m_TimeStep))
        {
          mitk::StateEvent newStateEvent( EIDYES, newPosEvent );
          this->HandleEvent( &newStateEvent );
          ok = true;

          //saving the spot for calculating the direction vector in moving
          m_LastPoint = posEvent->GetWorldPosition();
        }
        else //not selected then call event EIDNO
        {
          //new Event with information NO
          mitk::StateEvent newStateEvent( EIDNO, newPosEvent );
          this->HandleEvent( &newStateEvent );
          ok = true;
        }
        delete newPosEvent;
      }
      //the position wasn't set properly. If necessary: search the given
      //point in list and set var position
      else
      {
        /*
         mitk::StatusBar::GetInstance()->DisplayText(
          "Message from mitkPointSetInteractor: Error in Actions! Check Config XML-file",
          10000);
        */
        ok = false;
      }

      break;
    }

  //generate Events if the set will be full after the addition of the
  // point or not.
  case AcCHECKNMINUS1:
    {
      // number of points not limited->pass on
      // "Amount of points in Set is smaller then N-1"
      if (m_N<0)
      {
        mitk::StateEvent newStateEvent(EIDSTSMALERNMINUS1, stateEvent->GetEvent());
        this->HandleEvent( &newStateEvent );
        ok = true;
      }
      else
      {
        if (pointSet->GetSize( m_TimeStep ) < m_N-1 )
          //pointset after addition won't be full
        {
          mitk::StateEvent newStateEvent(EIDSTSMALERNMINUS1, stateEvent->GetEvent());
          this->HandleEvent( &newStateEvent );
          ok = true;
        }
        else
          //after the addition of a point, the container will be full
        {
          mitk::StateEvent newStateEvent(EIDSTLARGERNMINUS1, stateEvent->GetEvent());
          this->HandleEvent( &newStateEvent );
          ok = true;
        }//else
      }//else
    }
    break;
  case AcCHECKEQUALS1:
    {
      //the number of points in the list is 1 (or smaler)
      if (pointSet->GetSize( m_TimeStep ) <= 1)
      {
        mitk::StateEvent newStateEvent(EIDYES, stateEvent->GetEvent());
        this->HandleEvent( &newStateEvent );
        ok = true;
      }
      else //more than 1 points in list, so stay in the state!
      {
        mitk::StateEvent newStateEvent(EIDNO, stateEvent->GetEvent());
        this->HandleEvent( &newStateEvent );
        ok = true;
      }
    }
    break;
  case AcCHECKNUMBEROFPOINTS:
    {
      //the number of points in the list is 1 (or smaler), so will be empty after delete
     if (pointSet->GetSize( m_TimeStep ) <= 1)
      {
        mitk::StateEvent newStateEvent(EIDEMPTY, stateEvent->GetEvent());
        this->HandleEvent( &newStateEvent );
        ok = true;
      }
      else if (pointSet->GetSize( m_TimeStep ) <= m_N || m_N <= -1)
       //m_N is set to unlimited points allowed or more than 1 points in list, but not full, so stay in the state!
     {
       // if the number of points equals m_N and no point of the point set is selected switch to state EIDEQUALSN
       if ((pointSet->GetSize( m_TimeStep ) == m_N)&&(pointSet->GetNumberOfSelected()==0))
       {
         mitk::StateEvent newStateEvent(EIDEQUALSN, stateEvent->GetEvent());
         this->HandleEvent( &newStateEvent );
         ok = true;
       }
       // if the number of points is small than or equal m_N and point(s) are selected stay in state
       else
       {
         mitk::StateEvent newStateEvent(EIDSMALLERN, stateEvent->GetEvent());
         this->HandleEvent( &newStateEvent );
         ok = true;
       }
     }
      else
        //pointSet->GetSize( m_TimeStep ) >=m_N.
        // This can happen if the points were not added
        // by interaction but by loading a .mps file
      {
        mitk::StateEvent newStateEvent(EIDEQUALSN, stateEvent->GetEvent());
        this->HandleEvent( &newStateEvent );
        ok = true;
      }
    }
    break;
  case AcSELECTPICKEDOBJECT://and deselect others
    {
      mitk::PositionEvent const  *posEvent =
        dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
      if (posEvent == NULL) return false;

      mitk::Point3D itkPoint;
      itkPoint = posEvent->GetWorldPosition();

      //search the point in the list
      int position = pointSet->SearchPoint(itkPoint, 0.0, m_TimeStep);
      //distance set to 0, cause we already got the exact point from last
      //State checkpoint but we also need the position in the list to move it
      if (position>=0)//found a point
      {
        //first deselect the other points
        //undoable deselect of all points in the DataList
        this->UnselectAll( m_TimeStep, timeInMS);

        PointOperation* doOp = new mitk::PointOperation(OpSELECTPOINT,
          timeInMS, itkPoint, position);

        //Undo
        if (m_UndoEnabled)  //write to UndoMechanism
        {
          PointOperation* undoOp = new mitk::PointOperation(OpDESELECTPOINT,
            timeInMS, itkPoint, position);
          OperationEvent *operationEvent =
            new OperationEvent(pointSet, doOp, undoOp);
          m_UndoController->SetOperationEvent(operationEvent);
        }

        //execute the Operation
        pointSet->ExecuteOperation(doOp);

        if ( !m_UndoEnabled )
          delete doOp;

        ok = true;
      }

      // Update the display
      mitk::RenderingManager::GetInstance()->RequestUpdateAll();
      break;
    }

  case AcDESELECTOBJECT:
    {
      mitk::PositionEvent const  *posEvent =
        dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
      if (posEvent == NULL)
        return false;

      mitk::Point3D itkPoint;
      itkPoint = posEvent->GetWorldPosition();

      //search the point in the list
      int position = pointSet->SearchPoint(itkPoint, 0.0, m_TimeStep);

      //distance set to 0, cause we already got the exact point from last
      // State checkpoint but we also need the position in the list to move it
      if (position>=0)//found a point
      {
        //Undo
        PointOperation* doOp = new mitk::PointOperation(OpDESELECTPOINT,
          timeInMS, itkPoint, position);
        if (m_UndoEnabled)  //write to UndoMechanism
        {
          PointOperation* undoOp = new mitk::PointOperation(OpSELECTPOINT,
            timeInMS, itkPoint, position);
          OperationEvent *operationEvent = new OperationEvent(pointSet, doOp, undoOp);
          m_UndoController->SetOperationEvent(operationEvent);
        }
        //execute the Operation
        pointSet->ExecuteOperation(doOp);

        if ( !m_UndoEnabled )
          delete doOp;

        ok = true;
      }

      // Update the display
      mitk::RenderingManager::GetInstance()->RequestUpdateAll();
      break;
    }

  case AcDESELECTALL:
    {
      //undo-supported able deselect of all points in the DataList
      this->UnselectAll( m_TimeStep, timeInMS );
      ok = true;

      // Update the display
      mitk::RenderingManager::GetInstance()->RequestUpdateAll();
      break;
    }

  case AcFINISHMOVEMENT:
    {
      mitk::PositionEvent const *posEvent =
        dynamic_cast <const mitk::PositionEvent *> (stateEvent->GetEvent());
      if (posEvent == NULL)
        return false;

      //finish the movement:
      //the final point is m_LastPoint
      //m_SumVec stores the movement in a vector
      //the operation would not be necessary, but we need it for the undo Operation.
      //m_LastPoint is for the Operation
      //the point for undoOperation calculates from all selected
      //elements (point) - m_SumVec

      //search all selected elements and move them with undo-functionality.
      mitk::PointSet::PointsIterator it, end;
      it = points->Begin();
      end = points->End();
      while( it != end )
      {
        int position = it->Index();
        if ( pointSet->GetSelectInfo(position, m_TimeStep) )//if selected
        {
          PointSet::PointType pt = pointSet->GetPoint(position, m_TimeStep);
          Point3D itkPoint;
          itkPoint[0] = pt[0];
          itkPoint[1] = pt[1];
          itkPoint[2] = pt[2];
          PointOperation* doOp = new mitk::PointOperation(OpMOVE,
            timeInMS, itkPoint, position);

          if ( m_UndoEnabled )//&& (posEvent->GetType() == mitk::Type_MouseButtonRelease)
          {
            //set the undo-operation, so the final position is undo-able
            //calculate the old Position from the already moved position - m_SumVec
            mitk::Point3D undoPoint = ( itkPoint - m_SumVec );
            PointOperation* undoOp =
              new mitk::PointOperation(OpMOVE, timeInMS, undoPoint, position);
            OperationEvent *operationEvent =
              new OperationEvent(pointSet, doOp, undoOp, "Move point");
            m_UndoController->SetOperationEvent(operationEvent);
          }
          //execute the Operation
          pointSet->ExecuteOperation(doOp);

          if ( !m_UndoEnabled )
            delete doOp;

        }
        ++it;
      }

      //set every variable for movement calculation to zero
      // commented out: increases usebility in derived classes.
      /*m_LastPoint.Fill(0);
      m_SumVec.Fill(0);*/

      //increase the GroupEventId, so that the Undo goes to here
      this->IncCurrGroupEventId();
      ok = true;

      // Update the display
      mitk::RenderingManager::GetInstance()->RequestUpdateAll();
      break;
    }

  case AcCLEAR:
    {
      this->Clear( m_TimeStep, timeInMS );

      // Update the display
      mitk::RenderingManager::GetInstance()->RequestUpdateAll();
      break;
    }

  default:
    return Superclass::ExecuteAction( action, stateEvent );
  }
  // indicate modification of data tree node
  m_DataNode->Modified();
  return ok;
}
Пример #6
0
int main() {
  doOp(-63, 5);
}
bool mitk::DisplayVectorInteractor::ExecuteAction(Action* action, mitk::StateEvent const* stateEvent)
{
  bool ok=false;
  
  const DisplayPositionEvent* posEvent=dynamic_cast<const DisplayPositionEvent*>(stateEvent->GetEvent());
  if(posEvent==NULL) return false;

  int actionId = action->GetActionId();
  //initzoom and initmove is the same!
  if (actionId == AcINITZOOM)
    actionId = AcINITMOVE;
  switch(actionId)
  {
  //case 0:
  //  {
  //    DisplayCoordinateOperation* doOp = new mitk::DisplayCoordinateOperation(OpTEST,  posEvent->GetSender(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition());
  //
  //    //execute the Operation
  //    m_Destination->ExecuteOperation(doOp);
  //    ok = true;
  //    break;
  //  }
  case AcSENDCOORDINATES:
    {
      DisplayCoordinateOperation* doOp = new mitk::DisplayCoordinateOperation(OpSENDCOORDINATES,  posEvent->GetSender(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition(), posEvent->GetDisplayPosition());
      m_Destination->ExecuteOperation(doOp);
      ok = true;
      break;
    }
  case AcINITMOVE:
    {
      m_Sender=posEvent->GetSender();

      mitk::Vector2D origin = m_Sender->GetDisplayGeometry()->GetOriginInMM();
       double scaleFactorMMPerDisplayUnit = m_Sender->GetDisplayGeometry()->GetScaleFactorMMPerDisplayUnit();

      m_StartDisplayCoordinate=posEvent->GetDisplayPosition();
      m_LastDisplayCoordinate=posEvent->GetDisplayPosition();
      m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
      m_StartCoordinateInMM=mitk::Point2D( ( origin+m_StartDisplayCoordinate.GetVectorFromOrigin()*scaleFactorMMPerDisplayUnit ).GetDataPointer() );
      ok = true;
      break;
    }
  case AcMOVE:
    {
      DisplayCoordinateOperation doOp(OpMOVE,  m_Sender, m_StartDisplayCoordinate, m_CurrentDisplayCoordinate, posEvent->GetDisplayPosition());
      //make Operation
      m_LastDisplayCoordinate=m_CurrentDisplayCoordinate;
      m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
      
      //execute the Operation
      m_Destination->ExecuteOperation(&doOp);
      ok = true;
      break;
    }
  case AcFINISHMOVE:
    {     
      ok = true;
      break;
    }
  case AcZOOM:
    {
      DisplayCoordinateOperation doOp(OpZOOM,  m_Sender, m_StartDisplayCoordinate, m_LastDisplayCoordinate, posEvent->GetDisplayPosition(),m_StartCoordinateInMM);
            
      //make Operation
      m_LastDisplayCoordinate=m_CurrentDisplayCoordinate;
      m_CurrentDisplayCoordinate=posEvent->GetDisplayPosition();
      //MITK_INFO << m_CurrentDisplayCoordinate << std::endl;
      
      //execute the Operation
      m_Destination->ExecuteOperation(&doOp);
      ok = true;
      break;
    }
  default:
    ok = false;
    break;
  }
  return ok;
}
Пример #8
0
void _FSSEnvironment::runStage(const Operation& subject, 
		DynamicArray<StyleTreeNode*>& styleTreePositions,
		HashMap<StyleTreeNode*, bool, HashCollection::pointerHash<StyleTreeNode>,
			HashCollection::pointerMatch<StyleTreeNode>>& styleTreePositionSet,
		Allocator& stackAllocator, FDUint depth) {

#ifdef FD_FSS_DIAGNOSTIC_PRINT
	const char* depthString = "                                         ";
	FDUint depthStringLen = strlen(depthString);
	printf("%s%c/%s\n", depthString + depthStringLen - depth, 
			subject.getName().ownerType, subject.getName().name);
#endif

	int positionsListingStart = styleTreePositions.getSize();
	StyleTree& tree = styleSheet.getTree();
	DynamicArray<StyleTreeNode*> styleTreePositionsToAdd(stackAllocator);
	HashMap<PropertyDef*, void*, HashCollection::pointerHash<PropertyDef>,
			HashCollection::pointerMatch<PropertyDef>> defToProperty(
			stackAllocator);

	// Check the style sheet tree for the properties of the subject.
	{
		Profiler p("FSS check for properties", true);

		Profiler pApplicable("Def Applicable Rules", true);
		DynamicArray<StyleRule*> applicableRules(stackAllocator);
		pApplicable.close();

		// Follow up on rules suggested by the subject.
		// Note that we do not keep such rules in the listing of styleTreePositions
		// - instead we only store multi-atom rules that have a first-atom match.
		{
			Profiler p("FSS check rules", true);

			Array<StyleRule* const> relatedRules = subject.getRelatedRules();
			for (int i = 0; i < relatedRules.length; i++) {
				applicableRules.append(relatedRules[i]);
				Selector& selector = relatedRules[i]->getSelector();
				tree.advanceTopRule(*relatedRules[i], subject, 
						styleTreePositionsToAdd, styleTreePositionSet);
			}
		}

		// Extract properties from the list of rules.
		{
			Profiler p("FSS extract properties", true);

			FDUint ruleCount = applicableRules.getSize();
			for (FDUint i = 0; i < ruleCount; i++) {
				Array<Style> styles = applicableRules[i]->getStyles();

				for (int j = 0; j < styles.length; j++) {
					Style& style = styles[j];
					StyleDef& styleDef = style.getDef();
					PropertyDef& propertyDef = styleDef.getPropertyDef();

					// Create the property if it doesn't already exist.
					void* prop;
					if (!defToProperty.get(&propertyDef, prop)) {
						prop = propertyDef.createProperty(stackAllocator);
						defToProperty[&propertyDef] = prop;
					}

					style.invoke(prop);
				}
			}
		}

		{
			Profiler p("FSS do inline styles.", true);

			Array<const Style> inlineStyles = subject.getInlineStyles();
			FDUint inlineStyleCount = inlineStyles.length;

			for (FDUint i = 0; i < inlineStyleCount; i++) {
				const Style& style = inlineStyles[i];

				StyleDef& styleDef = style.getDef();
				PropertyDef& propertyDef = styleDef.getPropertyDef();

				// Create the property if it doesn't already exist.
				void* prop;
				if (!defToProperty.get(&propertyDef, prop)) {
					Profiler pNF("Not found shit", true);
					prop = propertyDef.createProperty(stackAllocator);
					defToProperty[&propertyDef] = prop;
				}

				Profiler p("Invoke Style", true);
				style.invoke(prop);
			}
		}

		Profiler pC("FSS prop check cleanup.", true);
	}

	
	void* hideVS;
	FDbool hasHideProp = defToProperty.get(environment.hidePDef, hideVS);
	if (!hasHideProp || 
			!((SinglePropertyDef<FDbool>::ValueSpecificity*)hideVS)->value) {

		DoOperation doOp(subject, defToProperty);

		user->onDoOperation(doOp);

		// Recurse on children.
		void* childrenVoid;
		bool hasChildren = defToProperty.get(
				styleSheet.getDefaultDefs().childrenDef, childrenVoid);
		if (hasChildren) {
			Profiler p("FSS Children operations", true);

			DefaultDefCollection::OpSet* children = 
					(DefaultDefCollection::OpSet*)childrenVoid;

			FDUint count = children->getSize();
			OpConstraint* ops = FD_NEW_ARRAY(OpConstraint, count, *allocator, 
					allocator);

			DefaultDefCollection::OpSetIterator childrenIterator(*children);
			Operation* key;
			bool value;
			FDUint i = 0;
			while (childrenIterator.getNext(key, value)) {
				ops[i++].op = key;
			}

			// Set up constraints here
			void* orderVoid;
			bool hasConstraints = defToProperty.get(
					styleSheet.getDefaultDefs().orderDef, orderVoid);
			if (hasConstraints) {
				DefaultDefCollection::ConstraintSet* constraints =
						(DefaultDefCollection::ConstraintSet*)orderVoid;

				// Iterate through constraints.
				DefaultDefCollection::ConstraintSetIterator 
						constraintIterator(*constraints);
				Pair<Selector, Selector>* key;
				bool value;
				while (constraintIterator.getNext(key, value)) {

					// TODO: Make this better. I know this can be better,
					// this is a w f u l.

					// We first obtain a list of the things that are supposed to
					// happen before.
					OpConstraint* priors[100];
					FDUint priorCount = 0;
					for (i = 0; i < count; i++) {
						if (key->first.isAtomMatch(*ops[i].op)) {
							priors[priorCount++] = &ops[i];
						}
					}

					// We then match that list to the things that are supposed to
					// happen after.
					for (i = 0; i < count; i++) {
						if (!key->second.isAtomMatch(*ops[i].op)) {
							continue;
						}

						for (FDUint j = 0; j < priorCount; j++) {

							// We check that i isn't already dependent on j.
							if (ops[i].constraints.contains(priors[j])) {
								continue;
							}

							ops[i].constraints.append(priors[j]);
						}
					}

				}
			}

			p.close();

			// Go through the children, respecting the constraints.
			FDUint renderCount = 0;
			for (i = 0; i < count; i++) {

				FDUint current = i;
				if (!ops[i].alreadyRendered) {
					constraintRecurse(ops[i], styleTreePositions, 
							styleTreePositionSet, stackAllocator, depth);
				}
			}

			FD_FREE(ops, *allocator);
		}

		Profiler p("FSS Undo", true);

		user->onUndoOperation(doOp);
	}

	// Clean up positions listing
	int positionsToAddCount = styleTreePositionsToAdd.getSize();
	for (int i = 0; i < positionsToAddCount; i++) {
		styleTreePositionSet.remove(styleTreePositionsToAdd[i]);
	}

	// Clean up defToProperty listing
	{
		HashMap<PropertyDef*, void*, HashCollection::pointerHash<PropertyDef>,
				HashCollection::pointerMatch<PropertyDef>>::Iterator 
				propertyIterator(defToProperty);
		PropertyDef* key;
		void* value;
		while (propertyIterator.getNext(key, value)) {
			key->deleteProperty(value, stackAllocator);
		}
	}
}
Пример #9
0
void Expression::traverseTree( BTreeNode *root, bool conditionalRoot )
{
	Traverser t(root);
	t.start();
	
	// special case: if we are starting at the root node then
	// we are dealing with something of the form variable = 6
	// or variable = portb
	///TODO reimplement assignments as two branched trees?
	if ( t.current() == root &&
			!root->hasChildren() &&
			t.current()->childOp() != pin &&
			t.current()->childOp() != notpin &&
			t.current()->childOp() != function &&
			t.current()->childOp() != read_keypad )
	{
		switch(root->type())
		{
			case number: m_pic->assignNum(root->value()); break;
			case variable: m_pic->assignVar(root->value()); break;
			default: break; // Should never get here
		}
		// no need to traverse the tree as there is none.
		return;
	}
	
	t.setCurrent(root);
	
	if(t.current()->hasChildren())
	{
		// Here we work out what needs evaulating, and in which order.
		// To minimize register usage, if only one branch needs traversing,
		// then that branch should be done first.
		bool evaluateLeft = t.current()->left()->needsEvaluating();
	
		BTreeNode *evaluateFirst;
		BTreeNode *evaluateSecond;
	
		// If both need doing, then it really doesn't matter which we do
		// first (unless we are looking to do really complex optimizations...
	
		// Cases: 
		// - Both need evaluating,
		// - or left needs doing first,
		// in both cases we evaluate left, then right.
		if( evaluateLeft )
		{
			evaluateFirst = t.current()->left();
			evaluateSecond = t.current()->right();
		}
		// Otherwise it is best to evaluate right first for reasons given above.
		else
		{
			evaluateFirst = t.current()->right();
			evaluateSecond = t.current()->left();
		}
		
		QString dest1 = mb->dest();
		mb->incDest();
		QString dest2 = mb->dest();
		mb->decDest();
	
		bool evaluated = false;
		if( evaluateFirst->hasChildren() )
		{	
			traverseTree(evaluateFirst);
			evaluated = true;
		}
		else if( isUnaryOp(evaluateFirst->childOp()) )
		{
			doUnaryOp( evaluateFirst->childOp(), evaluateFirst );
			evaluated = true;
		}
		if ( evaluated )
		{
			// We need to save the result if we are going tro traverse the other
			// branch, or if we are performing a subtraction in which case the
			// value wanted in working is not the current value.
			// But as the optimizer will deal with unnecessary variables anyway,
			// always save to a register
			
			evaluateFirst->setReg( dest1 );
			evaluateFirst->setType( variable );
			m_pic->saveToReg( dest1 );
		}
	
		evaluated = false;
		if( evaluateSecond->hasChildren() )
		{
			mb->incDest();
			mb->incDest();
			traverseTree(evaluateSecond);
			evaluated = true;
			mb->decDest();
			mb->decDest();
		}
		else if( isUnaryOp(evaluateSecond->childOp()) )
		{
			doUnaryOp( evaluateSecond->childOp(), evaluateSecond );
			evaluated = true;
		}
		if ( evaluated )
		{
			evaluateSecond->setReg( dest2 );
			evaluateSecond->setType( variable );
			m_pic->saveToReg( dest2 );
		}
	}
	
	if(t.current()->childOp()==divbyzero)
	{
		mistake( Microbe::DivisionByZero );
	}
	
	// If we are at the top level of something like 'if a == 3 then', then we are ready to put
	// in the if code, else the expression just evaluates to 0 or 1
	if(conditionalRoot && t.current() == root)
		m_pic->setConditionalCode(m_ifCode, m_elseCode);

	// Handle operations
	// (functions are not actually supported)
	if(isUnaryOp(t.current()->childOp()))
		doUnaryOp( t.current()->childOp(), t.current() );
	else
		doOp( t.current()->childOp(), t.current()->left(), t.current()->right() );

}
// Relict from the old times, when automous decisions were accepted
// behavior. Remains in here, because some RenderWindows do exist outside
// of StdMultiWidgets.
bool
SliceNavigationController
::ExecuteAction( Action* action, StateEvent const* stateEvent )
{
  bool ok = false;

  const PositionEvent* posEvent = dynamic_cast< const PositionEvent * >(
    stateEvent->GetEvent() );
  if ( posEvent != NULL )
  {
    if ( m_CreatedWorldGeometry.IsNull() )
    {
      return true;
    }
    switch (action->GetActionId())
    {
    case AcMOVE:
      {
        BaseRenderer *baseRenderer = posEvent->GetSender();
        if ( !baseRenderer )
        {
          baseRenderer = const_cast<BaseRenderer *>(
            GlobalInteraction::GetInstance()->GetFocus() );
        }
        if ( baseRenderer )
          if ( baseRenderer->GetMapperID() == 1 )
          {
            PointOperation doOp(OpMOVE, posEvent->GetWorldPosition());

            this->ExecuteOperation( &doOp );

            // If click was performed in this render window than we have to update the status bar information about position and pixel value.
            if(baseRenderer == m_Renderer)
            {
              {
                std::string statusText;
                TNodePredicateDataType<mitk::Image>::Pointer isImageData = TNodePredicateDataType<mitk::Image>::New();

                mitk::DataStorage::SetOfObjects::ConstPointer nodes = baseRenderer->GetDataStorage()->GetSubset(isImageData).GetPointer();
                mitk::Point3D worldposition = posEvent->GetWorldPosition();
                //int  maxlayer = -32768;
                mitk::Image::Pointer image3D;
                mitk::DataNode::Pointer node;
                mitk::DataNode::Pointer topSourceNode;

                bool isBinary (false);

                node = this->GetTopLayerNode(nodes,worldposition);
                if(node.IsNotNull())
                {
                  node->GetBoolProperty("binary", isBinary);
                  if(isBinary)
                  {
                    mitk::DataStorage::SetOfObjects::ConstPointer sourcenodes = baseRenderer->GetDataStorage()->GetSources(node, NULL, true);
                    if(!sourcenodes->empty())
                    {
                      topSourceNode = this->GetTopLayerNode(sourcenodes,worldposition);
                    }
                    if(topSourceNode.IsNotNull())
                    {
                      image3D = dynamic_cast<mitk::Image*>(topSourceNode->GetData());
                    }
                    else
                    {
                      image3D = dynamic_cast<mitk::Image*>(node->GetData());
                    }
                  }
                  else
                  {
                    image3D = dynamic_cast<mitk::Image*>(node->GetData());
                  }
                }
                std::stringstream stream;
                stream.imbue(std::locale::classic());

                // get the position and gray value from the image and build up status bar text
                if(image3D.IsNotNull())
                {
                  Index3D p;
                  image3D->GetGeometry()->WorldToIndex(worldposition, p);
                  stream.precision(2);
                  stream<<"Position: <" << std::fixed <<worldposition[0] << ", " << std::fixed << worldposition[1] << ", " << std::fixed << worldposition[2] << "> mm";
                  stream<<"; Index: <"<<p[0] << ", " << p[1] << ", " << p[2] << "> ";
                  mitk::ScalarType pixelValue = image3D->GetPixelValueByIndex(p, baseRenderer->GetTimeStep());
                  if (fabs(pixelValue)>1000000 || fabs(pixelValue) < 0.01)
                  {
                    stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: " << std::scientific<< pixelValue <<"  ";
                  }
                  else
                  {
                    stream<<"; Time: " << baseRenderer->GetTime() << " ms; Pixelvalue: "<< pixelValue <<"  ";
                  }
                }
                else
                {
                  stream << "No image information at this position!";
                }

                statusText = stream.str();
                mitk::StatusBar::GetInstance()->DisplayGreyValueText(statusText.c_str());

              }

            }
            ok = true;
            break;
          }
      }
    default:
      ok = true;
      break;
    }
    return ok;
  }

  const DisplayPositionEvent *displPosEvent =
    dynamic_cast< const DisplayPositionEvent * >( stateEvent->GetEvent() );

  if ( displPosEvent != NULL )
  {
    return true;
  }

  return false;
}