text:
// src/Inventor/Qt/viewers/SoQtExaminerViewer.cpp.  Generated from SoGuiExaminerViewer.cpp.in by configure.

// This file contains the generic, "templatize-able" parts of the
// So*ExaminerViewer sourcecode.

// *************************************************************************

/*!
  \class SoQtExaminerViewer SoQtExaminerViewer.h Inventor/Qt/viewers/SoQtExaminerViewer.h
  \brief The SoQtExaminerViewer class is a 3D-model examination viewer.
  \ingroup components viewers

  This class is the viewer considered to be the most "general purpose"
  viewer, and it is often used in rapid prototyping to examine simple
  models aswell as complete scenes (although for the latter, you might
  be better off with one of the other viewer classes).

  Here is a complete, stand-alone example that shows how to set up an
  SoQtExaminerViewer as a model viewer that loads Inventor and VRML
  files from disk and places them inside the viewer for the end-user
  to examine:

  \code
  #include <Inventor/Qt/SoQt.h>
  #include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
  #include <Inventor/nodes/SoBaseColor.h>
  #include <Inventor/nodes/SoCone.h>
  #include <Inventor/nodes/SoSeparator.h>

  int
  main(int argc, char ** argv)
  {
    if (argc < 2) {
      (void)fprintf(stderr, "\n\n\tUsage: %s <modelfilename>\n\n",
                    argc > 0 ? argv[0] : "viewerapp");
      exit(1);
    }

    // Initialize SoQt and Inventor API libraries. This returns a main
    // window to use.
    QWidget * mainwin = SoQt::init(argc, argv, argv[0]);

    // Open the argument file..
    SoInput in;
    SbBool ok = in.openFile(argv[1]);
    if (!ok) { exit(1); }

    // ..and import it.
    SoSeparator * root = SoDB::readAll(&in);
    if (root == NULL) { exit(1); }
    root->ref();

    // Use the ExaminerViewer, for a nice interface for 3D model
    // inspection.
    SoQtExaminerViewer * viewer = new SoQtExaminerViewer(mainwin);
    viewer->setSceneGraph(root);
    viewer->show();

    // Pop up the main window.
    SoQt::show(mainwin);
    // Loop until exit.
    SoQt::mainLoop();

    // Clean up resources.
    delete viewer;
    root->unref();

    return 0;
  }
  \endcode

  SoQtExaminerViewer has a convenient interface for repositioning
  and reorientation of the camera, by panning, rotating and zooming
  it's position. The following controls can be used:

hold down left mousebutton and move mouse pointer to rotate the
  camera around it's current focal point (the focal point can be
  changed by doing a seek operation)

hold middle mousebutton to pan (or a CTRL-key plus left
  mousebutton, or a SHIFT-key plus left mousebutton)

hold down left + middle mousebutton to zoom / dolly, or CTRL +
  middle mousebutton, or CTRL + SHIFT + the left mousebutton

click 's', then pick with the left mousebutton to seek

right mousebutton opens the popup menu

click 'ESC' key to switch to and from 'camera interaction' mode
  and 'scenegraph interaction' mode (see setViewing()
  documentation)

'q' quits the application

  The SoQtExaminerViewer provides a user decoration's button for
  toggling between orthographic or perspective camera view volumes and
  projection methods. This is the bottom-most click button on the
  right decoration border.

  It also inherits the decoration buttons from the SoQtFullViewer:
  the arrow for switching to "scenegraph interaction" mode, the hand
  for setting back to "camera interaction" mode, the house for "reset
  camera to home position", the blueprint house for "set new camera
  home position", the eye for "zoom camera out to view full scene" and
  the flashlight for setting "click to seek" mode.

  Note that a common faulty assumption about all the viewer-classes is
  that user interaction (in the "examine"-mode, not the
  scenegraph-interaction mode) influences the model or 3D-scene in the
  view. This is not correct, as it is always the viewer's \e camera
  that is translated and rotated.

  The initial position of the camera is placed such that all of the
  scenegraph's geometry fits within it's view.

  \sa SoQtFlyViewer, SoQtPlaneViewer
*/

// *************************************************************************

// Documentation shared between So* toolkits follows below.

/*!
  \fn SoQtExaminerViewer::SoQtExaminerViewer(QWidget * parent, const char * name, SbBool embed, SoQtFullViewer::BuildFlag flag, SoQtViewer::Type type)

  Constructor.  See parent class for explanation of arguments.
  Calling this constructor will make sure the examiner viewer widget
  will be built immediately.
*/

/*!
  \fn SoQtExaminerViewer::SoQtExaminerViewer(QWidget * parent, const char * name, SbBool embed, SoQtFullViewer::BuildFlag flag, SoQtViewer::Type type, SbBool build)

  Constructor. See parent class for explanation of arguments.
*/

// *************************************************************************
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif // HAVE_CONFIG_H

#include <assert.h>
#include <math.h>

#include <Inventor/SbTime.h>
#include <Inventor/errors/SoDebugError.h>
#include <Inventor/nodes/SoOrthographicCamera.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/projectors/SbSphereSheetProjector.h>
#include <Inventor/projectors/SbSpherePlaneProjector.h>
#include <Inventor/events/SoKeyboardEvent.h>
#include <Inventor/events/SoMouseButtonEvent.h>
#include <Inventor/events/SoLocation2Event.h>
#include <Inventor/events/SoMotion3Event.h>

#include <soqtdefs.h>
#include <qt-config.h>
#ifdef __APPLE__
#include <OpenGL/gl.h>
#else
#include <GL/gl.h>
#endif

#include <Inventor/Qt/viewers/SoQtExaminerViewer.h>
#include <Inventor/Qt/viewers/SoQtExaminerViewerP.h>

#include <Inventor/Qt/SoQtBasic.h>
#include <Inventor/Qt/SoQtCursor.h>
#include <Inventor/Qt/viewers/SoGuiFullViewerP.h> // for pan() and zoom()

#define PRIVATE(obj) ((obj)->pimpl)
#define PUBLIC(obj) ((obj)->pub)

static const int MOUSEPOSLOGSIZE = 16;

// Bitmap representations of an "X", a "Y" and a "Z" for the axis cross.
static GLubyte xbmp[] = { 0x11,0x11,0x0a,0x04,0x0a,0x11,0x11 };
static GLubyte ybmp[] = { 0x04,0x04,0x04,0x04,0x0a,0x11,0x11 };
static GLubyte zbmp[] = { 0x1f,0x10,0x08,0x04,0x02,0x01,0x1f };

// ************************************************************************

/*!
  Decide if it should be possible to start a spin animation of the
  model in the viewer by releasing the mouse button while dragging.

  If the \a enable flag is \c FALSE and we're currently animating, the
  spin will be stopped.

  \sa isAnimationEnabled
*/
void
SoQtExaminerViewer::setAnimationEnabled(const SbBool enable)
{
  PRIVATE(this)->spinanimatingallowed = enable;
  if (!enable && this->isAnimating()) { this->stopAnimating(); }
}

// *************************************************************************

/*!
  Query whether or not it is possible to start a spinning animation by
  releasing the left mouse button while dragging the mouse.

  \sa setAnimationEnabled
*/

SbBool
SoQtExaminerViewer::isAnimationEnabled(void) const
{
  return PRIVATE(this)->spinanimatingallowed;
}

// *************************************************************************

/*!
  Stop the model from spinning.
*/

void
SoQtExaminerViewer::stopAnimating(void)
{
  if (PRIVATE(this)->currentmode != SoGuiExaminerViewerP::SPINNING) {
#if SOQT_DEBUG
    SoDebugError::postWarning("SoQtExaminerViewer::stopAnimating",
                              "not animating");
#endif // SOQT_DEBUG
    return;
  }
  PRIVATE(this)->setMode(this->isViewing() ?
                         SoGuiExaminerViewerP::IDLE :
                         SoGuiExaminerViewerP::INTERACT);
}

// *************************************************************************

/*!
  Query if the model in the viewer is currently in spinning mode after
  a user drag.
*/

SbBool
SoQtExaminerViewer::isAnimating(void) const
{
  return PRIVATE(this)->currentmode == SoGuiExaminerViewerP::SPINNING;
}

// ************************************************************************

/*!
  Set the flag deciding whether or not to show the axis cross.

  \sa isFeedbackVisible, getFeedbackSize, setFeedbackSize
*/

void
SoQtExaminerViewer::setFeedbackVisibility(const SbBool enable)
{
  if (enable == PRIVATE(this)->axiscrossEnabled) {
#ifdef SOQT_EXTRA_DEBUG
    SoDebugError::postWarning("SoQtExaminerViewer::setFeedbackVisibility",
                              "feedback visibility already set to %s", enable ? "true" : "false");
#endif // SOQT_EXTRA_DEBUG
    return;
  }
  PRIVATE(this)->axiscrossEnabled = enable;

  if (this->isViewing()) { this->scheduleRedraw(); }
}

/*!
  Check if the feedback axis cross is visible.

  \sa setFeedbackVisibility, getFeedbackSize, setFeedbackSize
*/

SbBool
SoQtExaminerViewer::isFeedbackVisible(void) const
{
  return PRIVATE(this)->axiscrossEnabled;
}

// ************************************************************************

