public static BitmapSource BuildOptTexture(Texture texture, int paletteIndex = TextureUtils.DefaultPalette, int level = 0) { if (texture == null || paletteIndex < 0 || paletteIndex > 15 || level < 0 || level >= texture.MipmapsCount) return null; int bpp = texture.BitsPerPixel; if (bpp == 8) { var palette = new BitmapPalette(Enumerable.Range(0, 256) .Select(i => { ushort c = BitConverter.ToUInt16(texture.Palette, paletteIndex * 512 + i * 2); byte r = (byte)((c & 0xF800) >> 11); byte g = (byte)((c & 0x7E0) >> 5); byte b = (byte)(c & 0x1F); r = (byte)((r * (0xffU * 2) + 0x1fU) / (0x1fU * 2)); g = (byte)((g * (0xffU * 2) + 0x3fU) / (0x3fU * 2)); b = (byte)((b * (0xffU * 2) + 0x1fU) / (0x1fU * 2)); return Color.FromRgb(r, g, b); }) .ToList()); int texWidth; int texHeight; byte[] texImageData = texture.GetMipmapImageData(level, out texWidth, out texHeight); int size = texWidth * texHeight; byte[] imageData = new byte[size * 4]; for (int i = 0; i < size; i++) { int colorIndex = texImageData[i]; imageData[i * 4 + 0] = palette.Colors[colorIndex].B; imageData[i * 4 + 1] = palette.Colors[colorIndex].G; imageData[i * 4 + 2] = palette.Colors[colorIndex].R; imageData[i * 4 + 3] = texture.AlphaData == null ? (byte)255 : texture.AlphaData[i]; } return BitmapSource.Create(texWidth, texHeight, 96, 96, PixelFormats.Bgra32, null, imageData, texWidth * 4); } else if (bpp == 32) { int texWidth; int texHeight; byte[] texImageData = texture.GetMipmapImageData(level, out texWidth, out texHeight); return BitmapSource.Create(texWidth, texHeight, 96, 96, PixelFormats.Bgra32, null, texImageData, texWidth * 4); } else { return null; } }
private void ExecuteSaveAsCommand(Texture texture) { if (texture == null) { return; } BusyIndicatorService.Run(() => { string fileName = FileDialogService.GetSaveTextureFileName(texture.Name); if (fileName == null) { return; } try { texture.Save(fileName); } catch (Exception ex) { Messenger.Instance.Notify(new MessageBoxMessage(texture.Name, ex)); } }); }
private void ExecuteReplaceMapCommand(Texture texture) { if (texture == null) { return; } BusyIndicatorService.Run(dispatcher => { string fileName = FileDialogService.GetOpenTextureFileName(texture.Name); if (fileName == null) { return; } try { var newTexture = Texture.FromFile(fileName); newTexture.Name = texture.Name; this.OptModel.File.Textures[newTexture.Name] = newTexture; dispatcher(() => this.OptModel.File = this.OptModel.File); } catch (Exception ex) { Messenger.Instance.Notify(new MessageBoxMessage(texture.Name, ex)); } }); }
private void ExecuteReplaceAlphaMapCommand(Texture texture) { if (texture == null) { return; } BusyIndicatorService.Run(dispatcher => { string name = texture.Name + "_alpha"; string fileName = FileDialogService.GetOpenTextureFileName(name); if (fileName == null) { return; } try { this.OptModel.File.Textures[texture.Name].SetAlphaMap(fileName); dispatcher(() => this.OptModel.File = this.OptModel.File); } catch (Exception ex) { Messenger.Instance.Notify(new MessageBoxMessage(name, ex)); } }); }
private static Texture GetFileBitmap(Bitmap image) { var rect = new Rectangle(0, 0, image.Width, image.Height); int length = image.Width * image.Height; byte[] bytes = new byte[length * 4]; using (var bitmap = image.Clone(rect, PixelFormat.Format32bppArgb)) { var data = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat); try { Marshal.Copy(data.Scan0, bytes, 0, length * 4); } finally { bitmap.UnlockBits(data); } } byte[] alphaData = new byte[length]; bool hasAlpha = false; for (int i = 0; i < length; i++) { byte a = bytes[i * 4 + 3]; alphaData[i] = a; if (a != (byte)255) { hasAlpha = true; } } var texture = new Texture(); texture.Width = image.Width; texture.Height = image.Height; texture.ImageData = bytes; texture.AlphaData = hasAlpha ? alphaData : null; texture.Palette = new byte[8192]; return texture; }
public static bool AreEquals(Texture textureA, Texture textureB) { if (textureA == null || textureB == null) { return false; } if (textureA.Width == 0 || textureA.Height == 0 || textureA.ImageData == null) { return false; } if (textureB.Width == 0 || textureB.Height == 0 || textureB.ImageData == null) { return false; } if (textureA.Width != textureB.Width) { return false; } if (textureA.Height != textureB.Height) { return false; } if ((textureA.Palette != null) != (textureB.Palette != null)) { return false; } if (textureA.Palette != null) { if (textureA.Palette.Length != textureB.Palette.Length) { return false; } for (int i = 0; i < textureA.Palette.Length; i++) { if (textureA.Palette[i] != textureB.Palette[i]) { return false; } } } if (textureA.ImageData.Length != textureB.ImageData.Length) { return false; } for (int i = 0; i < textureA.ImageData.Length; i++) { if (textureA.ImageData[i] != textureB.ImageData[i]) { return false; } } if ((textureA.AlphaData != null) != (textureB.AlphaData != null)) { return false; } if (textureA.AlphaData != null) { if (textureA.AlphaData.Length != textureB.AlphaData.Length) { return false; } for (int i = 0; i < textureA.AlphaData.Length; i++) { if (textureA.AlphaData[i] != textureB.AlphaData[i]) { return false; } } } return true; }
public static OptFile An8ToOpt(string an8Path, bool scale) { string an8Directory = Path.GetDirectoryName(an8Path); var an8 = An8File.FromFile(an8Path); var opt = new OptFile(); foreach (var mesh in an8.Objects .SelectMany(t => t.Components) .SelectMany(t => Converter.EnumMeshes(t))) { var optMesh = new Mesh(); opt.Meshes.Add(optMesh); if (scale) { foreach (var v in mesh.Points) { optMesh.Vertices.Add(new Vector(v.X / OptFile.ScaleFactor, v.Z / OptFile.ScaleFactor, v.Y / OptFile.ScaleFactor)); } } else { foreach (var v in mesh.Points) { optMesh.Vertices.Add(new Vector(v.X, v.Z, v.Y)); } } foreach (var v in mesh.TexCoords) { optMesh.TextureCoordinates.Add(new TextureCoordinates(v.U, -v.V)); } foreach (var v in mesh.Normals) { optMesh.VertexNormals.Add(new Vector(v.X, v.Z, v.Y)); } optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 0)); optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 0)); optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 1)); optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 1)); var optLod = new MeshLod(); optMesh.Lods.Add(optLod); foreach (var face in mesh.Faces) { if (face.PointIndexes.Length < 3) { continue; } bool isQuad = face.PointIndexes.Length > 3; var optFaceGroup = new FaceGroup(); optLod.FaceGroups.Add(optFaceGroup); var materialName = mesh.MaterialList.ElementAtOrDefault(face.MaterialIndex); if (!string.IsNullOrEmpty(materialName)) { optFaceGroup.Textures.Add(materialName); } Index verticesIndex = new Index( face.PointIndexes[0], face.PointIndexes[1], face.PointIndexes[2], isQuad ? face.PointIndexes[3] : -1); if (verticesIndex.A >= optMesh.Vertices.Count) { verticesIndex.A = 0; } if (verticesIndex.B >= optMesh.Vertices.Count) { verticesIndex.B = 0; } if (verticesIndex.C >= optMesh.Vertices.Count) { verticesIndex.C = 0; } if (verticesIndex.D >= optMesh.Vertices.Count) { verticesIndex.D = 0; } Index textureCoordinatesIndex = new Index( face.TexCoordIndexes[0], face.TexCoordIndexes[1], face.TexCoordIndexes[2], isQuad ? face.TexCoordIndexes[3] : -1); if (textureCoordinatesIndex.A >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.A = 0; } if (textureCoordinatesIndex.B >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.B = 0; } if (textureCoordinatesIndex.C >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.C = 0; } if (textureCoordinatesIndex.D >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.D = 0; } Index vertexNormalsIndex = new Index( face.NormalIndexes[0], face.NormalIndexes[1], face.NormalIndexes[2], isQuad ? face.NormalIndexes[3] : -1); if (vertexNormalsIndex.A >= optMesh.VertexNormals.Count) { vertexNormalsIndex.A = 0; } if (vertexNormalsIndex.B >= optMesh.VertexNormals.Count) { vertexNormalsIndex.B = 0; } if (vertexNormalsIndex.C >= optMesh.VertexNormals.Count) { vertexNormalsIndex.C = 0; } if (vertexNormalsIndex.D >= optMesh.VertexNormals.Count) { vertexNormalsIndex.D = 0; } if (textureCoordinatesIndex.A < 0 || textureCoordinatesIndex.B < 0 || textureCoordinatesIndex.C < 0 || (verticesIndex.D >= 0 && textureCoordinatesIndex.D < 0)) { textureCoordinatesIndex.A = optMesh.TextureCoordinates.Count - 4; textureCoordinatesIndex.B = optMesh.TextureCoordinates.Count - 3; textureCoordinatesIndex.C = optMesh.TextureCoordinates.Count - 2; textureCoordinatesIndex.D = verticesIndex.D < 0 ? -1 : optMesh.TextureCoordinates.Count - 1; } Vector normal = Vector.Normal( optMesh.Vertices.ElementAtOrDefault(verticesIndex.A), optMesh.Vertices.ElementAtOrDefault(verticesIndex.B), optMesh.Vertices.ElementAtOrDefault(verticesIndex.C)); if (vertexNormalsIndex.A < 0 || vertexNormalsIndex.B < 0 || vertexNormalsIndex.C < 0 || (verticesIndex.D >= 0 && vertexNormalsIndex.D < 0)) { optMesh.VertexNormals.Add(normal); vertexNormalsIndex.A = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.B = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.C = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.D = verticesIndex.D < 0 ? -1 : optMesh.VertexNormals.Count - 1; } var optFace = new Face() { VerticesIndex = verticesIndex, TextureCoordinatesIndex = textureCoordinatesIndex, VertexNormalsIndex = vertexNormalsIndex, Normal = normal }; optFaceGroup.Faces.Add(optFace); } } opt.CompactBuffers(); opt.ComputeHitzones(); foreach (var material in an8.Materials .Concat(an8.Objects.SelectMany(t => t.Materials)) .Where(t => t.FrontSurface != null) .Select(t => new { Name = t.Name, Diffuse = t.FrontSurface.Diffuse, Alpha = t.FrontSurface.Alpha })) { Texture texture; var an8Texture = material.Diffuse.TextureName != null ? an8.Textures.FirstOrDefault(t => string.Equals(t.Name, material.Diffuse.TextureName, StringComparison.Ordinal)) : null; if (an8Texture == null) { byte r = material.Diffuse.Red; byte g = material.Diffuse.Green; byte b = material.Diffuse.Blue; int width = 8; int height = 8; int length = width * height; byte[] data = new byte[length * 4]; for (int i = 0; i < length; i++) { data[i * 4 + 0] = b; data[i * 4 + 1] = g; data[i * 4 + 2] = r; data[i * 4 + 3] = 255; } texture = new Texture(); texture.Name = material.Name; texture.Width = width; texture.Height = height; texture.ImageData = data; } else { string colorFileName = Path.Combine(an8Directory, Path.GetFileName(an8Texture.Files[0])); texture = Texture.FromFile(colorFileName); texture.Name = material.Name; } if (material.Alpha > 0 && material.Alpha < 255) { byte alpha = (byte)material.Alpha; int length = texture.Width * texture.Height; byte[] alphaData = new byte[length]; var data = texture.ImageData; for (int i = 0; i < length; i++) { alphaData[i] = alpha; data[i * 4 + 3] = alpha; } texture.AlphaData = alphaData; } opt.Textures.Add(texture.Name, texture); } opt.GenerateTexturesMipmaps(); return opt; }
public static OptFile ObjToOpt(string objPath, bool scale) { string objDirectory = Path.GetDirectoryName(objPath); var obj = ObjFile.FromFile(objPath); var opt = new OptFile(); foreach (var mesh in obj.Meshes) { var optMesh = new Mesh(); opt.Meshes.Add(optMesh); if (scale) { foreach (var v in obj.Vertices) { optMesh.Vertices.Add(new Vector(v.X / OptFile.ScaleFactor, v.Z / OptFile.ScaleFactor, v.Y / OptFile.ScaleFactor)); } } else { foreach (var v in obj.Vertices) { optMesh.Vertices.Add(new Vector(v.X, v.Z, v.Y)); } } foreach (var v in obj.VertexTexCoords) { optMesh.TextureCoordinates.Add(new TextureCoordinates(v.U, -v.V)); } foreach (var v in obj.VertexNormals) { optMesh.VertexNormals.Add(new Vector(v.X, v.Z, v.Y)); } optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 0)); optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 0)); optMesh.TextureCoordinates.Add(new TextureCoordinates(1, 1)); optMesh.TextureCoordinates.Add(new TextureCoordinates(0, 1)); var optLod = new MeshLod(); optMesh.Lods.Add(optLod); foreach (var faceGroup in mesh.FaceGroups) { var optFaceGroup = new FaceGroup(); optLod.FaceGroups.Add(optFaceGroup); if (!string.IsNullOrEmpty(faceGroup.MaterialName)) { optFaceGroup.Textures.Add(faceGroup.MaterialName); } foreach (var face in faceGroup.Faces) { Index verticesIndex = new Index( face.VerticesIndex.A, face.VerticesIndex.B, face.VerticesIndex.C, face.VerticesIndex.D); if (verticesIndex.A >= optMesh.Vertices.Count) { verticesIndex.A = 0; } if (verticesIndex.B >= optMesh.Vertices.Count) { verticesIndex.B = 0; } if (verticesIndex.C >= optMesh.Vertices.Count) { verticesIndex.C = 0; } if (verticesIndex.D >= optMesh.Vertices.Count) { verticesIndex.D = 0; } Index textureCoordinatesIndex = new Index( face.VertexTexCoordsIndex.A, face.VertexTexCoordsIndex.B, face.VertexTexCoordsIndex.C, face.VertexTexCoordsIndex.D); if (textureCoordinatesIndex.A >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.A = 0; } if (textureCoordinatesIndex.B >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.B = 0; } if (textureCoordinatesIndex.C >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.C = 0; } if (textureCoordinatesIndex.D >= optMesh.TextureCoordinates.Count) { textureCoordinatesIndex.D = 0; } Index vertexNormalsIndex = new Index( face.VertexNormalsIndex.A, face.VertexNormalsIndex.B, face.VertexNormalsIndex.C, face.VertexNormalsIndex.D); if (vertexNormalsIndex.A >= optMesh.VertexNormals.Count) { vertexNormalsIndex.A = 0; } if (vertexNormalsIndex.B >= optMesh.VertexNormals.Count) { vertexNormalsIndex.B = 0; } if (vertexNormalsIndex.C >= optMesh.VertexNormals.Count) { vertexNormalsIndex.C = 0; } if (vertexNormalsIndex.D >= optMesh.VertexNormals.Count) { vertexNormalsIndex.D = 0; } if (textureCoordinatesIndex.A < 0 || textureCoordinatesIndex.B < 0 || textureCoordinatesIndex.C < 0 || (verticesIndex.D >= 0 && textureCoordinatesIndex.D < 0)) { textureCoordinatesIndex.A = optMesh.TextureCoordinates.Count - 4; textureCoordinatesIndex.B = optMesh.TextureCoordinates.Count - 3; textureCoordinatesIndex.C = optMesh.TextureCoordinates.Count - 2; textureCoordinatesIndex.D = verticesIndex.D < 0 ? -1 : optMesh.TextureCoordinates.Count - 1; } Vector normal = Vector.Normal( optMesh.Vertices.ElementAtOrDefault(verticesIndex.A), optMesh.Vertices.ElementAtOrDefault(verticesIndex.B), optMesh.Vertices.ElementAtOrDefault(verticesIndex.C)); if (vertexNormalsIndex.A < 0 || vertexNormalsIndex.B < 0 || vertexNormalsIndex.C < 0 || (verticesIndex.D >= 0 && vertexNormalsIndex.D < 0)) { optMesh.VertexNormals.Add(normal); vertexNormalsIndex.A = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.B = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.C = optMesh.VertexNormals.Count - 1; vertexNormalsIndex.D = verticesIndex.D < 0 ? -1 : optMesh.VertexNormals.Count - 1; } var optFace = new Face() { VerticesIndex = verticesIndex, TextureCoordinatesIndex = textureCoordinatesIndex, VertexNormalsIndex = vertexNormalsIndex, Normal = normal }; optFaceGroup.Faces.Add(optFace); } } } opt.CompactBuffers(); opt.ComputeHitzones(); foreach (var material in obj.Materials.Values) { Texture texture; if (material.DiffuseMapFileName == null) { var color = material.DiffuseColor; byte r = (byte)(color.X * 255.0f); byte g = (byte)(color.Y * 255.0f); byte b = (byte)(color.Z * 255.0f); int width = 8; int height = 8; int length = width * height; byte[] data = new byte[length * 4]; for (int i = 0; i < length; i++) { data[i * 4 + 0] = b; data[i * 4 + 1] = g; data[i * 4 + 2] = r; data[i * 4 + 3] = 255; } texture = new Texture(); texture.Name = material.Name; texture.Width = width; texture.Height = height; texture.ImageData = data; } else { string colorFileName = Path.Combine(objDirectory, material.DiffuseMapFileName); texture = Texture.FromFile(colorFileName); texture.Name = material.Name; } if (material.AlphaMapFileName != null) { string alphaFileName = Path.Combine(objDirectory, material.AlphaMapFileName); texture.SetAlphaMap(alphaFileName); } else if (material.DissolveFactor > 0.0f && material.DissolveFactor < 1.0f) { byte alpha = (byte)(material.DissolveFactor * 255.0f); int length = texture.Width * texture.Height; byte[] alphaData = new byte[length]; var data = texture.ImageData; for (int i = 0; i < length; i++) { alphaData[i] = alpha; data[i * 4 + 3] = alpha; } texture.AlphaData = alphaData; } opt.Textures.Add(texture.Name, texture); } opt.GenerateTexturesMipmaps(); return opt; }
public static BitmapSource BuildOptTextureAlpha(Texture texture) { if (texture == null || !texture.HasAlpha) { return null; } int size = texture.Width * texture.Height; byte[] imageData = new byte[size]; Array.Copy(texture.AlphaData, imageData, size); return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Gray8, null, imageData, texture.Width); }
public static BitmapSource BuildOptTexture(Texture texture, int paletteIndex) { if (texture == null || paletteIndex < 0 || paletteIndex > 15) { return null; } int size = texture.Width * texture.Height; int bpp = texture.BitsPerPixel; if (bpp == 8) { var palette = new BitmapPalette(Enumerable.Range(0, 256) .Select(i => { ushort c = BitConverter.ToUInt16(texture.Palette, paletteIndex * 512 + i * 2); byte r = (byte)((c & 0xF800) >> 11); byte g = (byte)((c & 0x7E0) >> 5); byte b = (byte)(c & 0x1F); r = (byte)((r * (0xffU * 2) + 0x1fU) / (0x1fU * 2)); g = (byte)((g * (0xffU * 2) + 0x3fU) / (0x3fU * 2)); b = (byte)((b * (0xffU * 2) + 0x1fU) / (0x1fU * 2)); return Color.FromRgb(r, g, b); }) .ToList()); //if (texture.AlphaData == null) //{ // byte[] imageData = new byte[size]; // Array.Copy(texture.ImageData, imageData, size); // return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Indexed8, palette, imageData, texture.Width); //} //else { byte[] imageData = new byte[size * 4]; for (int i = 0; i < size; i++) { int colorIndex = texture.ImageData[i]; imageData[i * 4 + 0] = palette.Colors[colorIndex].B; imageData[i * 4 + 1] = palette.Colors[colorIndex].G; imageData[i * 4 + 2] = palette.Colors[colorIndex].R; //imageData[i * 4 + 3] = texture.AlphaData[i]; imageData[i * 4 + 3] = texture.AlphaData != null ? texture.AlphaData[i] : (byte)255; } return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Bgra32, null, imageData, texture.Width * 4); } } else if (bpp == 32) { byte[] imageData = new byte[size * 4]; Array.Copy(texture.ImageData, imageData, size * 4); return BitmapSource.Create(texture.Width, texture.Height, 96, 96, PixelFormats.Bgra32, null, imageData, texture.Width * 4); } else { return null; } }
public static BitmapSource BuildOptTexture(Texture texture) { return TextureHelpers.BuildOptTexture(texture, TextureHelpers.DefaultPalette); }
private void CreateTexture(TextureNode textureNode) { if (textureNode.Name == null) { textureNode.Name = string.Format(CultureInfo.InvariantCulture, "Tex{0}", textureNode.UniqueId); } Texture texture = new Texture(); texture.Name = textureNode.Name; if (textureNode.Width == 0 || textureNode.Height == 0) { Texture id = this.Textures.Values .FirstOrDefault(t => t.Id == textureNode.UniqueId); if (id == null && this.Textures.Count != 0) { id = this.Textures.ElementAt(this.Textures.Count - 1).Value; } if (id == null) { throw new InvalidDataException("invalid 0x0 texture"); } texture.Id = id.Id; texture.Width = id.Width; texture.Height = id.Height; texture.Palette = id.Palette; texture.ImageData = id.ImageData; texture.AlphaData = id.AlphaData; } else { texture.Id = textureNode.UniqueId; texture.Width = textureNode.Width; texture.Height = textureNode.Height; texture.Palette = textureNode.Palettes; texture.ImageData = textureNode.Bytes; TextureAlphaNode alphaNode = (TextureAlphaNode)textureNode.Nodes .FirstOrDefault(t => t.NodeType == NodeType.TextureAlpha); if (alphaNode != null) { texture.AlphaData = alphaNode.Bytes; } } this.Textures.Add(texture.Name, texture); }
public static OptFile RhinoToOpt(string rhinoPath, bool scale) { string rhinoDirectory = Path.GetDirectoryName(rhinoPath); var opt = new OptFile(); using (var file = Rhino.FileIO.File3dm.Read(rhinoPath)) { float scaleFactor = scale ? (1.0f / OptFile.ScaleFactor) : 1.0f; if (file.Settings.ModelUnitSystem != Rhino.UnitSystem.Meters) { scaleFactor *= (float)Rhino.RhinoMath.UnitScale(file.Settings.ModelUnitSystem, Rhino.UnitSystem.Meters); scale = true; } var groups = file.Objects .Where(t => { using (var geometry = t.Geometry) { return geometry.ObjectType == Rhino.DocObjects.ObjectType.Mesh; } }) .GroupBy(t => { using (var attributes = t.Attributes) { return attributes.LayerIndex; } }) .ToList(); foreach (var group in groups) { var mesh = new Mesh(); opt.Meshes.Add(mesh); var lod = new MeshLod(); mesh.Lods.Add(lod); foreach (var obj in group) { var faceGroup = new FaceGroup(); lod.FaceGroups.Add(faceGroup); int baseIndex = mesh.Vertices.Count; using (var geometry = (Rhino.Geometry.Mesh)obj.Geometry) { if (scale) { foreach (var vertex in geometry.Vertices) { mesh.Vertices.Add(new Vector(vertex.X * scaleFactor, vertex.Y * scaleFactor, vertex.Z * scaleFactor)); } } else { foreach (var vertex in geometry.Vertices) { mesh.Vertices.Add(new Vector(vertex.X, vertex.Y, vertex.Z)); } } foreach (var texCoords in geometry.TextureCoordinates) { mesh.TextureCoordinates.Add(new TextureCoordinates(texCoords.X, -texCoords.Y)); } foreach (var normal in geometry.Normals) { mesh.VertexNormals.Add(new Vector(normal.X, normal.Y, normal.Z)); } foreach (var geoFace in geometry.Faces) { var face = new Face(); faceGroup.Faces.Add(face); Index index = geoFace.IsTriangle ? new Index(baseIndex + geoFace.C, baseIndex + geoFace.B, baseIndex + geoFace.A) : new Index(baseIndex + geoFace.D, baseIndex + geoFace.C, baseIndex + geoFace.B, baseIndex + geoFace.A); face.VerticesIndex = index; face.VertexNormalsIndex = index; face.TextureCoordinatesIndex = index; face.Normal = Vector.Normal(mesh.Vertices[index.A], mesh.Vertices[index.B], mesh.Vertices[index.C]); } } using (var attributes = obj.Attributes) { if (attributes.MaterialIndex != -1) { using (var material = file.Materials[attributes.MaterialIndex]) { faceGroup.Textures.Add(material.Name); } } } } } opt.CompactBuffers(); opt.ComputeHitzones(); for (int materialIndex = 0; materialIndex < file.Materials.Count; materialIndex++) { using (var material = file.Materials[materialIndex]) { if (opt.Textures.ContainsKey(material.Name)) { continue; } string colorMap = null; string alphaMap = null; using (var tex = material.GetBitmapTexture()) { if (tex != null && !string.IsNullOrEmpty(tex.FileName)) { colorMap = Path.GetFileName(tex.FileName); } } using (var tex = material.GetTransparencyTexture()) { if (tex != null && !string.IsNullOrEmpty(tex.FileName)) { alphaMap = Path.GetFileName(tex.FileName); } } Texture texture; if (colorMap == null) { var color = material.DiffuseColor; byte r = color.R; byte g = color.G; byte b = color.B; int width = 8; int height = 8; int length = width * height; byte[] data = new byte[length * 4]; for (int i = 0; i < length; i++) { data[i * 4 + 0] = b; data[i * 4 + 1] = g; data[i * 4 + 2] = r; data[i * 4 + 3] = 255; } texture = new Texture(); texture.Name = material.Name; texture.Width = width; texture.Height = height; texture.ImageData = data; } else { string colorFileName = Path.Combine(rhinoDirectory, colorMap); texture = Texture.FromFile(colorFileName); texture.Name = material.Name; } if (alphaMap != null) { string alphaFileName = Path.Combine(rhinoDirectory, alphaMap); texture.SetAlphaMap(alphaFileName); } else if (material.Transparency > 0.0 && material.Transparency < 1.0) { byte alpha = (byte)(material.Transparency * 255.0f); int length = texture.Width * texture.Height; byte[] alphaData = new byte[length]; var data = texture.ImageData; for (int i = 0; i < length; i++) { alphaData[i] = alpha; data[i * 4 + 3] = alpha; } texture.AlphaData = alphaData; } opt.Textures.Add(texture.Name, texture); } } opt.GenerateTexturesMipmaps(); } return opt; }