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
- 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
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):
- ESRI.ArcGIS.ArcScene
- ESRI.ArcGIS.Framework
- ESRI.ArcGIS.3DAnalyst (ESRI.ArcGIS.Analyst3D)
- ESRI.ArcGIS.Animation
- ESRI.ArcGIS.Carto
- ESRI.ArcGIS.Controls
- ESRI.ArcGIS.Display
- ESRI.ArcGIS.Geodatabase
- ESRI.ArcGIS.Geometry
- ESRI.ArcGIS.System (ESRI.ArcGIS.esriSystem)
- System.Windows.Forms
- System
See the following sections for more information about this namespace:
- Prerequisites
- Scene
- SceneGraph
- 3D properties
- Scene exporters
- Scene and globe viewer
- 3D symbols
- Animations
Prerequisites
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
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
- Minimizes the cost of visualization
- Organizes and applies Scene object properties
- Manages the invalidation, retrieval, and recording of the internal caches
//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
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
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:\temp\test.wrl"
sceneExporter3d.ExportScene(scene)
Scene and globe viewer
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
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