Implementation Model Editor of AVEVA in OpenSceneGraph

Implementation Model Editor of AVEVA in OpenSceneGraph

eryar@163.com

摘要Abstract:本文紧要对工厂和海工设计软件AVEVA的交互情势举办详尽介绍,对OpenSceneGraph中的人机交互工具拖拽器举行求证,并在其中落实了模型直接互动操作。对相互建模感兴趣的读者可组成其源代码,对其落实细节举办剖析。 

关键字Key Words:AVEVA, Model Editor, OpenSceneGraph, Dragger 

一、引言 Introduction

在现世的三维协助设计软件中,交互建模设计已经变成主流。友好、高效的对三维模型直接举办编制或修改,不仅可以增强用户的工作功效,还会给用户留下美好记念,即软件可以的用户体验。交互建模的常见模式有:拖曳、约束、栅格捕捉、橡皮筋方法、重力场等,拖曳就是直接对拔取的模子在三维空间中拖动来改变地方和趋势;约束措施就是在拖曳的时候增长约束规范,如不得不沿某个方向举办牵引,软件中的应用有AutoCAD中的极轴捕捉效率;栅格捕捉也是一种带约束的牵引,即拖曳的过程中只可以沿正交网格中直线的交点拖动;橡皮筋方法首要用在绘制二维图形;引力场方法就像AutoCAD中的磁吸功用。如何设计很快、友好、方便的用户接口是眼下各开发类其它厂家和我们所共同关心的题材,它的宏图上下可能直接影响用户是否接受其制品。 

本文首要对工厂和海工设计软件AVEVA的交互形式举办详细介绍,对OpenSceneGraph中的人机交互工具拖拽器举行认证,并在内部落实了模型直接互动操作。通过程序实施,感觉使用OpenSceneGraph来进展编码依然很清爽的,因为其代码规范,设计很好。对相互建模感兴趣的读者可整合其源代码,对其落实细节举行解析。 

二、模型编辑器Model Editor of AVEVA

AVEVA(原CADCENTRE)是国际资深的厂子工程消息技术集团,创设于1967年,总部设在大英帝国俄亥俄州立;AVEVA所提供的厂子工程全体解决方案包含了陆地和海域石油天然气、电力、石化、化工、核电、造船、环保、造纸、制药、冶金、矿山等五个行业,同时提供专业工厂工程技术咨询、技术服务和本地化可持续发展的应用开发。
AVEVA是当前全世界提升最快的厂子工程音信技术集团之一,1996年在大英帝国London上市,2007财年年产值超过25亿新币。AVEVA在全球拥有超过1600名用户,每日有超常26,000名工程人员在使用AVEVA的解决方案。AVEVA在世界30六个国家和地段设有超过50个常驻办事机构,在英帝国俄亥俄州立总部及另外研发要旨具有超越300名探究和开发人员,为世界上最大的厂子工程音信技术琢磨和支付团队。AVEVA的高效发展与其有利易用,卓绝的互动建模形式分不开,本文重要对其交互建模部分举办介绍。 

AVEVA交互建模首如果采纳模型编辑器Model Editor,使用Model
Editor可以只用鼠标就可以开展建模设计了。编辑采纳的模型如下图所示: 

ea平台365bet体育在线 1

Figure 2.1 Model Editor on a Equipment 

利用的Handle可以对模型多种格局的编排,如轴向移动、平面移动、旋转等,如下图所示: 

ea平台365bet体育在线 2

Figure 2.2 Locator Handle of Model Editor 

2.1 移动 Movement

对接纳的模子举行轴向移动或平面移动时,可以动用Model Editor的Linear and
Planar
handles。沿轴向或锁定在某个平面上拖动模型,即能够运动模型。移动是按一定的长短递增的,可由活动增量(the
Movement
Increment)来设置,这样来保管拖动模型相对先导地点的精度。选中handle上某个轴,就可以沿那些轴的方平昔运动模型,如下图所示: 

ea平台365bet体育在线 3

Figure 2.3 Linear Movement 

入选并拖动Model
Editor的平面移动handle,就足以在锁定的平面上活动模型,如下图所示: 

ea平台365bet体育在线 4

Figure 2.4 Planar Movement 

