当前位置: 首页 > news >正文

Python+OpenGL绘制3D模型(七)制作3dsmax导出插件

系列文章

一、逆向工程
Sketchup 逆向工程(一)破解.skp文件数据结构
Sketchup 逆向工程(二)分析三维模型数据结构
Sketchup 逆向工程(三)软件逆向工程从何处入手
Sketchup 逆向工程(四)破解的乐趣 钩子 外挂 代码注入

二、OpenGL渲染模型
Python+OpenGL绘制3D模型(一)Python 和 PyQt环境搭建
Python+OpenGL绘制3D模型(二)程序框架PyQt5
Python+OpenGL绘制3D模型(三)程序框架PyQt6
Python+OpenGL绘制3D模型(四)绘制线段
Python+OpenGL绘制3D模型(五)绘制三角型
Python+OpenGL绘制3D模型(六)材质文件载入和贴图映射
Python+OpenGL绘制3D模型(七)制作3dsmax导出插件
Python+OpenGL绘制3D模型(八)绘制插件导出的插件
Python+OpenGL绘制3D模型(九)完善插件功能: 矩阵,材质,法线
Python+OpenGL 杂谈(一)

三、成果
疫情期间关在家里实在没事干,破解了Sketchup,成功做出可以读取并显示.skp文件的程序SuViewer

前言

Sketchup作为目前设计院最为流行的设计软件(非工程制图软件),深受设计师的喜爱,软件小巧,而功能强大,有不少为之开发的插件应运而生,不过呢,关于底层数据结构和工作原理相关的文章少之又少,本文意在填补一下这方面的空缺,通过逆向软件分析,展示软件内部奥秘。本文用到的工具:IDA Pro,Immunity Debugger,Visual Studio (逆向工程三件套)数据结构属于知识产权的核心机密:


在这里插入图片描述

文章目录

  • 系列文章
  • 前言
    • 一、介绍
    • 二、使用方法
    • 三、插件源代码
  • 系列文章预告

一、介绍

3dsmax支持python2.7,所以同样可以用python编写插件,不需要编译安装,一键执行,非常方便,
编写插件是个比较复杂的过程,涉及3dsmax中模型、材质、贴图、等数据的组织结构,以后专门用一个专题详细介绍,有兴趣的同学可以仔细读一下插件源代码
插件和程序需要交换文件数据格式,这里定义一个CModel,数据保存使用了python内置的pickle,也是一键保存,在程序里一键载入,不需要专门编写读写文件的代码

二、使用方法

1、下载源代码,保存到:c:/temp/maxplus_export_sel_model.py
2、打开3dsmax,菜单 》Scripting 》 MAXScript Listener
3、运行 python.ExecuteFile “C:/temp/maxplus_export_sel_model.py”

如果看到如下输出,说明已经导出成功

find INode: Teapot001, <0X0000000048D3CBB0>, class:Teapot
---ProcMesh()---
numVertics:530
numFaces:1024
#success

模型导出到 “c:/temp/CModel.pickle”

注意:保证c:/temp存在,否则导出失败

三、插件源代码

maxplus_export_sel_model.py