/*!
  Set the size of the feedback axiscross.  The value is interpreted as
  an approximate percentage chunk of the dimensions of the total
  canvas.

  \sa getFeedbackSize, isFeedbackVisible, setFeedbackVisibility
*/
void
SoQtExaminerViewer::setFeedbackSize(const int size)
{
#if SOQT_DEBUG
  if (size < 1) {
    SoDebugError::postWarning("SoQtExaminerViewer::setFeedbackSize",
                              "the size setting should be larger than 0");
    return;
  }
#endif // SOQT_DEBUG

  PRIVATE(this)->axiscrossSize = size;

  if (this->isFeedbackVisible() && this->isViewing()) {
    this->scheduleRedraw();
  }
}

/*!
  Return the size of the feedback axis cross. Default is 25.

  \sa setFeedbackSize, isFeedbackVisible, setFeedbackVisibility
*/

int
SoQtExaminerViewer::getFeedbackSize(void) const
{
  return PRIVATE(this)->axiscrossSize;
}

// *************************************************************************

// Documented in superclass.
SbBool
SoQtExaminerViewer::processSoEvent(const SoEvent * const ev)
{
#if SOQT_DEBUG && 0 // debug
  SoDebugError::postInfo("SoQtExaminerViewer::processSoEvent",
                          "[invoked], event '%s'",
                          ev->getTypeId().getName().getString());
#endif // debug

  // We're in "interact" mode (ie *not* the camera modification mode),
  // so don't handle the event here. It should either be forwarded to
  // the scenegraph, or caught by SoQtViewer::processSoEvent() if
  // it's an ESC or ALT press (to switch modes).
  if (!this->isViewing()) { return inherited::processSoEvent(ev); }

  // Events when in "ready-to-seek" mode are ignored, except those
  // which influence the seek mode itself -- these are handled further
  // up the inheritance hierarchy.
  if (this->isSeekMode()) { return inherited::processSoEvent(ev); }

  const SoType type(ev->getTypeId());

  const SbVec2s size(this->getGLSize());
  const SbVec2f prevnormalized = PRIVATE(this)->lastmouseposition;
  const SbVec2s pos(ev->getPosition());
  const SbVec2f posn((float) pos[0] / (float) SoQtMax((int)(size[0] - 1), 1),
                     (float) pos[1] / (float) SoQtMax((int)(size[1] - 1), 1));

  PRIVATE(this)->lastmouseposition = posn;

  // Set to true if any event processing happened. Note that it is not
  // necessary to restrict ourselves to only do one "action" for an
  // event, we only need this flag to see if any processing happened
  // at all.
  SbBool processed = false;

  const SoGuiExaminerViewerP::ViewerMode currentmode = PRIVATE(this)->currentmode;
  SoGuiExaminerViewerP::ViewerMode newmode = currentmode;

  PRIVATE(this)->ctrldown = ev->wasCtrlDown();
  PRIVATE(this)->shiftdown = ev->wasShiftDown();

  // Mouse Button / Spaceball Button handling

  if (type.isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {

    processed = true;

    const SoMouseButtonEvent * const event = (const SoMouseButtonEvent *) ev;
    const int button = event->getButton();
    const SbBool press = event->getState() == SoButtonEvent::DOWN ? true : false;

    switch (button) {
    case SoMouseButtonEvent::BUTTON1:
      PRIVATE(this)->button1down = press;
      if (press && (currentmode == SoGuiExaminerViewerP::SEEK_WAIT_MODE)) {
        newmode = SoGuiExaminerViewerP::SEEK_MODE;
        this->seekToPoint(pos); // implicitly calls interactiveCountInc()
      }
      break;
    case SoMouseButtonEvent::BUTTON2:
      processed = false; // pass on to superclass, so popup menu is shown
      break;
    case SoMouseButtonEvent::BUTTON3:
      PRIVATE(this)->button3down = press;
      break;
#ifdef HAVE_SOMOUSEBUTTONEVENT_BUTTON5
    case SoMouseButtonEvent::BUTTON4:
      if (press) SoGuiFullViewerP::zoom(this->getCamera(), 0.1f);
      break;
    case SoMouseButtonEvent::BUTTON5:
      if (press) SoGuiFullViewerP::zoom(this->getCamera(), -0.1f);
      break;
#endif // HAVE_SOMOUSEBUTTONEVENT_BUTTON5
    default:
      break;
    }
  }
  // Keyboard handling
  if (type.isDerivedFrom(SoKeyboardEvent::getClassTypeId())) {
    const SoKeyboardEvent * const event = (const SoKeyboardEvent *) ev;
    const SbBool press = event->getState() == SoButtonEvent::DOWN ? true : false;
    switch (event->getKey()) {
    case SoKeyboardEvent::LEFT_CONTROL:
    case SoKeyboardEvent::RIGHT_CONTROL:
      processed = true;
      PRIVATE(this)->ctrldown = press;
      break;
    case SoKeyboardEvent::LEFT_SHIFT:
    case SoKeyboardEvent::RIGHT_SHIFT:
      processed = true;
      PRIVATE(this)->shiftdown = press;
      break;
    default:
      break;
    }
  }

  // Mouse Movement handling
  if (type.isDerivedFrom(SoLocation2Event::getClassTypeId())) {
    const SoLocation2Event * const event = (const SoLocation2Event *) ev;

    processed = true;

    if (PRIVATE(this)->currentmode == SoGuiExaminerViewerP::ZOOMING) {
      PRIVATE(this)->zoomByCursor(posn, prevnormalized);
    }
    else if (PRIVATE(this)->currentmode == SoGuiExaminerViewerP::PANNING) {
      SoGuiFullViewerP::pan(this->getCamera(), this->getGLAspectRatio(),
                            PRIVATE(this)->panningplane, posn, prevnormalized);
    }
    else if (PRIVATE(this)->currentmode == SoGuiExaminerViewerP::DRAGGING) {
      PRIVATE(this)->addToLog(event->getPosition(), event->getTime());
      PRIVATE(this)->spin(posn);
    }
    else {
      processed = false;
    }
  }

  // Spaceball & Joystick handling
  if (type.isDerivedFrom(SoMotion3Event::getClassTypeId())) {
    SoMotion3Event * const event = (SoMotion3Event *) ev;
    SoCamera * const camera = this->getCamera();
    if (camera) {
      if (PRIVATE(this)->motion3OnCamera) {
        SbVec3f dir = event->getTranslation();
        camera->orientation.getValue().multVec(dir,dir);
        camera->position = camera->position.getValue() + dir;
        camera->orientation =
          event->getRotation() * camera->orientation.getValue();
        processed = true;
      }
      else {
        // FIXME: move/rotate model
#if SOQT_DEBUG
        SoDebugError::postInfo("SoQtExaminerViewer::processSoEvent",
                               "SoMotion3Event for model movement is not implemented yet");
#endif // SOQT_DEBUG
        processed = true;
      }
    }
  }

  enum {
    BUTTON1DOWN = 1 << 0,
    BUTTON3DOWN = 1 << 1,
    CTRLDOWN =    1 << 2,
    SHIFTDOWN =   1 << 3
  };
  unsigned int combo =
    (PRIVATE(this)->button1down ? BUTTON1DOWN : 0) |
    (PRIVATE(this)->button3down ? BUTTON3DOWN : 0) |
    (PRIVATE(this)->ctrldown ? CTRLDOWN : 0) |
    (PRIVATE(this)->shiftdown ? SHIFTDOWN : 0);

  switch (combo) {
  case 0:
    if (currentmode == SoGuiExaminerViewerP::SPINNING) { break; }
    newmode = SoGuiExaminerViewerP::IDLE;
    if ((currentmode == SoGuiExaminerViewerP::DRAGGING) &&
        this->isAnimationEnabled() && (PRIVATE(this)->log.historysize >= 3)) {
      SbTime stoptime = (ev->getTime() - PRIVATE(this)->log.time[0]);
      if (stoptime.getValue() < 0.100) {
        const SbVec2s glsize(this->getGLSize());
        SbVec3f from = PRIVATE(this)->spinprojector->project(SbVec2f(float(PRIVATE(this)->log.position[2][0]) / float(SoQtMax(glsize[0]-1, 1)),
                                                                     float(PRIVATE(this)->log.position[2][1]) / float(SoQtMax(glsize[1]-1, 1))));
        SbVec3f to = PRIVATE(this)->spinprojector->project(posn);
        SbRotation rot = PRIVATE(this)->spinprojector->getRotation(from, to);

        SbTime delta = (PRIVATE(this)->log.time[0] - PRIVATE(this)->log.time[2]);
        double deltatime = delta.getValue();
        rot.invert();
        rot.scaleAngle(float(0.200 / deltatime));

        SbVec3f axis;
        float radians;
        rot.getValue(axis, radians);
        if ((radians > 0.01f) && (deltatime < 0.300)) {
          newmode = SoGuiExaminerViewerP::SPINNING;
          PRIVATE(this)->spinRotation = rot;
        }
      }
    }
    break;
  case BUTTON1DOWN:
    newmode = SoGuiExaminerViewerP::DRAGGING;
    break;
  case BUTTON3DOWN:
  case CTRLDOWN|BUTTON1DOWN:
  case SHIFTDOWN|BUTTON1DOWN:
    newmode = SoGuiExaminerViewerP::PANNING;
    break;
  case BUTTON1DOWN|BUTTON3DOWN:
  case CTRLDOWN|BUTTON3DOWN:
  case CTRLDOWN|SHIFTDOWN|BUTTON1DOWN:
    newmode = SoGuiExaminerViewerP::ZOOMING;
    break;

    // There are many cases we don't handle that just falls through to
    // the default case, like SHIFTDOWN, CTRLDOWN, CTRLDOWN|SHIFTDOWN,
    // SHIFTDOWN|BUTTON3DOWN, SHIFTDOWN|CTRLDOWN|BUTTON3DOWN, etc.
    // This is a feature, not a bug. :-)
    //
    // mortene.

  default:
    // The default will make a spin stop and otherwise not do
    // anything.
    if ((currentmode != SoGuiExaminerViewerP::SEEK_WAIT_MODE) &&
        (currentmode != SoGuiExaminerViewerP::SEEK_MODE)) {
      newmode = SoGuiExaminerViewerP::IDLE;
    }
    break;
  }
  if (newmode != currentmode) {
    PRIVATE(this)->setMode(newmode);
  }

  // If not handled in this class, pass on upwards in the inheritance
  // hierarchy.
  return processed || inherited::processSoEvent(ev);
}

// *************************************************************************

// documented in superclass
void
SoQtExaminerViewer::setSeekMode(SbBool on)
{
  // Overrides this method to make sure any animations are stopped
  // before we go into seek mode.

  // Note: this method is almost identical to the setSeekMode() in the
  // SoQtFlyViewer and SoQtPlaneViewer, so migrate any changes.

#if SOQT_DEBUG
  if (on == this->isSeekMode()) {
    SoDebugError::postWarning("SoQtExaminerViewer::setSeekMode",
                              "seek mode already %sset", on ? "" : "un");
    return;
  }
#endif // SOQT_DEBUG

  if (this->isAnimating()) { this->stopAnimating(); }
  inherited::setSeekMode(on);
  PRIVATE(this)->setMode(on ?
                         SoGuiExaminerViewerP::SEEK_WAIT_MODE :
                         (this->isViewing() ?
                          SoGuiExaminerViewerP::IDLE : SoGuiExaminerViewerP::INTERACT));
}

// *************************************************************************

/*!
  Decide whether or not the mouse pointer cursor should be visible in
  the rendering canvas.
*/
void
SoQtExaminerViewer::setCursorEnabled(SbBool enable)
{
  inherited::setCursorEnabled(enable);
  PRIVATE(this)->setCursorRepresentation(PRIVATE(this)->currentmode);
}

// *************************************************************************

// Documented in superclass.
const char *
SoQtExaminerViewer::getDefaultWidgetName(void) const
{
  return "SoQtExaminerViewer";
}

// *************************************************************************

// Documented in superclass.
const char *
SoQtExaminerViewer::getDefaultTitle(void) const
{
  return "Examiner Viewer";
}

// *************************************************************************

// Documented in superclass.
const char *
SoQtExaminerViewer::getDefaultIconTitle(void) const
{
  return "Examiner Viewer";
}

// *************************************************************************

// Documented in superclass. Overrides this method to be able to draw
// the axis cross, if selected, and to keep a continuous animation
// upon spin.
void
SoQtExaminerViewer::actualRedraw(void)
{
  SbTime now = SbTime::getTimeOfDay();
  double secs = now.getValue() -  PRIVATE(this)->prevRedrawTime.getValue();

  PRIVATE(this)->prevRedrawTime = now;

  if (this->isAnimating()) {
    SbRotation deltaRotation = PRIVATE(this)->spinRotation;
    deltaRotation.scaleAngle(float(secs * 5.0));
    PRIVATE(this)->reorientCamera(deltaRotation);
  }

  inherited::actualRedraw();

  if (this->isFeedbackVisible()) { PRIVATE(this)->drawAxisCross(); }

  // Immediately reschedule to get continous spin animation.
  if (this->isAnimating()) { this->scheduleRedraw(); }
}

// *************************************************************************

// doc in super
void
SoQtExaminerViewer::afterRealizeHook(void)
{
  inherited::afterRealizeHook();
  PRIVATE(this)->setCursorRepresentation(PRIVATE(this)->currentmode);
}

// *************************************************************************

// Documented in superclass. Overridden to provide the examiner viewer
// functionality on the left thumbwheel (x axis rotation).
void
SoQtExaminerViewer::leftWheelMotion(float value)
{
  if (this->isAnimating()) this->stopAnimating();

  float newval = PRIVATE(this)->rotXWheelMotion(value, this->getLeftWheelValue());
  inherited::leftWheelMotion(newval);
}

// Documented in superclass. Overridden to provide the examiner viewer
// functionality on the bottom thumbwheel (y axis rotation).
void
SoQtExaminerViewer::bottomWheelMotion(float value)
{
  if (this->isAnimating()) this->stopAnimating();

  float newval = PRIVATE(this)->rotYWheelMotion(value, this->getBottomWheelValue());
  inherited::bottomWheelMotion(newval);
}

// Documented in superclass. Overridden to provide the examiner viewer
// functionality on the left thumbwheel (dolly/zoom).
void
SoQtExaminerViewer::rightWheelMotion(float value)
{
  SoGuiFullViewerP::zoom(this->getCamera(), this->getRightWheelValue() - value);
  inherited::rightWheelMotion(value);
}

// *************************************************************************

// Documented in superclass. This method overridden from parent class
// to make sure the mouse pointer cursor is updated.
void
SoQtExaminerViewer::setViewing(SbBool enable)
{
  if (!!this->isViewing() == !!enable) {
#if SOQT_DEBUG
    SoDebugError::postWarning("SoQtExaminerViewer::setViewing",
                              "current state already %s", enable ? "true" : "false");
#endif // SOQT_DEBUG
    return;
  }

  PRIVATE(this)->setMode(enable ?
                         SoGuiExaminerViewerP::IDLE :
                         SoGuiExaminerViewerP::INTERACT);
  inherited::setViewing(enable);
}

// *************************************************************************

#ifndef DOXYGEN_SKIP_THIS

// Remaining code is for the SoGuiExaminerViewerP "private
// implementation" class.

SoGuiExaminerViewerP::SoGuiExaminerViewerP(SoQtExaminerViewer * publ)
{
  PUBLIC(this) = publ;
}

SoGuiExaminerViewerP::~SoGuiExaminerViewerP()
{
}

void
SoGuiExaminerViewerP::genericConstructor(void)
{
  this->currentmode = SoGuiExaminerViewerP::IDLE;

  this->prevRedrawTime = SbTime::getTimeOfDay();
  this->spinanimatingallowed = true;
  this->spinsamplecounter = 0;
  this->spinincrement = SbRotation::identity();

  // FIXME: use a smaller sphere than the default one to have a larger
  // area close to the borders that gives us "z-axis rotation"?
  // 19990425 mortene.
  this->spinprojector = new SbSphereSheetProjector(SbSphere(SbVec3f(0, 0, 0), 0.8f));
  SbViewVolume volume;
  volume.ortho(-1, 1, -1, 1, -1, 1);
  this->spinprojector->setViewVolume(volume);

  this->axiscrossEnabled = false;
  this->axiscrossSize = 25;

  this->spinRotation.setValue(SbVec3f(0, 0, -1), 0);

  this->log.size = MOUSEPOSLOGSIZE;
  this->log.position = new SbVec2s [ MOUSEPOSLOGSIZE ];
  this->log.time = new SbTime [ MOUSEPOSLOGSIZE ];
  this->log.historysize = 0;
  this->button1down = false;
  this->button3down = false;
  this->ctrldown = false;
  this->shiftdown = false;
  this->pointer.now = SbVec2s(0, 0);
  this->pointer.then = SbVec2s(0, 0);
  this->motion3OnCamera = true;
}

void
SoGuiExaminerViewerP::genericDestructor(void)
{
  delete this->spinprojector;
  delete[] this->log.position;
  delete[] this->log.time;
}

// ************************************************************************

// rotate a camera around its focalpoint, in the direction around the
// given axis, by the given delta value (in radians)
void
SoGuiExaminerViewerP::rotateCamera(SoCamera * cam,
                                   const SbVec3f & aroundaxis,
                                   const float delta)
{
  const SbVec3f DEFAULTDIRECTION(0, 0, -1);
  const SbRotation currentorientation = cam->orientation.getValue();

  SbVec3f currentdir;
  currentorientation.multVec(DEFAULTDIRECTION, currentdir);

  const SbVec3f focalpoint = cam->position.getValue() +
    cam->focalDistance.getValue() * currentdir;

  // set new orientation
  cam->orientation = SbRotation(aroundaxis, delta) * currentorientation;

  SbVec3f newdir;
  cam->orientation.getValue().multVec(DEFAULTDIRECTION, newdir);
  cam->position = focalpoint - cam->focalDistance.getValue() * newdir;
}

// The "rotX" wheel is the wheel on the left decoration on the
// examiner viewer.  This function translates interaction with the
// "rotX" wheel into camera movement.
float
SoGuiExaminerViewerP::rotXWheelMotion(float value, float oldvalue)
{
  SoCamera * cam = PUBLIC(this)->getCamera();
  if (cam == NULL) return 0.0f; // can happen for empty scenegraph

  SoGuiExaminerViewerP::rotateCamera(cam, SbVec3f(-1, 0, 0), value - oldvalue);
  return value;
}

// The "rotY" wheel is the wheel on the bottom decoration on the
// examiner viewer.  This function translates interaction with the
// "rotX" wheel into camera movement.
float
SoGuiExaminerViewerP::rotYWheelMotion(float value, float oldvalue)
{
  SoCamera * cam = PUBLIC(this)->getCamera();
  if (cam == NULL) return 0.0f; // can happen for empty scenegraph

  SoGuiExaminerViewerP::rotateCamera(cam, SbVec3f(0, -1, 0), value - oldvalue);
  return value;
}

// ************************************************************************

// The viewer is a state machine, and all changes to the current state
// are made through this call.
void
SoGuiExaminerViewerP::setMode(const ViewerMode newmode)
{
  const ViewerMode oldmode = this->currentmode;
  if (newmode == oldmode) { return; }

  switch (newmode) {
  case DRAGGING:
    // Set up initial projection point for the projector object when
    // first starting a drag operation.
    this->spinprojector->project(this->lastmouseposition);
    PUBLIC(this)->interactiveCountInc();
    this->clearLog();
    break;

  case SPINNING:
    PUBLIC(this)->interactiveCountInc();
    PUBLIC(this)->scheduleRedraw();
    break;

  case PANNING:
    {
      // The plane we're projecting the mouse coordinates to get 3D
      // coordinates should stay the same during the whole pan
      // operation, so we should calculate this value here.
      SoCamera * cam = PUBLIC(this)->getCamera();
      if (cam == NULL) { // can happen for empty scenegraph
        this->panningplane = SbPlane(SbVec3f(0, 0, 1), 0);
      }
      else {
        SbViewVolume vv = cam->getViewVolume(PUBLIC(this)->getGLAspectRatio());
        this->panningplane = vv.getPlane(cam->focalDistance.getValue());
      }
    }
    PUBLIC(this)->interactiveCountInc();
    break;

  case ZOOMING:
    PUBLIC(this)->interactiveCountInc();
    break;

  default: // include default to avoid compiler warnings.
    break;
  }

  switch (oldmode) {
  case SPINNING:
  case DRAGGING:
  case PANNING:
  case ZOOMING:
    PUBLIC(this)->interactiveCountDec();
    break;

  default:
    break;
  }

#if SOQT_DEBUG && 0 // debug
  if (oldmode == ZOOMING) {
    SbVec3f v = PUBLIC(this)->getCamera()->position.getValue();
    SoDebugError::postInfo("SoQtExaminerViewerP::setMode",
                           "new camera position after zoom: <%e, %e, %e>",
                           v[0], v[1], v[2]);
  }
#endif // debug

  this->setCursorRepresentation(newmode);
  this->currentmode = newmode;
}

// ************************************************************************

void
SoGuiExaminerViewerP::drawAxisCross(void)
{
  // FIXME: convert this to a superimposition scenegraph instead of
  // OpenGL calls. 20020603 mortene.

  // Store GL state.
  glPushAttrib(GL_ALL_ATTRIB_BITS);
  GLfloat depthrange[2];
  glGetFloatv(GL_DEPTH_RANGE, depthrange);
  GLdouble projectionmatrix[16];
  glGetDoublev(GL_PROJECTION_MATRIX, projectionmatrix);

  glDepthFunc(GL_ALWAYS);
  glDepthMask(GL_TRUE);
  glDepthRange(0, 0);
  glEnable(GL_DEPTH_TEST);
  glDisable(GL_LIGHTING);
  glEnable(GL_COLOR_MATERIAL);
  glDisable(GL_BLEND); // Kills transparency.

  // Set the viewport in the OpenGL canvas. Dimensions are calculated
  // as a percentage of the total canvas size.
  SbVec2s view = PUBLIC(this)->getGLSize();
  const int pixelarea =
    int(float(this->axiscrossSize)/100.0f * SoQtMin(view[0], view[1]));
#if 0 // middle of canvas
  SbVec2s origin(view[0]/2 - pixelarea/2, view[1]/2 - pixelarea/2);
#endif // middle of canvas
#if 1 // lower right of canvas
  SbVec2s origin(view[0] - pixelarea, 0);
#endif // lower right of canvas
  glViewport(origin[0], origin[1], pixelarea, pixelarea);

  // Set up the projection matrix.
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  const float NEARVAL = 0.1f;
  const float FARVAL = 10.0f;
  const float dim = NEARVAL * float(tan(M_PI / 8.0)); // FOV is 45° (45/360 = 1/8)
  glFrustum(-dim, dim, -dim, dim, NEARVAL, FARVAL);

  // Set up the model matrix.
  glMatrixMode(GL_MODELVIEW);
  glPushMatrix();
  SbMatrix mx;
  SoCamera * cam = PUBLIC(this)->getCamera();

  // If there is no camera (like for an empty scene, for instance),
  // just use an identity rotation.
  if (cam) { mx = cam->orientation.getValue(); }
  else { mx = SbMatrix::identity(); }

  mx = mx.inverse();
  mx[3][2] = -3.5; // Translate away from the projection point (along z axis).
  glLoadMatrixf((float *)mx);

  // Find unit vector end points.
  SbMatrix px;
  glGetFloatv(GL_PROJECTION_MATRIX, (float *)px);
  SbMatrix comb = mx.multRight(px);

  SbVec3f xpos;
  comb.multVecMatrix(SbVec3f(1,0,0), xpos);
  xpos[0] = (1 + xpos[0]) * view[0]/2;
  xpos[1] = (1 + xpos[1]) * view[1]/2;
  SbVec3f ypos;
  comb.multVecMatrix(SbVec3f(0,1,0), ypos);
  ypos[0] = (1 + ypos[0]) * view[0]/2;
  ypos[1] = (1 + ypos[1]) * view[1]/2;
  SbVec3f zpos;
  comb.multVecMatrix(SbVec3f(0,0,1), zpos);
  zpos[0] = (1 + zpos[0]) * view[0]/2;
  zpos[1] = (1 + zpos[1]) * view[1]/2;

  // Render the cross.
  {
    glLineWidth(2.0);

    enum { XAXIS, YAXIS, ZAXIS };
    int idx[3] = { XAXIS, YAXIS, ZAXIS };
    float val[3] = { xpos[2], ypos[2], zpos[2] };

    // Bubble sort.. :-}
    if (val[0] < val[1]) { SoQtSwap(val[0], val[1]); SoQtSwap(idx[0], idx[1]); }
    if (val[1] < val[2]) { SoQtSwap(val[1], val[2]); SoQtSwap(idx[1], idx[2]); }
    if (val[0] < val[1]) { SoQtSwap(val[0], val[1]); SoQtSwap(idx[0], idx[1]); }
    assert((val[0] >= val[1]) && (val[1] >= val[2])); // Just checking..

    for (int i=0; i < 3; i++) {
      glPushMatrix();
      if (idx[i] == XAXIS) {                       // X axis.
        glColor3f(0.500f, 0.125f, 0.125f);
      } else if (idx[i] == YAXIS) {                // Y axis.
        glRotatef(90, 0, 0, 1);
        glColor3f(0.125f, 0.500f, 0.125f);
      } else {                                     // Z axis.
        glRotatef(-90, 0, 1, 0);
        glColor3f(0.125f, 0.125f, 0.500f);
      }
      this->drawArrow();
      glPopMatrix();
    }
  }

  // Render axis notation letters ("X", "Y", "Z").
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(0, view[0], 0, view[1], -1, 1);

  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  GLint unpack;
  glGetIntegerv(GL_UNPACK_ALIGNMENT, &unpack);
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

  glColor3fv(SbVec3f(0.8f, 0.8f, 0.0f).getValue());

  glRasterPos2d(xpos[0], xpos[1]);
  glBitmap(8, 7, 0, 0, 0, 0, xbmp);
  glRasterPos2d(ypos[0], ypos[1]);
  glBitmap(8, 7, 0, 0, 0, 0, ybmp);
  glRasterPos2d(zpos[0], zpos[1]);
  glBitmap(8, 7, 0, 0, 0, 0, zbmp);

  glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);
  glPopMatrix();

  // Reset original state.

  // FIXME: are these 3 lines really necessary, as we push
  // GL_ALL_ATTRIB_BITS at the start? 20000604 mortene.
  glDepthRange(depthrange[0], depthrange[1]);
  glMatrixMode(GL_PROJECTION);
  glLoadMatrixd(projectionmatrix);

  glPopAttrib();
}