2.2 旋转 Rotation

旋转是通过Model Editor的Rotation
handle来完成的。旋转是按一定的角度来递增的,可由旋转增量(the Rotation
Increment)来设置。这样就保险了旋转绝对于开端地点的精度。选中并拖动Rotation
handle,就可以对模型举办旋转了,如下图所示: 

ea平台365bet体育在线 5

Figure 2.5 Rotation 

ea平台365bet体育在线 6
ea平台365bet体育在线 7

Figure 2.6 Use Model Editor to Modify a Valve 

相互建模时使用Model
Editor如上图2.6所示,由图可以,在AVEVA中对模型的移动和旋转非凡便于。 

2.3 对齐 Alignment

经过对齐功效,可以一本万利地将模型对齐到点、边或面,如下图所示: 

ea平台365bet体育在线 8

Figure 2.7 Alignment features 

透过上文对AVEVA中的Model
Editor的牵线可以,在AVEVA中三维交互建模很有利,且精度高。纵观国内当下看似产品,有些还停留在二维建模格局,有些依赖其他平台的交互形式,不过在易用性上觉得都稍有欠缺,或没有独立的文化产权。 

三、拖拽器Dragger of OpenSceneGraph

1997年,一个称呼Don Burns的软件工程师受雇于当时的Silicon
Graphics(SGI)集团,负责针对滑翔机飞行的杜撰仿真工作开展研商。他使用即时的OpenGL
Performer系统,设计了一套广受好评的滑翔仿真软件,并开首尝试在Linux中行使Mesa3D和3dfx
Voodoo显卡设备继续周到自己的假冒伪劣软件。 

1998年,Don在一个滑翔爱好者的邮件组中遭遇了RobertOsfield,也就是当下OpenSceneGraph项目标根本领导者。当时罗Bert在苏格兰的油气集团做事,但对电脑图形学和可视化技术具有深刻的趣味。志趣相投的六人走到了一起,起首合作对Don的虚伪软件拓展改善。Robert指出将SG作为独立的开源场景图形项目继续支付,并由自己充当项目为主,项目标称呼改为OpenSceneGraph,简称OSG。 

今昔,非凡一些高性能的软件已经使用了OSG来完成复杂气象的渲染工作。大部分基于OSG的软件开发更适用于可视化设计和工业仿真,包括地理音讯体系(GIS)、总计机扶助设计(CAD)、建模和数字媒体撰写(DCC)及数据库开发、虚拟现实、动画、游戏和娱乐业等。 

OpenSceneGraph引擎由一多元图形学相关的功用模块组成,重要为图形图像应用程序的开发提供场景管理和图纸渲染优化的坚守。它接纳可移植的ANSI
C++编写,并应用已成为工业标准的OpenGL底层渲染API。OSG具备跨平台的特点,可以运行在多数项指标操作系统上,并行使抽象层的定义,使OSG的函数接口可以独立于用户的本地操作系统使用。OSG听从开源磋商发表,其用户许可办法是一种修改过的GNU宽通用公共许可证(GNU
Lesser General Public License,
LGPL),称为OSGPL。OSG首要存有以下优势:疾速支付,高格调,高性能,高质料代码,可扩张性,可移植性,低费用,没有知识产权问题,然则OSG目前也设有许多供不应求,如参考文档较少、代码风格不联合、部分效率的实现过于臃肿,无法利用于实践等,这一个都有待更多的开发者和进献者去发现和系数。 

三维用户交互是一种与三维环境本身特性相匹配的相互动作,可使用户在虚拟场景中拿到接近的直观感受。三维世界的交互技术相当于一种“控制-呈现”的炫耀,用户设备(例如鼠标、键盘、操纵杆等)向系统输入控制音信,然后系统向用户输出执行结果。三维交互涉及的天职繁多,包括三维场景对象的选料和操控、三维世界中的导航漫游、改变三维场景的意况,乃至时下流行的三维交互建模等。作为一款周到的实时渲染引擎,OSG实现了三维场景的观光及气象中三维对象的操控那二种重要的三维场景交互形式,更多的相互动作则需要我们自行钻研和落实。 

