palette gef_GEF走向3D

palette gef

在模型驱动的开发领域,模型扮演着重要角色。 通常,模型是通过二维图可视化的,UML图可能是最突出的示例。 但是,在某些情况下,二维根本不够。 有时,模型需要三维表示,或者应同时显示多个二维图。 后一种情况可以可视化所谓的图间关系,即不同图的元素之间的连接。 GEF3D [2]框架允许以非常简单的方式创建三维图编辑器。

GEF3D已在作者的博士学位中作为一种工具启动。 该项目,并在2008年秋天成为Eclipse项目。目前,该项目只有两个提交者–我们一直在寻求开源社区的更多帮助! 由作者实现的图1,给人以GEF3D功能的印象。 正如Holger Voorman所预见的那样,将来在这里可以看到两层抽象,更准确地说是一个用例图,该用例图已转换为健壮性图(请参阅[3])。 图的元素通过所谓的转换轨迹连接。 迹线是关系图之间关系的典型示例,在这种情况下,迹线连接转换的源元素和目标元素。

在Eclipse的世界中,(几乎总是)使用GEF [4]或GMF [5](因此GMF基于GEF)创建图形编辑器。 GEF3D的基本思想是扩展GEF,以支持三维编辑器。 因此,可以使用与2D编辑器相同的技术和概念来实现3D编辑器–在大多数情况下,不需要3D编程方面的专门知识。 此外,GEF3D提供了适应现有2D编辑器的技术,以便在3D场景中使用它们-我们称这种现象为2D编辑器的“ 3D定位”。 只需一点努力就可以实现。 总体策略是将2D编辑器的输出投影到3D空间中的平面上,并对它们进行一些调整以启用3D编辑。 GEF3D中提供了一些示例编辑器来演示这一点:ecore编辑器(来自EMF工具[6])或UML2工具中的类,活动和用例编辑器[7]。 实际上,图1显示了UML2工具编辑器的3D立体版本。

下面,我们将更详细地介绍GEF3D。 在简要解释了GEF之后,我们将描述GEF3D如何扩展GEF。 然后,我们将使用GEF创建一个小型2D编辑器,然后再用3D-fy创建该编辑器。

了解GEF3D需要具备GEF的一些基本知识。 因此,我们首先强调GEF的一些设计特征,其次描述如何将这些特征用于3D合成。 图2作为指导,说明了GEF和GEF3D中使用的主要类别和模式。 不用担心,乍一看这个数字看起来有点不知所措,但是情况很快就会变得清楚起来。 我们将从内到外描述图中所示的元素。

在GEF的中心,我们可以识别模型视图控制(MVC)模式,因此它也显示在图2的中心(浅蓝色背景)。 MVC的实现非常精细,也就是说,对于每个可编辑项,都需要MVC三元组。 例如,对于该图,每个节点,甚至每个应可编辑的标签,您将需要一个MVC三元组。 包含数据的模型可以通过简单的Java类实现,而无需实现任何接口或扩展特殊类。 但是,该模型通常使用Eclipse建模框架(EMF [8])来实现,如果使用GMF,甚至需要EMF。 视图部分由GEF附带的名为Draw2D的单独插件实现。 元素通过所谓的数字可视化。 图形以树的形式构造,其根包含在名为LightweightSystem的类中。 轻量级系统是图形和SWT之间的一种适配器。 它将数字绘制到SWT画布上,并将事件从SWT委托给GEF。 如前所述,必须为每个可编辑元素提供一个控制器。 控制器由所谓的EditParts实现 ,它们不仅处理事件,还创建图形。 与其他MVC实现相反,控制器是GEF中MVC三元组中最重要的部分,它是图形和模型之间的中介。 特别是,该图不听模型,甚至根本不依赖模型元素。 就像图一样, EditPart也被组织成一棵树。

