如何导出用户可以360度旋转的交互式三维绘图(.obj/html)(仅限Python)

2024-05-12 15:04:09 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图可视化三维箱子包装模型的结果(显示不同大小的物品如何包装在一个更大的箱子中)

下面是使用matplotlib3D的完整代码和可视化方法。但是,它不能保存为类似于3D文件的格式,用户可以在将其保存为png格式后将其旋转360度。根据模型计算出的每个项目的位置数据,如何生成外观与matplotlib3D plot相同的.obj文件,或以html格式生成.obj文件,该文件允许在浏览器中打开以旋转图片

from py3dbp import Packer, Bin, Item
from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection
import numpy as np
import matplotlib.pyplot as plt
import random

trucks = [
    [250, 250, 500],
    [500, 500, 400],
    [300, 300, 300],
    [300, 300, 200],
    [300, 300, 100],
    [500, 500, 500]
]

for t in range(len(trucks)):
    packer = Packer()

    # packer.add_bin(Bin('small-envelope', 11.5, 6.125, 0.25, 10))
    # packer.add_bin(Bin('large-envelope', 15.0, 12.0, 0.75, 15))
    # packer.add_bin(Bin('small-box', 8.625, 5.375, 1.625, 70.0))
    # packer.add_bin(Bin('medium-box', 11.0, 8.5, 5.5, 70.0))
    # packer.add_bin(Bin('medium-2-box', 13.625, 11.875, 3.375, 70.0))
    # packer.add_bin(Bin('large-box', 240, 244, 1360, 70.0))
    # packer.add_bin(Bin('large-2-box', 23.6875, 11.75, 3.0, 70.0))

    truckX = trucks[t][0]
    truckY = trucks[t][1]
    truckZ = trucks[t][2]

    packer.add_bin(Bin('LB', truckX, truckY, truckZ, 3000.0))

    for i in range(300):
        packer.add_item(Item('boxL' + str(i), 20, 40, 20, 1))

    for i in range(10):
        packer.add_item(Item('boxU' + str(i), 100, 100, 100, 1))

    for i in range(5):
        packer.add_item(Item('boxU' + str(i), 200, 100, 50, 1))

    for i in range(10):
        packer.add_item(Item('boxU' + str(i), 40, 40, 20, 1))

    # packer.pack()
    packer.pack(bigger_first=False)

    positions = []
    sizes = []
    colors = []

    for b in packer.bins:
        print(":::::::::::", b.string())

        print("FITTED ITEMS:")
        for item in b.items:
            print("====> ", item.string())
            x = float(item.position[0])
            y = float(item.position[1])
            z = float(item.position[2])
            positions.append((x, y, z))
            sizes.append(
                (float(item.get_dimension()[0]), float(item.get_dimension()[1]), float(item.get_dimension()[2])))

        print("UNFITTED ITEMS:")
        for item in b.unfitted_items:
            print("====> ", item.string())

        print("***************************************************")
        print("***************************************************")


    def cuboid_data2(o, size=(1, 1, 1)):
        X = [[[0, 1, 0], [0, 0, 0], [1, 0, 0], [1, 1, 0]],
             [[0, 0, 0], [0, 0, 1], [1, 0, 1], [1, 0, 0]],
             [[1, 0, 1], [1, 0, 0], [1, 1, 0], [1, 1, 1]],
             [[0, 0, 1], [0, 0, 0], [0, 1, 0], [0, 1, 1]],
             [[0, 1, 0], [0, 1, 1], [1, 1, 1], [1, 1, 0]],
             [[0, 1, 1], [0, 0, 1], [1, 0, 1], [1, 1, 1]]]
        X = np.array(X).astype(float)
        for i in range(3):
            X[:, :, i] *= size[i]
        X += np.array(o)
        return X


    def plotCubeAt2(positions, sizes=None, colors=None, **kwargs):
        if not isinstance(colors, (list, np.ndarray)): colors = ["C0"] * len(positions)
        if not isinstance(sizes, (list, np.ndarray)): sizes = [(1, 1, 1)] * len(positions)
        g = []
        for p, s, c in zip(positions, sizes, colors):
            g.append(cuboid_data2(p, size=s))
        return Poly3DCollection(np.concatenate(g),
                                facecolors=np.repeat(colors, 6), **kwargs)


    colorList = ["crimson", "limegreen", "g", "r", "c", "m", "y", "k"]

    for i in range(len(b.items)):
        f = random.randint(0, 7)
        colors.append(colorList[f])

    print(colors)

    fig = plt.figure()
    ax = fig.gca(projection='3d')
    ax.set_aspect('auto')

    pc = plotCubeAt2(positions, sizes, colors=colors, edgecolor="k")
    ax.add_collection3d(pc)

    ax.set_xlim([0, truckX])
    ax.set_ylim([0, truckY])
    ax.set_zlim([0, truckZ])

    plt.show()

enter image description here


Tags: inimportaddforbinnprangefloat
1条回答
网友
1楼 · 发布于 2024-05-12 15:04:09

您可以使用plotly包。它生成一个可在浏览器中打开的交互式html文件Here3D绘图示例。
您可以轻松地集成一些图形,并使用dash创建交互式仪表板(here some examples)。
这两个软件包都需要特定的语法(我不会在这里报告生成绘图的语法,因为这不是您的特定问题),您必须了解这些语法,但我认为它们正是您需要的语法。
除了plotly,您还可以使用bokeh

相关问题 更多 >