// Draw an arrow for the axis representation directly through OpenGL.
void
SoGuiExaminerViewerP::drawArrow(void)
{
  glBegin(GL_LINES);
  glVertex3f(0.0f, 0.0f, 0.0f);
  glVertex3f(1.0f, 0.0f, 0.0f);
  glEnd();
  glDisable(GL_CULL_FACE);
  glBegin(GL_TRIANGLES);
  glVertex3f(1.0f, 0.0f, 0.0f);
  glVertex3f(1.0f - 1.0f / 3.0f, +0.5f / 4.0f, 0.0f);
  glVertex3f(1.0f - 1.0f / 3.0f, -0.5f / 4.0f, 0.0f);
  glVertex3f(1.0f, 0.0f, 0.0f);
  glVertex3f(1.0f - 1.0f / 3.0f, 0.0f, +0.5f / 4.0f);
  glVertex3f(1.0f - 1.0f / 3.0f, 0.0f, -0.5f / 4.0f);
  glEnd();
  glBegin(GL_QUADS);
  glVertex3f(1.0f - 1.0f / 3.0f, +0.5f / 4.0f, 0.0f);
  glVertex3f(1.0f - 1.0f / 3.0f, 0.0f, +0.5f / 4.0f);
  glVertex3f(1.0f - 1.0f / 3.0f, -0.5f / 4.0f, 0.0f);
  glVertex3f(1.0f - 1.0f / 3.0f, 0.0f, -0.5f / 4.0f);
  glEnd();
}

