/*----------------------------------------------------------------------------------------------------------------------------
FUNCTION:
static void event_cb(void * ud, SoEventCallback * n) 事件响应函数
static SoSeparator *pickedPointsSubGraph(void) 在鼠标点击处画一个点
Main(int, char **argv);主函数按照场景示意图绘制场景
PURPOSE: 利用线集节点(SoLineSet)绘制两个四边形的剖面。用鼠标在四边形上点击,在点击处画一个点,并在屏幕上输出所点击的点在笛卡尔坐标系下的坐标。
HISTORY: Date:26/11/2007 Author:Shao Yanhong
Comment: 该程序还有缺陷,就是在初始的绘制图中莫名其妙地多了一个点。目前还没有找到它出现的原因,望看到该程序的有心人可以,帮忙解决一下。当然,在以后的学习中,我也会多摸索,找出该程序的问题所在。
----------------------------------------------------------------------------------------------------------------------------------*/
#include <Inventor/Win/SoWin.h>
#include <Inventor/Win/viewers/SoWinExaminerViewer.h>
#include <Inventor/nodes/SoCoordinate3.h>
#include <Inventor/nodes/SoLineSet.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoVertexProperty.h>
#include <Inventor/SoPickedPoint.h>
#include <Inventor/actions/SoRayPickAction.h>
#include <Inventor/events/SoMouseButtonEvent.h>
#include <Inventor/nodes/SoEventCallback.h>
#include <Inventor/nodes/SoPerspectiveCamera.h>
#include <Inventor/nodes/SoPickStyle.h>
#include <Inventor/nodes/SoPointSet.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoDrawStyle.h>
static SoCoordinate3 * pickpoints = NULL; // 储存拾取点信息
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());//使用Open Inventor自带的隐含相机
SoPickedPoint * point = rp.getPickedPoint();//获得拾取物体上的拾取点
if (point == NULL)
{
(void)fprintf(stderr, "/n** miss! **/n/n");
return;
}
n->setHandled();
//const SbVec3f& SoPickedPoint::getPoint() const [inline]:Returns the intersection point in world space
SbVec3f v = point->getPoint(); // 点的坐标
(void)fprintf(stdout, "point=<%f, %f, %f>/n",v[0], v[1], v[2]);
// 在选取点处做个标记
const int idx = pickpoints->point.getNum();
//void SoMFVec3f::set1Value(int index, const SbVec3f &newValue ):Sets the index'th value in the
//array to newValue. The array will be automatically expanded, if necessary
pickpoints->point.set1Value(idx, v);
}
}
//在鼠标点击处画一个点
//返回的分隔符节点SoSeparator中包括SoPickStyle,SoDrawStyle,SoCoordinate3,SoPointSet
static SoSeparator *pickedPointsSubGraph(void)
{
SoSeparator * picksep = new SoSeparator;
SoPickStyle * pickstyle = new SoPickStyle;
pickstyle->style = SoPickStyle::UNPICKABLE; //使拾取动作对后面画的那个点无效,其默认值为SHAPE
picksep->addChild(pickstyle); //SHAPE表示可以对场景图中的形状物体上的点进行拾取。
SoDrawStyle * drawstyle = new SoDrawStyle; //SoDrawStyle 的style 域默认值为FILLED
//FILLED 区域填充模式(默认值)
drawstyle->pointSize = 10; //::pointSize Radius of points (for POINTS style).
picksep->addChild(drawstyle);
pickpoints = new SoCoordinate3;
picksep->addChild(pickpoints);
picksep->addChild(new SoPointSet);
return picksep;
}
int main(int argc, char **argv)
{
HWND window = SoWin::init(argv[0]);
SoWinExaminerViewer * viewer = new SoWinExaminerViewer(window);
SoSeparator * root = new SoSeparator;
root->ref();
root->addChild(pickedPointsSubGraph());
SoEventCallback * ecb = new SoEventCallback;
ecb->addEventCallback(SoMouseButtonEvent::getClassTypeId(),event_cb, viewer);
root->addChild(ecb);
if (argc!=2)
{
(void)fprintf(stderr, "/nSepecify an Inventor file as argument./n");
return 1;
}
SoInput input;
if (!input.openFile(argv[1])) {return 1;}
SoSeparator *r =SoDB::readAll(&input);
if (r==NULL) {return 1; }
root->addChild(r);
viewer->setSceneGraph(root);
viewer->setBackgroundColor(SbColor(0.92f, 0.92f, 0.92f));
viewer->show();
SoWin::show(window);
SoWin::mainLoop();
delete viewer;
root->unref();
return 0;
}
project/settings/debugs/program arguments内填上11.txt
所使用的11.txt文件的内容为:
#Inventor V2.1 ascii
Separator{
Separator{
Material{
diffuseColor 0.0 0.0 1.0
ambientColor 1.0 0.8 0.8
}
Coordinate3{ point [1.0 2.0 1.0, 2.0 2.0 1.0,]}
LineSet{ }
}
Separator{
Material{
diffuseColor 0.0 0.0 1.0
ambientColor 1.0 0.8 0.8
}
Coordinate3{ point [2.0 2.0 1.0, 2.0 2.0 2.0,]}
LineSet{ }
}
Separator{
Material{
diffuseColor 0.0 0.0 1.0
ambientColor 1.0 0.8 0.8
}
Coordinate3{ point [2.0 2.0 2.0, 1.0 2.0 2.0,]}
LineSet{ }
}
Separator{
Material{
diffuseColor 0.0 0.0 1.0
ambientColor 1.0 0.8 0.8
}
Coordinate3{ point [1.0 2.0 2.0, 1.0 2.0 1.0,]}
LineSet{ }
}
Separator{
Material{
diffuseColor 0.0 1.0 1.0
ambientColor 1.0 0.8 0.8
}
Coordinate3{ point [1.0 1.0 1.0, 2.0 1.0 1.0,]}
LineSet{ }
}
Separator{
Material{
diffuseColor 0.0 1.0 1.0
ambientColor 1.0 0.8 0.8
}
Coordinate3{ point [2.0 1.0 1.0, 2.0 1.0 2.0,]}
LineSet{ }
}
Separator{
Material{
diffuseColor 0.0 1.0 1.0
ambientColor 1.0 0.8 0.8
}
Coordinate3{ point [2.0 1.0 2.0, 1.0 1.0 2.0,]}
LineSet{ }
}
Separator{
Material{
diffuseColor 0.0 1.0 1.0
ambientColor 1.0 0.8 0.8
}
Coordinate3{ point [1.0 1.0 2.0, 1.0 1.0 1.0,]}
LineSet{ }
}
}