|
阅读:2949回复:2
ArcObjects 3D开发简介
<P ><B><FONT size=2>一<FONT>、</FONT>ArcOjects 3D<FONT>开发方法简介</FONT></FONT></B></P>
<P ><FONT size=2><FONT>众所周知,在</FONT>ArcGIS 3D<FONT>分析扩展模块中提供了丰富的三维可视化和分析功能:你可以通过不同的视角查看表面数据,对表面数据进行查询,以及对表面数据进行坡度、坡向、视域分析等操作,进行三维动画模拟等等。其中所涉及的</FONT>3D<FONT>对象都是</FONT>ArcObjects<FONT>的一部分,针对</FONT>3D<FONT>的开发,实际上是</FONT>ArcObjects<FONT>的开发,所以具体的开发方法有:</FONT></FONT></P> <UL> <LI> <P ><FONT size=2><FONT>基于</FONT>ArcScene<FONT>中内嵌的</FONT>VBA<FONT>开发;</FONT></FONT> </P> <LI> <P ><FONT size=2><FONT>通过</FONT>VB<FONT>、</FONT>VC<FONT>++等兼容</FONT>COM<FONT>的开发语言进行开发新的</FONT>3D<FONT>组件和功能。</FONT></FONT> </P></LI></UL> <P align=justify><B><FONT size=2><FONT>二、基本的</FONT>3D<FONT>对象模型</FONT></FONT></B></P> <P align=left><FONT size=2><IMG src="http://www.esrichina-bj.cn/library/chinanews/image/cn14-shen1.gif" border=0> <FONT>在</FONT>3D<FONT>开发中,我们可以用</FONT>ArcMap<FONT>对应</FONT>ArcScene<FONT>,其中</FONT>MxDocument<FONT>对象对应</FONT>SxDocument<FONT>对象,</FONT>Map<FONT>对象对应着</FONT>Scene<FONT>对象,而相对于</FONT>Display<FONT>显示对象,在</FONT>ArcScene<FONT>中有</FONT>SceneGraph<FONT>对象。在对象模型图的顶部是</FONT>Application<FONT>对象,从它我们可以执行和应用相关的任务,比如打开文档或者访问和应用相关的其它对象。在</FONT>VBA<FONT>中,我们可以直接获得</FONT>Application<FONT>对象:</FONT></FONT></P> <BLOCKQUOTE> <P align=left><FONT size=2>Dim pApp as IApplicaiton</FONT></P> <P align=left><FONT size=2>Set pApp = Application</FONT></P></BLOCKQUOTE> <P align=justify><FONT size=2><FONT>如果你在</FONT>VB DLL<FONT>中实现命令和工具,那么在具体实例化这个类时你可以获得和</FONT>Application<FONT>对象挂接的钩子(</FONT>hook<FONT>):</FONT></FONT></P> <P align=justify><FONT size=2>Implements ICommand</FONT></P> <BLOCKQUOTE> <P align=justify><FONT size=2>Private m_pApp as esriCore.Iapplication</FONT></P> <P align=justify><FONT size=2>Private Sub ICommand_OnCreate(ByVal Hook As Object)</FONT></P></BLOCKQUOTE> <P align=justify><FONT size=2>Set m_pApp = Hook</FONT></P> <P align=justify><FONT size=2>…</FONT></P> <BLOCKQUOTE> <P align=justify><FONT size=2>End Sub</FONT></P></BLOCKQUOTE> <P align=justify><FONT size=2><FONT>有了</FONT>Application<FONT>对象,你就可以访问它所包含的其它所有对象了。比如可以获得</FONT>SxDocument<FONT>对象,而它包含一个</FONT>Scene<FONT>对象,</FONT>Scene<FONT>对应的</FONT>SceneGraph<FONT>对象包含了一个或多个</FONT>SceneViewer<FONT>对象,每个</FONT>SceneViewer<FONT>对象中有一个</FONT>Camera<FONT>对象,它代表了观察点的特性。在</FONT>Scene<FONT>对象中可以访问</FONT>Layer<FONT>对象和</FONT>GraphicsLayer3D<FONT>对象,这两个对象都包含着一个</FONT>3DProperties<FONT>对象,用来控制图层中有关三维方面的特性。具体有关对象的特性可以参考联机帮助中对象上提供的接口所属的方法和属性。</FONT></FONT></P><FONT size=3> <P align=justify> </P></FONT> <P align=justify><B><FONT size=2><FONT>三、</FONT>3D<FONT>几何模型和定制对象介绍</FONT></FONT></B><FONT size=2> 3D<FONT>模型可以包括两种:矢量模型和表面模型,表面模型包括</FONT>TIN<FONT>和</FONT>Raster<FONT>,有关表面模型的创建、数据结构访问和分析在本文中不做介绍。在此只介绍三维矢量模型的生成和访问等。</FONT>3D<FONT>矢量模型包括所有含有</FONT>Z<FONT>值的几何对象:点、线、面,以及</FONT>MultiPatch<FONT>(多片)。其中多片又可以分为:三角条带(</FONT>Triangle Strip<FONT>)、三角扇(</FONT>Triangle Fan<FONT>)和环(</FONT>Ring<FONT>)。</FONT></FONT></P> <P align=center><IMG src="http://www.esrichina-bj.cn/library/chinanews/image/cn14-shen2.gif" border=0></P> <P align=justify><FONT size=2><FONT>在</FONT>ArcScene<FONT>中可以通过二维的点、线、面数据来构建三维模型,通过</FONT>ArcScene<FONT>中提供的拉伸功能可以将点要素构建成垂直的线,线要素构建成墙,而多边形要素构建成块,拉伸的值的大小可以是一定常数,也可以是通过要素属性字段中的值计算得出,或者通过数据自身记录的</FONT>Z<FONT>值。在</FONT>ArcObjects<FONT>中可以通过在</FONT>Geometry<FONT>几何对象构建过程中,任意点除了</FONT>X<FONT>、</FONT>Y<FONT>坐标值,指定坐标</FONT>Z<FONT>值来构建三维点、线和面对象;对于多片,则通过构建相应的</FONT>Multipatch<FONT>对象,并指定每一个顶点的</FONT>X<FONT>、</FONT>Y<FONT>和</FONT>Z<FONT>值。下面的代码描述了如何由多片来构建一个房子对象,它的房顶由三角扇构建,没有窗户的墙由三角条带构建,带窗户的墙由环构建。</FONT></FONT></P> <P align=justify><FONT size=2>Dim pMultiPatch As esriCore.IMultiPatch</FONT></P> <P align=justify><FONT size=2>Set pMultiPatch = New MultiPatch</FONT></P> <P align=justify><FONT size=2>Dim pGeoCol As esriCore.IGeometryCollection</FONT></P> <P align=justify><FONT size=2>Set pGeoCol = pMultiPatch</FONT></P> <P align=justify><FONT size=2>Dim pPoints As esriCore.IPointCollection</FONT></P> <P align=justify><FONT size=2>Dim pPoint As IPoint</FONT></P> <P align=justify><FONT size=2>‘<FONT>创建屋顶</FONT></FONT></P> <P align=justify><FONT size=2>Set pPoints = New esriCore.TriangleFan</FONT></P> <P align=justify><FONT size=2>Set pPoint = New Point</FONT></P> <P align=justify><FONT size=2>pPoint.PutCoords 5, 4<IMG src="http://www.esrichina-bj.cn/library/chinanews/image/cn14-shen3.gif" align=right border=0></FONT></P> <P align=justify><FONT size=2>pPoint.Z = 10</FONT></P> <P align=justify><FONT size=2>pPoints.AddPoint pPoint</FONT></P> <P align=justify><FONT size=2>Set pPoint = New Point</FONT></P> <P align=justify><FONT size=2>pPoint.PutCoords 0, 0</FONT></P> <P align=justify><FONT size=2>pPoint.Z = 5</FONT></P> <P align=justify><FONT size=2>pPoints.AddPoint pPoint</FONT></P> <P align=justify><FONT size=2>‘<FONT>屋顶的其它顶点</FONT>:</FONT></P> <P align=justify><FONT size=2>. . . (10, 0, 5); (10, 8, 5); ( 0, 8, 5); ( 0, 0, 5)</FONT></P> <BLOCKQUOTE> <BLOCKQUOTE> <P align=justify><FONT size=2>‘<FONT>将扇加到</FONT>MultiPatch</FONT></P></BLOCKQUOTE> <P align=justify><FONT size=2>pGeoCol.AddGeometry pPoints</FONT></P> <BLOCKQUOTE> <P align=justify><FONT size=2>‘<FONT>为没有窗户的墙创建条带</FONT></FONT></P></BLOCKQUOTE></BLOCKQUOTE> <P align=justify><FONT size=2>Set pPoints = New esriCore.TriangleStrip</FONT></P> <P align=justify><FONT size=2>‘<FONT>添加条带顶点</FONT>:</FONT></P> <P align=justify><FONT size=2>. . . (10, 0, 5); (10, 0, 0); (10, 8, 5)</FONT></P> <P align=justify><FONT size=2>. . . (10, 8, 0); ( 0, 8, 5); ( 0, 8, 0)</FONT></P> <P align=justify><FONT size=2>. . . ( 0, 0, 5); ( 0, 0, 0)</FONT></P> <P align=justify><FONT size=2>‘<FONT>将条带添加到</FONT>MultiPatch</FONT></P> <P align=justify><FONT size=2>pGeoCol.AddGeometry pPoints</FONT></P> <P align=justify><FONT size=2>‘<FONT>为前面的墙创建外环</FONT></FONT></P> <P align=justify><FONT size=2>Set pPoints = New esriCore.Ring</FONT></P> <P align=justify><FONT size=2>‘<FONT>添加外环顶点</FONT>:</FONT></P> <P align=justify><FONT size=2>. . . (10, 0, 5); (10, 0, 0); (10, 8, 5)</FONT></P> <P align=justify><FONT size=2>. . . (10, 8, 0); ( 0, 8, 5); ( 0, 8, 0)</FONT></P> <P align=justify><FONT size=2>. . . ( 0, 0, 5); ( 0, 0, 0)</FONT></P><FONT size=3> <P align=justify> </P></FONT> <P align=justify><FONT size=2>‘<FONT>将外环添加到</FONT>MultiPatch</FONT></P> <P align=justify><FONT size=2>pGeoCol.AddGeometry pPoints</FONT></P> <P align=justify><FONT size=2>pMultiPatch.PutRingType pPoints, esriMultiPatchOuterRing</FONT></P> <P align=justify><FONT size=2>‘<FONT>为前面的墙创建内环</FONT></FONT></P> <P align=justify><FONT size=2>Set pPoints = New esriCore.Ring</FONT></P> <P align=justify><FONT size=2>‘<FONT>添加内环顶点</FONT>:</FONT></P> <P align=justify><FONT size=2>. . .(1, 0, 2);(3, 0, 2);(3, 0, 4);(1, 0, 4);(1, 0, 2)</FONT></P> <P align=justify><FONT size=2>pGeoCol.AddGeometry pPoints</FONT></P> <P align=justify><FONT size=2>pMultiPatch.PutRingType pPoints, esriMultiPatchInnerRing</FONT></P><FONT size=3> <P align=justify> </P></FONT> <P align=justify><FONT size=2>Set pPoints = New esriCore.Ring</FONT></P> <P align=justify><FONT size=2>‘<FONT>添加内环顶点</FONT>:</FONT></P> <P align=justify><FONT size=2>. . .(7, 0, 2);(9, 0, 2);(9, 0, 4);(7, 0, 4);(7, 0, 2)</FONT></P> <P align=justify><FONT size=2>pGeoCol.AddGeometry pPoints</FONT></P> <P align=justify><FONT size=2>pMultiPatch.PutRingType pPoints, esriMultiPatchInnerRing</FONT></P> <P align=justify><FONT size=2> </FONT></P> <P align=justify><FONT size=2>‘<FONT>设置</FONT>Z<FONT>和</FONT>M<FONT>坐标</FONT>awareness</FONT></P> <P align=justify><FONT size=2>Dim pZAware As esriCore.IZAware</FONT></P> <P align=justify><FONT size=2>Set pZAware = pMultiPatch</FONT></P> <P align=justify><FONT size=2>pZAware.ZAware = True</FONT></P><FONT size=3> <P align=justify> </P></FONT> <P align=justify><FONT size=2>Dim pMAware As esriCore.IMAware</FONT></P> <P align=justify><FONT size=2>Set pMAware = pMultiPatch</FONT></P> <P align=justify><FONT size=2>pMAware.MAware = False</FONT></P><FONT size=3> <P align=justify> </P></FONT> <P align=justify><FONT size=2><FONT>通常,多片是用来描述阴影平面集合,并且可以在其上粘贴影像,也就是贴图。为了粘贴影像,需要在</FONT>Multipatch<FONT>的每一个定点上记录纹理坐标。纹理坐标记录为</FONT>s<FONT>和</FONT>t<FONT>,值为</FONT>0<FONT>到</FONT>1<FONT>,表示了从</FONT>x<FONT>到</FONT>y<FONT>方向影像的起点到终点。在</FONT>ArcObjects<FONT>中将</FONT>s<FONT>和</FONT>t<FONT>编码存储在定点的</FONT>M<FONT>值中。另外,如果要用</FONT>Multipatch<FONT>表达复杂连续的几何对象,比如球体,为了平滑阴影平面之间的转折,需要在</FONT>Multipatch<FONT>的每一个顶点上记录它的法向量,同样法向量也是编码后存储在定点的</FONT>M<FONT>值中。如下面的代码:</FONT></FONT></P><B><FONT size=3> <P align=justify></FONT></B><FONT size=2>Dim pNormal As esriCore.IVector3D</FONT></P> <P align=justify><FONT size=2>Dim pVertex As esriCore.Ipoint</FONT></P> <P align=justify><FONT size=2>Dim m As Double</FONT></P> <P align=justify><FONT size=2>m = 0</FONT></P> <P align=justify><FONT size=2>. . .</FONT></P> <P align=justify><FONT size=2>Dim pEncoder As IEncode3DProperties</FONT></P> <P align=justify><FONT size=2>Set pEncoder = New GeometryEnvironment</FONT></P> <P align=justify><FONT size=2>pEncoder.PackNormal vNormal, m</FONT></P> <BLOCKQUOTE><B> <P align=justify></B><FONT size=2>pEncoder.PackTexture2D s, t, m</FONT></P></BLOCKQUOTE> <P align=justify><FONT size=2>pVertex.M = m</FONT></P><FONT size=3> <P align=justify> </P></FONT> <P align=justify><B><FONT size=2><FONT>四、</FONT>3D<FONT>渲染和动画功能定制简介</FONT></FONT></B></P><FONT size=3> <P align=justify></FONT><FONT size=2><FONT>在</FONT>ArcObjects<FONT>中的</FONT>3D<FONT>对象内部调用了</FONT>OpenGL<FONT>图形库,所以有关</FONT>3D<FONT>渲染方面的开发是基于</FONT>OpenGL<FONT>图形库方面的知识。在</FONT>ArcObjects<FONT>中的定制渲染工作原理如下图,在</FONT>SceneGraph::Redraw<FONT>绘制开始和结束时分别会激活</FONT>SceneGraph<FONT>或其它外部事件处理器的</FONT>OnBeforeDraw<FONT>和</FONT>OnAfterDraw<FONT>事件,我们可以在这两个事件添加自己的渲染效果,比如在</FONT>OnBeforeDraw<FONT>事件中添加雾化效果等,而可以在</FONT>OnAfterDraw<FONT>事件中添加三维文字标注等。</FONT></FONT></P> <P align=center><IMG src="http://www.esrichina-bj.cn/library/chinanews/image/cn14-shen4.gif" border=0></P><FONT size=3> <P align=justify></FONT><FONT size=2>动画使得场景有动态的感觉,我们可以通过对视角、图层的可见性、以及场景的属性进行定制来达到动画的效果。下图是在动画定制中将会涉及到的部分类和接口。</FONT></P> <P align=center><IMG src="http://www.esrichina-bj.cn/library/chinanews/image/cn14-shen5.gif" border=0></P> <P align=justify><FONT size=2><FONT>从此对象模型图我们可以看出在</FONT>Scene<FONT>对象中可以访问动画轨迹对象(</FONT>AnimationTrack<FONT>),而动画轨迹是由关键帧组成的,关键帧分成场景的、图层的和书签(照相机)的。同时动画类型也分为场景、图层和照相机三种。这些类都是</FONT>CoClass<FONT>,可以通过创建的方式实例化,从而来控制动画的定制。另外,在</FONT>ArcObjects<FONT>中提供了控制动画演播和录制的相应方法,具体参考帮助文档中</FONT>AnimationTrack<FONT>类和</FONT>ScreenViewer<FONT>类。</FONT></FONT></P><FONT size=3> <P align=justify> </P></FONT> <P align=justify><B><FONT size=2>五、三维控件</FONT></B></P><FONT size=3> <P align=justify></FONT><FONT size=2><FONT>在</FONT>ArcObjects<FONT>中包含一个</FONT>ActiveX viewer<FONT>控件,它为</FONT>ActiveX<FONT>控件容器如</FONT>Microsoft Word<FONT>、</FONT>Microsoft PowerPoint<FONT>等提供了显示三维文档、图层及图形数据的功能。下面的代码显示了如何在</FONT>VB<FONT>中使用此控件:</FONT></FONT></P> <P align=justify><FONT size=2>‘ <FONT>引用</FONT>ArcScene<FONT>文档</FONT></FONT></P> <P align=justify><FONT size=2>SceneViewerCtrl1.DocName = “c:\temp\myscene.sxd”</FONT></P> <P align=justify><FONT size=2>或者</FONT></P> <P align=justify><FONT size=2>‘ <FONT>添加一个图层</FONT></FONT></P> <P align=justify><FONT size=2>SceneViewerCtrl.SceneGraph.Scene.AddLayer pLayer</FONT></P> <P align=justify><FONT size=2>或者</FONT></P> <P align=justify><FONT size=2>‘<FONT>添加一个图形元素</FONT></FONT></P> <P align=justify><FONT size=2>Dim pMap As IBasicMap</FONT></P> <P align=justify><FONT size=2>Set pMap = SceneViewerCtrl1.SceneGraph.Scene</FONT></P> <P align=justify><FONT size=2>Dim pGCon As IGraphicsContainer3D</FONT></P> <P align=justify><FONT size=2>Set pGCon = pMap.BasicGraphicsLayer</FONT></P> <P align=justify><FONT size=2>Set pGCon = pGLayer</FONT></P> <P align=justify><FONT size=2>pGCon.AddElement pElement</FONT></P> <P align=justify><FONT size=2>Viewer.Redraw False</FONT></P><FONT size=3> <P align=justify> </P></FONT> <P align=justify><FONT size=2>六、总结</FONT></P><FONT size=3> <P align=left></FONT><FONT size=2><FONT>本文旨在对</FONT>ArcObjects<FONT>?中有关</FONT>3D<FONT>的部分做一个简单的介绍,具体详细的</FONT>3D<FONT>对象描述及所涉及的具体方法和属性等可参考《</FONT>Exploring ArcObjects<FONT>》一书,以及随机开发人员帮助。</FONT></FONT></P> |
|
|
|
1楼#
发布于:2004-08-15 23:10
<P>了解</P>
|
|
|
|
2楼#
发布于:2004-09-02 09:44
<img src="images/post/smile/dvbbs/em02.gif" />
|
|