Python+OpenGL绘制3D模型(八)绘制插件导出的模型

文章详细介绍了如何通过逆向工程破解Sketchup的.skp文件,以及使用Python和OpenGL进行3D模型的绘制,包括数据结构解析、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 杂谈(一)

前言

Sketchup作为目前设计院最为流行的设计软件(非工程制图软件),深受设计师的喜爱,软件小巧,而功能强大,有不少为之开发的插件应运而生,不过呢,关于底层数据结构和工作原理相关的文章少之又少,本文意在填补一下这方面的空缺。


在这里插入图片描述

一、载入模型文件

由于文件用pickle直接dump出来,用的时候一键载入,非常简单

import pickle

with open("c:/temp/CModel.pickle",  "rb") as hf:
    model = pickle.Unpickler(hf).load()

二、绘制

3dsmax中有2种模型的数据,triMesh polyMesh,
读3dsmax的API就是读3dsmax软件的整个发展史,这里面有很多历史遗留问题,最早建模是三角形建模技术,后来才发展为更先进的四边形建模技术(也叫细分面建模),一个4边型可以分成4个,再分成16个。3dsmax在使用了新的建模架构,又不得不保留老的数据结构,导致api和源代码无比膨胀,难于维护,让人有点莫名其妙,这2种模型数据,可以互相转换,最终我们导出的是triMesh数据
在这里插入图片描述

三、1个主要问题

3dsmax中模型的大部分是4边型,但是转成了triMesh的模型,为什么在3dsmax中显示的还能保持是四边面,这是因为转成的三角形数据,edge是有影藏属性的,可以任然显示层4边型,如果打开显示影藏,就能看到3dsmax中的模型是三角型了

解决的办法,在导出插件的时候,我们导出了edgevis的信息,这就可以辅助显示四边面了

在构建线框的时候,加入如下代码

        for tri in mesh.list_tris:
            vi1 = tri.a[0]
            vi2 = tri.b[0]
            vi3 = tri.c[0]
            if tri.edgevis[0]:
                add_edge(vi1, vi2)
            if tri.edgevis[1]:
                add_edge(vi2, vi3)
            if tri.edgevis[2]:
                add_edge(vi3, vi1)

修改后的线框绘制如下

在这里插入图片描述
这个效果就很Nice了

四、源代码

Draw1.py

import pickle

################################
#                   FILE DESCRIPTION
#  文件描述:Draw Model()
#  对应文章:Python+OpenGL绘制3D模型(八)绘制插件导出的模型
#  作者:李航 Lihang
#
################################
MODEL_FILE = "c:/temp/CModel.pickle"

class Draw1:
    def __init__(self):
        self.model=None
    
    ############
    # load
    #   载入模型文件
    ############
    def load(self, filepath=MODEL_FILE):
        with open(filepath,  "rb") as hf:
            self.model = pickle.Unpickler(hf).load()

            for mesh in self.model.list_mesh:
                self.build_edges(mesh)
    
    ############
    # draw
    #   主入口
    ############
    def draw(self, gl):
        
        if self.model is None:
            return
            
        for mesh in self.model.list_mesh:
            # 设置z-buff偏移
            gl.glEnable(gl.GL_POLYGON_OFFSET_FILL)
            gl.glPolygonOffset(1, 1)
            
            # 绘制填充面
            self.drawMesh(mesh, gl)
        
            # 关闭z-buff偏移
            gl.glDisable(gl.GL_POLYGON_OFFSET_FILL)
            
            # 绘制线框
            gl.glColor3f(0.0, 0.0, 0.0)
            self.drawMesh_linemode(mesh, gl)
    
    ############
    # build_edges
    #   1、创建edges列表
    #   2、公用的线不重复绘制
    #   3、3dsmax中的隐藏线不绘制(edgevis)
    ############
    def build_edges(self, mesh)</
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值