3

我正在使用 Autodesk Fusion 360 为 3D 零件建模(见下图),然后我可以将其导出并保存为 .step、.iges、.sat 或 .smt 文件。

我想要实现的是将此部分转换为 Python 中的 3D numpy 数组。数组的每个元素将是01,以指示该位置是否有固体材料或根本没有材料(空气)。

例如,如果我的对象具有图形的尺寸,则大小为 100x100x50 的数组的每个元素将代表 1 mm 3的对象体积。所有浅蓝色的小立方体的值为1表示该位置有固体物质,而红色立方体的值为0表示该空间不包含固体物质。

在此处输入图像描述

这可以使用 FreeCAD API 完成吗?或者有没有其他方法可以在 Python 中导入 .step/.iges/.sat/.smt 文件并转换/解析它以创建所需的数组?

4

3 回答 3

1

我终于找到了一种适合我的方法,并且实际上可以更好地解释我一直在努力实现的目标。

显然,FreeCAD 有一个选项,在您激活“点”工作台后,您可以选择将您的对象转换为“点云”。每个点都没有任何质量,整个新的点云结构可以导出到以空格分隔的“.asc”文件中。

之后,将其导入 Python numpy 数组很简单。我个人使用基于体素的表示在 Python 中可视化导入的对象,这可以使用最新的 matplotlib 或 mayavi 来完成(这是我至少尝试过的两个)。

于 2017-10-26T14:06:55.597 回答
0

将部分拆分为小部分是可能的,如下所示 /Mod/Part/BOPTools/SplitFeatures.py。但它还不能满足您的需求,需要时间来采用。但绝对可以将零件拆分为您喜欢的任何形状的许多部分: https ://www.freecadweb.org/wiki/Part_Slice

然后您可以使用此代码构建一个 numpy 数组:

import FreeCAD
import Part
import numpy as np

# Creating sample parts
solid_ = Part.makeBox(10, 10, 10)
shell_ = Part.makeShell(solid_.Shells)
part_compound = [solid_, shell_]

# Generate numpy array
result = []
for part in part_compound:
    result = [*result, [part.CenterOfMass.x,
                        part.CenterOfMass.y,
                        part.CenterOfMass.z,
                        isinstance(part, Part.Solid)]]
print(np.array(result))

这将产生一个数组,其中每个部分的质心将由其 x、y、z 表示,如果这些部分是实心的,则第四个元素将为 1,否则为 0。

代码仅与 Python 3.6 兼容,因此请使用 docker 镜像: https ://github.com/ZhukovGreen/docker-freecad-cli

于 2017-10-24T09:06:33.970 回答
0

您可以检查一个点是否位于实体内部:

solid_shape.isInside(point:App.Vector, tolerance:float, on_boundary_is_inside:bool)

例子:

import numpy as np
import FreeCAD as App
import Part

num_pts = 50

shape = Part.makeSphere(1)  # radius
bb = shape.BoundBox
x = np.linspace(bb.XMin, bb.XMax, num_pts)
y = np.linspace(bb.YMin, bb.YMax, num_pts)
z = np.linspace(bb.ZMin, bb.ZMax, num_pts)

mesh_x = np.array([[x] * num_pts] * num_pts).transpose(0, 1, 2)
mesh_y = np.array([[y] * num_pts] * num_pts).transpose(2, 0, 1)
mesh_z = np.array([[z] * num_pts] * num_pts).transpose(1, 2, 0)

mesh = np.array([mesh_x.flatten(), mesh_y.flatten(), mesh_z.flatten()]).T
bool_array = np.array([shape.isInside(App.Vector(p), 0.000001, False) for p in mesh])

v_r = float(sum(bool_array)) / float(len(bool_array))
v_r   # estimation of Volumeratio
于 2018-03-02T09:35:40.030 回答