3D MAX导出插件编写

2023-11-03

[转]3D MAX导出插件编写

2011-6-9阅读1667 评论0

文章版权归博客园 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,可以简单的获取材质信息。


//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,会有默认路径的,

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

3D MAX导出插件编写 的相关文章

  • 图象:sine(正弦)、cosine(余弦)与Tangent(正切)

    http www 97ae com aebiaodashi geometry trig graphs html 目录 矢量加法 距离与长度 三角函数 图象 正弦 余弦与正切 圆周函数 简谐运动 频率与振幅 波形加法与乘法 反函数 其他材料
  • 码农干货系列【1】--方向包围盒(OBB)碰撞检测

    码农干货系列 1 方向包围盒 OBB 碰撞检测 2012 06 07 11 40 by 当耐特 9251 阅读 20 评论 收藏 编辑 干货 最近一直在删文章 不是要关博洗手什么的 而是被删的文章没有达到 干货 的标准 干货的反义词是水货
  • 使用CopperCube(IrrEdit)创建Irrlicht场景

    使用CopperCube IrrEdit 创建Irrlicht场景 标签 Irrlicht游戏引擎 2013 11 22 19 32 3384人阅读 评论 7 收藏 举报 分类 Irrlicht 13 版权声明 本文为博主原创文章 未经博主
  • 成功编译RenderingPluginExample53的cpp项目的步骤

    备忘 unity中调用d3d功能的示例项目 两个方面的配置 1 为了在项目中能够找到d3d12 h d3d11 h d3d9 h等 做如下操作 在项目属性中 VC 目录 包含目录 中添加 C Program Files x86 Window
  • 高级纹理映射技术(6)

    高级纹理映射技术 6 对一些特殊的应用需要对纹理坐标进行处理 主要包括纹理坐标自动生成和纹理坐标变换 下图显示了纹理坐标的来源 处理过程以及到达光栅处理器的过程 纹理坐标自动生成 在Direct3D程序中 不仅可以在模型载入阶段或渲染阶段指
  • win10 graphedit存储的路径

    如果安装郭windows SDK的话 可能的存储位置为C Program Files x86 Windows Kits 10 bin x86 C Program Files x86 Windows Kits 10 bin x64
  • fvf采用另外一种方式渲染

    if FAILED hr getActiveD3D9Device gt SetVertexDeclaration d3ddecl gt getD3DVertexDeclaration getGlobalInstanceVertexBuffe
  • Ogre:Hardwarebuffer

    Ogre Hardwarebuffer 分类 OGRE 2012 07 03 15 56 1097人阅读 评论 0 收藏 举报 buffer float byte 存储 图形 upload Ogre中的硬件缓存是指在显卡上的存储 这和在内存
  • D3D9Texture::_loadNormTex

    D3D9Texture loadNormTex D3D9Texture loadImpl
  • d3dUtility.cpp 统一回答:在vs2015中调试D3D9龙书 代码示例:4.4 d3dUtility.cpp

    龙书d3d9的代码 在作者的资源中 可查找 免分 注意 如果可能的话 请先安装DXSDK Jun10 exe 然后再安装VS2010或VS2015 否则 会在安装DXSDK Jun10 exe的过程的最后阶段会报错 不过 即使是报错 也不影
  • 深入理解Direct3D9

    String Of Brilliant Blue QQ群 8082814 随笔 34 文章 32 评论 136 博客园 首页 新随笔 联系 管理 深入理解Direct3D9 深入理解D3D9对图形程序员来说意义重大 我把以前的一些学习笔记都
  • GT1030和730哪个好?GT1030与GT730区别对比 (全文)

    对于显卡硬件厂商来说 当属NVIDIA可谓异常活跃 我们知道在游戏领域 N卡一直占据着绝大部分市场 旗下的显卡定位也非常明确 如最新的10系显卡 今年5月份NVIDIA低调发布了定位入门级显卡 GT1030 这款显卡上市之后立马引起了不少玩
  • 关于visual studio中的$(ConfigurationName)疑问

    关于visual studio中的 ConfigurationName 疑问 2012 12 02 16 09 15 转载 标签 it 分类 程序员之路 关于vs中的各种路径的值de查看方法 来源 http social msdn micr
  • Texture::getSourceFileType()

    Texture getSourceFileType
  • cocos2d-x 卡牌翻牌效果的实现

    cocos2d x 卡牌翻牌效果的实现 2012年07月25日 综合 共 3085字 字号 小 中 大 评论关闭 猴子原创 欢迎转载 转载请注明 转载自Cocos2D开发网 Cocos2Dev com 谢谢 原文地址 http www co
  • mesa 教程

    只有这个是靠谱的 Compiling and Installing The Mesa 3D Graphics Library latest documentation
  • 三维旋转:旋转矩阵,欧拉角,四元数

    在介绍下面的文章前 大家如果接触到欧拉角的话 就一定要关注一个词 要顺规 在欧拉角体系里面 有12种顺规 这一点是好多文章没有让读书意识到 导致后面学习图形学里面的 heading pitch bank 时对不上号 一般百度百科里面说到的
  • Ogre引擎源码——资源之Skeleton

    Ogre引擎源码 资源之Skeleton 分类 OGRE 游戏开发 引擎开发 图形引擎 游戏引擎 2012 09 21 06 17 1231人阅读 评论 0 收藏 举报 引擎 animation vector binding pointer
  • OpenGL图形管线和坐标变换

    1 OpenGL 渲染管线 OpenGL渲染管线分为两大部分 模型观测变换 ModelView Transformation 和投影变换 Projection Transformation 做个比喻 计算机图形开发就像我们照相一样 目的就是
  • opengl 学习<二>

    opengl 学习 lt 二 gt 在学习opengl过程中 我是用了 交互式的计算机图形学 自顶向下的分析 这本书着实不错 是一本理论兼opengl实践的图形学教程 在学习上 我总会是杂乱无章的学 为什么呢 我一般是在需要某个理论的时候才

