【问题标题】:How to export interactive 3D plot (.obj/html) that can be rotated 360 degree by users (Python only)如何导出用户可以旋转 360 度的交互式 3D 绘图 (.obj/html)(仅限 Python)
【发布时间】:2021-10-28 22:29:29
【问题描述】:

我正在尝试可视化 3D 箱包装模型的结果(显示不同尺寸的物品如何包装在更大的箱中)。

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

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()

【问题讨论】:

    标签: python html matplotlib 3d mplot3d


    【解决方案1】:

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

    【讨论】:

    • 嗨 Zephyr,我知道这个包,但我确定它是如何工作的。您能否提供一个采用上述数据的示例?如果它运作良好,我相信它对将来访问此帖子的很多人有用。
    • 对不起,这不是免费的代码服务。你必须展示你的努力来解决你的问题。所以我建议你打开一个报告你的数据的问题(只有你的数据,即盒子顶点的坐标,而不是py3dbp 代码),并要求一种方法来正确绘制一个 3d 图形,你想实现什么,报告您为此付出的努力以及您无法解决的问题
    猜你喜欢
    • 1970-01-01
    • 2012-06-05
    • 1970-01-01
    • 2018-10-03
    • 2020-07-02
    • 1970-01-01
    • 1970-01-01
    • 2013-03-15
    相关资源
    最近更新 更多