现在,我们将重点放在下一层,即图2中蓝色背景上绘制的元素。这些元素仍然是GEF的一部分,我们从EditPolicy的右侧开始,并沿逆时针方向在圆周围徘徊。 EditPart(扮演控制器的角色)必须完成许多任务:从管理项目选择到创建元素,再到更多特定于应用程序的任务。 为了避免怪物类(带有意大利面条代码),策略模式(也称为策略模式)用于将功能提取到单独的类中,称为策略类。 如果需要,将“安装”策略并调用该策略以管理特定任务。 除了减小EditPart的大小外,还可以动态更改其行为。 这可以通过简单地安装新策略或在运行时替换现有策略来完成。 我们将进行后者,以便将3D功能添加到已创建的EditParts中。 Apropos创建:从图中可以看出, EditPart是使用工厂模式创建的,工厂在这里称为EditPartFactory 。 EditPartViewer是一个将所有零件放在一起的容器:它包含对工厂的引用,它包含已经说明的LightweightSystem,并且还包含编辑零件树的根(图中未显示)。 查看器本身是GraphicalEditor的一部分,它是Eclipse平台的接口,它通过Eclipse插件机制注册为编辑器。

总而言之,MVC实现了关注点分离,尤其是可视化与内容分离。 可以使用策略来动态修改(控制器的)行为,使用工厂创建控制器本身。 稍后我们将看到,这些设计模式将在以后用于3D-fy现有编辑器。

GEF3D概述

最后但并非最不重要的一点,我们看一下外圈(红色),其中显示了GEF3D提供的类。 这次我们从图2的底部开始,然后顺时针移动。 最本质上,我们必须在二维视图中添加一个新维度。 这意味着我们必须替换MVC三元组的view元素。 由于控制器应该能够使用新的三维视图,因此我们只需扩展原始图形,我们启用3D的子类称为Figure3D。 现在我们不必使用SWT-Canvas绘画,而必须使用OpenGL进行渲染,而现在必须使用称为GLCanvas的3D画布。 实际上,GEF3D不依赖于任何特定的3D渲染库。 相反,必须实现通用接口以适应具体的渲染库。 当前,存在用于LWJGL [10]的适配器,并且计划用于JOGL [11]的适配器。 因此,提供了轻量级系统的3D版本,LightweightSystem3D和对应的GraphicalViewer3D。 查看器是由编辑器创建和配置的,还提供了3D编辑器的基本版本,尽管在大多数情况下,现有的2D编辑器类是子类的,我们将在后面看到。

基本上,这些是GEF3D的最重要的类,并且可以使用这些类构造3D编辑器。 大多数3D特定问题是由GEF3D在后台处理的,对3D编辑器进行编程与对2D编辑器进行编程非常相似。 例如,GEF3D处理3D场景中的元素选择(称为“拾取”)或提供用于导航的摄像机。 对于客户端代码,坐标透明地从2D转换为3D,反之亦然。 当要重用现有的2D代码时,这特别有用,我们将在后面看到。

调整模式

为了为3D编辑器利用GEF的大多数概念和技术,付出了很多努力。 结果,现有的2D编辑器只需很少的更改就可以进行3D处理,编辑器的大部分可以不变地重复使用。 尤其是为了适应现有的编辑器,GEF3D提供了新的模式并利用了现有的模式。 策略模式在所有这些方法中都起着关键作用,因为它可以在运行时修改行为,而无需更改实际代码。 这个想法很简单:适用于二维应用程序的现有策略将由适当的3D版本替换。 幸运的是,由于大多数功能独立于图形表示,因此仅需交换少量策略。

通常,在3D处理过程中不应更改现有的2D代码。 而是将在3D场景中启用原始2D编辑器所需的完整3D相关代码放置在独立的插件中,该插件取决于原始2D插件。 原始类尽可能多地被重用,并且由于代码未更改,因此它们的行为在运行时会更改。 用来更改现有EditParts行为的中央模式称为Borg Factory –如果这使您想起Start Trek,则您并不完全错误。 Borg Factory模式所涉及的类显示在图2的右上方。首先,一个所谓的BorgFactory替换了原始的EditPartFactory,原始工厂嵌套在BorgFactory中–这与代理模式非常相似。 。 为了执行某些修改,可以在BorgFactory注册所谓的同化器。 当要创建一个新元素时,顺序如下:首先,嵌套的原始工厂基于给定的模型元素创建EditPart。 创建EditPart之后,它将传递给已注册的同化器。 他们现在可以修改创建的EditPart,例如,可以添加或删除策略。 如果修改EditPart太难了,甚至可以完全替换它-“电阻是徒劳的”。

