• WPF下的3d模型导出,从MeshGeometry3D 导出到 obj 文件


    MeshGeometry3D时WPF中的一种3d显示类,之前有人发帖解决了从3dmax文件自动生成MeshGeometry3D的方法(http://www.cnblogs.com/enjoyeclipse/archive/2012/03/21/2410439.html)。

    这里反其道而行发布一种将MeshGeometry3D模型导出到obj文件格式可以使用3dmax打开查看。

    内容如下:

      1 using System;
      2 using System.Collections.Generic;
      3 using System.Linq;
      4 using System.Text;
      5 using System.Windows.Media.Imaging;
      6 using System.IO;
      7 using System.Windows.Media.Media3D;
      8 using System.Windows;
      9 
     10 namespace ZUI.Tools
     11 {
     12     public class ObjWriter
     13     {
     14         MeshGeometry3D _model;
     15         BitmapSource _texture;
     16 
     17         const string SPLITER = "#==================================================================================================";
     18         const string STR_BETWEEN_BLOCKS = "\r\n\r\n\r\n\r\n";
     19 
     20         public ObjWriter(MeshGeometry3D modle, BitmapSource texture)
     21         {
     22             _model = modle;
     23             _texture = texture;
     24         }
     25 
     26         public void OutPut(string fileName,string fileSafeName)
     27         {
     28             CreatObj(fileName, fileSafeName);
     29             CreatMtl(fileName, fileSafeName);
     30             CreatReadMe(fileName, fileSafeName);
     31             CreatTexture(fileName);
     32         }
     33         public void CreatReadMe(string fileName, string fileSafeName)
     34         {
     35             FileStream fileStream = new FileStream(fileName + "Read Me.txt", FileMode.Create, FileAccess.ReadWrite);
     36             StreamWriter streamWriter = new StreamWriter(fileStream);
     37 
     38             streamWriter.WriteLine(SPLITER);
     39             streamWriter.WriteLine("#");
     40             streamWriter.WriteLine("#  Those files listed below is auto generated. Please DO NOT edit them !  ");
     41             streamWriter.WriteLine("#  You can run the first file in meshlab or 3dmax . But you MUST have all those THREE files !");
     42             streamWriter.WriteLine("#  If you have more question please send e-mail to \"zhao_chenhui_scu@163.com\".");
     43             streamWriter.WriteLine("#");
     44             streamWriter.WriteLine("#  1. " + fileSafeName);
     45             streamWriter.WriteLine("#  2. " + fileSafeName+".bmp");
     46             streamWriter.WriteLine("#  3. " + fileSafeName+".mtl");
     47             streamWriter.WriteLine("#");
     48             streamWriter.WriteLine("#  Thank you ! And have a nice day !");
     49             streamWriter.WriteLine("#  Generated Time : " + DateTime.Now.ToString());
     50             streamWriter.WriteLine(SPLITER);
     51 
     52             streamWriter.Flush();
     53             streamWriter.Close();
     54             fileStream.Close();
     55         }
     56 
     57         private void CreatTexture(string fileName)
     58         {
     59             FileStream fileStream = new FileStream(fileName + ".bmp", FileMode.Create, FileAccess.ReadWrite);
     60 
     61             BmpBitmapEncoder encoder = new BmpBitmapEncoder();
     62             encoder.Frames.Add(BitmapFrame.Create(_texture)) ;
     63             encoder.Save(fileStream);
     64 
     65             fileStream.Close();
     66         }
     67 
     68         private void CreatMtl(string fileName, string fileSafeName)
     69         {
     70             FileStream fileStream = new FileStream(fileName + ".mtl", FileMode.Create, FileAccess.ReadWrite);
     71             StreamWriter streamWriter = new StreamWriter(fileStream);
     72 
     73             streamWriter.WriteLine(SPLITER);
     74             streamWriter.WriteLine("#");
     75             streamWriter.WriteLine("# Warming        : This file is auto generated . Please DO NOT edit it ! ");
     76             streamWriter.WriteLine("#");
     77             streamWriter.WriteLine("# Generated Time : " + DateTime.Now.ToString());
     78             streamWriter.WriteLine("#");
     79             streamWriter.WriteLine("# Description    :You can open this file in meshlab or 3dmax .");
     80             streamWriter.WriteLine("#                 If you have more question please send e-mail to \"zhao_chenhui_scu@163.com\".");
     81             streamWriter.WriteLine("#                 This file MUST work with other two files named:\"" + fileSafeName + "\" and \"" + fileSafeName + ".bmp\".");
     82             streamWriter.WriteLine("#");
     83             streamWriter.WriteLine(SPLITER);
     84             streamWriter.WriteLine(STR_BETWEEN_BLOCKS);
     85 
     86             streamWriter.WriteLine("newmtl mt1");
     87             streamWriter.WriteLine("Ka 0.0000 0.0000 0.0000");
     88             streamWriter.WriteLine("Kd 0.0000 0.0000 0.0000");
     89             streamWriter.WriteLine("Ks 0.0000 0.0000 0.0000");
     90             streamWriter.WriteLine("Ke 0.9725 0.9725 0.9725");
     91 
     92             streamWriter.WriteLine("map_Ka " + fileSafeName + ".bmp");
     93             streamWriter.WriteLine("map_Kd " + fileSafeName + ".bmp");
     94 
     95 
     96             streamWriter.Flush();
     97             streamWriter.Close();
     98             fileStream.Close();
     99         }
    100 
    101         private void CreatObj(string fileName, string fileSafeName)
    102         {
    103             FileStream fileStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
    104             StreamWriter streamWriter = new StreamWriter(fileStream);
    105 
    106             streamWriter.WriteLine(GetHeadString(fileSafeName));
    107             streamWriter.WriteLine(STR_BETWEEN_BLOCKS);
    108 
    109             streamWriter.WriteLine(GetMatralString(fileSafeName));
    110             streamWriter.WriteLine(STR_BETWEEN_BLOCKS);
    111 
    112             streamWriter.Write(GetVerticesString());
    113             streamWriter.WriteLine(STR_BETWEEN_BLOCKS);
    114 
    115             streamWriter.Write(GetTexturePointString());
    116             streamWriter.WriteLine(STR_BETWEEN_BLOCKS);
    117 
    118             streamWriter.Write(GetFaceString());
    119 
    120             streamWriter.Flush();
    121             streamWriter.Close();
    122             fileStream.Close();
    123         }
    124 
    125         private string GetHeadString(string fileSafeName)
    126         {
    127             StringBuilder result = new StringBuilder();
    128 
    129             result.AppendLine(SPLITER);
    130             result.AppendLine("#");
    131             result.AppendLine("# Warming        : This file is auto generated . Please DO NOT edit it ! ");
    132             result.AppendLine("#");
    133             result.AppendLine("# Generated Time : "+DateTime.Now.ToString());
    134             result.AppendLine("#");
    135             result.AppendLine("# Description    :You can open this file in meshlab or 3dmax .");
    136             result.AppendLine("#                 If you have more question please send e-mail to \"zhao_chenhui_scu@163.com\".");
    137             result.AppendLine("#                 This file MUST work with other two files named:\"" + fileSafeName + ".mtl\" and \""+fileSafeName+".bmp\".");
    138             result.AppendLine("#");
    139             result.AppendLine(SPLITER);
    140 
    141             return result.ToString();
    142         }
    143 
    144         private string GetMatralString(string fileSafeName)
    145         {
    146             StringBuilder result = new StringBuilder();
    147 
    148             result.AppendLine(SPLITER + "\r\n");
    149             result.AppendLine("#  Matral : 1  \r\n");
    150             result.AppendLine("mtllib " + fileSafeName + ".mtl");
    151             result.AppendLine("\r\n#  Matral End \r\n");
    152             result.AppendLine(SPLITER );
    153 
    154             return result.ToString();
    155         }
    156 
    157         private string GetVerticesString()
    158         {
    159             StringBuilder result = new StringBuilder();
    160 
    161             result.AppendLine(SPLITER+"\r\n");
    162             result.AppendLine("#  Vertices: "+ _model.Positions.Count + "\r\n");
    163 
    164             foreach (Point3D p in _model.Positions)
    165                result.AppendLine("v " + p.X + " " + p.Y + " " + p.Z);
    166 
    167             result.AppendLine("\r\n#  Vertices End");
    168             result.AppendLine("\r\n" + SPLITER);
    169 
    170             return result.ToString();
    171         }
    172 
    173         private string GetTexturePointString()
    174         {
    175             StringBuilder result = new StringBuilder();
    176 
    177             result.AppendLine(SPLITER + "\r\n");
    178             result.AppendLine("#  Texture Coordinates: " + _model.TextureCoordinates.Count + "\r\n");
    179 
    180             foreach(Point p in _model.TextureCoordinates)
    181                  result.AppendLine("vt " + p.X  + " " + p.Y + " 0");
    182 
    183 
    184             result.AppendLine("\r\n#  Texture Coordinates End");
    185             result.AppendLine("\r\n" + SPLITER);
    186 
    187             return result.ToString();
    188         }
    189 
    190         private string GetFaceString()
    191         {
    192             StringBuilder result = new StringBuilder();
    193 
    194             result.AppendLine(SPLITER + "\r\n");
    195             result.AppendLine("#  Faces: " + _model.TriangleIndices.Count/3 + "\r\n");
    196             result.AppendLine("usemtl mt1" + "\r\n");
    197 
    198             for (int i = 0; i < _model.TriangleIndices.Count - 1; i+=3)
    199             {
    200 
    201                 result.Append("f ");
    202 
    203                 int p1 = _model.TriangleIndices[i] + 1;
    204                 int p2 = _model.TriangleIndices[i + 1] + 1;
    205                 int p3 = _model.TriangleIndices[i + 2] + 1;
    206 
    207                 result.Append(p1 + "/" + p1 + " ");
    208                 result.Append(p2 + "/" + p2 + " ");
    209                 result.Append(p3 + "/" + p3 + " ");
    210 
    211                 result.AppendLine();
    212              }
    213 
    214             result.AppendLine("\r\n#  Faces End");
    215             result.AppendLine("\r\n" + SPLITER);
    216 
    217             return result.ToString();
    218         }
    219     }
    220 }

    使用方法如下:

     1  private void ObjOutPut_Click(object sender, RoutedEventArgs e)
     2         {
     3             try
     4             {
     5                 if (Modle == null || Modle.Geometry == null)
     6                 {
     7                     MessageBox.Show("模型不能为空");
     8                     return;
     9                 }
    10                 SaveFileDialog dialog = new SaveFileDialog();
    11                 dialog.Filter = "模型(*.obj)|*.obj";
    12                 dialog.FileName = Title;
    13                 dialog.Title = "保存模型";
    14 
    15                 double r = sliderrate.Value;
    16                 if (dialog.ShowDialog() == true)
    17                 {
    18                     ObjWriter ow = new ObjWriter(Modle.Geometry as MeshGeometry3D, _texture);
    19                     ow.OutPut(dialog.FileName,dialog.SafeFileName);
    20                     MessageBox.Show("Output Success !");
    21                 }
    22             }
    23             catch (Exception ex)
    24             {
    25                 MessageBox.Show(ex.Message);
    26             }
    27         }

    运行的结果导出4个文件

    全名如下:

    #  1. box.obj
    #  2. box.obj.bmp
    #  3. box.obj.mtl

    #  4.box.objRead Me.txt

    其中前三个是有用的可以用第一个导入3dMAX

    参考:

    http://www.cppblog.com/lovedday/archive/2008/06/13/53153.html obj文件结构

    http://hi.baidu.com/ab_xyz/blog/item/efff4fc518a11ba48326acbe.html  mtl文件结构

  • 相关阅读:
    观察者模式
    如何通过反射创建对象?
    java8新特性
    idea 常用快捷键--标蓝
    java多线程基础篇-01
    zookeeper单机版及操作
    redis和jedis常用api
    Mac连接服务器
    redis基本介绍及安装01
    docker 安装mobsf及部分命令01
  • 原文地址:https://www.cnblogs.com/GhostZCH/p/2549711.html
Copyright © 2020-2023  润新知