文章版权归博客园 BigCoder所有,转载请于明显位置标明原文作者及出处,以示尊重!!

原文出处:http://www.cnblogs.com/csyisong/archive/2009/09/01/1558051.html

想想研究3D MAX 的SDK已经有了不短的时间,真正算起来也有两个月了吧,但是讲到收获,确实不大。作为一个3D MAX二次开发的学习者,我首先学习了导出插件的编写,网上有很多参考资料,写的都差不多,可是都是写到关键的地方或者说比较模糊的地方就说不清楚了,今天我就结合自己所做的工作来讲讲3D MAX导出插件的编写心得。
     首先,需要做好如下的准备工作:
     1. 安装一个完整版本的3D MAX与Visual Stdio。
        我安装的是3D MAX 2009,最好是找一个完整的版本,因为完整的版本中有很多的学习资料与sdk供学习,很省事。3D MAX的二次开发对VS的要求是有一个对应关系的,在SDK文档中可以找到,3D MAX 2009对应的VS开发版本应该是VS 2005,确保电脑上已经安装了VS 2005。
     2.定制3D MAX plug-in向导。
        a.找到安装目录的3dsmaxPluginWizard文件夹(我的安装目录是C:/Program Files/Autodesk/3ds Max 9 SDK ),
          b.打开此目录下的MaxPluginWizard.vsz 文件,编辑ABSOLUTE  PATH参数为:

/maxsdk/howto/3dsmaxPluginWizard

Param="ABSOLUTE_PATH=C:/Program Files/Autodesk/3ds Max 9/SDK/maxsdk/howto/3dsmaxPluginWizard"

c.将3dsmaxPluginWizard文件夹下的三个文件3dsmaxPluginWizard.ico、3dsmaxPluginWizard.vsdir、3dsmaxPluginWizard.vsz拷贝到VS 2005安装目录的 VC  Projects 目录下,我电脑上的目录是C:/Program Files/Microsoft Visual Studio 8/VC/vcprojects。
          d.启动VS 2005,File-New Project,选择Visual C++就可以看到3ds max Plugin Wizard选项,说明定制成功。
      以上只是开发前的一些准备工作,都可以直接在3D MAX SDK的文档中直接找到,不过文档可都是英文的哦,要耐心的读下去
     在以上准备工作做好以后,就可以开始开发一个插件了,由简单到复杂,先做一个简单的插件程序。插件程序的编写有两种方法,一是用插件向导,就是刚才上面所说的;另一种是通过手工创建一个插件项目,在这里暂时只讨论用插件向导来开发,比较便捷,手工开发以后在补上。
     1.第一步,生成一个插件程序的工程,具体如下:
       a. 打开File —>New Project —>选择3ds max Plugin Wizard,输入project名字,如 “MyExport”。
       b. 进入Welcome to the 3ds max Plugin Wizard 画面,选择plugin type如图所示:
          
      c.这里显示各种插件类型,目前要做的是一个文件的导出插件,所以选择FileExport类型。
      d.下一步,再出现一个对话框        。     
      e.再下一步,设置一些路径,具体见图及注明。
              
      

    

Enter your MAXSDK path指的是3D MAX SDK的安装目录

Enter your Plugin output path 指的是生成插件文件.dll存放的目录,可以自己设置

Enter your 3dsmax.exe path指的是3D MAX的安装目录

2.项目生成以后,在MyExport.cpp文件中找到Ext(int n)函数,改为return _T("MY3D"), "MY3D"是根据自己的要求来添加的;
        找到ShortDesc()函数,改为return _T ("MyExportPlugin");

找到DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options)内添加:

AllocConsole();

_cprintf( "Export Begin/n" );//记得#include <conio.h>

3. 生成并调试你的插件,系统会执行3dsmax.exe以启动3ds Max,然后选择“文件”->”导出”,如果能看到"MyExportPlugin(*.My3D)"
                说明导出成功,然后定义一个导出文件的名称即可.这样一个空的导出插件就编写成功了!接下来请看: 3D MAX导出插件编写II

在3D MAX导出插件编写I中已经具有了一个插件程序的基本框架,但这还是远远不够的,接下来,我们对I中的程序来补充肌肉、注入血液。
      在正式写插件之前,也必须要弄清楚一些概念,比如说Node,Object,Mesh,Face,以及他们之间的关系,还有就是3D MAX场景的组织方式,关于这些内容我会专门安排一篇文章来进行归纳总结,请阅读:3D MAX中的重要概念及场景组织方式
      
在写程序之前,有一点必须弄明白的是,需要导出的什么数据,在这里,我们需要的导出的数据有:
      1.几何信息——顶点坐标、顶点法线向量、面法线向量、顶点颜色
      2.材质信息——基本材质信息(材质的Ambient、Diffuse、Specular、Shininess)、纹理信息(纹理图片的文件名)
      从读程序开始,首先找到程序的入口点DoExport()函数,在这个函数中有一个重要的类ExpInterface,在这个类中包含IScene这个类,这个类很关键,我们先看它在SDK 9.0中的描述:

Description:

Methods of this class may be used to enumerate the scene and to flag certain nodes in the scene. Nodes chosen by the plug-in may be flagged using the EnumTree() method. Selected nodes may be flagged using FlagFGSelected().         由上面的描述可以看出这个类的作用是列举场景中所有的Nodes,而这个功能是由函数EnumTree()实现的,而这个函数会在程序的入口处被调用。对于每个结点,都有一个ITreeEnumProc *proc对象来描述它,proc对象是作为EnumTree()的参数传递进去的,再看类ITreeEnumProc的描述:
 Description:

This is the callback object used by IScene::EnumTree(). To use it, derive a class from this class, and implement the callback method.

可见,这个类中对Node信息的获取就是通过callback()这个函数来实现的。这个函数的完整形式是:virtual int ITreeEnumProc::callback(INode* node)
      还有,由上面描述可知ITreeEnumProc这个类必须通过继承去实现其中的callback()函数才行,继承类MyTreeEnum如下:

有了这样类,剩下的导出数据的工作就都在这个函数中实现。 
       接下来,是一个callback函数的简单框架:

class MyTreeEnum : public ITreeEnumProc

{

public:

MyTreeEnum(void);

~MyTreeEnum(void);

public:

int callback( INode *node );

};

int MyTreeEnum::callback(INode *node)
{
ObjectState os = node->EvalWorldState(10);

if ( os.obj->CanConvertToType( Class_ID(TRIOBJ_CLASS_ID, 0) ) )
    {
        _cprintf( "TRIOBJECT %s/n", node->GetName());

Mtl *pMtl = node->GetMtl();

if ( pMtl )
        {
            _cprintf( "MATERIAL %s/n",pMtl->GetName() );

}
        return TREE_CONTINUE;
    }

if (os.obj)

{
        switch(os.obj->SuperClassID()) 
        {
            case CAMERA_CLASS_ID:

_cprintf( "CAMERA %s/n", node->GetName());

break;

case LIGHT_CLASS_ID:

_cprintf( "LIGHT %s/n", node->GetName());

break;

}
}
    return TREE_CONTINUE;
}


      而在程序的入口函数处需要修改一下:

int  MaxExportTest::DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options)
{
    MyTreeEnum tempProc;
    ei->theScene->EnumTree( &tempProc );
    return TRUE;
}

最后,编译它,开始调试,找一个有物体,材质,灯光,摄像机的场景进行导出,如果你能在控制台输出窗口看到每个结点的名字,说明你的代码成功了。

其实上面的代码部分不是自己的,作者分析的不错,我就直接copy过来了,见参考链接:http://www.cgsir.com/download/tut_files/3dsmax_export_plugin.htm

后面导出信息的代码,就自己写了一些,继续。
 

      1. 在SDK中有一个Mesh的概念,Node的几何信息都可以通过这个Mesh类获取到。在获取到TriObject对象后,获取Mesh对象就很容易了。
  Mesh* pMesh = &tri->GetMesh();

然后分别获取顶点信息、法向量信息、纹理坐标。

        Mesh *pMesh = &triobj->GetMesh();
        int VerticesNum = pMesh->getNumVerts();
        for ( int i=0; i<VerticesNum; i++ )
            {
                Point3     Coord,Normal,VColor,TCoord;
                int FaceNumber;
                //导出顶点坐标
                Coord = pMesh->getVert(i);
                
                //导出顶点的法向量
                pMesh->buildNormals();
                Normal = pMesh->getNormal(i);
                
                //导出顶点的纹理坐标
                TCoord = pMesh->tVerts[i];
             }

寥寥几行代码,就可以导出node的几何信息。除此,还需要导出node的材质信息,对于单纹理的node,可以简单的获取材质信息。

Code
//Access the material information 
Mtl* pMtl = inode->GetMtl();

if(pMtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0))
{    
   StdMat* std = (StdMat *)pMtl;
   //Access the ambient,diffuse,specular,shininess,emission 
   const MSTR& sMtlName = pMtl->GetName();
   Color m_Ambient = std->GetAmbient(0); 
   Color m_diffuse = std->GetDiffuse(0);
   Color m_specular = std->GetSpecular(0);
   float m_shininess = std->GetShininess(0);
   float m_shiniStrength = std->GetShinStr(0);
   if (pMtl->GetSelfIllumColorOn())
    {
        float r = pMtl->GetSelfIllumColor().r;
        float g = pMtl->GetSelfIllumColor().g;
        float b = pMtl->GetSelfIllumColor().b; 
        }
   else
       Texmap *tmap = pMtl->GetSubTexmap(ID_DI);
       if (tmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0))
    {
      BitmapTex *bmt = (BitmapTex*)tmap;
      if(bmt)
       {
        char* MapName = bmt->GetMapName();
       }
    }
}