// ************************************************************************

// Rotate the camera by the given amount, then reposition it so we're
// still pointing at the same focal point.
void
SoGuiExaminerViewerP::reorientCamera(const SbRotation & rot)
{
  SoCamera * cam = PUBLIC(this)->getCamera();
  if (cam == NULL) return;

  // Find global coordinates of focal point.
  SbVec3f direction;
  cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
  SbVec3f focalpoint = cam->position.getValue() +
    cam->focalDistance.getValue() * direction;

  // Set new orientation value by accumulating the new rotation.
  cam->orientation = rot * cam->orientation.getValue();

  // Reposition camera so we are still pointing at the same old focal point.
  cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
  cam->position = focalpoint - cam->focalDistance.getValue() * direction;
}

// ************************************************************************

// Uses the sphere sheet projector to map the mouseposition unto
// a 3D point and find a rotation from this and the last calculated point.
void
SoGuiExaminerViewerP::spin(const SbVec2f & pointerpos)
{
  if (this->log.historysize < 2) return;
  assert(this->spinprojector != NULL);

  SbVec2s glsize(PUBLIC(this)->getGLSize());
  SbVec2f lastpos;
  lastpos[0] = float(this->log.position[1][0]) / float(SoQtMax((int)(glsize[0]-1), 1));
  lastpos[1] = float(this->log.position[1][1]) / float(SoQtMax((int)(glsize[1]-1), 1));

  this->spinprojector->project(lastpos);
  SbRotation r;
  this->spinprojector->projectAndGetRotation(pointerpos, r);
  r.invert();
  this->reorientCamera(r);

  // Calculate an average angle magnitude value to make the transition
  // to a possible spin animation mode appear smooth.

  SbVec3f dummy_axis, newaxis;
  float acc_angle, newangle;
  this->spinincrement.getValue(dummy_axis, acc_angle);
  acc_angle *= this->spinsamplecounter; // weight
  r.getValue(newaxis, newangle);
  acc_angle += newangle;

  this->spinsamplecounter++;
  acc_angle /= this->spinsamplecounter;
  // FIXME: accumulate and average axis vectors aswell? 19990501 mortene.
  this->spinincrement.setValue(newaxis, acc_angle);

  // Don't carry too much baggage, as that'll give unwanted results
  // when the user quickly trigger (as in "click-drag-release") a spin
  // animation.
  if (this->spinsamplecounter > 3) this->spinsamplecounter = 3;
}

