搅拌机;自定义导出“平面”三角形顶点

Posted

技术标签:

【中文标题】搅拌机;自定义导出“平面”三角形顶点【英文标题】:Blender; custom export 'flat' triangle vertices 【发布时间】:2021-09-25 22:09:30 【问题描述】:

给定一个由单独对象组成的 Blender(2.9 版)模型,每个对象都是一个三角形,我有一个脚本可以将它们导出为自定义格式,其中包括每个三角形的位置、欧拉旋转和顶点。

因为我的目标程序使用指定的对象欧拉角旋转三角形,我需要将每个三角形的顶点“展平”为 XY 坐标,就好像三角形是二维的一样。

这是我的第一个 Blender 脚本和第一个 Python 脚本,所以它非常基础,没有任何错误检查。假设我的对象肯定都是三角形 :) 它目前以 3D 形式“按原样”导出顶点。

bl_info = 
    "name": "Dave's Export",
    "author": "Dave",
    "version": (1, 2),
    "blender": (2, 83, 0),
    "location": "File > Export > Dave's Export",
    "warning": "",
    "description": "Export active mesh",
    "category": "Import-Export",


import bpy
import os

from bpy_extras.io_utils import ExportHelper

class DavesExport(bpy.types.Operator, ExportHelper):

    bl_idname = "export_scene.custom_export"
    bl_label = "Export"
    bl_options = 'PRESET', 'UNDO'
    filename_ext = ".dave"

    def execute(self, context):

        filepath = self.filepath
        filepath = bpy.path.ensure_ext(filepath, self.filename_ext)

        out = open(filepath, "w")
        scene = bpy.data.scenes[0]

        for obj in scene.objects:

            if obj.type == 'MESH':

                # Note; obj is just a triangle.

                # Position
                out.write(str(obj.location.x) + ' ' + str(obj.location.y) + ' ' + str(obj.location.z))
                out.write('|')

                # Rotation
                out.write(str(obj.rotation_euler.x) + ' ' + str(obj.rotation_euler.y) + ' ' + str(obj.rotation_euler.z))
                out.write('|')

                # Vertices (x3)
                for vertex in obj.data.vertices:

                    out.write(str(vertex.co.x) + ' ' + str(vertex.co.y) + ' ' + str(vertex.co.z))
                    out.write('|')

                out.write('\n')

        out.close()

        return 'FINISHED'

    # Constructor (?)

    def invoke(self, context, event):

        wm = context.window_manager
        wm.fileselect_add(self)

        return 'RUNNING_MODAL'

# This function adds an item to the export menu.

def menu_button(self, context):

    self.layout.operator(DavesExport.bl_idname, text="Dave's Export")

# Executes on Blender startup (?)

def register():

    bpy.utils.register_class(DavesExport)
    bpy.types.TOPBAR_MT_file_export.append(menu_button)

# Executes on Blender exit (?)

def unregister():

    bpy.utils.unregister_class(DavesExport)
    bpy.types.TOPBAR_MT_file_export.remove(menu_button)

(此外,我希望这个脚本代表一个用于 2.9 的简单导出器,以便人们可以从中学习 - 我花了一整天的时间才让它工作,因为没有太多关于此的最新信息)

【问题讨论】:

【参考方案1】:

我不太确定您的目标是什么,但“展平”顶点听起来像是一种投影操作,您需要转换顶点位置以使 Z 等于零。为此,您可以计算三角形的面方向并将三角形顶点旋转为负值。但是也不清楚局部偏移的意义是什么,旋转将围绕该偏移发生。 您可以尝试详细说明您想要实现的结果,您正在使用的源数据或您迄今为止的尝试,因为解决方案可能只是在导出时忽略三角形顶点的 Z 值,如果它们是已经提供了与 X 和 Y 轴平面对齐的平面。

添加来自以下 cmets 的答案:

1: 以中心点P为中心旋转三角形,其中P为3个顶点的平均位置(V0+V1+V2)/3,旋转R来源于面法线它是用向量 V1-V0 和 V2-V0 的点积计算的,如下所述https://***.com/a/1516330/15786521 顶点需要移动 P 的负数,旋转 R 的负数,然后移动 P 或矩阵运算其中V是顶点位置:

V' = V x M(-P) x M(-R) x M(P)

但问题是旋转不通勤,这意味着先绕 X 轴再绕 Y 轴旋转的结果与绕 Y 轴再绕 X 轴旋转的结果不同。 在您的情况下,围绕偏航旋转,然后俯仰并忽略滚动可能会起作用,但我不知道哪种方式最适合您,因为如果您首先旋转俯仰,三角形的滚动会有所不同。

2:如果您只是想将三角形​​映射到纹理等上,其中只有比例很重要,而 3d 方向无关紧要,因为目标似乎要中和/展平它,那么只需获取向量 V1-V0 和 V2-V0 的点积和距离,并从中构建三角形的二维表示。

【讨论】:

您是正确的,我想投影以使 Z = 0。传入数据是 Blender 的 API 提供的数据。我目前在我的目标程序中忽略了 Z,但这会错误地渲染模型;它通常显得平坦。三角形将围绕它们的中心旋转。至于以哪种方式旋转它们(首先是哪个轴?) - 我想我需要为每个三角形定义一个局部“前向”方向,比如 -Y 是前向,-X 是左向。这些信息有帮助吗?我会试试你关于“消极取向”的建议——那只是消极的脸正常吗?谢谢你的回答! 好的,那么现在已知支点 P = [(V0.x + V1.x + V2.x)/3, (V0.y + V1.y + V2.y) /3, (V0.z + V1.z + V2.z)/3] 即所有 3 个顶点的平均位置。现在您需要从每个顶点中减去它,执行从面法线派生 R 的旋转,然后将其放回原处。对于矩阵,这看起来像 V' = V x M(-P) x M(-R) x M(P) 虽然我不知道你需要如何旋转它。您可以通过偏航旋转它,然后俯仰并忽略滚动。 尽管如果您只是想将其映射到展开或纹理表,您可以简单地获得 V0 x V1 和 V0 x V2 的点积和距离,并从中导出三角形的 2D 表示。 这真的很有帮助!我会将您的 cmets 添加到您的答案中,并在我完成工作后将其标记为已接受,我现在对此非常有信心,谢谢。 啊,“建议的编辑队列已满”。也许您可以编辑您的答案以包含它们?

以上是关于搅拌机;自定义导出“平面”三角形顶点的主要内容,如果未能解决你的问题,请参考以下文章

在给定三个边的坐标平面中绘制三角形

DirectX学习笔记:利用平面着色和Gouraud着色模式绘制具有颜色的三角形

搅拌机在 X-Y 平面上移动顶点

OpenGL ES——导入.stl格式的3D模型

Three.js教程:Face3对象定义Geometry的三角形面

BZOJ4445[Scoi2015]小凸想跑步 半平面交