用作首要的三维空间的人机交互手段之一,场景漫游的风味是透过不断更改阅览者(相机)的职务、姿态,使其相对世界的洞察方位和角度拥有变化,可是世界本身却不会爆发其他变动。无论草木、建筑,如故街道上的万人空巷,构成它们的每一个终端都尚未爆发任何偏移,如果阅览者将来有那么一天回到原地的话,他眼中的百分之百都不会发生变动。 

而对此三维物体的操控则是另一种概念,它并未改观观看者的眼光和视点,而是依照用户传递的竞相事件,对中选的目标开展运动、缩放和旋转操作,就像是嘲弄橡皮泥一样。被收拾过的对象将转移原来的形态,换句话说,只要不回复到操控前的情事,那么不论是从什么地方举行察看,这个目标都将维持它说到底的模样。当然,就算操控物体的定义如此,间接修改物体的终点坐标未免还是有些吃力不讨好,最好的艺术是为要操控的实体设置一个矩阵变换的父节点(MatrixTransform),通过改变这些父节点的变换矩阵的值,举行改动当做操控对象的子节点的表现形式—这就是osgManipulator库中拖拽器(Dragger)的落实形式。OSG内置了两种拖拽器,其操作办法和效应表明如下: 

l
TabPlaneDragger平面拖拽器:其边、顶点上都有拖拽点,可以开展某个2D平面上的缩放; 

ea平台365bet体育在线 9

Figure 3.1 TabPlaneDragger in OpenSceneGraph 

l
TabPlaneTrackballDragger平面轨迹球拖拽器:顾名思义除了平面拖拽器的意义外,还多了个轨迹球拖拽功用; 

ea平台365bet体育在线 10

Figure 3.2 TabPlaneTrackballDragger in OpenSceneGraph 

l TrackballDragger轨迹球拖拽器:即旋转操纵器,没有缩放效用; 

ea平台365bet体育在线 11

Figure 3.3 TrackballDragger in OpenSceneGraph 

l Translate1DDragger一维平移拖拽器:沿一个直线举行拖拽; 

ea平台365bet体育在线 12

Figure 3.4 Translate1DDragger in OpenSceneGraph 

l Translate2DDragger二维平移拖拽器:在某个平面上对模型举行拖拽; 

ea平台365bet体育在线 13

Figure 3.5 Translate2DDragger in OpenSceneGraph 

l TranslateAxisDragger三维平移拖拽器:可在三个样子上对模型举办拖拽; 

ea平台365bet体育在线 14

Figure 3.6 TranslateAxisDragger in OpenSceneGraph 

l
TabBoxDragger盒式拖拽器:由五个平面拖拽器构成,可在逐一面上进行缩放、平移; 

ea平台365bet体育在线 15

Figure 3.7 TabBoxDragger in OpenSceneGraph 

ea平台365bet体育在线,还有此外的拖拽器可以参见其源代码: 

n ScaleAxisDragger:三维缩放拖拽器; 

n Scale2DDragger:二维缩放拖拽器; 

n Scale1DDragger一维缩放拖拽器; 

n RotateSphereDragger:旋转球拖拽器; 

n RotateCylinderDragger旋转圆柱拖拽器; 

出于选用了组合情势(CompositeDragger),可将下边的拖拽器组合成更复杂的拖拽器。如三维平称拖拽器(TranslateAxisDragger)就是带有了两个一维拖拽器(Translate1DDragger)的组合拖拽器。因为程序开源,所以可依据实际需要,将拖拽器举行自定义。即可以定义出和AVEVA的Model
Editor完全相同的操纵器。 

四、示例程序 Example Code

要对气象中的模型进行拖拽,首先需要将其当选,然后在当选的模子上打开拖拽器,对模型的职务和可行性举行编辑。对象的拾取紧要看重场景图形的交运算来落实。拖拽器中用到的一个类PointerInfo表示一个消息的联谊。例如,使用鼠标选中待操作对象上的某个点,以及当前相机的观赛矩阵和投影矩阵等,都急需即刻反映到这多少个输入参数中,以便拖拽器遵照实际情况展开判断并生成命令。下面给出一个行使拖拽器Dragger来操作场景中模型的切切实实实例,程序代码如下所示: 

