// fileName of the form "d:\Temp\Image.jpg" private byte[] GetBufferFromImageFile(string fileName, esriTextureCompressionType compressionType) { System.Drawing.Image image = System.Drawing.Image.FromFile(fileName); MemoryStream memoryStream = new MemoryStream(); System.Drawing.Imaging.ImageFormat format = compressionType == esriTextureCompressionType.CompressionJPEG ? System.Drawing.Imaging.ImageFormat.Jpeg : System.Drawing.Imaging.ImageFormat.Bmp; image.Save(memoryStream, format); byte[] imageBuffer = memoryStream.ToArray(); return(imageBuffer); }
// sUri of the form "pack://application:,,,/myPack;component/Images/image.jpg" private byte[] GetBufferImage(string sUri, esriTextureCompressionType compressionType) { System.Drawing.Imaging.ImageFormat format = (compressionType == esriTextureCompressionType.CompressionJPEG) ? System.Drawing.Imaging.ImageFormat.Jpeg : System.Drawing.Imaging.ImageFormat.Bmp; Uri uri = new Uri(sUri, UriKind.RelativeOrAbsolute); StreamResourceInfo info = Application.GetResourceStream(uri); System.Drawing.Image image = System.Drawing.Image.FromStream(info.Stream); MemoryStream memoryStream = new MemoryStream(); image.Save(memoryStream, format); byte[] imageBuffer = memoryStream.ToArray(); return(imageBuffer); }
protected override async void OnClick() { // make sure there's an OID from a created feature if (Module1.MultipatchOID == -1) { return; } if (MapView.Active?.Map == null) { return; } // find layer var member = MapView.Active.Map.GetLayersAsFlattenedList().FirstOrDefault(l => l.Name == "MultipatchWithTextureSimple") as FeatureLayer; if (member == null) { return; } // create the textures esriTextureCompressionType compressionType = esriTextureCompressionType.CompressionJPEG; byte[] brickImageBuffer = GetBufferImage("pack://application:,,,/MultipatchBuilderEx;component/Textures/Brick.jpg", compressionType); var brickTextureResource = new TextureResource(new JPEGTexture(brickImageBuffer)); BasicMaterial brickMaterialTexture = new BasicMaterial(); brickMaterialTexture.TextureResource = brickTextureResource; byte[] blocksImageBuffer = GetBufferImage("pack://application:,,,/MultipatchBuilderEx;component/Textures/Retaining_Blocks.jpg", compressionType); var blocksTextureResource = new TextureResource(new JPEGTexture(blocksImageBuffer)); BasicMaterial blockskMaterialTexture = new BasicMaterial(); blockskMaterialTexture.TextureResource = blocksTextureResource; byte[] waterImageBuffer = GetBufferImage("pack://application:,,,/MultipatchBuilderEx;component/Textures/water.jpg", compressionType); var waterTextureResource = new TextureResource(new JPEGTexture(waterImageBuffer)); BasicMaterial waterMaterialTexture = new BasicMaterial(); waterMaterialTexture.TextureResource = waterTextureResource; // set up a set of TextureCoordinates - these determine how the texture is draped over a face // In this scenario we will use the same textureCoordinates for each face var textureCoords = new List <Coordinate2D>() { new Coordinate2D(0, 0), new Coordinate2D(1, 0), new Coordinate2D(1, -1), new Coordinate2D(0, 0), new Coordinate2D(1, -1), new Coordinate2D(0, -1), }; bool result = await QueuedTask.Run(() => { // get the multipatch shape using the Inspector var insp = new Inspector(); insp.Load(member, Module1.MultipatchOID); var origMultipatch = insp.Shape as Multipatch; // create a builder var mpb = new ArcGIS.Core.Geometry.MultipatchBuilderEx(origMultipatch); // apply the texture materials to the patches var patches = mpb.Patches; patches[0].Material = brickMaterialTexture; patches[0].TextureCoords2D = textureCoords; patches[1].Material = blockskMaterialTexture; patches[1].TextureCoords2D = textureCoords; patches[2].Material = brickMaterialTexture; patches[2].TextureCoords2D = textureCoords; patches[3].Material = waterMaterialTexture; patches[3].TextureCoords2D = textureCoords; patches[4].Material = blockskMaterialTexture; patches[4].TextureCoords2D = textureCoords; patches[5].Material = waterMaterialTexture; patches[5].TextureCoords2D = textureCoords; // use this method to determine patches which contain the specified texture //var texture = mpb.QueryPatchIndicesWithTexture(brickTextureResource); // get the modified multipatch geometry var newMultipatch = mpb.ToGeometry() as Multipatch; // modify operation var modifyOp = new EditOperation(); modifyOp.Name = "Apply textures to multipatch"; modifyOp.Modify(member, Module1.MultipatchOID, newMultipatch); if (modifyOp.Execute()) { return(true); } return(false); }); }
protected override async void OnClick() { #region Initialization // set up a set of TextureCoordinates - these determine how the texture is draped over a face // In this scenario we will use the same textureCoordinates for each face var textureCoords = new List <Coordinate2D>() { new Coordinate2D(4.67909908294678, -2.89953231811523), new Coordinate2D(-3.7085223197937, -2.89953231811523), new Coordinate2D(-3.6790623664856, 1.89953279495239), new Coordinate2D(4.67909908294678, -2.89953231811523), new Coordinate2D(-3.6790623664856, 1.89953279495239), new Coordinate2D(4.7085223197937, 1.89953327178955) }; esriTextureCompressionType compressionType = esriTextureCompressionType.CompressionJPEG; byte[] glassImageBuffer = GetBufferImage("pack://application:,,,/MultipatchBuilder;component/Textures/Glass.jpg", compressionType); var glassTextureResource = new TextureResource(new JPEGTexture(glassImageBuffer)); byte[] roofImageBuffer = GetBufferImage("pack://application:,,,/MultipatchBuilder;component/Textures/Roof.jpg", compressionType); var roofTextureResource = new TextureResource(new JPEGTexture(roofImageBuffer)); var materialGray = new BasicMaterial { Color = System.Windows.Media.Colors.Gray }; #endregion if (MapView.Active?.Map == null) { return; } // find footprint layer var footPrintLyr = MapView.Active.Map.GetLayersAsFlattenedList().FirstOrDefault(l => l.Name == "BuildingFootprints") as FeatureLayer; if (footPrintLyr == null) { MessageBox.Show("Can't find layer: BuildingFootprint"); return; } var buildingLyr = MapView.Active.Map.GetLayersAsFlattenedList().FirstOrDefault(l => l.Name == "BuildingStructure") as FeatureLayer; if (buildingLyr == null) { MessageBox.Show("Can't find layer: BuildingStructure"); return; } // create the multipatch var mpb = await QueuedTask.Run <MultipatchBuilderEx>(() => { // get all selected lines and use them as the building footprint var footPrintSelection = footPrintLyr.GetSelection(); Polygon footPrint = null; int floorLevels = 1; #region Get Footprint and Floor levels foreach (var footprintOid in footPrintSelection.GetObjectIDs()) { // get the multipatch shape using the Inspector var insp = new Inspector(); insp.Load(footPrintLyr, footprintOid); footPrint = GeometryEngine.Instance.ReverseOrientation(insp.Shape as Multipart) as Polygon; floorLevels = (int)insp["Floors"]; } if (footPrint == null) { MessageBox.Show("No selected building footprint found"); return(null); } #endregion // Create the MultipatchBuilder using the building footprints and the floorlevels as height return(MyMultipatchBuilder.CreateTriangleMultipatchBuilder(footPrint, floorLevels)); }); // apply texture or material // create a builder to work on the multipatch geometry switch (Module1.SelectedTexture) { case "Glass": // create the textures for walls and roof BasicMaterial glassMaterialTexture = new BasicMaterial { TextureResource = glassTextureResource }; BasicMaterial roofMaterialTexture = new BasicMaterial { TextureResource = roofTextureResource }; // apply the texture materials to the patches var patches = mpb.Patches; for (var iPatch = 0; iPatch < patches.Count; iPatch++) { if (iPatch == patches.Count - 1) { // roof patches[iPatch].Material = roofMaterialTexture; patches[iPatch].TextureCoords2D = textureCoords; } else { // walls patches[iPatch].Material = glassMaterialTexture; patches[iPatch].TextureCoords2D = textureCoords; } } break; case "Red-solid": // create some materials var materialRed = new BasicMaterial { Color = System.Windows.Media.Colors.Brown }; // apply the materials to the patches for (var iPatch = 0; iPatch < mpb.Patches.Count; iPatch++) { if (iPatch == mpb.Patches.Count - 1) { // roof mpb.Patches[iPatch].Material = materialGray; } else { // walls mpb.Patches[iPatch].Material = materialRed; } } break; case "Gray-solid": // create some materials var materialSilver = new BasicMaterial { Color = System.Windows.Media.Colors.Silver }; // apply the materials to the patches for (var iPatch = 0; iPatch < mpb.Patches.Count; iPatch++) { if (iPatch == mpb.Patches.Count - 1) { // roof mpb.Patches[iPatch].Material = materialGray; } else { // walls mpb.Patches[iPatch].Material = materialSilver; } } break; } // create a new feature using the multipatch bool result = await QueuedTask.Run(() => { // track the newly created objectID long newObjectID = -1; var op = new EditOperation { Name = "Create multipatch feature", SelectNewFeatures = false }; Module1.NewMultipatch = mpb.ToGeometry() as Multipatch; op.Create(buildingLyr, Module1.NewMultipatch, oid => newObjectID = oid); if (op.Execute()) { // save the oid in the module for other commands to use Module1.NewMultipatchOID = newObjectID; return(true); } var msg = op.ErrorMessage; return(false); }); }