<commit_before>/*=========================================================================

  Program:   itkUNC
  Module:    $RCSfile: itkSpline1D.cxx,v $
  Language:  C++
  Date:      $Date: 2003/01/13 19:59:26 $
  Version:   $Revision: 1.3 $

  Copyright (c) 2002 CADDLab @ UNC. All rights reserved.
  See itkUNCCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkSpline1D.h"
#include <cmath>

namespace itk
{

class Spline1DValFunc : public UserFunc<double, double>
{
  Spline1D * spline;
  double cVal;
public:
  Spline1DValFunc(Spline1D * newSpline)
    {
    spline = newSpline;
    cVal = 0;
    };
  const double & value(const double & x)
    {
    cVal = spline->value(x);
    return cVal;
    };
};

class Spline1DDerivFunc : public UserFunc<double, double>
{
  Spline1D * spline;
  double cDeriv;
public:
  Spline1DDerivFunc(Spline1D * newSpline)
    {
    spline = newSpline;
    cDeriv = 0;
    };
  const double & value(const double & x)
    {
    cDeriv = spline->valueD(x);
    return cDeriv;
    }
};

//
//
//
Spline1D::
Spline1D()
{
  cDefined = false;

  cClip = true;

  cXMin = 0;
  cXMax = 1;

  cOpt1DVal = new Spline1DValFunc(this);
  cOpt1DDeriv = new Spline1DDerivFunc(this);

  use(NULL, NULL);
}

Spline1D::
Spline1D(UserFunc<int, double> *newFuncVal, Optimizer1D *newOpt1D)
{
  cDefined = false;

  cClip = true;

  cXMin = 0;
  cXMax = 1;

  cData.set_size(4);

  cOpt1DVal = new Spline1DValFunc(this);
  cOpt1DDeriv = new Spline1DDerivFunc(this);

  use(newFuncVal, newOpt1D);
}

Spline1D::
~Spline1D()
{
  if(cDefined)
  {
    cDefined = false;

    delete cOpt1DVal;
    delete cOpt1DDeriv;
  }
}

//
//
//
void Spline1D::
use(UserFunc<int, double> *newFuncVal, Optimizer1D *newOpt1D)
{
    cDefined = true;

    cFuncVal = newFuncVal;

    cOpt1D = newOpt1D;
    if(cOpt1D != NULL)
        cOpt1D->use(cOpt1DVal, cOpt1DDeriv);

    cNewData = true;
}

//
//
//
bool Spline1D::
clipEdge(void)
{
    return cClip;
}

void Spline1D::
clipEdge(bool newClip)
{
    cClip = newClip;
}

int Spline1D::
xMin(void)
{
    return cXMin;
}

void Spline1D::
xMin(int newXMin)
{
    cXMin = newXMin;
}

int Spline1D::
xMax(void)
{
    return cXMax;
}

void Spline1D::
xMax(int newXMax)
{
    cXMax = newXMax;
}

//
//
//
bool Spline1D::
newData(void)
{
    return cNewData;
}

void Spline1D::
newData(bool newNewData)
{
    cNewData = newNewData;
}

//
//
//
void Spline1D::
cGetData(double x)
{
  static int xi = (int)x;

  if((int)x != xi || cNewData)
    {
    int lx = xi;
    xi = (int)x;
    int offset = xi-lx;
    if( cNewData )
      {
      offset = 100;
      }
    cNewData = false;
    vnl_vector<double> tmpData(4);
    int j=0;
    for(int i=xi-1; i<=xi+2; i++)
      {
      if( j+offset >= 0 && j+offset <= 3 )
        {
        tmpData[j] = cData[j+offset];
        //std::cout << "j = " << j << " : reuse i = " << i
          //<< " : v = " << tmpData[j] << std::endl;
        j++;
        }
      else
        {
        if(i>=cXMin && i<=cXMax)
          {
          tmpData[j++] = cFuncVal->value(i);
          }
        else
          {
          if(i<cXMin)
            {
            if(cClip)
              {
              tmpData[j++] = 0;
              }
            else
              {
              tmpData[j++] = cFuncVal->value(cXMin) / (1+(cXMin-i));
              }
            }
          else
            {
            if(i>cXMax)
              {
              if(cClip)
                {
                tmpData[j++]= 0;
                }
              else
                {
                tmpData[j++] = cFuncVal->value(cXMax) / (1+(i-cXMax));
                }
              }
            }
          }
        }
      }
    for(j=0; j<4; j++)
      {
      cData[j] = tmpData[j];
      //std::cout << "  cData[" << j << "] = " << cData[j] << std::endl;
      }
    }
}

//
//
//
double Spline1D::
value(double x)
{
    if(!cDefined || (cClip && ((int)x<cXMin || (int)x>cXMax)))
        return 0;

    cGetData(x);

    return dataValue(cData, x - (int)x);
}

double Spline1D::
valueD(double x)
{
    if(!cDefined || (cClip && ((int)x<cXMin || (int)x>cXMax)))
        return 0;

    cGetData(x);

    return dataValueD(cData, x - (int)x);
}

double Spline1D::
valueD2(double x)
{
    if(!cDefined || (cClip && ((int)x<cXMin || (int)x>cXMax)))
        return 0;

    cGetData(x);

    return dataValueD2(cData, x - (int)x);
}

double Spline1D::
curv(double x)
{
    if(!cDefined || (cClip && ((int)x<cXMin || (int)x>cXMax)))
        return 0;

    double xp = valueD(x);

    double xpp = valueD2(x);

    return xpp/pow(1.0+xp*xp, 1.5);
}

double Spline1D::
valueJet(double x, double * d, double * d2)
{
  if(!cDefined || (cClip && ((int)x<cXMin || (int)x>cXMax)))
  {
    return 0;
  }

  cGetData(x);

  return dataValueJet(cData, x - (int)x, d, d2);
}

//
//
//
bool Spline1D::
extreme(double * extX, double * extVal)
{
    return cOpt1D->extreme(extX, extVal);
}

}; // namespace
<commit_msg>ENH: Setting the spline's limits sets the optimizer's limits.<commit_after>/*=========================================================================

  Program:   itkUNC
  Module:    $RCSfile: itkSpline1D.cxx,v $
  Language:  C++
  Date:      $Date: 2003/01/13 19:59:26 $
  Version:   $Revision: 1.3 $

  Copyright (c) 2002 CADDLab @ UNC. All rights reserved.
  See itkUNCCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "itkSpline1D.h"
#include <cmath>

namespace itk
{

class Spline1DValFunc : public UserFunc<double, double>
{
  Spline1D * spline;
  double cVal;
public:
  Spline1DValFunc(Spline1D * newSpline)
    {
    spline = newSpline;
    cVal = 0;
    };
  const double & value(const double & x)
    {
    cVal = spline->value(x);
    std::cout << "Spline x = " << x << " : val = " << cVal << std::endl;
    return cVal;
    };
};

class Spline1DDerivFunc : public UserFunc<double, double>
{
  Spline1D * spline;
  double cDeriv;
public:
  Spline1DDerivFunc(Spline1D * newSpline)
    {
    spline = newSpline;
    cDeriv = 0;
    };
  const double & value(const double & x)
    {
    cDeriv = spline->valueD(x);
    std::cout << "Spline x = " << x << " : dx = " << cDeriv << std::endl;
    return cDeriv;
    }
};

//
//
//
Spline1D::
Spline1D()
{
  cDefined = false;

  cClip = true;

  cXMin = 0;
  cXMax = 1;

  cOpt1DVal = new Spline1DValFunc(this);
  cOpt1DDeriv = new Spline1DDerivFunc(this);

  use(NULL, NULL);
}

Spline1D::
Spline1D(UserFunc<int, double> *newFuncVal, Optimizer1D *newOpt1D)
{
  cDefined = false;

  cClip = true;

  cXMin = 0;
  cXMax = 1;

  cData.set_size(4);

  cOpt1DVal = new Spline1DValFunc(this);
  cOpt1DDeriv = new Spline1DDerivFunc(this);

  use(newFuncVal, newOpt1D);
}

Spline1D::
~Spline1D()
{
  if(cDefined)
  {
    cDefined = false;

    delete cOpt1DVal;
    delete cOpt1DDeriv;
  }
}

//
//
//
void Spline1D::
use(UserFunc<int, double> *newFuncVal, Optimizer1D *newOpt1D)
{
    cDefined = true;

    cFuncVal = newFuncVal;

    cOpt1D = newOpt1D;
    if(cOpt1D != NULL)
      {
      cOpt1D->use(cOpt1DVal, cOpt1DDeriv);
      }

    cNewData = true;
}

//
//
//
bool Spline1D::
clipEdge(void)
{
    return cClip;
}

void Spline1D::
clipEdge(bool newClip)
{
    cClip = newClip;
}

int Spline1D::
xMin(void)
{
    return cXMin;
}

void Spline1D::
xMin(int newXMin)
{
    cXMin = newXMin;
    if(cOpt1D)
      {
      cOpt1D->xMin( cXMin );
      }
}

int Spline1D::
xMax(void)
{
    return cXMax;
}

void Spline1D::
xMax(int newXMax)
{
    cXMax = newXMax;
    if(cOpt1D)
      {
      cOpt1D->xMax( cXMax );
      }
}

//
//
//
bool Spline1D::
newData(void)
{
    return cNewData;
}

void Spline1D::
newData(bool newNewData)
{
    cNewData = newNewData;
}

//
//
//
void Spline1D::
cGetData(double x)
{
  static int xi = (int)x;

  if((int)x != xi || cNewData)
    {
    int lx = xi;
    xi = (int)x;
    int offset = xi-lx;
    if( cNewData )
      {
      offset = 100;
      }
    cNewData = false;
    vnl_vector<double> tmpData(4);
    int j=0;
    for(int i=xi-1; i<=xi+2; i++)
      {
      if( j+offset >= 0 && j+offset <= 3 )
        {
        tmpData[j] = cData[j+offset];
        //std::cout << "j = " << j << " : reuse i = " << i
          //<< " : v = " << tmpData[j] << std::endl;
        j++;
        }
      else
        {
        if(i>=cXMin && i<=cXMax)
          {
          tmpData[j++] = cFuncVal->value(i);
          }
        else
          {
          if(i<cXMin)
            {
            if(cClip)
              {
              tmpData[j++] = 0;
              }
            else
              {
              tmpData[j++] = cFuncVal->value(cXMin) / (1+(cXMin-i));
              }
            }
          else
            {
            if(i>cXMax)
              {
              if(cClip)
                {
                tmpData[j++]= 0;
                }
              else
                {
                tmpData[j++] = cFuncVal->value(cXMax) / (1+(i-cXMax));
                }
              }
            }
          }
        }
      }
    for(j=0; j<4; j++)
      {
      cData[j] = tmpData[j];
      //std::cout << "  cData[" << j << "] = " << cData[j] << std::endl;
      }
    }
}

//
//
//
double Spline1D::
value(double x)
{
    if(!cDefined || (cClip && ((int)x<cXMin || (int)x>cXMax)))
        return 0;

    cGetData(x);

    return dataValue(cData, x - (int)x);
}

double Spline1D::
valueD(double x)
{
    if(!cDefined || (cClip && ((int)x<cXMin || (int)x>cXMax)))
        return 0;

    cGetData(x);

    return dataValueD(cData, x - (int)x);
}

double Spline1D::
valueD2(double x)
{
    if(!cDefined || (cClip && ((int)x<cXMin || (int)x>cXMax)))
        return 0;

    cGetData(x);

    return dataValueD2(cData, x - (int)x);
}

double Spline1D::
curv(double x)
{
    if(!cDefined || (cClip && ((int)x<cXMin || (int)x>cXMax)))
        return 0;

    double xp = valueD(x);

    double xpp = valueD2(x);

    return xpp/pow(1.0+xp*xp, 1.5);
}

double Spline1D::
valueJet(double x, double * d, double * d2)
{
  if(!cDefined || (cClip && ((int)x<cXMin || (int)x>cXMax)))
  {
    return 0;
  }

  cGetData(x);

  return dataValueJet(cData, x - (int)x, d, d2);
}

//
//
//
bool Spline1D::
extreme(double * extX, double * extVal)
{
    return cOpt1D->extreme(extX, extVal);
}

}; // namespace
<|endoftext|>


<commit_before>#include "GreaterThan.h"

    GreaterThan::GreaterThan(Runcmd* r, Runcmd* l) : Connector(">",r,l)
    {

    }

    bool GreaterThan::run()
    {

            char file[256];
            strcpy(file, rhs->getCmd().c_str());
            int redir;
            if((redir = open(file, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IROTH | S_IRGRP)) == -1)
            {
    			perror("Redir Error: Could not open file");
    			return false;

    		}
            int saveStdout = dup(1);

            if(-1 == dup2(redir, 1))
            {
	        	perror("There was an error with dup2");

            }

            lhs->run();

            if(-1 == dup2(saveStdout, 1))
            {
	        	perror("There was an error with dup2");

            }
            return true;

    }
<commit_msg>Create GreaterThan.cpp<commit_after>#include "GreaterThan.h"

    GreaterThan::GreaterThan(Runcmd* r, Runcmd* l) : Connector(">",r,l)
    {

    }

    bool GreaterThan::run()
    {

            char file[256];
            strcpy(file, rhs->getCmd().c_str());
            int redir;
            if((redir = open(file, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IROTH | S_IRGRP)) == -1)
            {
    			perror("Redir Error: Could not open file");
    			return false;

    		}
            int sd = dup(1);

            if(-1 == dup2(redir, 1))
            {
	        	perror("There was an error with dup2");

            }

            lhs->run();

            if(-1 == dup2(sd, 1))
            {
	        	perror("There was an error with dup2");

            }
            return true;

    }
<|endoftext|>


<commit_before>/***************************************************************************
 *   Copyright (c) 2007 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <boost/signals.hpp>
# include <boost/bind.hpp>
# include <qapplication.h>
# include <qregexp.h>
# include <QEvent>
# include <QCloseEvent>
# include <QMdiSubWindow>
#include <iostream>
#endif

#include "MDIView.h"
#include "Command.h"
#include "Document.h"
#include "Application.h"
#include "MainWindow.h"
#include "ViewProviderDocumentObject.h"

using namespace Gui;

TYPESYSTEM_SOURCE_ABSTRACT(Gui::MDIView,Gui::BaseView);

MDIView::MDIView(Gui::Document* pcDocument,QWidget* parent, Qt::WFlags wflags)
  : QMainWindow(parent, wflags), BaseView(pcDocument),currentMode(Child), wstate(Qt::WindowNoState)
{
    setAttribute(Qt::WA_DeleteOnClose);

    connectDelObject = pcDocument->signalDeletedObject.connect
      (boost::bind(&ActiveObjectList::objectDeleted, &ActiveObjects, _1));
}

MDIView::~MDIView()
{
    //This view might be the focus widget of the main window. In this case we must
    //clear the focus and e.g. set the focus directly to the main window, otherwise
    //the application crashes when accessing this deleted view.
    //This effect only occurs if this widget is not in Child mode, because otherwise
    //the focus stuff is done correctly.
    if (getMainWindow()) {
        QWidget* foc = getMainWindow()->focusWidget();
        if (foc) {
            QWidget* par = foc;
            while (par) {
                if (par == this) {
                    getMainWindow()->setFocus();
                    break;
                }
                par = par->parentWidget();
            }
        }
    }

}

void MDIView::deleteSelf()
{
    // When using QMdiArea make sure to remove the QMdiSubWindow
    // this view is associated with.
    //
    // #0001023: Crash when quitting after using Windows > Tile
    // Use deleteLater() instead of delete operator.
#if !defined (NO_USE_QT_MDI_AREA)
    QWidget* parent = this->parentWidget();
    if (qobject_cast<QMdiSubWindow*>(parent))
        parent->deleteLater();
    else
#endif
        this->deleteLater();
    _pcDocument = 0;
}

void MDIView::setOverrideCursor(const QCursor& c)
{
}

void  MDIView::restoreOverrideCursor()
{
}

void MDIView::onRelabel(Gui::Document *pDoc)
{
    if (!bIsPassive) {
        // Try to separate document name and view number if there is one
        QString cap = windowTitle();
        // Either with dirty flag ...
        QRegExp rx(QLatin1String("(\\s\\:\\s\\d+\\[\\*\\])$"));
        int pos = rx.lastIndexIn(cap);
        if (pos == -1) {
            // ... or not
            rx.setPattern(QLatin1String("(\\s\\:\\s\\d+)$"));
            pos = rx.lastIndexIn(cap);
        }
        if (pos != -1) {
            cap = QString::fromUtf8(pDoc->getDocument()->Label.getValue());
            cap += rx.cap();
            setWindowTitle(cap);
        }
        else {
            cap = QString::fromUtf8(pDoc->getDocument()->Label.getValue());
            cap = QString::fromAscii("%1[*]").arg(cap);
            setWindowTitle(cap);
        }
    }
}

void MDIView::viewAll()
{
}

/// receive a message
bool MDIView::onMsg(const char* pMsg,const char** ppReturn)
{
    return false;
}

bool MDIView::onHasMsg(const char* pMsg) const
{
    return false;
}

bool MDIView::canClose(void)
{
    if (!bIsPassive && getGuiDocument() && getGuiDocument()->isLastView()) {
        this->setFocus(); // raises the view to front
        return (getGuiDocument()->canClose());
    }

    return true;
}

void MDIView::closeEvent(QCloseEvent *e)
{
    if (canClose()) {
        e->accept();
        if (!bIsPassive) {
            // must be detached so that the last view can get asked
            Document* doc = this->getGuiDocument();
            if (doc && !doc->isLastView())
                doc->detachView(this);
        }

        // Note: When using QMdiArea we must not use removeWindow()
        // because otherwise the QMdiSubWindow will loose its parent
        // and thus the notification in QMdiSubWindow::closeEvent of
        // other mdi windows to get maximized if this window
        // is maximized will fail.
        // This odd behaviour is caused by the invocation of
        // d->mdiArea->removeSubWindow(parent) which we must let there
        // because otherwise other parts don't work as they should.
#if defined (NO_USE_QT_MDI_AREA)
        // avoid flickering
        getMainWindow()->removeWindow(this);
#endif
        QMainWindow::closeEvent(e);
    }
    else
        e->ignore();
}

void MDIView::windowStateChanged( MDIView* )
{
}

void MDIView::print(QPrinter* printer)
{
    std::cerr << "Printing not implemented for " << this->metaObject()->className() << std::endl;
}

void MDIView::print()
{
    std::cerr << "Printing not implemented for " << this->metaObject()->className() << std::endl;
}

void MDIView::printPdf()
{
    std::cerr << "Printing PDF not implemented for " << this->metaObject()->className() << std::endl;
}

void MDIView::printPreview()
{
    std::cerr << "Printing preview not implemented for " << this->metaObject()->className() << std::endl;
}

QSize MDIView::minimumSizeHint () const
{
    return QSize(400, 300);
}

void MDIView::changeEvent(QEvent *e)
{
    switch (e->type()) {
        case QEvent::ActivationChange:
            {
                // Forces this top-level window to be the active view of the main window
                if (isActiveWindow()) {
                    if (getMainWindow()->activeWindow() != this)
                        getMainWindow()->setActiveWindow(this);
                }
            }   break;
        case QEvent::WindowTitleChange:
        case QEvent::ModifiedChange:
            {
                // sets the appropriate tab of the tabbar
                getMainWindow()->tabChanged(this);
            }   break;
        default:
            {
                QMainWindow::changeEvent(e);
            }   break;
    }
}

#if defined(Q_WS_X11)
// To fix bug #0000345 move function declaration to here
extern void qt_x11_wait_for_window_manager( QWidget* w ); // defined in qwidget_x11.cpp
#endif

void MDIView::setCurrentViewMode(ViewMode mode)
{
    switch (mode) {
        // go to normal mode
        case Child:
            {
                if (this->currentMode == FullScreen) {
                    showNormal();
                    setWindowFlags(windowFlags() & ~Qt::Window);
                }
                else if (this->currentMode == TopLevel) {
                    this->wstate = windowState();
                    setWindowFlags( windowFlags() & ~Qt::Window );
                }

                if (this->currentMode != Child) {
                    this->currentMode = Child;
                    getMainWindow()->addWindow(this);
                    getMainWindow()->activateWindow();
                    update();
                }
            }   break;
        // go to top-level mode
        case TopLevel:
            {
                if (this->currentMode == Child) {
#if !defined (NO_USE_QT_MDI_AREA)
                    if (qobject_cast<QMdiSubWindow*>(this->parentWidget()))
#endif
                        getMainWindow()->removeWindow(this);
                    setWindowFlags(windowFlags() | Qt::Window);
                    setParent(0, Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
                                 Qt::WindowMinMaxButtonsHint);
                    if (this->wstate & Qt::WindowMaximized)
                        showMaximized();
                    else
                        showNormal();

#if defined(Q_WS_X11)
                    //extern void qt_x11_wait_for_window_manager( QWidget* w ); // defined in qwidget_x11.cpp
                    qt_x11_wait_for_window_manager(this);
#endif
                    activateWindow();
                }
                else if (this->currentMode == FullScreen) {
                    if (this->wstate & Qt::WindowMaximized)
                        showMaximized();
                    else
                        showNormal();
                }

                this->currentMode = TopLevel;
                update();
            }   break;
        // go to fullscreen mode
        case FullScreen:
            {
                if (this->currentMode == Child) {
#if !defined (NO_USE_QT_MDI_AREA)
                    if (qobject_cast<QMdiSubWindow*>(this->parentWidget()))
#endif
                        getMainWindow()->removeWindow(this);
                    setWindowFlags(windowFlags() | Qt::Window);
                    setParent(0, Qt::Window);
                    showFullScreen();
                }
                else if (this->currentMode == TopLevel) {
                    this->wstate = windowState();
                    showFullScreen();
                }

                this->currentMode = FullScreen;
                update();
            }   break;
    }
}

#include "moc_MDIView.cpp"
<commit_msg>Gui: MDIView: connection bug. SQUASH me to: a1c3ba8 Gui: ActiveObject: remove upon delete<commit_after>/***************************************************************************
 *   Copyright (c) 2007 Werner Mayer <wmayer[at]users.sourceforge.net>     *
 *                                                                         *
 *   This file is part of the FreeCAD CAx development system.              *
 *                                                                         *
 *   This library is free software; you can redistribute it and/or         *
 *   modify it under the terms of the GNU Library General Public           *
 *   License as published by the Free Software Foundation; either          *
 *   version 2 of the License, or (at your option) any later version.      *
 *                                                                         *
 *   This library  is distributed in the hope that it will be useful,      *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU Library General Public License for more details.                  *
 *                                                                         *
 *   You should have received a copy of the GNU Library General Public     *
 *   License along with this library; see the file COPYING.LIB. If not,    *
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
 *   Suite 330, Boston, MA  02111-1307, USA                                *
 *                                                                         *
 ***************************************************************************/