以上获取的这些信息还只是孤立的数据,要想把这些数据组织起来,需要获取Mesh类中的Face信息。

 

 

 

不用去管这些Plugin Detail,会有默认路径的,

3D MAX导出插件编写相关推荐

  1. 3D MAX导出插件编写I

    3D MAX导出插件编写I 想想研究3D MAX 的SDK已经有了不短的时间,真正算起来也有两个月了吧,但是讲到收获,确实不大.作为一个3D MAX二次开发的学习者,我首先学习了导出插件的编写,网上有 ...

  2. 3ds max sdk导出插件编写的心得

    3ds max sdk导出插件编写的心得 作者:yhchinabest 来自:CG先生-3D图形插件开发网http://www.cgsir.com 写在前面 为什么要写这个心得?去年11月份的时候我写 ...

  3. 3DsMax导出插件编写(一)——vs2010和3dsmax2011(64位)的配置方法

    作为3D开发人员,特别是3D引擎开发人员,经常会接触到各种三维模型的数据.虽然说3dsmax已经可以导出很多格式的模型,不过总是不一定合适自己用.所以总有一种想自己写一个导出插件,让3dmax导出自己 ...

  4. 关于Max导出插件的七七八八

    介绍几个东西,如何在Max插件里使用.net来做界面,怎么为插件增加maxScript的脚本接口以及命令行参数来直接测试导出插件. 先说第一个,首先是visualstudio的项目设置里开启clr的支 ...

  5. 3DsMax导出插件编写(三)——使用IGame收集模型信息

    之前介绍过用SDK的常规方法来获取模型的网格信息.这里再介绍另外一种方法. MaxSdk里面带了一个叫做IGame的包,里面包含有很多方便我们获取模型信息的方法.在sdk的自带例子里面,同样也有这个I ...

  6. VS2010插件编写学习总结

    VS2010 Addins 外接程序(插件)开发 http://www.cnblogs.com/Leo_wl/archive/2013/03/21/2973886.html 简单做了一个添加文件头注视 ...

  7. 使用Axe_free_v2.2.5_max2018.dle插件从3d max中导出.x文件

    怎么说呢,先前一直在网上搜导出x文件的插件和使用方法,但是搜到的大多都是panda插件,而panda插件呢又只有2012的好像,后面就没有了,所以没有办法,然后找到了AxeFree 这个插件.下载网站 ...

  8. 三维建模软件的插件安装教程——3D Max

    大家在使用三维建模软件3D Max的时候一定遇到过插件不知道如何安装的情况,今天我将把常用插件的类型和扩展名罗列如下方便大家安装收集也算抛砖引玉望各位高手查漏补缺不吝赐教. 3DSMAX的插件名后缀主 ...

  9. 3DMAX导出插件的编写

    原文链接: http://liweizhaolili.blog.163.com/blog/static/162307442013117731953/ 作为3D开发人员,特别是3D引擎开发人员,经常会接 ...

最新文章

  1. 套娃成功!在《我的世界》里运行Win95、玩游戏,软件和教程现已公开
  2. HDFS设计思路,HDFS使用,查看集群状态,HDFS,HDFS上传文件,HDFS下载文件,yarn web管理界面信息查看,运行一个mapreduce程序,mapreduce的demo
  3. 从Visual Studio中生成Linux设备
  4. mysql命令行导入和导出数据
  5. Debian系linux系统常用配置软件源
  6. iOS设计模式——委托(delegate)
  7. 树莓派7寸触屏,略贵
  8. 服务器虚拟化的重要性,服务器虚拟化:虚拟机迁移的重要性
  9. 蓝牙、Wi-Fi音箱音频功放
  10. webservice的接口测试工具
  11. JAVA——判断多选题的对错
  12. “统计套利”是怎么玩的?可以稳定获利吗?
  13. 获取滚动条滚动距离兼容写法
  14. Oracle CTAS
  15. 一一数落2006几大“恶心”事件
  16. 开发用于互操作性的应用程序_云标准:确保云应用互操作性的工具
  17. 火车头按照关键词采集文章的平台有哪些?亲测实录!
  18. C语言三个数取中间值
  19. HDU 6595. Everything Is Generated In Equal Probability (期望+逆元)
  20. 企业全方位改进(CMMI)咨询服务

热门文章

  1. 表单标签 input
  2. 接口缺方法调用时报错_TypeScript真香系列——接口篇
  3. 分布式系统面试连环炮
  4. 接触网作业车司机许新峰的春运
  5. JsChart组件使用
  6. 《机器人编程实战》一一1.2 给机器人指令
  7. swift获取图片像素颜色值
  8. Centos5.5系统备份
  9. iOS 开发笔记-加载/初始化
  10. Maven 实现依赖框架jar包的版本管理