import MaxPlus
import pickle
from CModel import CModel, CMesh, CTriangle, CVector3################################
#                   FILE DESCRIPTION
#  文件描述:CModelExport
#  对应文章:Python+OpenGL绘制3D模型(七) 制作3dsmax导出插件
#  作者:李航 Lihang
#  使用方法:
#   1、选择要导出的模型
#   2、在命令行窗口中输入
#          python.ExecuteFile "C:/_proj/SuViewer/articles/step3/maxplus_export_sel_model.py"
#   3、把命令行拖入工具栏可以生成快捷方式,方便下次使用
#   4、测试可使用的版本:3dsmax2016
#   ELSE..
################################# 注意: 保证c:/temp目录存在,否则无法导出
EXPORT_PATH_FILE = "c:/temp/CModel.pickle"############
# CModelExport
############  
class CModelExport:def __init__(self):self.list_mats = []############# export#   插件主入口############  def export(self):model = CModel()for n, obj, triObj in self.EnumSeletciontGeometry():print ("find %s, class:%s"%(n, obj.GetClassName()) )mesh = triObj.GetMesh()out_mesh = self.ProcMesh(n, mesh)model.list_mesh.append(out_mesh)with open(EXPORT_PATH_FILE,  "wb") as hf:pickle.dump(model,  hf,  2)############# EnumSeletciontGeometry#   1、遍历选择的物体#   2、生成列表sel_list并返回############  def EnumSeletciontGeometry(self):sel_list = []for n in MaxPlus.SelectionManager.Nodes:        # objectobj = n.EvalWorldState().Getobj()if obj.CanConvertToType(MaxPlus.ClassIds.TriMeshGeometry):triObj = obj.ConvertToType(MaxPlus.ClassIds.TriMeshGeometry)item = (n, obj, MaxPlus.TriObject._CastFrom(triObj))sel_list.append(item)#print ("find %s, class:%s"%(n, obj.GetClassName()) )else:print("can't conv triMesh, Type is:%s" % obj.GetClassName())return sel_list############# ProcMesh#   1、处理max中的模型#   2、转成需要的CModel数据############def ProcMesh(self, node, mesh):print("---ProcMesh()---")#=====================# Color#=====================new_mesh = CMesh()color1 = node.GetWireColor()new_mesh.color = (color1.GetR(), color1.GetG(), color1.GetB())#=====================# Vertices#=====================num_verts = mesh.GetNumVertices()print ("numVertics:%d"%num_verts)for i in range(num_verts):point = mesh.GetVertex(i)nv = CVector3(point.X, point.Y, point.Z)new_mesh.list_vertices.append(nv)#=====================# Triangles#=====================num_faces = mesh.GetNumFaces()print ("numFaces:%d"%num_faces)for i in range(num_faces):tri = mesh.GetFace(i)vi1 = tri.GetVert(0)vi2= tri.GetVert(1)vi3 = tri.GetVert(2)ev1 = True if tri.GetEdgeVis(0) else Falseev2 = True if tri.GetEdgeVis(1) else Falseev3 = True if tri.GetEdgeVis(2) else Falsent = CTriangle()nt.a = (vi1, 0, 0)nt.b = (vi2, 0, 0)nt.c = (vi3, 0, 0)norm = mesh.FaceNormal(i)nt.matId = tri.GetMatID()nt.faceNormal = CVector3(norm.X, norm.Y, norm.Z)nt.smGroup = tri.GetSmGroup()nt.edgevis = (ev1, ev2, ev3)new_mesh.list_tris.append(nt)return new_mesh############
# Main
#   1、创建插件导出对象CModelExport
#   2、执行export
############
modelExport = CModelExport()
modelExport.export()

CModel.py

class CModel:def __init__(self):self.list_mesh = []class CMesh:def __init__(self):self.name = ""self.color = (0, 0, 0)self.list_vertices = []self.list_tris = []class CTriangle:def __init__(self):self.a=(0, 0, 0)self.b=(0, 0, 0)self.c=(0, 0, 0)self.faceNormal = CVector3(0, 0, 0)self.matId = 0self.smGroup = 0self.edgevis=(True, True, True)class CVector3:def __init__(self, x, y, z):self.x=xself.y=yself.z=z

系列文章预告

目标是一个完善的Viewer,能够显示Sketchup的.skp文件中的3D模型
在这里插入图片描述

Corona渲染器照片级渲染效果
在这里插入图片描述

相关文章:

Python+OpenGL绘制3D模型(七)制作3dsmax导出插件

系列文章 一、逆向工程 Sketchup 逆向工程&#xff08;一&#xff09;破解.skp文件数据结构 Sketchup 逆向工程&#xff08;二&#xff09;分析三维模型数据结构 Sketchup 逆向工程&#xff08;三&#xff09;软件逆向工程从何处入手 Sketchup 逆向工程&#xff08;四&#xf…...

MediaPipeUnityPlugin Win10环境搭建(22年3月的记录,新版本已完全不同,这里只做记录)

https://github.com/homuler/MediaPipeUnityPlugin You cannot build libraries for Android with the following steps. 1、安装msys2配置系统环境变量Path添加 C:\msys64\usr\bin 执行 pacman -Su 执行 pacman -S git patch unzip 2、安装Python3.9.10 勾选系统环境变量 …...

Nginx - location块中的alias和try_files重定向