#include "PreCompiled.h"

#ifndef _PreComp_
# include <boost/signals.hpp>
# include <boost/bind.hpp>
# include <qapplication.h>
# include <qregexp.h>
# include <QEvent>
# include <QCloseEvent>
# include <QMdiSubWindow>
#include <iostream>
#endif

#include "MDIView.h"
#include "Command.h"
#include "Document.h"
#include "Application.h"
#include "MainWindow.h"
#include "ViewProviderDocumentObject.h"

using namespace Gui;

TYPESYSTEM_SOURCE_ABSTRACT(Gui::MDIView,Gui::BaseView);

MDIView::MDIView(Gui::Document* pcDocument,QWidget* parent, Qt::WFlags wflags)
  : QMainWindow(parent, wflags), BaseView(pcDocument),currentMode(Child), wstate(Qt::WindowNoState)
{
    setAttribute(Qt::WA_DeleteOnClose);

    if (pcDocument)
    {
      connectDelObject = pcDocument->signalDeletedObject.connect
        (boost::bind(&ActiveObjectList::objectDeleted, &ActiveObjects, _1));
      assert(connectDelObject.connected());
    }
}

MDIView::~MDIView()
{
    //This view might be the focus widget of the main window. In this case we must
    //clear the focus and e.g. set the focus directly to the main window, otherwise
    //the application crashes when accessing this deleted view.
    //This effect only occurs if this widget is not in Child mode, because otherwise
    //the focus stuff is done correctly.
    if (getMainWindow()) {
        QWidget* foc = getMainWindow()->focusWidget();
        if (foc) {
            QWidget* par = foc;
            while (par) {
                if (par == this) {
                    getMainWindow()->setFocus();
                    break;
                }
                par = par->parentWidget();
            }
        }
    }

}