// ************************************************************************

// Calculate a zoom/dolly factor from the difference of the current
// cursor position and the last.
void
SoGuiExaminerViewerP::zoomByCursor(const SbVec2f & thispos,
                                   const SbVec2f & prevpos)
{
  // There is no "geometrically correct" value, 20 just seems to give
  // about the right "feel".
  SoGuiFullViewerP::zoom(PUBLIC(this)->getCamera(),
                         (thispos[1] - prevpos[1]) * 20.0f);
}

// *************************************************************************
// Methods used for spin animation tracking.

// This method "clears" the mouse location log, used for spin
// animation calculations.
void
SoGuiExaminerViewerP::clearLog(void)
{
  this->log.historysize = 0;
}

// This method adds another point to the mouse location log, used for spin
// animation calculations.
void
SoGuiExaminerViewerP::addToLog(const SbVec2s pos, const SbTime time)
{
  // In case someone changes the const size setting at the top of this
  // file too small.
  assert (this->log.size > 2 && "mouse log too small!");

  if (this->log.historysize > 0 && pos == this->log.position[0]) {
#if SOQT_DEBUG && 0 // debug
    // This can at least happen under SoQt.
    SoDebugError::postInfo("SoGuiExaminerViewerP::addToLog", "got position already!");
#endif // debug
    return;
  }

  int lastidx = this->log.historysize;
  // If we've filled up the log, we should throw away the last item:
  if (lastidx == this->log.size) { lastidx--; }

  assert(lastidx < this->log.size);
  for (int i = lastidx; i > 0; i--) {
    this->log.position[i] = this->log.position[i-1];
    this->log.time[i] = this->log.time[i-1];
  }

  this->log.position[0] = pos;
  this->log.time[0] = time;
  if (this->log.historysize < this->log.size)
    this->log.historysize += 1;
}

// *************************************************************************

// This method sets whether Motion3 events should affect the camera or
// the model.
void
SoGuiExaminerViewerP::setMotion3OnCamera(SbBool enable)
{
  this->motion3OnCamera = enable;
}

// This method returns whether Motion3 events affects the camera or
// the model.
SbBool
SoGuiExaminerViewerP::getMotion3OnCamera(void) const
{
  return this->motion3OnCamera;
}

// ************************************************************************

// Set cursor graphics according to mode.
void
SoGuiExaminerViewerP::setCursorRepresentation(int modearg)
{
  if (!PUBLIC(this)->isCursorEnabled()) {
    PUBLIC(this)->setComponentCursor(SoQtCursor::getBlankCursor());
    return;
  }

  switch (modearg) {
  case SoGuiExaminerViewerP::INTERACT:
    PUBLIC(this)->setComponentCursor(SoQtCursor(SoQtCursor::DEFAULT));
    break;

  case SoGuiExaminerViewerP::IDLE:
  case SoGuiExaminerViewerP::DRAGGING:
  case SoGuiExaminerViewerP::SPINNING:
    PUBLIC(this)->setComponentCursor(SoQtCursor::getRotateCursor());
    break;

  case SoGuiExaminerViewerP::ZOOMING:
    PUBLIC(this)->setComponentCursor(SoQtCursor::getZoomCursor());
    break;

  case SoGuiExaminerViewerP::SEEK_MODE:
  case SoGuiExaminerViewerP::SEEK_WAIT_MODE:
    PUBLIC(this)->setComponentCursor(SoQtCursor(SoQtCursor::CROSSHAIR));
    break;

  case SoGuiExaminerViewerP::PANNING:
    PUBLIC(this)->setComponentCursor(SoQtCursor::getPanCursor());
    break;

  default: assert(0); break;
  }
}

#endif // DOXYGEN_SKIP_THIS

// *************************************************************************

#undef PRIVATE
#undef PUBLIC


text:
<?php

declare(strict_types=1);

namespace Respect\Validation\Exceptions;

/**
 * @author Henrique Moody <henriquemoody@gmail.com>
 */
final class ValidatorException extends AllOfException
{
}

redpajama_set_name: RedPajamaGithub


text:
using Lidgren.Network;
using LmpCommon.Message.Base;
using LmpCommon.Message.Types;

namespace LmpCommon.Message.Data.Warp
{
    public class WarpChangeSubspaceMsgData : WarpBaseMsgData
    {
        /// <inheritdoc />
        internal WarpChangeSubspaceMsgData() { }
        public override WarpMessageType WarpMessageType => WarpMessageType.ChangeSubspace;

        public string PlayerName;
        public int Subspace;

        public override string ClassName { get; } = nameof(WarpChangeSubspaceMsgData);

        internal override void InternalSerialize(NetOutgoingMessage lidgrenMsg)
        {
            base.InternalSerialize(lidgrenMsg);

            lidgrenMsg.Write(PlayerName);
            lidgrenMsg.Write(Subspace);
        }

        internal override void InternalDeserialize(NetIncomingMessage lidgrenMsg)
        {
            base.InternalDeserialize(lidgrenMsg);

            PlayerName = lidgrenMsg.ReadString();
            Subspace = lidgrenMsg.ReadInt32();
        }

        internal override int InternalGetMessageSize()
        {
            return base.InternalGetMessageSize() + PlayerName.GetByteCount() + sizeof(int);
        }
    }
}


text:
title: PhoneGap 1.0 Creates a Stir
date: 2011-08-08 15:54:57 Z
categories:
- News
author: Capulet
status: publish
type: post
format: html
tags_old:
- phonegap 1.0
---

We spend a lot of time watching the web, reading how developers work with PhoneGap and celebrating their apps. So, after last week's launch, we were pleased by the reception PhoneGap 1.0 received and the attention it got in the media. Here's a roundup of some of the tech publications that covered the release:

On [ReadWriteWeb](http://www.readwriteweb.com/mobile/2011/07/phonegap-1-0-launches-today.php):

> "Most of the improvements to PhoneGap 1.0 came from its community of developers, which Nitobi CEO Andre Charland says is PhoneGap's "greatest asset."

On [eWeek](http://www.eweek.com/c/a/Application-Development/Nitobi-Launches-PhoneGap-10-633395/):

> "PhoneGap 1.0 focuses on accessing native device APIs, which is new ground for the web. Other improvements include overall API stability and "pluggable" architecture, World Wide Consortium Device APIs and Policy (DAP) API compatibility, a contacts API and debugging tools."

On [engadget](http://www.google.com/url?q=http%3A%2F%2Fwww.engadget.com%2F2011%2F08%2F01%2Fphonegap-1-0-lets-devs-write-apps-for-six-platforms-wp7-not-inc%2F&sa=D&sntz=1&usg=AFQjCNH63TMDHbcbwBPRfozbNsrIuUyeSg):

> "It's been picking up steam, with about 40,000 downloads per month, 600,000 in total."

On [TheNextWeb](http://thenextweb.com/ca/2011/07/30/phonegap-is-a-swiss-army-knife-for-mobile-app-developers/):

> "With the open source code receiving contributions from a dedicated community of developers, PhoneGap has increased in both stability and durability – which has played a large part in the project averaging approximately 40,000 downloads per month at the time of writing."

[On HTML5 Report](http://www.google.com/url?q=http%3A%2F%2Fhtml5.tmcnet.com%2Ftopics%2Fhtml5%2Farticles%2F203139-nitobi-inc-announces-release-phonegap-10-first-ever.htm&sa=D&sntz=1&usg=AFQjCNGIIrujWA9Rmy2BJP9EiybV9WDpqQ):

> "Furthermore, the latest release from Nitobi incorporates a new unifying bridge interface which allows developers to easily add platforms and platform extensions. It also has a simplified plug-in development process."

News of PhoneGap's 1.0 release also caught the attention of writers in Russia, German and China, which is awesome!


text:
using System;
using SFA.DAS.Messaging.Attributes;

namespace SFA.DAS.EmployerAccounts.Events.Messages
{
    [Serializable]
    [MessageGroup("delete_paye_scheme")]
    public class PayeSchemeDeletedMessage : AccountMessageBase
    {
        //We have protected setters to support json serialsation due to the empty constructor
        public string PayeScheme { get; protected set; }
        public string OrganisationName { get; protected set; }

        public PayeSchemeDeletedMessage()
        { }

        public PayeSchemeDeletedMessage(string payeScheme, string organisationName, long accountId, string creatorName, string creatorUserRef)
            : base(accountId, creatorName, creatorUserRef)
        {
            PayeScheme = payeScheme;
            OrganisationName = organisationName;
        }
    }
}


text:
/*
*  General Notes:
*  Note we take x as horizontal --- This has been the biggest confusion so far for me working with images
*
*  attributes of annotation so far ..
*  img
*  flow
*  data
*       array of parts object
*           parts object has following attr
*               x,y,interp
*                   x,y are the coordinates
*                   interp is true if the coordinates are found by prediction
*                   algorithms else it is false
*/

/*
*  Global Variables --- comes from specific files
*  All the variables the user need to set should be on the top
*/
var img_path        = 'imgs/undercam/cam1logfile1/cam1logfile1_%05d.jpeg';
var flow_path       = 'flow/undercam/cam1logfile1/cam1logfile1_%05d.jpeg';
var nimages         = 100;              //TODO: This could be determined automatically
var FPS             = 10;               // Playing speed; TODO: Provide UI to change it

// control_points are the keypoints
// control_attr are the attributes applied to control points in different states.
// States are mouseover, interp (true), default (interp = false)
var control_points  = ["head","body","larm","rarm","tail","lleg","rleg","mtail","etail"];
var control_attr    = {"mouseover"  : {fill: "#FF8000", stroke: "none", opacity:0.5, r:10},
                       "interp"     : {fill: "#FF0000", stroke: "none", opacity:0.5, r:5 },
                       "default"    : {fill: "#00FF80", stroke: "none", opacity:0.5, r:5}};

// Connections is where to draw the line
var connections     =
["head-body","body-larm","body-rarm","body-tail","tail-lleg","tail-rleg","tail-mtail","mtail-etail"];
var connection_color= {"head-body" : "hsb(.3, .75, .75)",
                       "body-larm" : "hsb(.6, .75, .75)",
                       "body-rarm" : "hsb(.1, .75, .75)",
                       "body-tail" : "hsb(.3, .75, .75)",
                       "tail-lleg" : "hsb(.6, .75, .75)",
                       "tail-rleg" : "hsb(.1, .75, .75)",
                       "tail-mtail": "hsb(.3, .75, .75)",
                       "mtail-etail":"hsb(.3, .75, .75)"};

var center_point  = "body-tail";

// assigned when using random generation, take care the order should be same as control_points
var rand_coordinates ={};
    rand_coordinates.head = {x:240,y:240,interp:true};
    rand_coordinates.body = {x:240,y:280,interp:true};
    rand_coordinates.larm = {x:200,y:260,interp:true};
    rand_coordinates.rarm = {x:280,y:260,interp:true};
    rand_coordinates.tail = {x:240,y:330,interp:true};
    rand_coordinates.lleg = {x:200,y:300,interp:true};
    rand_coordinates.rleg = {x:280,y:300,interp:true};
    rand_coordinates.mtail= {x:240,y:360,interp:true};
    rand_coordinates.etail= {x:240,y:380,interp:true};

// Beyond this no change should be required by the user
var r;
var play;                       // this is set to stop the playing when paused or stopped
var current_image   = 1;        // the image we are looking at
var show_image      = true;
var show_annotation = true;
var annotation      = [];
// Note for annotation variable :
// This should contain image, flow, as well as annotations (coordinates);
// This is all the data we need to save or should be caring about.

// preload all the images and flow; To avoid lags
for (i=0; i<nimages; i++) {
    annotation[i]           = [];
    annotation[i].img       = new Image();
    annotation[i].img.src   = sprintf( img_path, [i+1] );  // name of the image file.
    annotation[i].flow      = new Image();
    annotation[i].flow.src  = sprintf( flow_path, [i+1]);  // name of flow file
}

// create raphael element
r = Raphael("holder",annotation[0].img.width,annotation[0].img.height);

// Note we have to keep track of every svg element we create so that we can reorder it.
//txt_element = r.text(310, 20, "drag the points to change the curves").attr({fill: "#fff", "font-size": 16});
//txt_element.toFront();

// This function handles drawing of svg and dragging
// Input : keypoints  is an array similar to data array in annotation
function draw_puppet(keypoints, color) {

// We draw all the line by moving(M) and drawing a line (L)
    //function to generate path arrays
    function gen_path_array(str1,str2){
        return ["M", keypoints[str1].x, keypoints[str1].y, "L", keypoints[str2].x, keypoints[str2].y];
    }

    // draw connections
    var path = {};
    var curve = {}
    function draw_connections(){
        connections.forEach( function(ele,idx){
            path[ele] = gen_path_array (ele.split("-")[0],ele.split("-")[1]);
        });
        connections.forEach( function (ele,idx){
            curve[ele] = r.path(path[ele]).attr({stroke: connection_color[ele]||Raphael.getColor(),"stroke-width": 4, "stroke-linecap": "round"});
        });
    }

    function redraw_connections(){
        connections.forEach( function(ele,idx){
            path[ele] = gen_path_array (ele.split("-")[0],ele.split("-")[1]);
        });
        connections.forEach( function (ele,idx){
            curve[ele].attr({path:path[ele]});
        });
        var t = center_point.split("-");
        center_control.attr({cx:(keypoints[t[0]].x+keypoints[t[1]].x)/2, cy: (keypoints[t[0]].y+keypoints[t[1]].y)/2});
    }

    draw_connections();
    controls = r.set();

    for (var prop in keypoints){
        var attr = (keypoints[prop].interp)? control_attr["interp"]: control_attr["default"];
        controls.push(r.circle(keypoints[prop].x, keypoints[prop].y, 5).attr(attr));
        //console.log(prop);
    }
    var t = center_point.split("-");
    center_control = r.circle( (keypoints[t[0]].x+keypoints[t[1]].x)/2, (keypoints[t[0]].y+keypoints[t[1]].y)/2,5).attr(control_attr["interp"]);

    // set control listeners for all the points.
    // This is a perfect example of why people call js a devil
    var base_id = controls[0].id;
    for (var i=0; i < controls.length; i++){
        controls[i].update = function (x, y) {
            var X = this.attr("cx") + x, Y = this.attr("cy") + y;
            keypoints[control_points[this.id-base_id]] = {x: X, y: Y, interp: false};
            this.attr({cx: X, cy: Y});
            this.attr(control_attr["default"]);
            redraw_connections();

        }
    }

    center_control.update = function (x,y){
        var p=0
        for (var prop in keypoints){
            keypoints[prop] = {x: keypoints[prop].x+x, y: keypoints[prop].y+y, interp:false}
            controls[p].attr({cx:keypoints[prop].x, cy:keypoints[prop].y}).attr(control_attr["default"]);
            p=p+1;
        }
        this.attr({cx: this.attr("cx")+x, cy: this.attr("cy")+y});
        this.attr(control_attr["default"]);
        redraw_connections();
    }

    controls.drag(move, up);
    center_control.drag(move,up);

    center_control.mouseover(function() {
        this.attr(control_attr["mouseover"]);
    });
    center_control.mousedown(function () {
        center_control.update(0,0);                     //set all interp to false
        this.attr(control_attr["mouseover"]);
    });

    center_control.mouseup(function(){
        this.attr (control_attr["default"]);
    });

    center_control.mouseout(function(){
        var check = true;
        for (var prop in keypoints){
            check = check & keypoints[prop].interp;
        }
        var attr = check ? control_attr["interp"]: control_attr["default"];
        this.attr(attr);
    });

    controls.mousedown(function () {
        this.attr(control_attr["mouseover"]);
    });
    controls.mouseover(function(){
        this.attr(control_attr["mouseover"]);
    });

    controls.mouseup(function () {
        var prop = control_points[this.id-base_id];
        var attr = (keypoints[prop].interp)? control_attr["interp"]: control_attr["default"];
        this.attr(attr);
        //look ahead till interp==false or end -- linearly intepolate
        var look_ahead = current_image+1;
        while (look_ahead < nimages && annotation[look_ahead].hasOwnProperty("data")
                && annotation[look_ahead].data[prop].interp===true){
            look_ahead++;
        }
        if (look_ahead < nimages && annotation[look_ahead].hasOwnProperty("data") ){
            //console.log("cont");
        }else{
            look_ahead--;
        }
            //interpolate...
        if (annotation[look_ahead].hasOwnProperty("data")){
            var x_inc = annotation[look_ahead].data[prop].x - annotation[current_image-1].data[prop].x ;
            var y_inc = annotation[look_ahead].data[prop].y - annotation[current_image-1].data[prop].y ;

            x_inc = x_inc/(look_ahead-current_image+1);
            y_inc = y_inc/(look_ahead-current_image+1);
            var x_init = annotation[current_image-1].data[prop].x;
            var y_init = annotation[current_image-1].data[prop].y;

            for (var p = current_image; p < look_ahead; p++){
                annotation[p].data[prop].x = x_init + x_inc*(p-current_image+1);
                annotation[p].data[prop].y = y_init + y_inc*(p-current_image+1);
            }
        }

        var look_back = current_image-3;
        while (look_back > -1 && annotation[look_back].hasOwnProperty("data")
                && annotation[look_back].data[prop].interp===true){
            look_back--;
        }
        //console.log(look_back);
        if (look_back > -1 && annotation[look_back].hasOwnProperty("data")
            && annotation[look_back].data[prop].interp===false ){        //interpolate...
            var x_inc = annotation[look_back].data[prop].x - annotation[current_image-1].data[prop].x ;
            var y_inc = annotation[look_back].data[prop].y - annotation[current_image-1].data[prop].y ;

            x_inc = x_inc/(look_back-current_image+1);
            y_inc = y_inc/(look_back-current_image+1);
            var x_init = annotation[current_image-1].data[prop].x;
            var y_init = annotation[current_image-1].data[prop].y;

            for (var p = current_image-2 ; p > look_back; p--){
                annotation[p].data[prop].x = x_init + x_inc*(p-current_image+1);
                annotation[p].data[prop].y = y_init + y_inc*(p-current_image+1);
            }
        }
            //look back till interp == false --- linearly intepolate else chill
       // console.log("Mouse up");
    });

    controls.mouseout(function(){
        var prop = control_points[this.id-base_id];
        var attr = (keypoints[prop].interp)? control_attr["interp"]: control_attr["default"];
        this.attr(attr);
    });
} // end draw_puppet

function move(dx, dy) {
    this.update(dx - (this.dx || 0), dy - (this.dy || 0));
    this.dx = dx;
    this.dy = dy;
}

function up() {
    this.dx = this.dy = 0;
}

// updates the frame
function update_image() {
    img = annotation[current_image-1].img;
    //r.clear();
    show_image ? r.image(img.src,0,0,img.width,img.height) : r.rect(0,0,img.width,img.height,0).attr({stroke:'#666'});

    if (show_annotation){
        if (annotation[current_image-1].hasOwnProperty("data")){
            var annotate = annotation[current_image-1].data;
            draw_puppet(annotate);
        }
    }

    var new_text = sprintf('you are currently on frame %d / %d', current_image, nimages);
    $('#info-text').text( new_text ); // update the text at the top
}

// set frame no to frame_no
function set_frame( frame_no ) {
    current_image  = frame_no;
    update_image();
}

// moves ahead by no_of_frame --- can take negative no. and go back
function advance_frame(no_of_frame){
    var temp_current_image = current_image + no_of_frame;
    if (temp_current_image > nimages){
        current_image = nimages;
    }else if (temp_current_image < 1){
            current_image = 1;
    }else{
        current_image = temp_current_image;
    }
    update_image();
    return ;
}

// return a data structure like annotation.data, which has new coordinates as per optical flow
function flow_prediction(predict_from){
    var new_data    = [];
    var img         = new Image();
    var c           = document.createElement("canvas")
    //console.log(predict_from);
    img.src  = annotation[predict_from].flow.src;           // TODO: fix this numbering; rename the files
                                                            // note that flow for current image is in number 1 less than the image
    c.width  = img.width;
    c.height = img.height;

    var w = img.width, h = img.height;
    var ctx = c.getContext("2d");
    ctx.drawImage(img, 0, 0);

    var idata = ctx.getImageData(0, 0, img.width, img.height);
    var p     = idata.data;
    var l;
    var data = annotation[predict_from].data
    for (var prop in data){
        l = (data[prop].y*w + data[prop].x)*4;
        new_data[prop] = {x:data[prop].x+p[l+1]-128,y:data[prop].y+p[l+2]-128};
    }
    return new_data;
}

// raise an error for the user
function raise_error(err_str){
    var err_el = r.text(r.width/2,20,err_str).attr({fill: "#FF0000", "font-size": 16});
    err_el.animate({ opacity : 0 },3000,">",function () { });
}

function chkbox(){
    var img_chk = document.getElementById("show_image_chkbox");
    img_chk.checked ? show_image = true : show_image = false;

    var annotation_chk = document.getElementById("show_annotation_chkbox");
    annotation_chk.checked ? show_annotation = true : show_annotation = false;

    update_image();
}

// copied from
// http://stackoverflow.com/questions/3665115/create-a-file-in-memory-for-user-to-download-not-through-server
function download(filename, text) {
  var pom = document.createElement('a');
  pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
  pom.setAttribute('download', filename);

  pom.style.display = 'none';
  document.body.appendChild(pom);

  pom.click();

  document.body.removeChild(pom);
}

function annotation_to_csv(a){
    return a.reduce(function(prev,cur,idx,arr) {
        var str="";
        if (cur.data !== undefined ){
            str=cur.img.src;
            for (var i=0;i<control_points.length;i++){
                str=str+" ,"+cur.data[control_points[i]].x+" ,"+cur.data[control_points[i]].y;
            }
        }
        return prev+"\n"+str;
    }
    ,"");
}

function annotation_to_json(a){
    var temp={};
    for (i=0;i<a.length;i++){
        temp[i]={};
        temp[i].src = a[i].img.src;
        if (a[i].data !== undefined){
            temp[i].data = {};
            for (var p=0;p<control_points.length;p++){
                temp[i].data[control_points[p]] = a[i].data[control_points[p]];
            }
        }
    }
    return JSON.stringify(temp);
}

function play_frames(){
    $('#gen_random_bttn').prop('disabled', true);
    $('#copy_prev_bttn').prop('disabled',true);
    $('#use_flow_bttn').prop('disabled',true);

    $('#play_bttn').hide();
    $('#pause_bttn').show();

    play = window.setInterval(function() {
        advance_frame(1);
        if (current_image == nimages){
            window.clearInterval(play);
            play = undefined;
            $('#gen_random_bttn').prop('disabled', false);
            $('#copy_prev_bttn').prop('disabled',false);
            $('#use_flow_bttn').prop('disabled',false);
        }
    },1000/FPS);
}
function pause_frames(){
    $('#gen_random_bttn').prop('disabled', false);
    $('#copy_prev_bttn').prop('disabled',false);
    $('#use_flow_bttn').prop('disabled',false);
    $('#play_bttn').show();
    $('#pause_bttn').hide();
    window.clearInterval(play);
            play = undefined;
}

function stop_frames(){
    window.clearInterval(play);
            play = undefined;
    $('#gen_random_bttn').prop('disabled', false);
    $('#copy_prev_bttn').prop('disabled',false);
    $('#use_flow_bttn').prop('disabled',false);
    $('#play_bttn').show();
    $('#pause_bttn').hide();
    set_frame(1);
}

function gen_rand_annotation(){
    // generate a random puppet
    if (!annotation[current_image-1].hasOwnProperty("data")){
        annotation[current_image-1].data = [];
    }
    var annotate = annotation[current_image-1].data;
    for (var prop in rand_coordinates){
        annotate[prop] ={x: rand_coordinates[prop].x, y: rand_coordinates[prop].y, interp: true};
    }
    update_image();
    //console.log('here');
}

function get_copy_num(){
    var ret = document.getElementById('copy_num').value;
    if (isNaN(ret)|| ret===""){
        return 1;
    }else{
        return Number(ret);
    }
    return 1;
}
function copy_annotation(){
    //copy previous annotation
    if (current_image == nimages){
        raise_error("There are no more frames ahead");
    }else{
        if (!annotation[current_image-1].hasOwnProperty("data")){
            raise_error('No annotation to copy');
        }else{
            var copy_num = get_copy_num();
            var annotate = annotation[current_image-1].data;
            for (var prop in annotate){
                annotate[prop].interp = false;
            }
            for (var i = current_image; i<current_image+copy_num && i<nimages; i++){
                annotation[i].data = jQuery.extend(true,{},annotation[current_image-1].data);
                var annotate = annotation[i].data;
                for (var prop in  annotate){
                    annotate[prop].interp = true;
                }
            }
        }
    }
    update_image();
}

function copy_with_flow(){
    if (current_image == nimages){
        raise_error ("There are no more frames ahead");
    }else{
        if (!annotation[current_image-1].hasOwnProperty("data")){
            raise_error ('No annotation to copy');
        }else{
            var copy_num = get_copy_num();
            var annotate = annotation[current_image-1].data;
            for (var prop in annotate){
                annotate[prop].interp = false;
            }
            for (var i = current_image; i<current_image+copy_num && i<nimages; i++){
                annotation[i].data = flow_prediction(i-1);
                var annotate = annotation[i].data;
                for (var prop in  annotate){
                    annotate[prop].interp = true;
                }
            }
        }
    }
    update_image();
}

function download_annotation(){
    value = $("input[name=download_fmt]:checked").val();
    if (value === "csv"){
        save_string = annotation_to_csv(annotation);
        download("data.txt", save_string);
    }else if (value === "json"){
        save_string = annotation_to_json(annotation);
        download("data.txt", save_string);
    }else{
        alert("no download format selected");
    }
}

$('#fwd_bttn').click(function () {
    advance_frame(1);
});

$('#play_bttn').click(function () {
    play_frames();
});

$('#pause_bttn').click(function () {
    pause_frames();
});

$('#stop_bttn').click(function () {
    stop_frames();
});

$('#back_bttn').click( function() {
    advance_frame(-1);
});

$('#gen_random_bttn').click(function() {
    gen_rand_annotation();
});

$('#copy_prev_bttn').click(function() {
    copy_annotation();
});

$('#use_flow_bttn').click(function() {
    copy_with_flow();
});

$('#dnld_annotation').click(function() {
    download_annotation();
});

$(document).keydown(function(e){
    switch (e.which){
        case 37: //left
                advance_frame(-1);
                break;
        case 39: //right
                advance_frame(1);
                break;
        case 32: //space
                if (e.ctrlKey){
                    advance_frame(-1);
                }else{
                    advance_frame(1);
                }
                break;
        case 67: //ctrl+c
                if (e.ctrlKey){
                    copy_annotation();
                }
                break;
        case 70: //f
                if (e.ctrlKey){
                    copy_with_flow();
                }
                break;
        case 82: //r
                if (e.ctrlKey){
                $('#gen_random_bttn').click();
                }
                break;
        case 83: //s
                if (e.ctrlKey){
                    download_annotation();
                }
                break;
        case 80: if (play===undefined){
                    $('#play_bttn').click();
                }else {
                    $('#pause_bttn').click();
                }
                break;
        case 65:
                if (e.ctrlKey){
                    $('#stop_bttn').click();
                }
                break;
        default: return;
    }
    e.preventDefault();
});

set_frame(1);

        // this should give you access to the precomputed flow.
        /* commenting it out for now as we are not using optical flow now- Umang
        var img = new image()
        var c = document.createelement("canvas")
        img.src = sprintf( flow_path, 1);
        img.onload = function() {
            c.width = img.width;
            c.height = img.height;
            var w = img.width, h = img.height;
            var ctx = c.getcontext("2d");
            ctx.drawimage(img, 0, 0);
            var idata = ctx.getimagedata(0, 0, img.width, img.height);
            var p     = idata.data;
            var lidx;
            var r, g, b, alpha;
            // loop through image pixels
            for (var y=0; y<img.height; y++) {
                for (var x=0; x<img.width; x++) {
                    l = ( y*w + x ) * 4; // convert to linear index
                    r = p[l];   // red should always be zero
                    g = p[l+1]; // green minus 128 is flow in x
                    b = p[l+2]  //  blue minus 128 is flow in y
                    alpha = p[l+3]; // alpha will always be 255
                }
            }
        }
        */


text: You  To add new posts, simply add a file in the


text:
layout: page
title: Singleton Family Reunion
date: 2016-05-24
author: Bobby Montes
tags: weekly links, java
status: published
summary: Suspendisse porttitor ornare sapien pellentesque.
banner: images/banner/people.jpg
booking:
  startDate: 01/30/2017
  endDate: 02/01/2017
  ctyhocn: TUSEAHX
  groupCode: SFR
published: true
---
Nullam commodo nec odio vel finibus. Sed et convallis justo. Aliquam semper diam orci. Quisque quis placerat turpis, et aliquam leo. Sed sollicitudin ornare risus, ac rhoncus nisi. Nunc sagittis, ante vitae iaculis placerat, velit ligula fringilla diam, in eleifend lorem mi quis tellus. Nullam semper mi ipsum, sit amet porta arcu facilisis vel. Donec quis sapien facilisis, bibendum massa egestas, congue odio. Mauris felis lectus, viverra ut tellus et, convallis ullamcorper risus. Aenean id nulla nec odio vehicula aliquet. Donec augue nisi, egestas et mi ac, facilisis elementum erat. Duis pharetra varius felis, sit amet suscipit leo auctor eget. In imperdiet molestie fermentum. Praesent vitae mi augue.

* Suspendisse gravida diam ut massa dignissim sollicitudin
* Nam vehicula nulla ac nulla consequat tempus
* Maecenas sollicitudin libero at sem pulvinar suscipit.

Nunc eu hendrerit risus, nec congue sem. Praesent ut tellus ipsum. Vestibulum vitae lorem tempus, porttitor purus in, convallis lorem. Etiam in malesuada urna, id pulvinar metus. Nulla sed enim vel erat maximus viverra. Aenean blandit tempor risus ac luctus. Maecenas porttitor nulla ipsum, sodales ultrices augue scelerisque vel. Integer mollis, lacus sed ultrices faucibus, velit metus egestas lorem, et hendrerit augue lorem et est. Vestibulum fringilla feugiat malesuada. Donec eu tortor ut est rutrum consequat quis sit amet arcu.


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <title>Statistics of PART in UD_English-Pronouns</title>
    <link rel="root" href=""/>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css">
    <link rel="stylesheet" type="text/css" href="../../css/jquery-ui-redmond.css"/>
    <link rel="stylesheet" type="text/css" href="../../css/style.css"/>
    <link rel="stylesheet" type="text/css" href="../../css/style-vis.css"/>
    <link rel="stylesheet" type="text/css" href="../../css/hint.css"/>

          home

          edit page
          issue tracker

          <gcse:search></gcse:search>

        This page pertains to UD version 2.

            It appears that you have Javascript disabled.
            Please consider enabling Javascript for this page to see the visualizations.

Treebank Statistics: UD_English-Pronouns: POS Tags: PART

There are 3 PART lemmas (5%), 5 PART types (6%) and 45 PART tokens (3%).
Out of 13 observed tags, the rank of PART is: 9 in number of lemmas, 7 in number of types and 9 in number of tokens.

The 10 most frequent PART lemmas: not, 's, to

The 10 most frequent PART types:  's, n't, not, nt, to

The 10 most frequent ambiguous lemmas: to (<tt>ADP</tt> 10, <tt>PART</tt> 5)

The 10 most frequent ambiguous types:  's (<tt>AUX</tt> 40, <tt>PART</tt> 10), to (<tt>ADP</tt> 10, <tt>PART</tt> 5)

's

<tt>AUX</tt> 40: It 's hers .

<tt>PART</tt> 10: The dealer 's cars and hers sell quickly .

to

<tt>ADP</tt> 10: The dealer gave fresh paint to hers .

<tt>PART</tt> 5: Hers is easy to clean .

Morphology

The form / lemma ratio of PART is 1.666667 (the average of all parts of speech is 1.212121).

The 1st highest number of forms (3) was observed with the lemma "not": n't, not, nt.

The 2nd highest number of forms (1) was observed with the lemma "'s": 's.

The 3rd highest number of forms (1) was observed with the lemma "to": to.

PART occurs with 1 features: <tt>Polarity</tt> (30; 67% instances)

PART occurs with 1 feature-value pairs: Polarity=Neg

PART occurs with 2 feature combinations.
The most frequent feature combination is Polarity=Neg (30 tokens).
Examples: n't, not, nt

Relations

PART nodes are attached to their parents using 3 different relations: <tt>advmod</tt> (30; 67% instances), <tt>case</tt> (10; 22% instances), <tt>mark</tt> (5; 11% instances)

Parents of PART nodes belong to 3 different parts of speech: <tt>PRON</tt> (30; 67% instances), <tt>NOUN</tt> (10; 22% instances), <tt>VERB</tt> (5; 11% instances)

45 (100%) PART nodes are leaves.

The highest child degree of a PART node is 0.

© 2014–2021
            Universal Dependencies contributors.
            Site powered by Annodoc and brat
.