1.率先定义了一个带拖拽器的节点ModelShape: 

#pragma once

#include <osg/Group>

#include <osgManipulator/Selection>
#include <osgManipulator/CommandManager>
#include <osgManipulator/TrackballDragger>
#include <osgManipulator/TranslateAxisDragger>


class ModelShape : public osg::Group
{
public:
    ModelShape(osg::Node* shape);
    ~ModelShape(void);

    void EnableDragger(void);
    void DisableDragger(void);

private:
    osg::ref_ptr<osg::Node> mShape;
    osg::ref_ptr<osgManipulator::Dragger> mDragger;
    osg::ref_ptr<osgManipulator::Selection> mSelection;
};

类实现代码如下所示: 

#include "ModelShape.h"

ModelShape::ModelShape(osg::Node* shape)
: mShape(shape)
, mDragger(new osgManipulator::TranslateAxisDragger())
, mSelection(new osgManipulator::Selection())
{
    float scale = shape->getBound().radius() * 1.6;
    mDragger->setMatrix(osg::Matrix::scale(scale, scale, scale) * 
        osg::Matrix::translate(shape->getBound().center()));

    mDragger->setupDefaultGeometry();

    mSelection->addChild(shape);
    addChild(mSelection);
}


ModelShape::~ModelShape(void)
{
}


void ModelShape::EnableDragger()
{
    addChild(mDragger);

    mDragger->addTransformUpdating(mSelection);
    mDragger->setHandleEvents(true);
}


void ModelShape::DisableDragger()
{
    removeChild(mDragger);

    mDragger->removeTransformUpdating(mSelection);
    mDragger->setHandleEvents(false);
}

2.在拍卖采用事件时,打开拖拽器,实现类是PickHandler: 

#pragma once

#include <osgGA/GUIEventHandler>


class PickHandler : public osgGA::GUIEventHandler
{
public:
    PickHandler(void);
    ~PickHandler(void);

    virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);

protected:
    void pick(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa);

private:
    float mX;
    float mY;
    bool mEnableDragger;
};

类实现代码如下所示: 

#include "PickHandler.h"
#include "ModelShape.h"

#include <osgViewer/Viewer>


PickHandler::PickHandler(void)
: mX(0.0f)
, mY(0.0f)
, mEnableDragger(true)
{

}


PickHandler::~PickHandler(void)
{
}