void MDIView::deleteSelf()
{
    // When using QMdiArea make sure to remove the QMdiSubWindow
    // this view is associated with.
    //
    // #0001023: Crash when quitting after using Windows > Tile
    // Use deleteLater() instead of delete operator.
#if !defined (NO_USE_QT_MDI_AREA)
    QWidget* parent = this->parentWidget();
    if (qobject_cast<QMdiSubWindow*>(parent))
        parent->deleteLater();
    else
#endif
        this->deleteLater();
    _pcDocument = 0;
}

void MDIView::setOverrideCursor(const QCursor& c)
{
}

void  MDIView::restoreOverrideCursor()
{
}

void MDIView::onRelabel(Gui::Document *pDoc)
{
    if (!bIsPassive) {
        // Try to separate document name and view number if there is one
        QString cap = windowTitle();
        // Either with dirty flag ...
        QRegExp rx(QLatin1String("(\\s\\:\\s\\d+\\[\\*\\])$"));
        int pos = rx.lastIndexIn(cap);
        if (pos == -1) {
            // ... or not
            rx.setPattern(QLatin1String("(\\s\\:\\s\\d+)$"));
            pos = rx.lastIndexIn(cap);
        }
        if (pos != -1) {
            cap = QString::fromUtf8(pDoc->getDocument()->Label.getValue());
            cap += rx.cap();
            setWindowTitle(cap);
        }
        else {
            cap = QString::fromUtf8(pDoc->getDocument()->Label.getValue());
            cap = QString::fromAscii("%1[*]").arg(cap);
            setWindowTitle(cap);
        }
    }
}

void MDIView::viewAll()
{
}

/// receive a message
bool MDIView::onMsg(const char* pMsg,const char** ppReturn)
{
    return false;
}

bool MDIView::onHasMsg(const char* pMsg) const
{
    return false;
}

bool MDIView::canClose(void)
{
    if (!bIsPassive && getGuiDocument() && getGuiDocument()->isLastView()) {
        this->setFocus(); // raises the view to front
        return (getGuiDocument()->canClose());
    }

    return true;
}

void MDIView::closeEvent(QCloseEvent *e)
{
    if (canClose()) {
        e->accept();
        if (!bIsPassive) {
            // must be detached so that the last view can get asked
            Document* doc = this->getGuiDocument();
            if (doc && !doc->isLastView())
                doc->detachView(this);
        }

        // Note: When using QMdiArea we must not use removeWindow()
        // because otherwise the QMdiSubWindow will loose its parent
        // and thus the notification in QMdiSubWindow::closeEvent of
        // other mdi windows to get maximized if this window
        // is maximized will fail.
        // This odd behaviour is caused by the invocation of
        // d->mdiArea->removeSubWindow(parent) which we must let there
        // because otherwise other parts don't work as they should.
#if defined (NO_USE_QT_MDI_AREA)
        // avoid flickering
        getMainWindow()->removeWindow(this);
#endif
        QMainWindow::closeEvent(e);
    }
    else
        e->ignore();
}

void MDIView::windowStateChanged( MDIView* )
{
}

void MDIView::print(QPrinter* printer)
{
    std::cerr << "Printing not implemented for " << this->metaObject()->className() << std::endl;
}

void MDIView::print()
{
    std::cerr << "Printing not implemented for " << this->metaObject()->className() << std::endl;
}

void MDIView::printPdf()
{
    std::cerr << "Printing PDF not implemented for " << this->metaObject()->className() << std::endl;
}

void MDIView::printPreview()
{
    std::cerr << "Printing preview not implemented for " << this->metaObject()->className() << std::endl;
}

QSize MDIView::minimumSizeHint () const
{
    return QSize(400, 300);
}

void MDIView::changeEvent(QEvent *e)
{
    switch (e->type()) {
        case QEvent::ActivationChange:
            {
                // Forces this top-level window to be the active view of the main window
                if (isActiveWindow()) {
                    if (getMainWindow()->activeWindow() != this)
                        getMainWindow()->setActiveWindow(this);
                }
            }   break;
        case QEvent::WindowTitleChange:
        case QEvent::ModifiedChange:
            {
                // sets the appropriate tab of the tabbar
                getMainWindow()->tabChanged(this);
            }   break;
        default:
            {
                QMainWindow::changeEvent(e);
            }   break;
    }
}

#if defined(Q_WS_X11)
// To fix bug #0000345 move function declaration to here
extern void qt_x11_wait_for_window_manager( QWidget* w ); // defined in qwidget_x11.cpp
#endif

void MDIView::setCurrentViewMode(ViewMode mode)
{
    switch (mode) {
        // go to normal mode
        case Child:
            {
                if (this->currentMode == FullScreen) {
                    showNormal();
                    setWindowFlags(windowFlags() & ~Qt::Window);
                }
                else if (this->currentMode == TopLevel) {
                    this->wstate = windowState();
                    setWindowFlags( windowFlags() & ~Qt::Window );
                }

                if (this->currentMode != Child) {
                    this->currentMode = Child;
                    getMainWindow()->addWindow(this);
                    getMainWindow()->activateWindow();
                    update();
                }
            }   break;
        // go to top-level mode
        case TopLevel:
            {
                if (this->currentMode == Child) {
#if !defined (NO_USE_QT_MDI_AREA)
                    if (qobject_cast<QMdiSubWindow*>(this->parentWidget()))
#endif
                        getMainWindow()->removeWindow(this);
                    setWindowFlags(windowFlags() | Qt::Window);
                    setParent(0, Qt::Window | Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
                                 Qt::WindowMinMaxButtonsHint);
                    if (this->wstate & Qt::WindowMaximized)
                        showMaximized();
                    else
                        showNormal();

#if defined(Q_WS_X11)
                    //extern void qt_x11_wait_for_window_manager( QWidget* w ); // defined in qwidget_x11.cpp
                    qt_x11_wait_for_window_manager(this);
#endif
                    activateWindow();
                }
                else if (this->currentMode == FullScreen) {
                    if (this->wstate & Qt::WindowMaximized)
                        showMaximized();
                    else
                        showNormal();
                }

                this->currentMode = TopLevel;
                update();
            }   break;
        // go to fullscreen mode
        case FullScreen:
            {
                if (this->currentMode == Child) {
#if !defined (NO_USE_QT_MDI_AREA)
                    if (qobject_cast<QMdiSubWindow*>(this->parentWidget()))
#endif
                        getMainWindow()->removeWindow(this);
                    setWindowFlags(windowFlags() | Qt::Window);
                    setParent(0, Qt::Window);
                    showFullScreen();
                }
                else if (this->currentMode == TopLevel) {
                    this->wstate = windowState();
                    showFullScreen();
                }

                this->currentMode = FullScreen;
                update();
            }   break;
    }
}

#include "moc_MDIView.cpp"
<|endoftext|>


<commit_before>#include "Interpreter.hpp"
#include <cmath>
#include <sstream>

int factorial(int n);
int nowspeek(std::istream& is);
double sgn(double x);

Interpreter::Interpreter()
{
}

double Interpreter::exponent(std::istream& is)
{
	double left = operand(is);

	while(true)
		switch(nowspeek(is))
		{
			case '^':
				is.get();
				left = std::pow(left, operand(is));
				break;
			case '!':
				is.get();
				left = factorial(left);
				break;
			default:
				return left;
		}
}

double Interpreter::factor(std::istream& is)
{
	double left = exponent(is);

	while(true)
		switch(nowspeek(is))
		{
			case '*':
				is.get();
				left *= exponent(is);
				break;
			case '/':
				is.get();
				left /= exponent(is);
				break;
			default:
				return left;
		}

	throw 1;
}

double Interpreter::interpret(std::istream& is)
{
	double value = term(is);
	is.ignore();
	return value;
}

double Interpreter::operand(std::istream& is)
{
	static const std::unordered_map<std::string, double(*)(double)> functions
	{
		{"abs", std::fabs},
		{"acos", std::acos},
		{"acosh", std::acosh},
		{"asin", std::asin},
		{"asinh", std::asinh},
		{"atan", std::atan},
		{"atanh", std::atanh},
		{"ceil", std::ceil},
		{"cos", std::cos},
		{"cosh", std::cosh},
		{"exp", std::exp},
		{"floor", std::floor},
		{"log", std::log},
		{"log10", std::log10},
		{"log2", std::log2},
		{"round", std::round},
		{"sgn", sgn},
		{"sin", std::sin},
		{"sinh", std::sinh},
		{"sqrt", std::sqrt},
		{"tan", std::tan},
		{"tanh", std::tanh},
		{"trunc", std::trunc},
	};

	static const std::unordered_map<std::string, double> constants
	{
		{"e", M_E},
		{"inf", INFINITY},
		{"nan", NAN},
		{"pi", M_PI},
	};

	switch(nowspeek(is))
	{
		case '-':
			is.get();
			return -operand(is);
		case '(':
			{
				is.get();

				double value = term(is);
				if(is.get() == ')')
					return value;

				break;
			}
		default:
			{
				std::string name;
				while(std::isalpha(nowspeek(is)))
					name += (char) is.get();

				if(!name.empty())
				{
					auto functionPosition = functions.find(name);
					if(functionPosition != functions.end())
						return functionPosition->second(operand(is));

					auto constantPosition = constants.find(name);
					if(constantPosition != constants.end())
						return constantPosition->second;

					switch(nowspeek(is))
					{
						case '=':
							is.get();
							return storage[name] = term(is);
						default:
							return storage[name];
					}
				}
				else
				{
					double value;

					if(is >> value)
						return value;
				}

				break;
			}
	}

	throw 1;
}