当修改的编辑器与其他编辑器结合使用时,需要图2中所示的其他模式,“多工厂”模式和“连接的元素”模式。 这两种模式将在后续文章中进行解释。

图形编辑器示例

现在,我们将看一个具体的示例,以说明如何使用GEF3D和新模式。 在下文中,我们将为具有节点(称为顶点)和连接(边缘)的图形实现非常简单的编辑器。 首先,我们将使用GEF实施2D编辑器,然后使用3D-fy编辑器。 最终结果如图3所示。该屏幕截图显示了如何移动两个节点,您可以看到GEF3D显示了3D手柄和3D反馈图形。

无论我们是否创建2D或3D编辑器,都必须首先创建一个模型。 最简单的方法是使用EMF。 用于示例编辑器的EMF模型如图4所示,该模型是使用ecore图表编辑器创建的[6]。

根据该模型,EMF可以自动生成Java实现。 由于我们以后要使用向导来创建模型,因此也将生成编辑和编辑器代码。

现在,我们必须实现作为插件创建的2D编辑器。 广义上讲,我们必须为模型元素实现一个编辑器类,编辑零件工厂以及视图和控制器类。 GEF使用命令模式修改了元素。 也就是说,元素不会由策略类的编辑部分直接更改,而是由策略创建适当的命令,然后执行修改。 因此,我们必须创建一些用于创建或修改元素的命令(在此省略用于删除元素的命令),并实现创建这些命令的相应策略。 下表列出了示例编辑器所需的所有类。 可以在GEF网站[3]上找到有关GEF的更多信息,在EMFs网站[8]上可以找到有关EMF的信息,示例编辑器的源代码是GEF3D示例的一部分(为简化起见,GEF3D图形示例包含非EMC模型,您可以在以下位置找到3D格式的图形编辑器:

org.eclipse.gef3d.examples.graph.editor.GraphEditor2D_3Dfied )。
类/文件 描述

GraphEditor2D

插入Eclipse的Editor类,在此处配置了带有其类的编辑器(例如EditPartFactory和Palette),并加载了模型

GraphEditPartFactory

用于根据给定的模型元素创建EditParts工厂。

GraphEditPart, VertexEditPart, EdgeEditPart

显示元素的控制器。 控制器为其模型元素提供服务,并相应地刷新视图。 此外,他们负责将模型映射到显示的图形元素。

GraphFigure, VertexFigure, EdgeFigure

显示模型元素的图。

VertexCreateCommand, VertexResizeCommand, EdgeCreateCommand

用于创建或更改(模型)元素的命令。 这些命令由下面列出的策略自行创建。

GraphLayoutPolicy, VertexEditPolicy

用于创建上述命令的策略。 顶点命令由GraphLayoutPolicy创建,边缘命令由VertexEditPolicy 。 策略安装在编辑部分。

plugin.xml

该编辑器必须在Eclipse平台上注册,其扩展点是org.eclipse.ui.editors
表1:只有14个文件的2D图形编辑器。 3D电影

为了在3D场景中使用先前创建的2D编辑器,只需要进行一些修改即可:不需要三个以上的类。 在GEF3D中,将2D内容投影到3D场景中的平面上。 因此,几乎可以重复使用2D编辑器的几乎所有部分,而无需进行任何修改。 由于我们要使用平面而不是2D区域,因此仅需替换显示图形的图形(在GraphFigure示例中)。 GraphEditPart也必须更改,因为我们必须立即创建3D图形,而不是2D图形。 我们分别将3D类称为GraphFigure3DGraphEditPart3D 。 GraphEditPart3D是GraphEditPart的子类,修改很小:创建GraphFigure3D而不是创建2D图形。 表2列出了3D-fy编辑器所需的所有三个类(和插件文件)。

类/文件 描述

GraphEditor3D