nginx.conf片段&#xff1a; location /logo/general/ {autoindex_localtime on;alias /opt/config/;try_files /logo/logo.png /www/html/logo.png 404;} 意为&#xff1a;访问/logo/general/地址时&#xff0c; 如&#xff1a;访问http://127.0.0.1/logo/general/logo.png…...

二刷Laravel 教程(用户模型)总结Ⅲ

一、数据库迁移 当我们运行迁移时&#xff0c;up 方法会被调用&#xff1b;&#xff08;创建表&#xff09; 当我们回滚迁移时&#xff0c;down 方法会被调用。&#xff08;删除表&#xff09; public function up() { //create 方法会接收两个参数&#xff1a;一个是数据…...

安装PyTorch及环境配置(应用于Python上的YOLO)

这个基本都是Bilibili网站里面叫“小手丫子”up的视频教程&#xff0c;此前自己需要装了好几次又卸载了好几次&#xff0c;现在根据视频教学整理出来自己所理解的文档。 注意事项 1.安装的pycharm版本和anaconda版本无要求。 2.运行pycharm尽量以管理员身份运行。 3.Cuda是独…...

【194】PostgreSQL 14.5 编写SQL从身份证号中查找性别,并且更新性别字段。

假设有一张用户表 t_user &#xff0c;该表设计如下&#xff1a; id: character varying 主键 name: character varying 姓名 idcard: character varying 身份证号 gender: smallint 性别&#xff0c;女是0&#xff0c;男是1根据身份证号查找所有未填写…...

微服务管家:NestJS 如何使用服务发现 Consul 实现高效的微服务节点管理

前言 在微服务架构中&#xff0c;服务发现是一项基础且关键的功能&#xff0c;它允许服务实例在网络中被动态发现。Consul 是一种服务网格解决方案&#xff0c;提供了服务发现、运行状况检查&#xff0c;过去和现代应用程序的连接等功能。 本教程将向您展示如何在 NestJS 框架…...

Baumer工业相机堡盟工业相机如何联合NEOAPI SDK和OpenCV实现相机图像转换为Mat图像格式(C++)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK实现相机掉线自动重连&#xff08;C&#xff09; Baumer工业相机Baumer工业相机的图像转换为OpenCV的Mat图像的技术背景在NEOAPI SDK里实现相机图像转换为Mat图像格式联合OpenCV实现相机图像转换为Mat图像格式测试演示图 工业相机…...

铁塔基站数字化管理监测解决方案

截至2023年10月&#xff0c;我国5G基站总数达321.5万个&#xff0c;占全国通信基站总数的28.1%。然而&#xff0c;随着5G基站数量的快速增长&#xff0c;基站的能耗问题也逐渐日益凸显&#xff0c;基站的用电给运营商带来了巨大的电费开支压力&#xff0c;降低5G基站的能耗成为…...

如何使用Python3 Boto3删除AWS CloudFormation的栈(Stacks)

文章目录 小结问题及解决有关Json文件的输入和输出使用Python3及正则表达式查找字符串包含某个子字符串使用Python3 Boto3删除AWS CloudFormation的栈&#xff08;Stacks&#xff09; 参考 小结 本文记录了使用Python3的Boto3包删除AWS CloudFormation的栈&#xff08;Stacks&…...

差分约束算法

差分约束 差分约束系统包含 m m m个涉及 n n n个变量的差额限制条件&#xff0c;这些差额限制条件每个都是形式为 x i − x j ≤ b ∈ [ 1 , m ] x_i-x_j\leq b_{\in[1,m]} xi​−xj​≤b∈[1,m]​的简单线性不等式。 通常我们要求解出一组可行解。 最短路差分约束 如果我们…...

彻底解决vue-video-player播放视频有黑边

需求 最近需要接入海康视频摄像头&#xff0c;然后把视频的画面接入到自己的网站系统中。以前对接过rtsp固定IP的显示视频&#xff0c;这次的不一样&#xff0c;没有了固定IP。海康的解决办法是&#xff0c;摄像头通过配置服务器到萤石云平台&#xff0c;然后购买企业版账号和…...

区域负责人常用的ChatGPT通用提示词模板