void Interpreter::setGlobalValue(const std::string& name, double value)
{
	storage[name] = value;
}

double Interpreter::term(std::istream& is)
{
	double left = factor(is);

	while(true)
		switch(nowspeek(is))
		{
			case '+':
				is.get();
				left += factor(is);
				break;
			case '-':
				is.get();
				left -= factor(is);
				break;
			default:
				return left;
		}

	throw 1;
}

double testInterpreter(Interpreter& interp, const std::string& expression);
void performTests();

int main(int, char**)
{

#ifdef DEBUG
	performTests();
#else
	Interpreter interp;

	while(true)
	{
		std::cout << ">> ";
		std::cout.flush();
		std::cout << interp.interpret(std::cin) << std::endl;
	}
#endif /* DEBUG */

	return 0;
}

int factorial(int n)
{
	if(n < 0)
		throw 1;
	else if(n == 0)
		return 1;
	else
		return n * factorial(n - 1);
}

int nowspeek(std::istream& is)
{
	while(is.peek() == ' ')
		is.get();

	return is.peek();
}

double sgn(double x)
{
	if(x < 0)
		return -1;
	else if(x > 0)
		return 1;
	else
		return 0;
}

double testInterpreter(Interpreter& interp, const std::string& expression)
{
	std::istringstream iss{expression};
	return interp.interpret(iss);
}

void performTests()
{
	Interpreter interp;

	double h;

	std::pair<double, std::string> tests[] =
	{
		{2+3, "2+3"},
		{-4*5, "-4*5"},
		{2+-4, "2+-4"},
		{5*3+4, "5*3+4"},
		{5+3*4, "5+3*4"},
		{(5+3)*4, "(5+3)*4"},
		{-(5+3)*4, "-(5+3)*4"},
		{5*-(6*(9+3)+4), "5*-(6*(9+3)+4)"},
		{6-8/3e4, "6-8/3e4"},
		{3*std::pow(4,5)-6, "3*4^5-6"},
		{7*factorial(6)+3, "7*6!+3"},
		{factorial(2*3+3), "(2*3+3)!"},
		{std::pow(4+7*8,9+4), "(4+7*8)^(9+4)"},
		{std::pow(3, std::pow(2, 4)), "3^(2^4)"},
		{M_PI*(3-9), "pi*(3-9)"},
		{(-M_E+4)*8, "(-e+4)*8"},
		{h=99, "h=99"},
		{h*8+3, "h*8+3"},
		{h=-(8+M_PI)/4, "h=-(8+pi)/4"},
		{h, "h"},
		{std::sin(45), "sin 45"},
		{std::sin(45*3), "sin(45*3)"},
		{std::trunc(45.3), "trunc 45.3"},
		{-std::ceil(45.333), "-ceil 45.333"},
	};

	std::size_t numTests = 0, numTestPassed = 0;

	for(const auto& test: tests)
	{
		double cpp = test.first, smi = testInterpreter(interp, test.second);

		std::cout
			<< test.second << std::endl
			<< "  C++ " << cpp << std::endl
			<< "  smi " << smi << std::endl
			<< "  " << (cpp == smi ? "PASSED" : "MAYBE FAILED")  << std::endl
			<< std::endl
			;

		++numTests;
		numTestPassed += (cpp == smi ? 1 : 0);
	}

	std::cout << "Tests " << numTests << ", passed " << numTestPassed << std::endl;
}
<commit_msg>Added error checks<commit_after>#include "Interpreter.hpp"
#include <cmath>
#include <sstream>

int factorial(int n);
int nowspeek(std::istream& is);
double sgn(double x);

Interpreter::Interpreter()
{
}

double Interpreter::exponent(std::istream& is)
{
	double left = operand(is);

	while(true)
		switch(nowspeek(is))
		{
			case '^':
				is.get();
				left = std::pow(left, operand(is));
				break;
			case '!':
				is.get();
				left = factorial(left);
				break;
			default:
				return left;
		}
}

double Interpreter::factor(std::istream& is)
{
	double left = exponent(is);

	while(true)
		switch(nowspeek(is))
		{
			case '*':
				is.get();
				left *= exponent(is);
				break;
			case '/':
				is.get();
				left /= exponent(is);
				break;
			default:
				return left;
		}

	throw 1;
}

double Interpreter::interpret(std::istream& is)
{
	double value = term(is);
	is.ignore();
	return value;
}

double Interpreter::operand(std::istream& is)
{
	static const std::unordered_map<std::string, double(*)(double)> functions
	{
		{"abs", std::fabs},
		{"acos", std::acos},
		{"acosh", std::acosh},
		{"asin", std::asin},
		{"asinh", std::asinh},
		{"atan", std::atan},
		{"atanh", std::atanh},
		{"ceil", std::ceil},
		{"cos", std::cos},
		{"cosh", std::cosh},
		{"exp", std::exp},
		{"floor", std::floor},
		{"log", std::log},
		{"log10", std::log10},
		{"log2", std::log2},
		{"round", std::round},
		{"sgn", sgn},
		{"sin", std::sin},
		{"sinh", std::sinh},
		{"sqrt", std::sqrt},
		{"tan", std::tan},
		{"tanh", std::tanh},
		{"trunc", std::trunc},
	};

	static const std::unordered_map<std::string, double> constants
	{
		{"e", M_E},
		{"inf", INFINITY},
		{"nan", NAN},
		{"pi", M_PI},
	};

	switch(nowspeek(is))
	{
		case '-':
			is.get();
			return -operand(is);
		case '(':
			{
				is.get();

				double value = term(is);
				if(is.get() == ')')
					return value;

				break;
			}
		default:
			{
				std::string name;
				while(std::isalpha(nowspeek(is)))
					name += (char) is.get();

				if(!name.empty())
				{
					auto functionPosition = functions.find(name);
					if(functionPosition != functions.end())
						return functionPosition->second(operand(is));

					auto constantPosition = constants.find(name);
					if(constantPosition != constants.end())
					{
						if(nowspeek(is) == '=')
						{
							std::string ignore;
							std::getline(is, ignore);
							throw 1;
						}

						return constantPosition->second;
					}

					switch(nowspeek(is))
					{
						case '=':
							is.get();
							return storage[name] = term(is);
						default:
							return storage[name];
					}
				}
				else
				{
					double value;

					if(is >> value)
						return value;
				}

				break;
			}
	}

	throw 1;
}

void Interpreter::setGlobalValue(const std::string& name, double value)
{
	storage[name] = value;
}

double Interpreter::term(std::istream& is)
{
	double left = factor(is);

	while(true)
		switch(nowspeek(is))
		{
			case '+':
				is.get();
				left += factor(is);
				break;
			case '-':
				is.get();
				left -= factor(is);
				break;
			default:
				return left;
		}

	throw 1;
}

double testInterpreter(Interpreter& interp, const std::string& expression);
void performTests();

int main(int, char**)
{

#ifdef DEBUG
	performTests();
#else
	Interpreter interp;

	while(true)
	{
		std::cout << ">> ";
		std::cout.flush();

		try
		{
			std::cout << interp.interpret(std::cin) << std::endl;
		}
		catch(...)
		{
			std::cout << "Error" << std::endl;
		}
	}
#endif /* DEBUG */

	return 0;
}

int factorial(int n)
{
	if(n < 0)
		throw 1;
	else if(n == 0)
		return 1;
	else
		return n * factorial(n - 1);
}

int nowspeek(std::istream& is)
{
	while(is.peek() == ' ')
		is.get();

	return is.peek();
}

double sgn(double x)
{
	if(x < 0)
		return -1;
	else if(x > 0)
		return 1;
	else
		return 0;
}

double testInterpreter(Interpreter& interp, const std::string& expression)
{
	std::istringstream iss{expression};
	return interp.interpret(iss);
}

void performTests()
{
	Interpreter interp;

	double h;

	std::pair<double, std::string> tests[] =
	{
		{2+3, "2+3"},
		{-4*5, "-4*5"},
		{2+-4, "2+-4"},
		{5*3+4, "5*3+4"},
		{5+3*4, "5+3*4"},
		{(5+3)*4, "(5+3)*4"},
		{-(5+3)*4, "-(5+3)*4"},
		{5*-(6*(9+3)+4), "5*-(6*(9+3)+4)"},
		{6-8/3e4, "6-8/3e4"},
		{3*std::pow(4,5)-6, "3*4^5-6"},
		{7*factorial(6)+3, "7*6!+3"},
		{factorial(2*3+3), "(2*3+3)!"},
		{std::pow(4+7*8,9+4), "(4+7*8)^(9+4)"},
		{std::pow(3, std::pow(2, 4)), "3^(2^4)"},
		{M_PI*(3-9), "pi*(3-9)"},
		{(-M_E+4)*8, "(-e+4)*8"},
		{h=99, "h=99"},
		{h*8+3, "h*8+3"},
		{h=-(8+M_PI)/4, "h=-(8+pi)/4"},
		{h, "h"},
		{std::sin(45), "sin 45"},
		{std::sin(45*3), "sin(45*3)"},
		{std::trunc(45.3), "trunc 45.3"},
		{-std::ceil(45.333), "-ceil 45.333"},
	};

	std::size_t numTests = 0, numTestPassed = 0;

	for(const auto& test: tests)
	{
		double cpp = test.first, smi = testInterpreter(interp, test.second);

		std::cout
			<< test.second << std::endl
			<< "  C++ " << cpp << std::endl
			<< "  smi " << smi << std::endl
			<< "  " << (cpp == smi ? "PASSED" : "MAYBE FAILED")  << std::endl
			<< std::endl
			;

		++numTests;
		numTestPassed += (cpp == smi ? 1 : 0);
	}

	std::cout << "Tests " << numTests << ", passed " << numTestPassed << std::endl;
}
<|endoftext|>


<commit_before><commit_msg>Add es-419 to the Accept-Language and UI language selection menu <commit_after><|endoftext|>


<commit_before>#include <OpenSim/OpenSim.h>

#define USE_RIGID_CONTACT

using namespace OpenSim;
using namespace SimTK;