3D编辑器将2D编辑器子类化。 修改了编辑零件的工厂,并创建了新的摄影机工具,以使用户能够在3D场景中导航。

GraphEditPart3D

3D平面的图表编辑部分是原始2D版本的子类(在这里为GraphEditPart ),唯一的修改是创建3D图形而不是2D图形。

GraphFigure3D

代替2D图形,将创建3D平面(即长方体)。 该图的元素投影到该平面上。

plugin.xml

3D编辑器也必须在Eclipse平台上注册,再次使用扩展点org.eclipse.ui.editors
表2:3D复制仅需要4个文件!

显示该图本身的图形(即GraphFigure3D )必须从头开始创建,原始2D图形无法重复使用。 但是,GEF3D提供了一些基础数据,这使其非常简单,在大多数情况下,不需要3D编程知识。 为了给的3D元素是如何与GEF3D中实现的印象,GraphFigure3D的整个代码是下面列出:

public class GraphFigure3D extends ShapeFigure3D {
 
  private ISurface m_surface = new FigureSurface(this);
     
  public GraphFigure3D() {
          SurfaceLayout.setDelegate(this, new FreeformLayout());
            getPosition3D().setLocation3D(IVector3f.NULLVEC3f);
               getPosition3D().setSize3D(new Vector3fImpl(400,300,20));
          setBackgroundColor(ColorConstants.white);
         setAlpha((byte) 0x44);
    }
 
  @Override
 public ISurface getSurface() {
            return m_surface;
 }

   @Override
 protected Shape createShape() {
           return new CuboidFigureShape(this);
       }

}
由于使用了辅助元素(即Shapes) ,因此3D图形的实现与2D图形之一非常相似。 由于通常使用形状来实际渲染图形,因此GEF3D提供了特殊的图形类ShapeFigure3D ,该类在内部使用形状。 如示例所示, ShapeFigure3D的子类必须仅实现抽象方法createShape() 。 GEF3D具有许多形状,例如长方体,球体或圆柱体。 为了能够将2D内容投影到图形的图形(GraphFigure)上,3D图形需要一个表面(请参见方法getSurface() )。 现在,实际渲染已隐藏在基类中。 与GEF相比,不是简单地通过(递归)调用渲染方法来渲染图形。 相反,第一步是收集所谓的RenderFragments 。 第二步,渲染这些片段,生成实际输出。 这样做是由于渲染透明对象时OpenGL的限制。 实际上,OpenGL不直接支持透明对象,因此GEF3D必须注意正确渲染这些对象。 这是通过使用按深度排序的RenderFragments来实现的-在大多数情况下,如示例中所示,这在客户端代码级别不可见。 剩下的工作最多是正确初始化3D编辑器。 如果无需重用2D编辑器类,则可以仅依靠GEF3D提供的3D编辑器类,例如GraphicalEditor3D 。 但是,在许多情况下,现有的2D编辑器已经存在,其中包含用于加载或保存模型和其他特定于应用程序的代码。 因此,必须将2D编辑器用作基类,并且必须在客户端代码中实现用于设置3D编辑器的代码。 因此,我们在这里重复使用2D编辑器为好,这是我们从GraphEditor2D获得GraphEditor3D。 现在,她必须实施所有3D特定的初始化代码,大致来说,必须完成以下操作:
  1. 代替GraphicalViewer ,必须创建GraphicalViewer3D
  2. 为了在3D场景中导航,必须安装摄像头。 这可以通过添加特殊工具( CameraTool )来完成。
  3. 代替2D图元素,必须创建先前创建的3D图图形(及其编辑器部分)。 此外,所有EditPart都将被修改为可在3D视图中进行编辑。 例如,应使用这些项目的3D版本,而不是二维的手柄和反馈图,如图4所示。
