• ArcGIS之Multipatch


    Multipatch是一种3D几何图形,用于表示在三维空间中占用离散区域或体积的要素的外表面或壳。多面体由平面3D环和三角形构成,将组合使用这两种形状以建立三维壳模型。可使用多面体来表示从简单对象(如球体和立方体)到复杂对象(如等值面和建筑物)的任何事物。

    >>Multipatch在arcgis里如何创建?还是只能外接导入?

    Multipatch 几何对象用于描述 3D 图形,可以由 TriangleStrip, TriangleFan, Triangle 和 ring 对象组合构成组成。Multipatch 可以通过多种方式创建,一种是通过导入外部 3D 格式数据文件(3D Studio Max .3ds files, OpenFlight .flt files, COLLADA .dae files, Sketchup .skp files, VRML .wrl files),另外 ArcGIS Engine 提供了多种创建 Multipatch 几何对象的方法:

    如果创建没有贴图纹理,没有法向,没有组成部分信息的 Multipatch 时,只需创建好组成的Multipatch 的各个部分即可,然后通过 MultiPatch 的 IGeometryCollection 接口添加各个组成部分即可。

    如果要为 Multipatch 每 个组成部 分 添加纹理 信 息,法向 信 息,属性 信 息就必须 使 用 GeneralMultiPatchCreator 对象来创建,通过其 IGeneralMultiPatchInfo 接口来为 MultiPatch 各个组成 部分定义法向,材质,属性信息。通过 IGeneralMultiPatchInfo 接口可以获取这些 MultiPatch 的各个组 成部分的信息。

    通过 IConstructMultiPatch 接口和 IExtrude 接口操作 GeometryEnvironment 对象可以通过拉伸Polyline 对象(拉伸为墙)和 Polygon 对象(拉伸为多面体)来创建 MultiPatch.

    通过访问 3D 符号库,获取 3DSymbol 来渲染点,把三维符号放置在点的位置从而生成 Multipatch.[https://malagis.com/arcgis-engine-10-develop-handbook-5-8.html]

    >>Multipatch如何可视化?

    https://www.cnblogs.com/xianyin05/archive/2009/04/17/1437799.html

    >>Multipatch简介:https://desktop.arcgis.com/zh-cn/arcmap/latest/extensions/3d-analyst/multipatches.htm 

    >>Multipatch导出Collada: https://pro.arcgis.com/zh-cn/pro-app/tool-reference/conversion/multipatch-to-collada.htm

    3DAnalyst三维分析模块

    Supported with:
    • Engine with 3D Analyst
    • ArcGIS for Desktop Basic with 3D Analyst
    • ArcGIS for Desktop Standard with 3D Analyst
    • ArcGIS for Desktop Advanced with 3D Analyst
    • Server with 3D Analyst
    Library dependencies: Version, System, SystemUI, Geometry, GraphicsCore, Display, Server, Output, Geodatabase, GISClient, DataSourcesFile, DataSourcesGDB, DataSourcesOleDB, DataSourcesRaster, DataSourcesNetCDF, GeoDatabaseDistributed, GeoDatabaseExtensions, Carto, NetworkAnalysis, Location, GeoAnalyst, Animation, Maplex, Geoprocessing, NetworkAnalyst, Schematic, SpatialAnalyst

    Additional library information: Contents, Object Model Diagram

    To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):

    The 3DAnalyst library contains objects for working with three-dimensional (3D) scenes in a similar way that the Carto library contains objects for working with two-dimensional (2D) maps. The Scene object is one of the main objects of the library; it is the container for data similar to the Map object. The Camera object specifies how the scene is viewed regarding the positioning of the features relative to the observer. A scene consists of one or more layers that specify the data in the scene and how the data is drawn. The 3DAnalyst library provides the base for customization of the scene, although it also addresses some aspects of globe (see the GlobeCore library for more details).
    A SceneControl and a set of scene commands exist in the Controls library together with a ToolbarControl, TOCControl, and helper objects for creating your own custom commands.

    See the following sections for more information about this namespace:

    Prerequisites

    Some of the code in this topic uses the GetScene helper function to obtain an IScene object. The GetScene function uses an m_application object, which is of type ESRI.ArcGIS.Framework.IApplication. The code for the GetScene helper function is as follows:
     [C#]
    public IScene GetScene()
    {
        try
        {
            ISxDocument sxDocument = null;
    
            if (!(m_application is ISxApplication))
            {
                return null;
            }
    
            IDocument document = m_application.Document;
            sxDocument = (ISxDocument)document;
            IScene scene = sxDocument.Scene;
            return scene;
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.InnerException.ToString(), "GetScene error");
            return null;
        }
    }
    [VB.NET]
    Public Function GetScene() As IScene
        
        Try
        Dim sxDocument As ISxDocument = Nothing
        
        If Not (TypeOf m_application Is ISxApplication) Then
            Return Nothing
        End If
        
        Dim document As IDocument = m_application.Document
        sxDocument = CType(document, ISxDocument)
        Dim scene As IScene = sxDocument.Scene
        Return scene
        Catch ex As Exception
        MessageBox.Show(ex.InnerException.ToString(), "GetScene error")
        Return Nothing
        End Try
        
    End Function

    Scene

    The Scene coclass is central to 3D Analyst and allows you to access the 3D view and the data it contains. Although you can directly use the Scene object in your applications, it is more common to use a higher-level object, such as the SceneControl or an ArcGIS for Desktop application. The higher-level object allows you to further control the 3D view and implement interfaces such as IScene, ISceneBookmarks, IAGAnimationTracks, and so on. There is only one Scene object instantiated in an ArcScene application or a SceneControl. Contained in a Scene object, the SceneGraph coclass handles the 3D drawing and rendering functionalities. The general relationship is shown in the following illustration:
    Illustration of the SceneGraph coclass and general relationship.
    When creating custom commands, tools, or menus, you can use the SceneHookHelper object, which makes it straightforward to create a command that works with the SceneControl, ToolbarControl, and the ArcScene application. The SceneHookHelper object is used to hold on to the hook, and the ISceneHookHelper interface it implements can return the SceneViewer, Scene, SceneGraph, and Camera regardless of the type of hook that is passed. The following code example in the ICommand.Create() function shows how to get a handle to the scene using the SceneHookHelper:
    [C#]
    ISceneHookHelper m_pSceneHookHelper;
    IScene m_pScene;
    
    //TODO: Your code here...
    
    public void OnCreate(object hook)
    {
        m_pSceneHookHelper = new SceneHookHelperClass();
        m_pSceneHookHelper.Hook = hook;
        m_pScene = m_pSceneHookHelper.Scene;
    }
    [VB.NET]
    Private m_pSceneHookHelper As ISceneHookHelper
    Private m_pScene As IScene
    
    'TODO: Your code here...
    
    Public Sub OnCreate(ByVal hook As Object)
        
        m_pSceneHookHelper = New SceneHookHelperClass()
        m_pSceneHookHelper.Hook = hook
        m_pScene = m_pSceneHookHelper.Scene
        
    End Sub

    SceneGraph

    The SceneGraph in 3DAnalyst, internally implemented as a directed acyclic graph (DAG), provides a hierarchical organization of the scene that makes some processes more efficient in 3D graphic applications. It performs the following three main functions:
    • Minimizes the cost of visualization
    • Organizes and applies Scene object properties
    • Manages the invalidation, retrieval, and recording of the internal caches
    In addition to these functions, the SceneGraph coclass also helps with the 3D rendering by implementing the IDisplay3D interface, which converts the layer data and symbology into drawing calls. Therefore, the SceneGraph coclass plays a pivotal role in visualization in 3D Analyst.
    The SceneGraph coclass is often the access point to other 3D rendering-related coclasses. The most important interfaces that the SceneGraph coclass implements are ISceneGraph, IViewer3D, and IDisplay3D. Use ISceneGraph to handle general rendering operations, IViewer3D to manage scene viewers, and IDisplay3D to perform flashings. Another useful interface is ISceneGraphEvents. If you need to make OpenGL calls to assist your visualization, you can embed those calls in a BeforeDraw event or an AfterDraw event. The following code example shows a common way to get a handle of the SceneGraph:
    [C#]
    //To get the SceneGraph.
    IScene scene = GetScene();
    ISceneGraph sceneGraph = scene.SceneGraph;
    
    //To get a camera of the active viewer.
    ISceneViewer sceneViewer = sceneGraph.ActiveViewer;
    ICamera camera = sceneViewer.Camera;
    
    //Some actions...
    
    //To refresh or redraw all viewers:
    sceneGraph.RefreshViewers();
    
    //To redraw an individual viewer (for example, the active viewer), use
    sceneViewer.Redraw(true);
    [VB.NET]
    'To get the SceneGraph.
    Dim scene As IScene = GetScene()
    Dim sceneGraph As ISceneGraph = scene.SceneGraph
    
    'To get a camera of the active viewer.
    Dim sceneViewer As ISceneViewer = sceneGraph.ActiveViewer
    Dim camera As ICamera = sceneViewer.Camera
    
    'Some actions...
    
    'To refresh or redraw all viewers:
    sceneGraph.RefreshViewers()
    
    'To redraw an individual viewer (for example, the active viewer), use
    sceneViewer.Redraw(True)

    3D properties

    There are several types of layers frequently used in the Scene coclass including graphics, features, triangulated irregular networks (TINs), and raster layers. Each of these layers can have its own 3D properties, such as base height, extrusions, and so on, which are available on their respective layer property pages on the user interface. Through ArcObjects, you can get and set these properties and reapply them to accommodate your specific 3D visualization needs. See the following illustration for their relationships:
    Illustration of the Scene properties and relationships.
    Access layer 3D properties via the LayerExtension collections. Previously, there was only one layer extension of I3DProperties type used by scene and getting a handle to it was straightforward. The following code example shows how to get a handle to the 3D properties of the first layer in the scene:
    [C#]
    IScene scene = GetScene();
    
    ILayer layer = scene.get_Layer(0);
    IFeatureLayer featureLayer = layer as IFeatureLayer;
    I3DProperties properties3D = null;
    ILayerExtensions layerExtensions = featureLayer as ILayerExtensions;
    
    for (int i = 0; i < layerExtensions.ExtensionCount; i++)
    {
        if (layerExtensions.get_Extension(i)is I3DProperties)
        {
            object extension3D = layerExtensions.get_Extension(i);
            properties3D = extension3D as I3DProperties;
            break;
        }
    }
    
    //Get or set the feature layer 3D properties.
    properties3D.SmoothShading = true;
    [VB.NET]
    Dim scene As IScene = GetScene()
    
    Dim layer As ILayer = scene.Layer(0)
    Dim featureLayer As IFeatureLayer = TryCast(layer, IFeatureLayer)
    Dim properties3D As I3DProperties = Nothing
    Dim layerExtensions As ILayerExtensions = TryCast(featureLayer, ILayerExtensions)
    
    For i As Integer = 0 To layerExtensions.ExtensionCount - 1
        If TypeOf layerExtensions.Extension(i) Is I3DProperties Then
            Dim extension3D As Object = layerExtensions.Extension(i)
            properties3D = TryCast(extension3D, I3DProperties)
            Exit For
        End If
    Next i
    
    'Get or set the feature layer 3D properties.
    properties3D.SmoothShading = True

    Scene exporters

    Scene exporters convert scenes to formats for use in other applications. Available exporters include VRMLExporter, AVIExporter, and QuickTimeExporter. The Virtual Reality Modeling Language (VRML) exporter, for use in scene only, converts the scene to VRML 2.0 format. This is an open, industry-standard, 3D graphics format. The Audio Video Interleaved (AVI) and QuickTime exporters can be used in both scene and globe and convert the animation defined in a document to one of these two common video formats. The following illustration shows that all three coclasses implement the ISceneExporter3D interface:
    Illustration that shows all three coclasses that implement ISceneExporter3D.
    Animations in scene can be created using ArcObjects in the Animation library. The ArcObjects in the 3DAnalyst library can still be used to export animations to AVI or QuickTime formats, but it is recommended that you use the objects in the Animation library instead. For more information, see the Animations section in this topic.
    The following code example shows the minimum way to export the scene to a VRML model. The assumption is that you have data already added to the scene. The script exports a VRML model using the default settings. To customize your settings, cast to ISceneVideoExporter and IVRMLExporter for VRMLExporter.
    [C#]
    IScene scene = GetScene();
    ISceneGraph sceneGraph = scene.SceneGraph;
    ISceneViewer sceneViewer = sceneGraph.ActiveViewer;
    
    //Export VRML.
    ISceneExporter3d sceneExporter3d = new VRMLExporterClass();
    sceneExporter3d.ExportFileName = "C:\temp\test.wrl";
    sceneExporter3d.ExportScene(scene);
    [VB.NET]
    Dim scene As IScene = GetScene()
    Dim sceneGraph As ISceneGraph = scene.SceneGraph
    Dim sceneViewer As ISceneViewer = sceneGraph.ActiveViewer
    
    'Export VRML.
    Dim sceneExporter3d As ISceneExporter3d = New VRMLExporterClass()
    sceneExporter3d.ExportFileName = "C:	emp	est.wrl"
    sceneExporter3d.ExportScene(scene)

    Scene and globe viewer

    The scene viewer represents a 3D display window in scene. The equivalent in ArcGlobe is the globe viewer. Both application programs support one or more viewers. The primary viewer is displayed in the main application window. Subviewers are opened in separate floating windows. The viewer with current focus is the active viewer. The perspective of a scene viewer is controlled by the Camera of the Scene (the equivalent for Globe is GlobeCamera). The I3DViewer interface extracts common properties and methods applicable to both scene and globe viewers and adds others—for example, full-screen viewing—so it can be used by both a scene and a globe. The following illustration shows these relationships for the scene and scene viewer and the globe and globe viewer:
    Illustration showing relationships for the scene and scene viewer and the globe and globe viewer.
    The following code example shows how to get the Camera object of the active scene viewer using both the ISceneViewer and I3DViewer interfaces. The usage for both interfaces is similar. The camera object returned is the same using either interface because both pointers (pSV and p3DV) are pointing to the same viewer (the active viewer) and there is only one camera object for each viewer.
    [C#]
    IScene scene = GetScene();
    ISceneGraph sceneGraph = scene.SceneGraph;
    ISceneViewer sceneViewer = sceneGraph.ActiveViewer;
    I3DViewer viewer3D = sceneViewer as I3DViewer;
    ICamera camera_SceneViewer = sceneViewer.Camera;
    ICamera camera_Vierwer3D = viewer3D.Camera;
    
    if (camera_SceneViewer == camera_Vierwer3D)
    {
        MessageBox.Show("camera_SceneViewer is equal to camera_Vierwer3D");
    }
    [VB.NET]
    Dim scene As IScene = GetScene()
    Dim sceneGraph As ISceneGraph = scene.SceneGraph
    Dim sceneViewer As ISceneViewer = sceneGraph.ActiveViewer
    Dim viewer3D As I3DViewer = TryCast(sceneViewer, I3DViewer)
    Dim camera_SceneViewer As ICamera = sceneViewer.Camera
    Dim camera_Vierwer3D As ICamera = viewer3D.Camera
    
    If camera_SceneViewer Is camera_Vierwer3D Then
        MessageBox.Show("camera_SceneViewer is equal to camera_Vierwer3D")
    End If

    3D symbols

    3D symbols provide enhanced capabilities for feature representation in 3D viewing environments. There are several types of 3D symbols for points, polylines, and polygons. They offer simple geometry primitives—for example, cubes, spheres, and tubes. They can also use complex and textured geometry, such as models of buildings or planes. This variety of capabilities is useful for the more abstract demands of scientific visualization as well as photo-realism for simulation. Supported 3D marker symbols are SimpleMarker3DSymbol, Marker3DSymbol, and CharacterMarker3DSymbol. Supported 3D line symbols are SimpleLine3DSymbol and TextureLineSymbol. TextureFillSymbol is used for polygons. The following illustration provides an overview of these symbols. For a detailed view of these 3D symbol components, see the 3DAnalyst Object Model diagram.
    Illustration showing an overview of 3D marker symbols.
    TextureLineSymbol and TextureFillSymbol have one associated GeometryMaterial; it can be read and set (by reference) using the symbol's Texture property. A 3D marker symbol can have multiple instances of GeometryMaterial. Each is maintained by the GeometryMaterialList coclass that is associated with a MultiPatch geometry. This, in turn, can be instantiated by using the GeneralMultiPatchCreator coclass or imported using the Import3DFile coclass. In fact, all symbol templates stored in the ESRI-provided 3D Marker Symbol styles are created by using either the GeneralMultiPatchCreator coclass or the Import3DFile coclass. The end result of using these two coclasses is a multipatch geometry that, when used with GeometryMaterial, can have color, texture (image), or both.
    To get the properties of a multipatch geometry, whether it is textured or not, use the IGeneralMultiPatchInfo interface of the MultiPatch coclass from the Geometry library. A multipatch can be persisted as the geometry (shape) of a feature in a feature class in either a personal geodatabase (*.mdb) or in ArcSDE. The same geometry, when persisted as the shape of a feature in a shapefile, loses its GeometryMaterial (color and texture). See the following illustration:
    Illustration of MultiPatch properties.
    The following code example shows how to get the GeometryMaterial count for the first feature of the first layer (assuming it is a feature layer) in the scene. It shows both ways to query the property when the layer consists of a textured multipatch feature class (query multipatch geometry property) or a point feature layer symbolized using a 3D marker symbol (query 3D marker symbol property).
    [C#]
    IScene scene = GetScene();
    ILayer layer = scene.get_Layer(0);
    IFeatureLayer featureLayer = layer as IFeatureLayer;
    IFeatureClass featureClass = featureLayer.FeatureClass;
    IFeatureCursor featureCursor = featureClass.Search(null, true);
    IFeature feature = featureCursor.NextFeature();
    
    if (featureClass.ShapeType == esriGeometryType.esriGeometryMultiPatch)
    {
        //If textured multipatch:
        IGeometry geometry = feature.Shape;
        IGeneralMultiPatchInfo generalMultiPatchInfo = geometry as
            IGeneralMultiPatchInfo;
        Int32 materialCount = generalMultiPatchInfo.MaterialCount;
        MessageBox.Show("Material Count in the 1st Feature of the 1st Layer: " +
            materialCount.ToString());
    }
    
    else if (featureClass.ShapeType == esriGeometryType.esriGeometryPoint)
    {
        //Else if point feature layer:
        IGeoFeatureLayer geoFeatureLayer = featureLayer as IGeoFeatureLayer;
        IFeatureRenderer featureRenderer = geoFeatureLayer.Renderer;
        ISymbol symbol = featureRenderer.get_SymbolByFeature(feature);
        if (symbol is IMarker3DSymbol)
        {
            //If 3D marker symbol:
            IMarker3DSymbol marker3DSymbol = symbol as IMarker3DSymbol;
            Int32 materialCount = marker3DSymbol.MaterialCount;
            MessageBox.Show(materialCount.ToString());
        }
    }
    [VB.NET]
    Dim scene As IScene = GetScene()
    Dim layer As ILayer = scene.Layer(0)
    Dim featureLayer As IFeatureLayer = TryCast(layer, IFeatureLayer)
    Dim featureClass As IFeatureClass = featureLayer.FeatureClass
    Dim featureCursor As IFeatureCursor = featureClass.Search(Nothing, True)
    Dim feature As IFeature = featureCursor.NextFeature()
    
    If featureClass.ShapeType = esriGeometryType.esriGeometryMultiPatch Then
        'If textured multipatch:
        
        Dim geometry As IGeometry = feature.Shape
        Dim generalMultiPatchInfo As IGeneralMultiPatchInfo = TryCast(geometry, IGeneralMultiPatchInfo)
        Dim materialCount As Int32 = generalMultiPatchInfo.MaterialCount
        MessageBox.Show("Material Count in the 1st Feature of the 1st Layer: " + materialCount.ToString)
        
    ElseIf featureClass.ShapeType = esriGeometryType.esriGeometryPoint Then
        'Else if point feature layer:
        
        Dim geoFeatureLayer As IGeoFeatureLayer = TryCast(featureLayer, IGeoFeatureLayer)
        Dim featureRenderer As IFeatureRenderer = geoFeatureLayer.Renderer
        Dim symbol As ISymbol = featureRenderer.SymbolByFeature(feature)
        
        If TypeOf symbol Is IMarker3DSymbol Then
            'If 3D marker symbol:
            
            Dim marker3DSymbol As IMarker3DSymbol = TryCast(symbol, IMarker3DSymbol)
            Dim materialCount As Int32 = marker3DSymbol.MaterialCount
            MessageBox.Show(materialCount.ToString)
        End If
        
    End If

    Animations

    Animations allow you to create dynamic visual effects by storing actions (behavior of objects), which can be replayed later. In scene, you can create animations to visualize changes in the view, scene properties, and layer properties as well as temporal changes in the data. Animations can be created using the Animation library.
    ArcObjects from the 3DAnalyst library that were used to create animations at ArcGIS 9 and 9.1 can still be used, and existing projects using these objects should still compile. If you have any compilation of projects issues, reference the Animation library. It is recommended that you use the objects in the Animation library for new projects.
    As described in the Animation library overview, an animation consists of one or more animation tracks (AGAnimationTracks), which control changes of the properties of an object, such as the scene's background color, the visibility of a layer, or a camera location. Each track is associated to a certain AGAnimationType. AGAnimationType properties—AnimationTypeCamera, AnimationTypeLayer, AnimationTypeScene, and AnimationTypeTimeLayer—are available out of the box in scene. You can optionally implement custom types.
     
  • 相关阅读:
    BZOJ3932 [CQOI2015]任务查询系统
    数位DP专练
    Codeforces #669 div2
    Codeforces #670 div2
    P1450 [HAOI2008] 硬币购物
    P3172 [CQOI2015]选数
    比赛-Round 1 (12 Jul, 2018)
    “记计帐”需求分析
    一个程序员的哲学思考
    中国式大学——我们需要获得什么?
  • 原文地址:https://www.cnblogs.com/2008nmj/p/14047137.html
Copyright © 2020-2023  润新知