int main()
{
    // Physical parameters.
    const double mass        = 1.;
    const double radius      = 0.25;
    const double stiffness   = 1.e7;
    const double dissipation = 0.1;
    const double mu_static   = 0.6;
    const double mu_dynamic  = 0.4;
    const double mu_viscous  = 0.01;
    const double restitution = 0.5;

    // Simulation parameters.
    const double initialHeight   = 10.*radius;
    const double initialHorizVel = 1.;
    const double simDuration     = 0.15;
    const double simStepSize     = 1.e-2;

    // Create model with gravity.
    auto osimModel = Model();
    osimModel.setName("BallDrop");
    osimModel.setGravity(Vec3(0, -9.81, 0));

    // Create unconstrained ball.
    auto ball = new OpenSim::Body("ball", mass, Vec3(0),
                                  mass*SimTK::Inertia::sphere(0.1));
    ball->scale(Vec3(radius), false);
    auto freeJoint = new FreeJoint("freeJoint", osimModel.getGround(), *ball);
    osimModel.addBody(ball);
    osimModel.addJoint(freeJoint);

    // Define contact geometry.
    auto ground = osimModel.updGround();
    auto groundContact = new ContactHalfSpace(Vec3(0), Vec3(0, 0, -0.5*SimTK_PI),
                                              ground, "groundContact");
    osimModel.addContactGeometry(groundContact);
    auto ballContact = new ContactSphere(radius, Vec3(0), *ball, "ballContact");
    osimModel.addContactGeometry(ballContact);

    // Define contact forces.
#ifdef USE_RIGID_CONTACT
    auto contactParams = new OpenSim::RigidContactForce::ContactParameters(
        restitution, mu_static, mu_dynamic, mu_viscous);
    contactParams->addGeometry("groundContact");
    contactParams->addGeometry("ballContact");
    auto contact = new OpenSim::RigidContactForce(contactParams);
#else
    auto contactParams = new OpenSim::HuntCrossleyForce::ContactParameters(
        stiffness, dissipation, mu_static, mu_dynamic, mu_viscous);
    contactParams->addGeometry("groundContact");
    contactParams->addGeometry("ballContact");
    auto contact = new OpenSim::HuntCrossleyForce(contactParams);
#endif
    osimModel.addForce(contact);

    // Initialize the system.
    auto& state = osimModel.initSystem();
    freeJoint->getCoordinate(FreeJoint::Coord::TranslationY)
        .setValue(state, initialHeight);
    freeJoint->getCoordinate(FreeJoint::Coord::TranslationX)
        .setSpeedValue(state, initialHorizVel);

    // Create integrator, manager, and force reporter.
    SimTK::RungeKuttaMersonIntegrator integrator(osimModel.getMultibodySystem());
    integrator.setAccuracy(1.e-4);
    Manager manager(osimModel, integrator);
    manager.setInitialTime(0.);

    // Simulate.
    std::cout << "Integrating...";
    double currTime = 0.;
    while (currTime < simDuration) {
        currTime += simStepSize;
        manager.setFinalTime(currTime);
        manager.integrate(state);
    }
    std::cout << " done" << std::endl;

    // TODO: Check the results.

    return 0;
}
<commit_msg>Added comments from PR. [ci skip]<commit_after>/* Comments from https://github.com/opensim-org/opensim-core/pull/663 that have
not yet been addressed:

@chrisdembia:
I like that the two are pretty much exactly the same. I wonder if it makes sense
though to _not_ have rigid contact and compliant contact be interchangeable
(i.e. have the same interface). One is a force element while the other is a
constraint. For example, I don't know how RigidContactForce would implement
`Force::calcForce()`.  Or maybe they can have the same interface but not both be
forces.

Would we also have a RigidCoordinateLimitForce to go along with
CoordinateLimitForce? Or would we have JointStopConstraint? Should all
unilateral constraints appear in the same inheritance hierarchy, or can we split
up things like joint stops (put in constraints) and sphere-plane contact (put in
forces)?

@sherm1:
That's a very close match for OpenSim's current HuntCrossley stuff, but that is
obsolete and I hope we can change to a better model in 4.0. The problem is that
it associates contact parameters with the force element rather than with the
contact surfaces. That was replaced in Simbody a long time ago with a better
approach where contact properties are associated with ContactSurface objects
fixed to bodies. Those are then combined pairwise when they are in contact to
compute the effective properties for a particular impact or contact. Then forces
get applied when pairs bump, but there is no separate force element.

A ContactSurface is a pair: geometry+material properties. The material
properties can be compliant or rigid or both. Then conceivably it is just a
request to the solver whether to use compliant or rigid contact; probably we'll
want to use both in the same simulations though.

That said, there are some simpler cases that it would be useful to try first. My
first cut at rigid contact in Simbody doesn't have the fancy broad phase
determination of which pairs of n things are in contact. At first I'll just have
pairwise contact elements: joint stops, ropes, and point-ground contacts where
each point has its own element. In those cases the contact element will be the
keeper of the contact parameters. It would be cool if those could also support
either compliant or rigid modeling for apples-to-apples comparisons; I don't
know how that would look in OpenSim. There are advantages to these pairwise
elements and I think we would want to keep them even once we have the nXn stuff
working.

Another tricky issue is how we should get output from these things. They will
generate forces when in contact but also very substantial impulses during impact
that ought to be reported somehow. Would that be in scope for pseudocode?

@sherm1:
> Would we also have a RigidCoordinateLimitForce to go along with
CoordinateLimitForce? Or would we have JointStopConstraint?

I don't think we should have any of these. Instead we should have a JointStop
(or CoordinateLimit) whose job is to keep a coordinate in a given range. Then we
should be able to control which model (compliant vs. rigid) at run time, just as
we control accuracy now. That is, we don't have "AccurateCoordinateLimitForce"
and "SloppyCoordinateLimitForce"; we just consider that something the solver
controls. Similarly, switching between compliant and rigid models is an "outer
loop" of accuracy control where we choose accurate vs. fast at the modeling
level.

@sherm1:
I'm hoping we can leave the old H&CForce contact system in place for backwards
compatibility in 4.0. I don't think it prevents us from adding a new contact
scheme. But I don't want to model the rigid contact after the obsolete H&CForce
stuff.

@sherm1:
I want to discuss this more but I think it would be easier in person and with a
whiteboard first. Hopefully we'll have some time at Thursday's meeting.

For example: most existing models provide a range for joint coordinates, but as
I understand it that range is only enforced during IK, which I'm sure is a
surprise to users. Now we could by default enforce those as momentum-conserving,
zero coefficient of restitution rigid joint limits. Should we?

@chrisdembia:
I don't think we should do something backwards-incompatible to something so
important. I think we could have an additional flag like
"turn_range_into_motion_constraints" or something named much better.

I definitely think we should exploit that range property though to avoid
redundancy and confusion.
*/

#include <OpenSim/OpenSim.h>

#define USE_RIGID_CONTACT

using namespace OpenSim;
using namespace SimTK;

int main()
{
    // Physical parameters.
    const double mass        = 1.;
    const double radius      = 0.25;
    const double stiffness   = 1.e7;
    const double dissipation = 0.1;
    const double mu_static   = 0.6;
    const double mu_dynamic  = 0.4;
    const double mu_viscous  = 0.01;
    const double restitution = 0.5;

    // Simulation parameters.
    const double initialHeight   = 10.*radius;
    const double initialHorizVel = 1.;
    const double simDuration     = 0.15;
    const double simStepSize     = 1.e-2;

    // Create model with gravity.
    auto osimModel = Model();
    osimModel.setName("BallDrop");
    osimModel.setGravity(Vec3(0, -9.81, 0));

    // Create unconstrained ball.
    auto ball = new OpenSim::Body("ball", mass, Vec3(0),
                                  mass*SimTK::Inertia::sphere(0.1));
    ball->scale(Vec3(radius), false);
    auto freeJoint = new FreeJoint("freeJoint", osimModel.getGround(), *ball);
    osimModel.addBody(ball);
    osimModel.addJoint(freeJoint);

    // Define contact geometry.
    auto ground = osimModel.updGround();
    auto groundContact = new ContactHalfSpace(Vec3(0), Vec3(0, 0, -0.5*SimTK_PI),
                                              ground, "groundContact");
    osimModel.addContactGeometry(groundContact);
    auto ballContact = new ContactSphere(radius, Vec3(0), *ball, "ballContact");
    osimModel.addContactGeometry(ballContact);

    // Define contact forces.
#ifdef USE_RIGID_CONTACT
    auto contactParams = new OpenSim::RigidContactForce::ContactParameters(
        restitution, mu_static, mu_dynamic, mu_viscous);
    contactParams->addGeometry("groundContact");
    contactParams->addGeometry("ballContact");
    auto contact = new OpenSim::RigidContactForce(contactParams);
#else
    auto contactParams = new OpenSim::HuntCrossleyForce::ContactParameters(
        stiffness, dissipation, mu_static, mu_dynamic, mu_viscous);
    contactParams->addGeometry("groundContact");
    contactParams->addGeometry("ballContact");
    auto contact = new OpenSim::HuntCrossleyForce(contactParams);
#endif
    osimModel.addForce(contact);

    // Initialize the system.
    auto& state = osimModel.initSystem();
    freeJoint->getCoordinate(FreeJoint::Coord::TranslationY)
        .setValue(state, initialHeight);
    freeJoint->getCoordinate(FreeJoint::Coord::TranslationX)
        .setSpeedValue(state, initialHorizVel);

    // Create integrator, manager, and force reporter.
    SimTK::RungeKuttaMersonIntegrator integrator(osimModel.getMultibodySystem());
    integrator.setAccuracy(1.e-4);
    Manager manager(osimModel, integrator);
    manager.setInitialTime(0.);

    // Simulate.
    std::cout << "Integrating...";
    double currTime = 0.;
    while (currTime < simDuration) {
        currTime += simStepSize;
        manager.setFinalTime(currTime);
        manager.integrate(state);
    }
    std::cout << " done" << std::endl;

    // TODO: Check the results.

    return 0;
}
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

#include "helpers.h"

#include <libdariadb/scheme/helpers.h>
#include <libdariadb/scheme/scheme.h>
#include <libdariadb/storage/manifest.h>
#include <libdariadb/utils/fs.h>

TEST(Scheme, FileTest) {
  const std::string storage_path = "schemeStorage";
  if (dariadb::utils::fs::path_exists(storage_path)) {
    dariadb::utils::fs::rm(storage_path);
  }

  dariadb::Id i1, i2, i3, i4, i5, i6;

  {
    auto settings = dariadb::storage::Settings::create(storage_path);
    auto data_scheme = dariadb::scheme::Scheme::create(settings);

    i1 = data_scheme->addParam("lvl1.lvl2.lvl3_1.param1");
    auto i1_2 = data_scheme->addParam("lvl1.lvl2.lvl3_1.param1");
    EXPECT_EQ(i1, i1_2);
    i2 = data_scheme->addParam("lvl1.lvl2.lvl3_1.param2");
    i3 = data_scheme->addParam("lvl1.lvl2.lvl3_1.param3");

    i4 = data_scheme->addParam("lvl1.lvl2.lvl3_2.param1");
    i5 = data_scheme->addParam("lvl1.lvl2.param1");
    i6 = data_scheme->addParam("lvl1.lvl2.lvl3.lvl4.param1");

    EXPECT_TRUE(i1 != i2 && i2 != i3 && i3 != i4 && i4 != i5 && i5 != i6);

    data_scheme->save();
    auto scheme_files = dariadb::utils::fs::ls(storage_path, ".js");
    EXPECT_EQ(scheme_files.size(), size_t(1));
  }
  {
    auto settings = dariadb::storage::Settings::create(storage_path);
    auto data_scheme = dariadb::scheme::Scheme::create(settings);
    auto all_values = data_scheme->ls();
    EXPECT_EQ(all_values.size(), size_t(6));

    EXPECT_TRUE(all_values.idByParam("lvl1.lvl2.lvl3_1.param1") == i1);

    for (auto kv : all_values) {
      auto md = kv.second;
      if (md.name == "lvl1.lvl2.lvl3_1.param1") {
        EXPECT_EQ(md.id, i1);
      }
      if (md.name == "lvl1.lvl2.lvl3_1.param2") {
        EXPECT_EQ(md.id, i2);
      }
      if (md.name == "lvl1.lvl2.lvl3_1.param3") {
        EXPECT_EQ(md.id, i3);
      }
      if (md.name == "lvl1.lvl2.lvl3_2.param1") {
        EXPECT_EQ(md.id, i4);
      }
      if (md.name == "lvl1.lvl2.param1") {
        EXPECT_EQ(md.id, i5);
      }
      if (md.name == "lvl1.lvl2.lvl3.lvl4.param1") {
        EXPECT_EQ(md.id, i6);
      }
    }

    auto i7 = data_scheme->addParam("lvl1.lvl2.lvl3.lvl4.param77");
    EXPECT_TRUE(i6 < i7);
    EXPECT_TRUE(i7 != dariadb::Id(0));
  }

  if (dariadb::utils::fs::path_exists(storage_path)) {
    dariadb::utils::fs::rm(storage_path);
  }
}

