// Copyright (C) 1998-2009 by Kongsberg SIM. All rights reserved. #include <Inventor/Win/SoWin.h> #include <Inventor/Win/viewers/SoWinExaminerViewer.h> #include <Inventor/SoInput.h> #include <Inventor/SoOutput.h> #include <Inventor/SoPickedPoint.h> #include <Inventor/actions/SoRayPickAction.h> #include <Inventor/events/SoMouseButtonEvent.h> #include <Inventor/nodes/SoBaseColor.h> #include <Inventor/nodes/SoCube.h> #include <Inventor/nodes/SoEventCallback.h> #include <Inventor/nodes/SoSeparator.h> #include <Inventor/nodes/SoSwitch.h> #include <Inventor/nodes/SoTranslation.h> #include <assert.h> #include <stdlib.h> #include <time.h> #include "ShapeScale.h" // Returns random value between 0.0f and 1.0f. static float normalized_rand(void) { return float(rand())/float(RAND_MAX); } static SoSeparator * construct_new_marker(const SbVec3f & v) { SoSeparator * markerroot = new SoSeparator; SoTranslation * t = new SoTranslation; t->translation = v; markerroot->addChild(t); ShapeScale * kit = new ShapeScale; kit->active = TRUE; kit->projectedSize = 5.0f; // create the marker SoSeparator * markersep = new SoSeparator; SoBaseColor * mat = new SoBaseColor; mat->rgb.setValue(normalized_rand(), normalized_rand(), normalized_rand()); markersep->addChild(mat); // marker shape should be unit size, with center in (0.0f, 0.0f, 0.0f) SoCube * cube = new SoCube; cube->width = 1.0f; cube->height = 1.0f; cube->depth = 1.0f; markersep->addChild(cube); kit->setPart("shape", markersep); markerroot->addChild(kit); return markerroot; } static void event_cb(void * ud, SoEventCallback * n) { const SoMouseButtonEvent * mbe = (SoMouseButtonEvent *)n->getEvent(); if (mbe->getButton() == SoMouseButtonEvent::BUTTON1 && mbe->getState() == SoButtonEvent::DOWN) { SoWinExaminerViewer * viewer = (SoWinExaminerViewer *)ud; SoRayPickAction rp(viewer->getViewportRegion()); rp.setPoint(mbe->getPosition()); rp.apply(viewer->getSceneManager()->getSceneGraph()); SoPickedPoint * point = rp.getPickedPoint(); if (point == NULL) { (void)fprintf(stderr, "/n** miss! **/n/n"); return; } n->setHandled(); const SoPath * p = rp.getCurPath(); for (int i = 0; i < p->getLength(); i++) { SoNode * n = p->getNodeFromTail(i); if (n->isOfType(SoGroup::getClassTypeId())) { SoGroup * g = (SoGroup *)n; g->addChild(construct_new_marker(point->getPoint())); break; } } } } void show_instructions(void) { (void)fprintf(stdout, "/nThis example program demonstrates the use of the ShapeScale nodekit./n" "/nQuick instructions:/n/n" " * place the marker by clicking on a shape with the left mouse button/n" " * hit ESC to toggle back and forth to view mode/n" " * zoom back and forth to see how the markers stay the same size/n/n"); } int main(int argc, char ** argv) { if (argc != 2) { (void) fprintf(stderr,"/nSpecify an Inventor file as argument./n"); return -1; } HWND window = SoWin::init(argv[0]); ShapeScale::initClass(); // init our extension nodekit SoWinExaminerViewer * ex1 = new SoWinExaminerViewer(window); SoInput input; SbBool ok = input.openFile(argv[1]); if (!ok) { (void) fprintf(stderr, "Unable to open file: %s/n", argv[1]); return -1; } SoSeparator * root = SoDB::readAll(&input); if (root == NULL) { (void) fprintf(stderr, "Unable to read file: %s/n", argv[1]); return -1; } show_instructions(); SoSeparator * newroot = new SoSeparator; newroot->ref(); newroot->addChild(root); // create event callback and marker nodes SoSeparator * sep = new SoSeparator; newroot->addChild(sep); SoEventCallback * ecb = new SoEventCallback; ecb->addEventCallback(SoMouseButtonEvent::getClassTypeId(), event_cb, ex1); sep->addChild(ecb); ex1->setSceneGraph(newroot); ex1->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_BLEND); ex1->setViewing(FALSE); ex1->show(); SoWin::show(window); SoWin::mainLoop(); delete ex1; newroot->unref(); return 0; }