bool PickHandler::handle(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
{
    osgViewer::View* view = dynamic_cast<osgViewer::View*> (&aa);
    if (NULL == view)
    {
        return false;
    }

    switch (ea.getEventType())
    {
    case osgGA::GUIEventAdapter::PUSH:
        {
            mX = ea.getX();
            mY = ea.getY();
        }
        break;

    case osgGA::GUIEventAdapter::RELEASE:
        {
            if (ea.getX() == mX && ea.getY() == mY)
            {
                pick(ea, aa);
            }
        }
        break;

    case osgGA::GUIEventAdapter::KEYDOWN:
        {
            if (ea.getKey() == 'd')
            {
                mEnableDragger = !mEnableDragger;
            }
        }
        break;

    default:
        break;
    }

    return false;
}


void PickHandler::pick(const osgGA::GUIEventAdapter &ea, osgGA::GUIActionAdapter &aa)
{
    osgViewer::View* view = dynamic_cast<osgViewer::View*> (&aa); 

    osgUtil::LineSegmentIntersector::Intersections hits;
    if (view->computeIntersections(ea.getX(), ea.getY(), hits))
    {
        osgUtil::LineSegmentIntersector::Intersection intersection = *hits.begin();
        osg::NodePath& nodePath = intersection.nodePath;
        int nNodeSize = static_cast<int> (nodePath.size());

        if (nNodeSize > 0)
        {
            osg::Node* node = nodePath[nNodeSize - 1];
            osg::Node* grandParent = node->getParent(0)->getParent(0);

            // This method maybe not right?
            ModelShape* shape = dynamic_cast<ModelShape*> (grandParent);
            if (shape)
            {
                mEnableDragger ? shape->EnableDragger() : shape->DisableDragger();
            }

        }
    }

}

3.在主函数中树立场景: 

/*
*    Copyright (c) 2013 eryar All Rights Reserved.
*
*           File : Main.cpp
*         Author : eryar@163.com
*           Date : 2013-12-28 17:00
*        Version : 1.0v
*
*    Description : Use dragger to manipulate shape objects.
*                  press key 'd' for enable or disable the dragger.
*
*      Key Words : OpenSceneGraph, Dragger
*                  
*/

#include <osgDB/ReadFile>
#include <osgGA/StateSetManipulator>

#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>


#include "ModelShape.h"
#include "PickHandler.h"


#pragma comment(lib, "osgd.lib")
#pragma comment(lib, "osgDBd.lib")
#pragma comment(lib, "osgGAd.lib")
#pragma comment(lib, "osgViewerd.lib")
#pragma comment(lib, "osgManipulatord.lib")


int main(void)
{
    osgViewer::Viewer viewer;

    osg::ref_ptr<osg::Group> root = new osg::Group();

    // build the scene with boxes and gliders.
    for (int i = 1; i < 10; ++i)
    {
        for (int j = 1; j < 10; ++j)
        {
            osg::ref_ptr<osg::MatrixTransform> box = new osg::MatrixTransform();
            osg::ref_ptr<osg::MatrixTransform> glider = new osg::MatrixTransform();

            box->setMatrix(osg::Matrix::translate(i * 6.0, j * 6.0, 0.0));
            glider->setMatrix(osg::Matrix::translate(i * 2.5, j * 2.5, 6.0));

            box->addChild(new ModelShape(osgDB::readNodeFile("box.stl")));
            glider->addChild(new ModelShape(osgDB::readNodeFile("glider.osg")));

            root->addChild(box);
            root->addChild(glider);
        }
    }

    viewer.setSceneData(root.get());

    viewer.addEventHandler(new osgViewer::StatsHandler());
    viewer.addEventHandler(new osgViewer::WindowSizeHandler());
    viewer.addEventHandler(new osgGA::StateSetManipulator(viewer.getCamera()->getOrCreateStateSet()));

    // add pick event handler to add dragger on the shape.
    viewer.addEventHandler(new PickHandler());

    return viewer.run();
}

先后行使模式为接纳要拖拽的模子,选中后为模型打开拖拽器,使用拖拽器对模型举行拖拽就足以修改模型的地点了。在键盘上按下‘d’可以打开/关闭拖拽器,默认为打开。当设置为关门时,再选中带有拖拽器的模型后,将会倒闭拖拽器。程序运行效果如下图所示: 

ea平台365bet体育在线 16

Figure 3.8  Use TranslateAxisDragger to dragger box 

ea平台365bet体育在线 17

Figure 3.9 Use TranslateAxisDragger to dragger glider 

ea平台365bet体育在线 18

Figure 3.10 Use TranslateAxisDragger in OpenSceneGraph 

五、结论 Conclusion

经过程序实施注脚,OpenSceneGraph中的人机交互的不二法门如故很便利的,并提供了三种拖拽器来支配模型。并且拖拽器采纳了咬合格局,便于扩大,即基于用户实际需要结合出更扑朔迷离或更具个性的拖拽器。 

不问可知,使用OpenSceneGraph来对模型举行体现与操作很便利,且是开源程序,方便程序调试,还不设有文化产权的题材。因为OpenSceneGraph紧如果用来虚拟仿真,还提供了过多冒牌效果,如烟雾、火焰、粒子效果(雨、雪、爆炸)、动画等,如若在建模设计的进程中得当添加部分效率,是不是很cool? 

六、参考资料 References

  1. AVEVA,Graphical Model Manipulation Guide 

  2. Donald Hearn,M. 保罗(Paul)ine Baker,Computer Graphics with
    OpenGL,电子工业出版社 

  3. 何援军,总计机图形学,机械工业出版社 

  4. 王锐,钱学雷,OpenSceneGraph三维渲染引擎计划与实施,北大大学出版社 

5.
肖鹏,刘更代,徐明亮,OpenSceneGraph三维渲染引擎编程指南,哈工大高校出版社 

 

PDF Version: Implementation Model Editor of AVEVA in
OpenSceneGraph

发表评论

电子邮件地址不会被公开。 必填项已用*标注