TEST(Scheme, Intervals) {
  const std::string storage_path = "schemeStorage";
  if (dariadb::utils::fs::path_exists(storage_path)) {
    dariadb::utils::fs::rm(storage_path);
  }
  dariadb::Id raw_id, hour_median_id, hour_sigma_id, day_median_id, day_cpu, raw_cpu;
  {
    auto settings = dariadb::storage::Settings::create(storage_path);
    auto data_scheme = dariadb::scheme::Scheme::create(settings);

    raw_id = data_scheme->addParam("memory.raw");
	raw_cpu = data_scheme->addParam("cpu.raw");
    hour_median_id = data_scheme->addParam("memory.median.hour");
    hour_sigma_id = data_scheme->addParam("memory.sigma.hour");
	day_cpu = data_scheme->addParam("cpu.sigma.hour");
    day_median_id = data_scheme->addParam("memory.median.day");
    data_scheme->save();
  }
  {
    auto settings = dariadb::storage::Settings::create(storage_path);
    auto data_scheme = dariadb::scheme::Scheme::create(settings);

    auto all_values = data_scheme->ls();
    EXPECT_EQ(all_values.size(), size_t(6));

    auto raw_id_descr = all_values[raw_id];
    EXPECT_TRUE(raw_id_descr.aggregation_func.empty());
    EXPECT_EQ(raw_id_descr.interval, "raw");
    EXPECT_EQ(raw_id_descr.prefix(), "memory");

    auto id_descr = all_values[hour_median_id];
    EXPECT_EQ(id_descr.name, "memory.median.hour");
    EXPECT_EQ(id_descr.aggregation_func, "median");
    EXPECT_EQ(id_descr.prefix(), "memory.median");
    EXPECT_EQ(id_descr.interval, "hour");

    id_descr = all_values[hour_sigma_id];
    EXPECT_EQ(id_descr.name, "memory.sigma.hour");
    EXPECT_EQ(id_descr.prefix(), "memory.sigma");
    EXPECT_EQ(id_descr.aggregation_func, "sigma");
    EXPECT_EQ(id_descr.interval, "hour");

    id_descr = all_values[day_median_id];
    EXPECT_EQ(id_descr.name, "memory.median.day");
    EXPECT_EQ(id_descr.aggregation_func, "median");
    EXPECT_EQ(id_descr.prefix(), "memory.median");
    EXPECT_EQ(id_descr.interval, "day");

    auto all_hour_vaues = data_scheme->lsInterval("hour");
    EXPECT_EQ(all_hour_vaues.size(), size_t(3));

    auto linkedHours = data_scheme->linkedForValue(all_values[raw_id]);
    EXPECT_EQ(linkedHours.size(), size_t(2));

	linkedHours = data_scheme->linkedForValue(all_values[raw_cpu]);
	EXPECT_EQ(linkedHours.size(), size_t(1));
  }
  if (dariadb::utils::fs::path_exists(storage_path)) {
    dariadb::utils::fs::rm(storage_path);
  }
}<commit_msg>one more test.<commit_after>#include <gtest/gtest.h>

#include "helpers.h"

#include <libdariadb/scheme/helpers.h>
#include <libdariadb/scheme/scheme.h>
#include <libdariadb/storage/manifest.h>
#include <libdariadb/utils/fs.h>

TEST(Scheme, FileTest) {
  const std::string storage_path = "schemeStorage";
  if (dariadb::utils::fs::path_exists(storage_path)) {
    dariadb::utils::fs::rm(storage_path);
  }

  dariadb::Id i1, i2, i3, i4, i5, i6;

  {
    auto settings = dariadb::storage::Settings::create(storage_path);
    auto data_scheme = dariadb::scheme::Scheme::create(settings);

    i1 = data_scheme->addParam("lvl1.lvl2.lvl3_1.param1");
    auto i1_2 = data_scheme->addParam("lvl1.lvl2.lvl3_1.param1");
    EXPECT_EQ(i1, i1_2);
    i2 = data_scheme->addParam("lvl1.lvl2.lvl3_1.param2");
    i3 = data_scheme->addParam("lvl1.lvl2.lvl3_1.param3");

    i4 = data_scheme->addParam("lvl1.lvl2.lvl3_2.param1");
    i5 = data_scheme->addParam("lvl1.lvl2.param1");
    i6 = data_scheme->addParam("lvl1.lvl2.lvl3.lvl4.param1");

    EXPECT_TRUE(i1 != i2 && i2 != i3 && i3 != i4 && i4 != i5 && i5 != i6);

    data_scheme->save();
    auto scheme_files = dariadb::utils::fs::ls(storage_path, ".js");
    EXPECT_EQ(scheme_files.size(), size_t(1));
  }
  {
    auto settings = dariadb::storage::Settings::create(storage_path);
    auto data_scheme = dariadb::scheme::Scheme::create(settings);
    auto all_values = data_scheme->ls();
    EXPECT_EQ(all_values.size(), size_t(6));

    EXPECT_TRUE(all_values.idByParam("lvl1.lvl2.lvl3_1.param1") == i1);

    for (auto kv : all_values) {
      auto md = kv.second;
      if (md.name == "lvl1.lvl2.lvl3_1.param1") {
        EXPECT_EQ(md.id, i1);
      }
      if (md.name == "lvl1.lvl2.lvl3_1.param2") {
        EXPECT_EQ(md.id, i2);
      }
      if (md.name == "lvl1.lvl2.lvl3_1.param3") {
        EXPECT_EQ(md.id, i3);
      }
      if (md.name == "lvl1.lvl2.lvl3_2.param1") {
        EXPECT_EQ(md.id, i4);
      }
      if (md.name == "lvl1.lvl2.param1") {
        EXPECT_EQ(md.id, i5);
      }
      if (md.name == "lvl1.lvl2.lvl3.lvl4.param1") {
        EXPECT_EQ(md.id, i6);
      }
    }

    auto i7 = data_scheme->addParam("lvl1.lvl2.lvl3.lvl4.param77");
    EXPECT_TRUE(i6 < i7);
    EXPECT_TRUE(i7 != dariadb::Id(0));
  }

  if (dariadb::utils::fs::path_exists(storage_path)) {
    dariadb::utils::fs::rm(storage_path);
  }
}

TEST(Scheme, Intervals) {
  const std::string storage_path = "schemeStorage";
  if (dariadb::utils::fs::path_exists(storage_path)) {
    dariadb::utils::fs::rm(storage_path);
  }
  dariadb::Id raw_id, hour_median_id, hour_sigma_id, day_median_id, day_cpu, raw_cpu;
  {
    auto settings = dariadb::storage::Settings::create(storage_path);
    auto data_scheme = dariadb::scheme::Scheme::create(settings);

    raw_id = data_scheme->addParam("memory.raw");
    raw_cpu = data_scheme->addParam("cpu.raw");
    hour_median_id = data_scheme->addParam("memory.median.hour");
    hour_sigma_id = data_scheme->addParam("memory.sigma.hour");
    day_cpu = data_scheme->addParam("cpu.sigma.hour");
    day_median_id = data_scheme->addParam("memory.median.day");
    data_scheme->save();
  }
  {
    auto settings = dariadb::storage::Settings::create(storage_path);
    auto data_scheme = dariadb::scheme::Scheme::create(settings);

    auto all_values = data_scheme->ls();
    EXPECT_EQ(all_values.size(), size_t(6));

    auto raw_id_descr = all_values[raw_id];
    EXPECT_TRUE(raw_id_descr.aggregation_func.empty());
    EXPECT_EQ(raw_id_descr.interval, "raw");
    EXPECT_EQ(raw_id_descr.prefix(), "memory");

    auto id_descr = all_values[hour_median_id];
    EXPECT_EQ(id_descr.name, "memory.median.hour");
    EXPECT_EQ(id_descr.aggregation_func, "median");
    EXPECT_EQ(id_descr.prefix(), "memory.median");
    EXPECT_EQ(id_descr.interval, "hour");

    id_descr = all_values[hour_sigma_id];
    EXPECT_EQ(id_descr.name, "memory.sigma.hour");
    EXPECT_EQ(id_descr.prefix(), "memory.sigma");
    EXPECT_EQ(id_descr.aggregation_func, "sigma");
    EXPECT_EQ(id_descr.interval, "hour");

    id_descr = all_values[day_median_id];
    EXPECT_EQ(id_descr.name, "memory.median.day");
    EXPECT_EQ(id_descr.aggregation_func, "median");
    EXPECT_EQ(id_descr.prefix(), "memory.median");
    EXPECT_EQ(id_descr.interval, "day");

    auto all_hour_vaues = data_scheme->lsInterval("hour");
    EXPECT_EQ(all_hour_vaues.size(), size_t(3));

    auto linkedHours = data_scheme->linkedForValue(all_values[raw_id]);
    EXPECT_EQ(linkedHours.size(), size_t(2));

    linkedHours = data_scheme->linkedForValue(all_values[raw_cpu]);
    EXPECT_EQ(linkedHours.size(), size_t(1));

    linkedHours = data_scheme->linkedForValue(all_values[day_median_id]);
    EXPECT_EQ(linkedHours.size(), size_t(0));
  }
  if (dariadb::utils::fs::path_exists(storage_path)) {
    dariadb::utils::fs::rm(storage_path);
  }
}<|endoftext|>


<commit_before>//
// Class AliRsnFunctionAxis
//
// Definition for a histogram type.
// Since one could do an analysis which is not an invariant mass
// the histogram definition should be more flexible, and it is stored
// separately in a new class.
// This class considers the possibility of a 1D or 2D histograms
// with its related binning, and can create a new histo from his definitions
//
#include "TObject.h"

#include "AliLog.h"

#include "AliRsnEvent.h"
#include "AliRsnPairParticle.h"
#include "AliRsnPairDef.h"
#include "AliRsnFunctionAxis.h"

ClassImp(AliRsnFunctionAxis)

//_____________________________________________________________________________
AliRsnFunctionAxis::AliRsnFunctionAxis() :
  fType(kAxisTypes),
  fNBins(0),
  fMin(0.0),
  fMax(0.0)
{
//
// Default constructor
//
}

//_____________________________________________________________________________
AliRsnFunctionAxis::AliRsnFunctionAxis
(EAxisType type, Int_t nbins, Double_t min, Double_t max) :
  fType(type),
  fNBins(0),
  fMin(0.0),
  fMax(0.0)
{
//
// Main constructor (version 1)
//

  SetBins(nbins, min, max);
}