区域市场分析&#xff1a;如何分析区域市场的特点、竞争态势和客户需求&#xff1f; 区域销售策略制定&#xff1a;如何制定针对区域市场的销售策略&#xff0c;包括产品定位、价格策略、渠道策略等&#xff1f; 区域销售目标设定&#xff1a;如何设定明确的区域销售目标&…...

Java Spring boot 可變參數,以及弊端

function中 不固定的參數 public boolean sendEmail(String manFrom, String manTo,String manCc, String subject, String... msg); 必須是最後一個參數&#xff0c;傳值時可以多個。 sendEmail(“a.gmail”,"b.gmail","c.gmail","subject",…...

机器视觉系统选型-线阵工业相机选型

线阵相机特点&#xff1a; 1.线阵相机使用的线扫描传感器通常只有一行感光单元&#xff08;少数彩色线阵使用三行感光单元的传感器&#xff09; 2.线阵相机每次只采集一行图像&#xff1b; 3.线阵相机每次只输出一行图像&#xff1b; 4.与传统的面阵相机相比&#xff0c;面阵扫…...

单机开机无感全自动进入B\S架构系统

单机开机无感全自动进入B\S架构系统 标题&#xff1a;单机用jar包启动项目bat&#xff08;批处理&#xff09;不弹黑窗口&#xff0c;并设置开机自启&#xff0c;打开浏览器&#xff0c;访问系统。引言&#xff1a;在实际工作中&#xff0c;遇到单机部署的情况&#xff0c;如今…...

大一,如何成为一名fpga工程师?

​ 1、数电&#xff08;必须掌握的基础&#xff09;&#xff0c;然后进阶学模电&#xff08;选学&#xff09;&#xff0c; 2、掌握HDL&#xff08;HDLverilogVHDL&#xff09;可以选择verilog或者VHDL&#xff0c;建议verilog就行。 3、掌握FPGA设计流程/原理&#xff08;推…...

MyBatisPlus学习三:Service接口、代码生成器

学习教程 黑马程序员最新MybatisPlus全套视频教程&#xff0c;4小时快速精通mybatis-plus框架 Service接口 简介 在MyBatis-Plus框架中&#xff0c;Service接口的作用是为实体类提供一系列的通用CRUD&#xff08;增删改查&#xff09;操作方法。通常情况下&#xff0c;Servi…...

产品经理如何选择城市?

年底&#xff0c;全国性的人口大迁徙即将开始。选择城市&#xff0c;堪称年轻人的“二次投胎”&#xff0c;族望留原籍&#xff0c;家贫走他乡。 古人在选择城市时&#xff0c;主要的考量因素是家族势力&#xff0c;这一点放在当代&#xff0c;大致也成立&#xff0c;如果在老…...

再谈“敏捷”与“瀑布”在产品开发过程中的反思

作为一家专注于软件开发的公司《智创有术》&#xff0c;我们致力于为客户提供创新、高效和可靠的解决方案。通过多年的经验和专业知识&#xff0c;我们已经在行业内建立了良好的声誉&#xff0c;并赢得了客户的信任和支持。 支持各种源码&#xff0c;网站搭建&#xff0c;APP&a…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)

本文把滑坡位移序列拆开、筛优质因子&#xff0c;再用 CNN-BiLSTM-Attention 来动态预测每个子序列&#xff0c;最后重构出总位移&#xff0c;预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵&#xff08;S…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

听写流程自动化实践,轻量级教育辅助

随着智能教育工具的发展&#xff0c;越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式&#xff0c;也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建&#xff0c;…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

免费PDF转图片工具

免费PDF转图片工具 一款简单易用的PDF转图片工具&#xff0c;可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件&#xff0c;也不需要在线上传文件&#xff0c;保护您的隐私。 工具截图 主要特点 &#x1f680; 快速转换&#xff1a;本地转换&#xff0c;无需等待上…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

上位机开发过程中的设计模式体会(1):工厂方法模式、单例模式和生成器模式

简介 在我的 QT/C 开发工作中&#xff0c;合理运用设计模式极大地提高了代码的可维护性和可扩展性。本文将分享我在实际项目中应用的三种创造型模式&#xff1a;工厂方法模式、单例模式和生成器模式。 1. 工厂模式 (Factory Pattern) 应用场景 在我的 QT 项目中曾经有一个需…...