OpenInventor实现三维模型的拖动

来源:互联网 发布:迅雷端口被屏蔽 编辑:程序博客网 时间:2024/06/05 01:16

OpenInventor是SGI公司开发的基于OpenGL的面向对象三维图形软件开发包。这里不多说,相必点击进来看的都是了解的。
本文主要介绍如何实现三维模型的拖动。本文中的模型是wrl格式的模型文件,通过SoVRMLGroup类进行读取,很多三维设计软件,比如SolidWorks,catia等都可以另存为该格式的文件。当然了,也可以是由open Inventor自带的内建的模型,比如SoCylinder,SoCone等之类的。
这里写图片描述

这里写图片描述

声明变量
初始化:
this->selection = new SoSelection;
this->root = new SoSeparator;
root->ref();
selection->addChild(root);
searcher = new SoSearchAction;

selection->addSelectionCallback(selectionCB, this);  selection->addDeselectionCallback(deselectionCB, this);myViewer = new SoQtExaminerViewer(ui.widget);myViewer->setSceneGraph(selection);myViewer->setBackgroundColor(SbColor(0.7,0.6,0.92));myViewer->viewAll();myViewer->show();

打开模型文件,并加入到场景中
void Select_Drag::openModel()
{
SoSeparator *tmpRoot = new SoSeparator;
tmpRoot->ref();
tmpRoot->setName(“Root_tmp”);
SoTransform *tmpTrans = new SoTransform;
tmpTrans->setName(“Trans”);
tmpRoot->addChild(tmpTrans);

QString filename = QFileDialog::getOpenFileName(this,"Open VRML file","/","VRML files(*.wrl)");if(filename != NULL){    SoInput myInput;    if(!myInput.openFile(filename.toStdString().data()))    {        qDebug()<<"file read failed!";        return;    }    SoVRMLGroup *objectModel = SoDB::readAllVRML(&myInput);    objectModel->setName("VRMLModel");    tmpRoot->addChild(objectModel);    root->addChild(tmpRoot);    myViewer->viewAll();}

}

关键部分代码
void Select_Drag::deselectionCB(void * userdata, SoPath * deselection)
{
isDragged = false;

Select_Drag *s = (Select_Drag *)userdata;SoPath * transform =  s->findRelatedTransform(s,deselection);  assert(transform != NULL);  SoTransformManip * manip = (SoTransformManip *) transform->getTail();SoTransform *tmpTrans = new SoTransform;SbVec3f pos = manip->translation.getValue();tmpTrans->translation.setValue(pos[0],pos[1],pos[2]);manip->replaceManip(transform, tmpTrans); qDebug()<<pos[0]*1000<<"  "<<pos[1]*1000<<"  "<<pos[2]*1000<<"\n";

}

void Select_Drag::selectionCB(void * userdata, SoPath * selection)
{
Select_Drag s = (Select_Drag )userdata;
SoPath * transform = s->findRelatedTransform(s,selection);
assert(transform != NULL);
SoTransformBoxManip * manip = new SoTransformBoxManip;
manip->replaceNode(transform);

///增加传感器节点,实时感知模型位姿变化SoFieldSensor *mySensor = new SoFieldSensor(positionChangedCB,manip);mySensor->attach(&manip->translation);SoFieldSensor *mySensor2 = new SoFieldSensor(rotationChangedCB,manip);mySensor2->attach(&manip->rotation);isDragged = true;s->timer->start();

}

SoPath Select_Drag::findRelatedTransform(void userdata,SoPath * pathtocube)
{
Select_Drag s = (Select_Drag )userdata;
SoSearchAction *sear = s->searcher;
sear->reset();
sear->setInterest(SoSearchAction::LAST);
sear->setType(SoTransform::getClassTypeId());
sear->apply(pathtocube);
return sear->getPath();
}

原创,不可侵权!

原创粉丝点击