在下文中,我们将解决所有这些问题。 也就是说,首先我们必须创建3D查看器。 为此,我们必须重写createGraphicalViewer() ,如下所示:
@Override
protected void createGraphicalViewer(Composite i_parent) {
  GraphicalViewer3DImpl viewer = new GraphicalViewer3DImpl();
       Control control = viewer.createControl3D(i_parent);
       setGraphicalViewer(viewer);
       configureGraphicalViewer();
       hookGraphicalViewer();
    initializeGraphicalViewer();
      control.addDisposeListener(viewer.getLightweightSystem3D());
}
摄像机只是作为工具安装。 为了重用原始工具(仍可以在3D版本中使用),在第一行中调用了原始调色板初始化:
protected PaletteRoot getPaletteRoot() {
   PaletteRoot root = super.getPaletteRoot();

  PaletteDrawer drawer = new PaletteDrawer("GEF3D");
        drawer.setDescription("GEF3D tools");
     drawer.add(new ToolEntry("Camera", "Camera Tool", null, null,
             CameraTool.class) {});
    root.add(0, drawer);
      return root;
}
这两个第一步非常简单。 修改编辑部分比较棘手,我们将需要Borg技术来解决该问题。 换句话说,我们必须在这里使用borg工厂模式:
protected BorgEditPartFactory createBorgFactory(
           EditPartFactory originalFactory) {
        BorgEditPartFactory borgFactory = new BorgEditPartFactory(originalFactory);
       
  // replace diagram edit part
      borgFactory.addAssimilator(new EditPartReplacer(GraphEditPart.class,
              GraphEditPart3D.class));

    // modify diagram edit part's policies 
   borgFactory.addAssimilator(new AbstractPolicyModifier() {

           public boolean match(EditPart part) {
                     return part instanceof GraphEditPart3D;
           }

           public void modifyPolicies(EditPart io_editpart) {
                        // feedback when creating a node:
                 io_editpart.installEditPolicy(
                            ShowLayoutFeedbackEditPolicy3D.ROLE,
                              new ShowLayoutFeedbackEditPolicy3D());
                    // handles and feedback when moving or resizing a node
                    io_editpart.installEditPolicy(
                            Handles3DEditPolicy.CHILD_DECORATOR,
                              new Handles3DEditPolicy());
               }
 });

 // modify node edit part's policies
       borgFactory.addAssimilator(new IAssimilator.InstanceOf(
           NodeEditPart.class) {

               public EditPart assimilate(EditPart io_editpart) {
                        // feedback when drawing a connection
                     io_editpart.installEditPolicy(
                            ShowSourceFeedback3DEditPolicy.ROLE,
                              new ShowSourceFeedback3DEditPolicy());
                    return io_editpart;
               }

   });
       return borgFactory;
}
该代码几乎是不言自明的。 首先,原始的编辑零件工厂嵌套在BorgEditPartFactory内部。 然后在博格工厂注册合适的同化剂。 第一个同化器是EditPartReplacer,它用3D编辑部件替换2D编辑部件。 在示例中,GraphEditPart是类型的编辑部分可以通过3D同行GraphEditPart3D代替。 第二个同化器AbstractPolicyModifier不会更改编辑部分本身,但是会向2D编辑部分添加两个新策略: ShowLayoutFeedbackEditPolicy3D在要创建节点时创建3D反馈图形,而Handles3DEditPolicy负责在创建节点时添加3D句柄。节点将被调整大小或移动。 第三个同化者还添加了一个新策略: ShowSourceFeedback3DEditPolicy在创建新连接时会创建3D反馈图形。 最后但并非最不重要的一点是,必须将BorgEditPartFactory设置为工厂,并要安装RootEditPart3D ,这在3D编辑器中是必需的:
protected void configureGraphicalViewer() {
        super.configureGraphicalViewer();
 EditPartFactory originalFactory = 
                getGraphicalViewer().getEditPartFactory();
        BorgEditPartFactory borgFactory = createBorgFactory(originalFactory);
     getGraphicalViewer().setEditPartFactory(borgFactory);

       ScalableFreeformRootEditPart root =     new ScalableFreeformRootEditPart3D();
     getGraphicalViewer().setRootEditPart(root);
}
而已! 这些是对现有编辑器进行3D-fy所需的更改。 我们必须使用著名的扩展点org.eclipse.ui.editors来注册新的3D编辑器,然后我们才能打开,查看和编辑3D相同的图,就像我们可以使用2D编辑器进行编辑一样。 结论如小示例所示,使用GEF3D创建3D编辑器非常简单。 目前,尚无GEF3D的正式版本可用,更多信息和当前限制可在“孵化器”框中找到。 通过退出3D,退出2D编辑器,这是迈出3D编程世界第一步的好方法。 虽然,GEF3D支持完整的3D编辑器,尤其是在要编辑预定义元素(例如图表元素)及其之间的连接时。 如果需要创建自己的CAD系统,则不建议使用GEF3D。 但是,GEF3D的设计和未来开发着眼于现有3D的2D编辑器,因为它是在模型驱动方法领域可视化模型(和模型链)的有趣技术。 在计划的第二篇文章中,我们将解释GEF3D的更多功能,例如,如何在单个3D场景中组合多个编辑器,以及如何对基于GMF的3D-fy编辑器。
孵化器目前,GEF3D在Eclipse孵化器中。 目前尚未提供GEF3D的正式版本(有关如何安装GEF3D的信息,请参见“安装”框)。 Bugzilla中记录了已知问题。 当前,最重要的限制是缺少用于在3D空间中移动3D图形(例如,用于旋转3D图形)的3D处理程序。 完全支持3D空间中图形的旋转和定位,目前根本不可能以交互方式进行。 此外,孵化器不仅意味着软件还不稳定,而且还意味着项目和团队必须变得更加成熟。 目前,只有两个提交者,我们非常感谢您的帮助! GEF3D为网站提供Wiki,在新闻组或开发人员邮件列表中回答问题[2]。
GEF3D安装GEF3D的正式版本尚不可用。 为了使用GEF3D,需要Eclipse(和GEF)3.5。 GEF3D必须从其子版本库(http://dev.eclipse.org/svnroot/technology/org.eclipse.gef3d/trunk)导入到工作区中。 将导入以下项目:
  • org.eclipse.draw3d
  • org.eclipse.draw3d.geometry
  • org.eclipse.draw3d.graphics3d
  • org.eclipse.draw3d.lwjgl
  • org.eclipse.draw3d.ui
  • org.eclipse.gef3d
  • org.eclipse.gef3d.ext
所有示例都可以在org.eclipse下找到。 gef3d.examples。* ,对于基于3D的基于GMF的编辑器,在org.eclipse.gef3d.gmf中提供了一些帮助程序类。 除了GEF3D(和Draw3D)代码外,还需要一个渲染库才能实际绘制3D场景。 为了在屏幕上创建3D输出,使用了OpenGL。 由于OpenGL仅提供C API,因此需要Java包装器库,例如LWJGL [10]。 在LWJGL更新站点( http://lwjgl.org/update ),可以下载Eclipse插件,该插件是在GEF3D上下文中创建的。 可以在GEF3D-wiki( http://wiki.eclipse.org/GEF3D )中找到最新的安装说明

Links & Literature [1] Voormann, H.: Quo vadis Eclipse? Eclipse Magazin 4 (2008), April, S. 20–27 [2] Eclipse GEF3D: www.eclipse.org/gef3d [3] Jacobson, I.: Object-Oriented Software Engineering: A Use Case Driven Approach. Addison-Wesley Professional, 1992 (acm press) [4] Eclipse GEF: www.eclipse.org/gef [5] Eclipse GMF: www.eclipse.org/gmf [6] Eclipse Modeling Framework Technology (EMFT): www.eclipse.org/modeling/emft [7] Eclipse Model Development Tools (MDT): www.eclipse.org/modeling/mdt [8] Eclipse EMF: www.eclipse.org/modeling/emf [9] Bokowski, B. ; Gerhardt, F.: GEF: Maßgeschneiderte grafische Editoren selbst erstellen. In: Eclipse Magazin 2 (2005), Februar, S. 85–90 [10] Lighweight Java Game Library (LWJGL): www.lwjgl.org [11] Java Bindings for OpenGL API (JOGL): jogl.dev.java.net

翻译自: https://jaxenter.com/gef-goes-3d-100077.html

palette gef

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值