应用SoRayPickAction类的交互式程序

/*---------------------------------------------------------------------------------------------------------------------------- 
   
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{ }
}

}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值