//_____________________________________________________________________________
AliRsnFunctionAxis::AliRsnFunctionAxis
(EAxisType type, Double_t min, Double_t max, Double_t step) :
  fType(type),
  fNBins(0),
  fMin(0.0),
  fMax(0.0)
{
//
// Main constructor (version 2)
//

  SetBins(min, max, step);
}

//_____________________________________________________________________________
const char* AliRsnFunctionAxis::GetName() const
{
//
// Return the name of this object defined by the type
//

  switch (fType)
  {
    case kPairInvMass:    return "IM";
    case kPairInvMassMC:  return "IMMC";
    case kPairInvMassRes: return "IMRES";
    case kPairPt:         return "PT";
    case kPairEta:        return "ETA";
    case kEventMult:      return "MULT";
    default:              return "UNDEF";
  }
}

//_____________________________________________________________________________
AliRsnFunctionAxis::EAxisObject AliRsnFunctionAxis::GetAxisObject()
{
//
// Tells what kind of object must be evaluated for this axis
//

  switch (fType)
  {
    case kPairInvMass:
    case kPairInvMassMC:
    case kPairInvMassRes:
    case kPairPt:
    case kPairEta:
      return kPair;
    case kEventMult:
      return kEvent;
    default:
      return kNone;
  }
}

//_____________________________________________________________________________
void AliRsnFunctionAxis::SetBins(Int_t n, Double_t min, Double_t max)
{
//
// Set binning for histogram.
//

  fNBins = n;

  if (min < max)
  {
    fMin = min;
    fMax = max;
  }
  else
  {
    fMin = max;
    fMax = min;
  }
}

//_____________________________________________________________________________
void AliRsnFunctionAxis::SetBins(Double_t min, Double_t max, Double_t step)
{
//
// Binning for histogram.
//

  if (min < max)
  {
    fMin = min;
    fMax = max;
  }
  else
  {
    fMin = max;
    fMax = min;
  }

  fNBins = (Int_t)((fMax - fMin) / (step)) + 1;
}

//_____________________________________________________________________________
Double_t AliRsnFunctionAxis::Eval(AliRsnDaughter *daughter)
{
//
// EValuation method for single tracks
// (currently disabled)
//

  return 0.0;
}

//_____________________________________________________________________________
Double_t AliRsnFunctionAxis::Eval(AliRsnPairParticle *pair, AliRsnPairDef *pairDef)
{
//
// EValuation method for pairs.
// Requires also the pair definitions, in order to retrieve mass.
//

  switch (fType)
  {
    case kPairInvMass:
      return pair->GetInvMass(pairDef->GetMass(0), pairDef->GetMass(1));
    case kPairInvMassMC:
      return pair->GetInvMassMC(pairDef->GetMass(0), pairDef->GetMass(1));
    case kPairInvMassRes:
      {
        Double_t value;
        value  = pair->GetInvMass(pairDef->GetMass(0), pairDef->GetMass(1));
        value -= pair->GetInvMassMC(pairDef->GetMass(0), pairDef->GetMass(1));
        value /= pair->GetInvMassMC(pairDef->GetMass(0), pairDef->GetMass(1));
        return value;
      }
    case kPairPt:
      return pair->GetPt();
    case kPairEta:
      return pair->GetEta();
    default:
      AliWarning("This axis type cannot be applied to pairs");
      return -999.0;
  }
}

//_____________________________________________________________________________
Double_t AliRsnFunctionAxis::Eval(AliRsnEvent *event)
{
//
// EValuation method for events
//

  switch (fType)
  {
    case kEventMult:
      return (Double_t)event->GetMultiplicity();
    default:
      AliWarning("This axis type cannot be applied to events");
      return 0.0;
  }
}
<commit_msg>fixed warning<commit_after>//
// Class AliRsnFunctionAxis
//
// Definition for a histogram type.
// Since one could do an analysis which is not an invariant mass
// the histogram definition should be more flexible, and it is stored
// separately in a new class.
// This class considers the possibility of a 1D or 2D histograms
// with its related binning, and can create a new histo from his definitions
//
#include "TObject.h"

#include "AliLog.h"

#include "AliRsnEvent.h"
#include "AliRsnPairParticle.h"
#include "AliRsnPairDef.h"
#include "AliRsnFunctionAxis.h"

ClassImp(AliRsnFunctionAxis)

//_____________________________________________________________________________
AliRsnFunctionAxis::AliRsnFunctionAxis() :
  fType(kAxisTypes),
  fNBins(0),
  fMin(0.0),
  fMax(0.0)
{
//
// Default constructor
//
}

//_____________________________________________________________________________
AliRsnFunctionAxis::AliRsnFunctionAxis
(EAxisType type, Int_t nbins, Double_t min, Double_t max) :
  fType(type),
  fNBins(0),
  fMin(0.0),
  fMax(0.0)
{
//
// Main constructor (version 1)
//

  SetBins(nbins, min, max);
}

//_____________________________________________________________________________
AliRsnFunctionAxis::AliRsnFunctionAxis
(EAxisType type, Double_t min, Double_t max, Double_t step) :
  fType(type),
  fNBins(0),
  fMin(0.0),
  fMax(0.0)
{
//
// Main constructor (version 2)
//

  SetBins(min, max, step);
}

//_____________________________________________________________________________
const char* AliRsnFunctionAxis::GetName() const
{
//
// Return the name of this object defined by the type
//

  switch (fType)
  {
    case kPairInvMass:    return "IM";
    case kPairInvMassMC:  return "IMMC";
    case kPairInvMassRes: return "IMRES";
    case kPairPt:         return "PT";
    case kPairEta:        return "ETA";
    case kEventMult:      return "MULT";
    default:              return "UNDEF";
  }
}

//_____________________________________________________________________________
AliRsnFunctionAxis::EAxisObject AliRsnFunctionAxis::GetAxisObject()
{
//
// Tells what kind of object must be evaluated for this axis
//

  switch (fType)
  {
    case kPairInvMass:
    case kPairInvMassMC:
    case kPairInvMassRes:
    case kPairPt:
    case kPairEta:
      return kPair;
    case kEventMult:
      return kEvent;
    default:
      return kNone;
  }
}

//_____________________________________________________________________________
void AliRsnFunctionAxis::SetBins(Int_t n, Double_t min, Double_t max)
{
//
// Set binning for histogram.
//

  fNBins = n;

  if (min < max)
  {
    fMin = min;
    fMax = max;
  }
  else
  {
    fMin = max;
    fMax = min;
  }
}

//_____________________________________________________________________________
void AliRsnFunctionAxis::SetBins(Double_t min, Double_t max, Double_t step)
{
//
// Binning for histogram.
//

  if (min < max)
  {
    fMin = min;
    fMax = max;
  }
  else
  {
    fMin = max;
    fMax = min;
  }

  fNBins = (Int_t)((fMax - fMin) / (step)) + 1;
}

//_____________________________________________________________________________
Double_t AliRsnFunctionAxis::Eval(AliRsnDaughter* /*daughter*/)
{
//
// EValuation method for single tracks
// (currently disabled)
//

  return 0.0;
}

//_____________________________________________________________________________
Double_t AliRsnFunctionAxis::Eval(AliRsnPairParticle *pair, AliRsnPairDef *pairDef)
{
//
// EValuation method for pairs.
// Requires also the pair definitions, in order to retrieve mass.
//

  switch (fType)
  {
    case kPairInvMass:
      return pair->GetInvMass(pairDef->GetMass(0), pairDef->GetMass(1));
    case kPairInvMassMC:
      return pair->GetInvMassMC(pairDef->GetMass(0), pairDef->GetMass(1));
    case kPairInvMassRes:
      {
        Double_t value;
        value  = pair->GetInvMass(pairDef->GetMass(0), pairDef->GetMass(1));
        value -= pair->GetInvMassMC(pairDef->GetMass(0), pairDef->GetMass(1));
        value /= pair->GetInvMassMC(pairDef->GetMass(0), pairDef->GetMass(1));
        return value;
      }
    case kPairPt:
      return pair->GetPt();
    case kPairEta:
      return pair->GetEta();
    default:
      AliWarning("This axis type cannot be applied to pairs");
      return -999.0;
  }
}