随机推荐

  • Nginx具体配置(三)

    一 Nginx配置实例 反向代理 实例一 1 1 实现效果 在Windows浏览器地址栏中输入www 123 com 跳转到Linux系统中的tomcat主页面 访问Nginx 192 168 92 130 80 访问Tomcat 192
  • 在colab上部署novelAI

    目录 一 获取模型 1 使用他人提供的模型链接直接在Google云端硬盘中添加快捷连接 推荐 2 自己上传模型到Google云端硬盘 二 colab上进行操作 第一步 加载Google云盘 第二步 克隆git仓库 第三步 安装依赖 第四步
  • Spring Boot 学习研究笔记(十七) -Spring boot JPA的复杂查询

    Spring boot JPA的复杂查询 一 JpaSpecificationExecutor 接口查询方式 1 JpaSpecificationExecutor接口 JPA 提供动态接口JpaSpecificationExecutor 利
  • JavaScript 算法 -- 贪心算法

    文章目录 贪心算法 例题一 分饼干 例题二 买卖股票的最佳时机 II 贪心算法 贪心算法是算法设计的一种方法 期盼通过每个阶段的局部最优选择 从而达到全局的最优 但最后的结果不一定最优 例题一 分饼干 param number g 胃口 p
  • 【机器学习算法】感知机模型

    文章目录 1 感知机模型 2 收敛性证明 Novikoff定理 3 感知机对偶形式 4 感知机的缺点 5 感知机的几个变形 5 1 投票感知机 5 2 平均感知机 1 感知机模型 感知机模型是一个二分类的模型 它通过形如 y w x
  • 前后端交互之解决跨域问题!!!!

    报错 XMLHttpRequest cannot load http 127 0 0 1 8080 detail all No Access Control Allow Origin header is present on the req
  • 小娜老师的讲义-Docker的管理工具们(Kubernetes)

    Kubernetes k8s 是自动化容器操作的开源平台 这些操作包括部署 调度和节点集群间扩展 如果你曾经用过Docker容器技术部署容器 那么可以将Docker看成Kubernetes内部使用的低级别组件 Kubernetes不仅仅支持
  • Python学习--函数与Lambda表达式

    链接 DataWhale函数与Lambda表达式 目录 1 函数 函数的定义 函数的调用 函数的返回值 函数文档及注解 函数参数 1 位置参数 2 默认参数 3 可变参数 4 关键字参数 5 命名关键字参数 6 参数组合 变量作用域 内嵌函
  • 一个能干掉90%候选人的Kafka面试连环炮!

    V xin ruyuanhadeng获得600 页原创精品文章汇总PDF 目录 1 写在前面 2 如何保证宕机时数据不丢失 3 多副本冗余的高可用机制 4 多副本之间数据如何同步 5 ISR到底指的什么东西 6 acks参数的含义 7 最后
  • Less 18 (请求头注入--user-agent注入)

    文章目录 1 题目分析 2 构造SQL 3 手工注入 4 使用python进行注入 5 SQLmap注入 1 题目分析 首先我们来分析一下题目 经过尝试 我们知道 当我们输入正确的用户名和密码的时候 后台会将User Agent返回到屏幕上
  • 全国计算机等级考试题库二级C操作题100套(第89套)

    第89套 给定程序中 函数fun的功能是 求出形参ss所指字符串数组中最长字符串的 长度 其余字符串左边用字符 补齐 使其与最长的字符串等长 字符串数组中共 有M个字符串 且串长
  • 正点STM32F407核心板+ESP8266实现简单通信(详细讲解)

    1 ESP8266固件库的烧录 如果用串口助手连上板子 给8266发送AT指令发现老是报错error 可以重新烧录一下固件库 正点的ESP8266资料下载网址 http www openedv com thread 308397 1 1 h
  • tcp连接多久会自动断开_K8s 节点断开连接后,本在运行的 Pod 会如何?

    在工作节点与主节点断开连接后 工作节点上的 Pod 是什么状态 是否在继续运行 Kubernetes 控制器又在做什么 本文对此进行了实例研究 一一解答 作者 Bhargav Bhikkaji 翻译 Bach 才云 校对 星空下的文仔 才云
  • 微信小程序云开发之初体验(详细教程)

    微信小程序云开发之初体验 小程序云开发是微信最近推出的新的一项能力 它弱化了后端以及运维的概念 开发者无需搭建服务器 使用微信平台提供的api即可完成核心的业务开发 目前提供三大基础能力支持 云函数 在云端运行的代码 微信私有协议天然鉴权
  • 刷脸支付普及逐渐攀升产业生态逐渐形成

    刷脸让支付生态重返硬件年代 刷脸支付机具的生产 销售 铺设 维护涉及大量成本 客观存在压货风险大 后期服务难 地推成本高等问题 模式重而受益低 导致银行和大多数中小支付机构入局刷脸支付的意愿则整体薄弱得多 银联高调入局之际 2019 也是支
  • 《啊哈算法》学习——桶排序

    学习啊哈算法第一天 第一章第一节最快最简单的桶排序 问题描述 班级五名同学的分数排序 十分制 问题分析及思路 借助大小为10的一维数组 初始化为0 意味该分数没有人得 接下来处理分数 如有两个人得5分 即将a 5 2 记录下分数即出现次数后
  • Spring Validation 接口入参校验

    一 前言 JSR 是 Java Specification Requests 的缩写 含义为 JAVA 规范提案 JSR 303 Bean Validation 规范 正是一套基于 JavaBean 参数校验的标准 Hibernate Va
  • s3c2440移植ucGUI

    编译环境 ADS1 2 开发板 TQ2440 主要参考这篇文章 stm32 UCGUI 完美移植 ucGUI版本 3 90 ucGUI3 90下载地址 UCGUI最新3 90版源码 屏幕 联想VGA电脑屏幕 最大分辨率1024x768 1
  • vue如何编写自定义指令directive

    vue已经给我们内置了很多很好用的指令了 v mode v show 等等 但是有时候当这些指令不能满足我们需求的时候 我们还可以使用vue的自定义指令功能编写我们的指令 这是一个很强大的功能 需要说明的是 尽管自定义指令这个功能很强大 但
  • 3D MAX导出插件编写

    转 3D MAX导出插件编写 2011 6 9阅读1667 评论0 文章版权归博客园 BigCoder所有 转载请于明显位置标明原文作者及出处 以示尊重 原文出处 http www cnblogs com csyisong archive