ArcGIS Pro SDK (九)几何 12 多面体
文章目录
1 通过拉伸多边形或折线构建多面体
string json = "{\"hasZ\":true,\"rings\":[[[0,0,0],[0,1,0],[1,1,0],[1,0,0],[0,0,0]]],\"spatialReference\":{\"wkid\":4326}}";
Polygon polygon = PolygonBuilderEx.FromJson(json);
Multipatch multipatch = GeometryEngine.Instance.ConstructMultipatchExtrude(polygon, 2);
json = "{\"hasZ\":true,\"rings\":[[[0,0,1],[0,1,2],[1,1,3],[1,0,4],[0,0,1]]],\"spatialReference\":{\"wkid\":4326}}";
polygon = PolygonBuilderEx.FromJson(json);
multipatch = GeometryEngine.Instance.ConstructMultipatchExtrudeFromToZ(polygon, -10, 20);
Coordinate3D coord = new Coordinate3D(10, 18, -10);
multipatch = GeometryEngine.Instance.ConstructMultipatchExtrudeAlongVector3D(polygon, coord);
json = "{\"hasZ\":true,\"paths\":[[[400,800,1000],[800,1400,1500],[1200,800,2000],[1800,1800,2500],[2200,800,3000]]],\"spatialReference\":{\"wkid\":3857}}";
Polyline polyline = PolylineBuilderEx.FromJson(json);
multipatch = GeometryEngine.Instance.ConstructMultipatchExtrudeToZ(polyline, 500);
Coordinate3D fromCoord = new Coordinate3D(50, 50, -500);
Coordinate3D toCoord = new Coordinate3D(200, 50, 1000);
multipatch = GeometryEngine.Instance.ConstructMultipatchExtrudeAlongLine(polyline, fromCoord, toCoord);
2 多面体属性
bool hasZ = multipatch.HasZ;
bool hasM = multipatch.HasM;
bool hasID = multipatch.HasID;
bool isEmpty = multipatch.IsEmpty;
var sr = multipatch.SpatialReference;
int patchCount = multiPatch.PartCount;
int pointCount = multiPatch.PointCount;
ReadOnlyPointCollection points = multipatch.Points;
IReadOnlyList<Coordinate3D> coordinates = multipatch.Copy3DCoordinatesToList();
bool hasMaterials = multiPatch.HasMaterials;
int materialCount = multiPatch.MaterialCount;
bool hasTextures = multiPatch.HasTextures;
int textureVertexCount = multiPatch.TextureVertexCount;
bool hasNormals = multiPatch.HasNormals;
int patchPriority = multiPatch.GetPatchPriority(patchIndex);
PatchType patchType = multiPatch.GetPatchType(patchIndex);
int patchPointCount = multiPatch.GetPatchPointCount(patchIndex);
int pointStartIndex = multiPatch.GetPatchStartPointIndex(patchIndex);
if (hasMaterials)
{
int materialIndex = multipatch.GetPatchMaterialIndex(patchIndex);
var color = multipatch.GetMaterialColor(materialIndex);
var edgeColor = multipatch.GetMaterialEdgeColor(materialIndex);
var edgeWidth = multipatch.GetMaterialEdgeWidth(materialIndex);
var shiness = multipatch.GetMaterialShininess(materialIndex);
var percent = multipatch.GetMaterialTransparencyPercent(materialIndex);
var cullBackFace = multipatch.IsMaterialCullBackFace(materialIndex);
bool isTextured = multipatch.IsMaterialTextured(materialIndex);
if (isTextured)
{
int columnCount = multipatch.GetMaterialTextureColumnCount(materialIndex);
int rowCount = multipatch.GetMaterialTextureRowCount(materialIndex);
int bpp = multipatch.GetMaterialTextureBytesPerPixel(materialIndex);
TextureCompressionType compressionType = multipatch.GetMaterialTextureCompressionType(materialIndex);
var texture = multipatch.GetMaterialTexture(materialIndex);
}
}
if (hasTextures)
{
int numPatchTexturePoints = multiPatch.GetPatchTextureVertexCount(patchIndex);
var coordinate2D = multiPatch.GetPatchTextureCoordinate(patchIndex, 0);
ICollection<Coordinate2D> textureCoordinates = new List<Coordinate2D>(numPatchTexturePoints);
multiPatch.GetPatchTextureCoordinates(patchIndex, ref textureCoordinates);
}
if (hasNormals)
{
Coordinate3D patchNormal = multipatch.GetPatchNormal(patchIndex, 0);
ICollection<Coordinate3D> normalCoordinates = new List<Coordinate3D>(patchPointCount);
multipatch.GetPatchNormals(patchIndex, ref normalCoordinates);
}
3 构建多面体
string binaryXml = multiPatch.ToBinaryXml();
Multipatch binaryMultipatch = MultipatchBuilderEx.FromBinaryXml(binaryXml);
string xml = multiPatch.ToXml();
Multipatch xmlMultipatch = MultipatchBuilderEx.FromXml(xml);
byte[] buffer = multiPatch.ToEsriShape();
Multipatch esriPatch = MultipatchBuilderEx.FromEsriShape(buffer);
Multipatch patchImport = GeometryEngine.Instance.ImportFromEsriShape(EsriShapeImportFlags.EsriShapeImportDefaults, buffer, multiPatch.SpatialReference) as Multipatch;
4 通过MultipatchBuilderEx构建多面体
var coords_face1 = new List<Coordinate3D>()
{
new Coordinate3D(12.495461061000071,41.902603910000039,62.552700000000186),
new Coordinate3D(12.495461061000071,41.902603910000039,59.504700000004959),
new Coordinate3D(12.495461061000071,41.902576344000067,59.504700000004959),
new Coordinate3D(12.495461061000071,41.902603910000039,62.552700000000186),
new Coordinate3D(12.495461061000071,41.902576344000067,59.504700000004959),
new Coordinate3D(12.495461061000071,41.902576344000067,62.552700000000186),
};
var coords_face2 = new List<Coordinate3D>()
{
new Coordinate3D(12.495461061000071, 41.902576344000067, 62.552700000000186),
new Coordinate3D(12.495461061000071, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902576344000067, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902576344000067, 62.552700000000186),
};
var coords_face3 = new List<Coordinate3D>()
{
new Coordinate3D(12.495488442000067, 41.902576344000067, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902576344000067, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902603910000039, 62.552700000000186),
};
var coords_face4 = new List<Coordinate3D>()
{
new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902576344000067, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
};
var coords_face5 = new List<Coordinate3D>()
{
new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902603910000039, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902603910000039, 59.504700000004959),
new Coordinate3D(12.495461061000071, 41.902603910000039, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902603910000039, 62.552700000000186),
};
var coords_face6 = new List<Coordinate3D>()
{
new Coordinate3D(12.495488442000067, 41.902603910000039, 62.552700000000186),
new Coordinate3D(12.495461061000071, 41.902603910000039, 62.552700000000186),
new Coordinate3D(12.495461061000071, 41.902576344000067, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902603910000039, 62.552700000000186),
new Coordinate3D(12.495461061000071, 41.902576344000067, 62.552700000000186),
new Coordinate3D(12.495488442000067, 41.902576344000067, 62.552700000000186),
};
var materialRed = new BasicMaterial();
materialRed.Color = System.Windows.Media.Colors.Red;
var materialTransparent = new BasicMaterial();
materialTransparent.Color = System.Windows.Media.Colors.White;
materialTransparent.TransparencyPercent = 80;
var blueTransparent = new BasicMaterial(materialTransparent);
blueTransparent.Color = System.Windows.Media.Colors.SkyBlue;
var patches = new List<Patch>();
var mpb = new ArcGIS.Core.Geometry.MultipatchBuilderEx();
var patch = mpb.MakePatch(PatchType.Triangles);
patch.Coords = coords_face1;
patches.Add(patch);
patch = mpb.MakePatch(PatchType.Triangles);
patch.Coords = coords_face2;
patches.Add(patch);
patch = mpb.MakePatch(PatchType.Triangles);
patch.Coords = coords_face3;
patches.Add(patch);
patch = mpb.MakePatch(PatchType.Triangles);
patch.Coords = coords_face4;
patches.Add(patch);
patch = mpb.MakePatch(PatchType.Triangles);
patch.Coords = coords_face5;
patches.Add(patch);
patch = mpb.MakePatch(PatchType.Triangles);
patch.Coords = coords_face6;
patches.Add(patch);
patches[0].Material = materialRed;
patches[1].Material = materialTransparent;
patches[2].Material = materialRed;
patches[3].Material = materialRed;
patches[4].Material = materialRed;
patches[5].Material = blueTransparent;
mpb.Patches = patches;
var red = mpb.QueryPatchIndicesWithMaterial(materialRed);
multipatch = mpb.ToGeometry() as Multipatch;
5 从另一个多面体构建多面体
var builder = new ArcGIS.Core.Geometry.MultipatchBuilderEx(multipatch);
bool hasM = builder.HasM;
bool hasZ = builder.HasZ;
bool hasID = builder.HasID;
bool isEmpty = builder.IsEmpty;
bool hasNormals = builder.HasNormals;
var patches = builder.Patches;
int patchCount = patches.Count;
if (patchCount > 0)
{
int pointCount = builder.GetPatchPointCount(0);
if (pointCount > 0)
{
var pt = builder.GetPoint(0, 0);
builder.SetPoint(0, 0, newPoint);
}
var texture = builder.QueryPatchIndicesWithTexture(brickTextureResource);
patches[0].Material = brickMaterialTexture;
}
builder.HasM = true;
builder.SynchronizeAttributeAwareness();
multipatch = builder.ToGeometry() as Multipatch;
6 从 3D 模型文件构建多面体
try
{
var model = ArcGIS.Core.Geometry.MultipatchBuilderEx.From3DModelFile(@"c:\Temp\My3dModelFile.dae");
bool modelIsEmpty = model.IsEmpty;
}
catch (FileNotFoundException)
{
}
catch (ArgumentException)
{
}
7 构建 3D 特殊多面体形状
var sr = MapView.Active.Map.SpatialReference;
var extent = MapView.Active.Extent;
var center = extent.Center;
var centerZ = MapPointBuilderEx.CreateMapPoint(center.X, center.Y, 500, sr);
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Cube, centerZ, 200, sr);
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Tetrahedron, centerZ, 200, sr);
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Diamond, centerZ, 200, sr);
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Hexagon, centerZ, 200, sr);
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.SphereFrame, centerZ, 200, 0.8, sr);
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Sphere, centerZ, 200, 0.8, sr);
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Cylinder, centerZ, 200, 0.8, sr);
multipatch = ArcGIS.Core.Geometry.MultipatchBuilderEx.CreateMultipatch(MultipatchConstructType.Cone, centerZ, 200, 0.8, sr);
builder = new MultipatchBuilderEx(MultipatchConstructType.Cone, centerZ, 200, 0.8, sr);
BasicMaterial faceMaterial = new BasicMaterial();
faceMaterial.Color = System.Windows.Media.Color.FromRgb(255, 0, 0);
faceMaterial.Shininess = 150;
faceMaterial.TransparencyPercent = 50;
faceMaterial.EdgeWidth = 20;
foreach (var patch in builder.Patches)
patch.Material = faceMaterial;
multipatch = builder.ToGeometry() as Multipatch;
8 创建基本材料
BasicMaterial material = new BasicMaterial();
System.Windows.Media.Color color = material.Color;
System.Windows.Media.Color edgeColor = material.EdgeColor;
int edgeWidth = material.EdgeWidth;
int transparency = material.TransparencyPercent;
int shininess = material.Shininess;
bool cullBackFace = material.IsCullBackFace;
material.Color = System.Windows.Media.Colors.Red;
material.EdgeColor = System.Windows.Media.Colors.Blue;
material.EdgeWidth = 10;
material.TransparencyPercent = 50;
material.Shininess = 25;
material.IsCullBackFace = true;
9 使用 JPEG 纹理创建基本材质
System.Drawing.Image image = System.Drawing.Image.FromFile(@"C:\temp\myImageFile.jpg");
MemoryStream memoryStream = new MemoryStream();
System.Drawing.Imaging.ImageFormat format = System.Drawing.Imaging.ImageFormat.Jpeg;
image.Save(memoryStream, format);
byte[] imageBuffer = memoryStream.ToArray();
var jpgTexture = new JPEGTexture(imageBuffer);
int bpp = jpgTexture.BytesPerPixel;
int columnCount = jpgTexture.ColumnCount;
int rowCount = jpgTexture.RowCount;
BasicMaterial material = new BasicMaterial();
material.TextureResource = new TextureResource(jpgTexture);
10 使用未压缩纹理创建基本材质
UncompressedTexture uncompressedTexture1 = new UncompressedTexture(new byte[10 * 12 * 3], 10, 12, 3);
int bpp = uncompressedTexture1.BytesPerPixel;
int columnCount = uncompressedTexture1.ColumnCount;
int rowCount = uncompressedTexture1.RowCount;
TextureResource tr = new TextureResource(uncompressedTexture1);
BasicMaterial material = new BasicMaterial();
material.TextureResource = tr;
11 获取多面体的纹理图像
public void GetMultipatchTextureImage(Multipatch multipatch, int patchIndex)
{
int materialIndex = multipatch.GetPatchMaterialIndex(patchIndex);
if (!multipatch.IsMaterialTextured(materialIndex))
return;
TextureCompressionType compressionType =
multipatch.GetMaterialTextureCompressionType(materialIndex);
string ext = compressionType == TextureCompressionType.CompressionJPEG ? ".jpg" : ".dat";
byte[] textureBuffer = multipatch.GetMaterialTexture(materialIndex);
Stream imageStream = new MemoryStream(textureBuffer);
System.Drawing.Image image = System.Drawing.Image.FromStream(imageStream);
image.Save(@"C:\temp\myImage" + ext);
}
12 获取多面体的法线坐标
public void DoSomethingWithNormalCoordinate(Multipatch multipatch, int patchIndex)
{
if (multipatch.HasNormals)
{
int numNormals = multipatch.GetPatchPointCount(patchIndex);
for (int pointIndex = 0; pointIndex < numNormals; pointIndex++)
{
Coordinate3D normal = multipatch.GetPatchNormal(patchIndex, pointIndex);
}
}
}
13 获取多面体的法线
public void DoSomethingWithNormalCoordinates(Multipatch multipatch)
{
if (multipatch.HasNormals)
{
int numPoints = multipatch.PointCount;
ICollection<Coordinate3D> normals = new List<Coordinate3D>(numPoints);
int numPatches = multipatch.PartCount;
for (int patchIndex = 0; patchIndex < numPatches; patchIndex++)
{
multipatch.GetPatchNormals(patchIndex, ref normals);
}
}
}
14 获取多面体的材质属性
public void GetMaterialProperties(Multipatch multipatch, int patchIndex)
{
if (multipatch.HasMaterials)
{
int materialIndex = multipatch.GetPatchMaterialIndex(patchIndex);
System.Windows.Media.Color color = multipatch.GetMaterialColor(materialIndex);
int tranparencyPercent = multipatch.GetMaterialTransparencyPercent(materialIndex);
bool isBackCulled = multipatch.IsMaterialCullBackFace(materialIndex);
if (multipatch.IsMaterialTextured(materialIndex))
{
int bpp = multipatch.GetMaterialTextureBytesPerPixel(materialIndex);
int columnCount = multipatch.GetMaterialTextureColumnCount(materialIndex);
int rowCount = multipatch.GetMaterialTextureRowCount(materialIndex);
}
}
}