//_____________________________________________________________________________
Double_t AliRsnFunctionAxis::Eval(AliRsnEvent *event)
{
//
// EValuation method for events
//

  switch (fType)
  {
    case kEventMult:
      return (Double_t)event->GetMultiplicity();
    default:
      AliWarning("This axis type cannot be applied to events");
      return 0.0;
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#include "colorful.hh"
#include "mark_sweep.hh"

namespace tadpole {

MarkSweep::MarkSweep() noexcept {
}

MarkSweep::~MarkSweep() {
  while (!objects_.empty()) {
    auto* o = objects_.back();
    objects_.pop_back();

    reclaim_object(o);
  }
}

void MarkSweep::collect() {
  mark_from_roots();
  sweep();

  gc_threshold_ = std::max(std::min(gc_threshold_, kGCThresholdMin), objects_.size() * kGCFactor);
  gc_threshold_ = as_align(gc_threshold_, kGCAlign);
}

void MarkSweep::append_object(BaseObject* o) {
  if (objects_.size() >= gc_threshold_)
    collect();
  objects_.push_back(o);
}

void MarkSweep::mark_object(BaseObject* o) {
  if (o == nullptr || o->is_marked())
    return;

#if defined(_TADPOLE_DEBUG_GC)
  std::cout
    << colorful::fg::lightcyan << "[" << o << "] mark object: `" << o->stringify() << "`"
    << colorful::reset << std::endl;
#endif

  o->set_marked(true);
  worklist_.push_back(o);
}

sz_t MarkSweep::get_count() const {
  return objects_.size();
}

sz_t MarkSweep::get_threshold() const {
  return gc_threshold_;
}

void MarkSweep::set_threshold(sz_t threshold) {
  gc_threshold_ = as_align(threshold, kGCAlign);
}

void MarkSweep::mark() {
  while (!worklist_.empty()) {
    auto* o = worklist_.back();
    worklist_.pop_back();

    o->iter_children([this](BaseObject* child) { mark_object(child); });
  }
}

void MarkSweep::mark_from_roots() {
  for (auto& r : roots_) {
    r.second->iter_objects([this](BaseObject* o) {
          mark_object(o);
          mark();
        });
  }

  for (auto& s : interned_strings_) {
    mark_object(s.second);
    mark();
  }
}

void MarkSweep::sweep() {
  for (auto it = interned_strings_.begin(); it != interned_strings_.end();) {
    if (!it->second->is_marked())
      interned_strings_.erase(it++);
    else
      ++it;
  }

  // TODO:
}

void MarkSweep::reclaim_object(BaseObject* o) {
#if defined(_TADPOLE_DEBUG_GC)
  std::cout
    << colorful::fg::gray << "[" << o << "] reclaim object type: `" << o->type_asstr() << "`"
    << colorful::reset << std::endl;
#endif

  delete o;
}

}
<commit_msg>:construction: chore(gc): updated the implementation of mark-sweep gc<commit_after>// Copyright (c) 2021 ASMlover. All rights reserved.
//
//  ______             __                  ___
// /\__  _\           /\ \                /\_ \
// \/_/\ \/    __     \_\ \  _____     ___\//\ \      __
//    \ \ \  /'__`\   /'_` \/\ '__`\  / __`\\ \ \   /'__`\
//     \ \ \/\ \L\.\_/\ \L\ \ \ \L\ \/\ \L\ \\_\ \_/\  __/
//      \ \_\ \__/.\_\ \___,_\ \ ,__/\ \____//\____\ \____\
//       \/_/\/__/\/_/\/__,_ /\ \ \/  \/___/ \/____/\/____/
//                             \ \_\
//                              \/_/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#include "colorful.hh"
#include "mark_sweep.hh"

namespace tadpole {

MarkSweep::MarkSweep() noexcept {
}

MarkSweep::~MarkSweep() {
  while (!objects_.empty()) {
    auto* o = objects_.back();
    objects_.pop_back();

    reclaim_object(o);
  }
}

void MarkSweep::collect() {
  mark_from_roots();
  sweep();

  gc_threshold_ = std::max(std::min(gc_threshold_, kGCThresholdMin), objects_.size() * kGCFactor);
  gc_threshold_ = as_align(gc_threshold_, kGCAlign);
}

void MarkSweep::append_object(BaseObject* o) {
  if (objects_.size() >= gc_threshold_)
    collect();
  objects_.push_back(o);
}

void MarkSweep::mark_object(BaseObject* o) {
  if (o == nullptr || o->is_marked())
    return;

#if defined(_TADPOLE_DEBUG_GC)
  std::cout
    << colorful::fg::lightcyan << "[" << o << "] mark object: `" << o->stringify() << "`"
    << colorful::reset << std::endl;
#endif

  o->set_marked(true);
  worklist_.push_back(o);
}

sz_t MarkSweep::get_count() const {
  return objects_.size();
}

sz_t MarkSweep::get_threshold() const {
  return gc_threshold_;
}

void MarkSweep::set_threshold(sz_t threshold) {
  gc_threshold_ = as_align(threshold, kGCAlign);
}

void MarkSweep::mark() {
  while (!worklist_.empty()) {
    auto* o = worklist_.back();
    worklist_.pop_back();

    o->iter_children([this](BaseObject* child) { mark_object(child); });
  }
}

void MarkSweep::mark_from_roots() {
  for (auto& r : roots_) {
    r.second->iter_objects([this](BaseObject* o) {
          mark_object(o);
          mark();
        });
  }

  for (auto& s : interned_strings_) {
    mark_object(s.second);
    mark();
  }
}

void MarkSweep::sweep() {
  for (auto it = interned_strings_.begin(); it != interned_strings_.end();) {
    if (!it->second->is_marked())
      interned_strings_.erase(it++);
    else
      ++it;
  }

  for (auto it = objects_.begin(); it != objects_.end();) {
    if (!(*it)->is_marked()) {
      reclaim_object(*it);
      objects_.erase(it++);
    }
    else {
      (*it)->set_marked(true);
      ++it;
    }
  }
}

void MarkSweep::reclaim_object(BaseObject* o) {
#if defined(_TADPOLE_DEBUG_GC)
  std::cout
    << colorful::fg::gray << "[" << o << "] reclaim object type: `" << o->type_asstr() << "`"
    << colorful::reset << std::endl;
#endif

  delete o;
}

}
<|endoftext|>


<commit_before>/*

    ofxTableGestures (formerly OF-TangibleFramework)
    Developed for Taller de Sistemes Interactius I
    Universitat Pompeu Fabra

    Copyright (c) 2010 Daniel Gallardo Grassot <daniel.gallardo@upf.edu>

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

*/

#ifndef CURSORFEEDBACK_H_INCLUDED
#define CURSORFEEDBACK_H_INCLUDED

#include "ofMain.h"
#include "InputGestureBasicFingers.hpp"
#include "Graphic.hpp"
#include "DirectPoint.hpp"
#include <map>
#include <list>

class time_point{
    public:
        time_point(float _time, DirectPoint p):time(_time),point(p){}
        float time;
        DirectPoint point;
};

class HistoryPoint: private DirectPoint{
    private:
        std::list<time_point> points;
        float & MAX_SECONDS;
    public:
        int sid;
        HistoryPoint(int sid, float x, float y):
        MAX_SECONDS(ofxGlobalConfig::getRef("FEEDBACK:CURSOR:MAX_TAIL_SECONDS",0.5f))
        {
            SetPoint(x,y);
        }
        void SetPoint(float x, float y){
            xpos = x;
            ypos = y;
            points.push_back(time_point(ofGetElapsedTimef(),DirectPoint(*this)));
        }
        void Update(float time){
            while (points.size() != 0 && time-points.front().time > MAX_SECONDS )
                points.pop_front();
        }
        void Draw(){
            static int & R = ofxGlobalConfig::getRef("FEEDBACK:CURSOR:COLOR:R",255);
            static int & G = ofxGlobalConfig::getRef("FEEDBACK:CURSOR:COLOR:G",0);
            static int & B = ofxGlobalConfig::getRef("FEEDBACK:CURSOR:COLOR:B",0);
            ///Draws cursor
            ofSetColor(R,G,B);
            ofCircle(xpos,ypos,0.007);
            ///Draws trace
            ofSetLineWidth(3);
            float actual_time = ofGetElapsedTimef();
            ofEnableAlphaBlending();
            glDisable(GL_DEPTH_TEST);
            glBegin(GL_LINE_STRIP);
            for (std::list<time_point>::iterator it = points.begin(); it != points.end(); it++){
                ofSetColor(R,G,B,(int)(255-255*(actual_time-it->time)/MAX_SECONDS));
                glVertex2f(it->point.getX(),it->point.getY());
            }
            glEnd();
            glEnable(GL_DEPTH_TEST);
            ofDisableAlphaBlending();
        }
};

class CursorFeedback: public CanBasicFingers < NotificationGraphic > {

    private:
        std::map<int,HistoryPoint*> finger_map;

    public:
        CursorFeedback();
        //CursorFeedback(Area * a);
        ~CursorFeedback();
        virtual void addTuioCursor(int id, float xpos,float ypos,float xspeed,float yspeed,float maccel);
        virtual void updateTuioCursor(int id, float xpos,float ypos,float xspeed,float yspeed,float maccel);
        virtual void removeTuioCursor(int id);
    protected:
        void update();
        void draw();

};

#endif // CURSORFEEDBACK_H_INCLUDED
<commit_msg>Using Vertex Arrays in CursorFeedback<commit_after>/*

    ofxTableGestures (formerly OF-TangibleFramework)
    Developed for Taller de Sistemes Interactius I
    Universitat Pompeu Fabra

    Copyright (c) 2010 Daniel Gallardo Grassot <daniel.gallardo@upf.edu>
    Copyright (c) 2010 Carles F. Julià <carles.fernandez@upf.edu>

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.

*/

#ifndef CURSORFEEDBACK_H_INCLUDED
#define CURSORFEEDBACK_H_INCLUDED

#include "ofMain.h"
#include "InputGestureBasicFingers.hpp"
#include "Graphic.hpp"
#include "DirectPoint.hpp"
#include <map>

class HistoryPoint : private DirectPoint{
    private:

        float & MAX_SECONDS;
        int MAX_POINTS;
        GLfloat * xycoordinates;
        GLubyte * colorcoordinates;
        float * times;

        int begin;
        int npoints;

    public:
        int sid;
        HistoryPoint(int sid, float x, float y):
        MAX_SECONDS(ofxGlobalConfig::getRef("FEEDBACK:CURSOR:MAX_TAIL_SECONDS",0.5f)),
        MAX_POINTS(ofxGlobalConfig::getRef("FEEDBACK:CURSOR:MAX_TAIL_POINTS",100)),
        begin(0),
        npoints(0)
        {
            xycoordinates = new GLfloat[(MAX_POINTS+1)*2];
            colorcoordinates = new GLubyte[(MAX_POINTS+1)*4];
            times = new float[MAX_POINTS];
            SetPoint(x,y);
        }
        ~HistoryPoint()
        {
            delete [] xycoordinates;
            delete [] colorcoordinates;
            delete [] times;
        }
        void SetPoint(float x, float y){
            xpos = x;
            ypos = y;

            if(npoints == MAX_POINTS)
            {
                begin= (begin+1)%MAX_POINTS;
                npoints--;
            }
            int pos = (begin + npoints) % MAX_POINTS;
            xycoordinates[pos*2] = x;
            xycoordinates[pos*2+1] = y;
            times[pos] = ofGetElapsedTimef();
            npoints++;

        }
        void Update(float time){

            while((npoints > 0 ) && (time-times[begin] > MAX_SECONDS) )
            {
                begin= (begin+1)%MAX_POINTS;
                npoints--;
            }
        }
        void Draw(){
            static int & R = ofxGlobalConfig::getRef("FEEDBACK:CURSOR:COLOR:R",255);
            static int & G = ofxGlobalConfig::getRef("FEEDBACK:CURSOR:COLOR:G",0);
            static int & B = ofxGlobalConfig::getRef("FEEDBACK:CURSOR:COLOR:B",0);
            ///Draws cursor
            ofSetColor(R,G,B);
            ofCircle(xpos,ypos,0.007);
            ///Draws trace
            ofSetLineWidth(3);
            float actual_time = ofGetElapsedTimef();

            unsigned int j = 0;
            for(unsigned int i = 0; i < MAX_POINTS; ++i)
            {
                colorcoordinates[j++] = R;
                colorcoordinates[j++] = G;
                colorcoordinates[j++] = B;
                colorcoordinates[j++] = (GLubyte) max(0.0f,255-255*(actual_time-times[i])/MAX_SECONDS);
            }

            colorcoordinates[j++] = colorcoordinates[0];
            colorcoordinates[j++] = colorcoordinates[1];
            colorcoordinates[j++] = colorcoordinates[2];
            colorcoordinates[j++] = colorcoordinates[3];

            xycoordinates[MAX_POINTS*2] = xycoordinates[0];
            xycoordinates[MAX_POINTS*2+1] = xycoordinates[1];

            ofEnableAlphaBlending();
            glDisable(GL_DEPTH_TEST);
            glEnableClientState(GL_VERTEX_ARRAY);
            glEnableClientState(GL_COLOR_ARRAY);
			glVertexPointer(2, GL_FLOAT, 0, xycoordinates);
			glColorPointer(4,GL_UNSIGNED_BYTE,0,colorcoordinates);
			glDrawArrays(GL_LINE_STRIP, begin, min(npoints,MAX_POINTS-begin+1));
			if(begin+npoints > MAX_POINTS)
			{
			    glDrawArrays(GL_LINE_STRIP, 0, (begin+npoints)%MAX_POINTS);
			}

			glDisableClientState(GL_COLOR_ARRAY);
			glDisableClientState(GL_VERTEX_ARRAY);
            glEnable(GL_DEPTH_TEST);
            ofDisableAlphaBlending();

        }
};

class CursorFeedback: public CanBasicFingers < NotificationGraphic > {

    private:
        std::map<int,HistoryPoint*> finger_map;

    public:
        CursorFeedback();
        //CursorFeedback(Area * a);
        ~CursorFeedback();
        virtual void addTuioCursor(int id, float xpos,float ypos,float xspeed,float yspeed,float maccel);
        virtual void updateTuioCursor(int id, float xpos,float ypos,float xspeed,float yspeed,float maccel);
        virtual void removeTuioCursor(int id);
    protected:
        void update();
        void draw();

};

#endif // CURSORFEEDBACK_H_INCLUDED
<|endoftext|>