在Python中导入CAD对象并存储为数组

问题描述 投票:1回答:3

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

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

例如,如果我的对象具有图形的尺寸,则大小为100x100x50的数组的每个元素将表示对象的1 mm3的体积。所有浅蓝色小立方体的值都为1,表示此位置有固体材料,而红色立方体的值为0表示该空间不是由固体材料组成。

enter image description here

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

python vertex cad freecad
3个回答
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


0
投票

我终于找到了一种对我有用的方法,可能会更好地解释我一直想要实现的目标。

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

在那之后,将它导入Python numpy数组是微不足道的。我亲自使用voxel-based表示来在Python中可视化导入的对象,这可以使用最新的matplotlib或mayavi来完成(这些是我至少尝试过的两个)。


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
© www.soinside.com 2019 - 2024. All rights reserved.