0

给定一个FreeCAD 模型,其中包括

  • 电子表格“参数”,其中一个单元格别名为“半径”,值为 50
  • 具有 Radius=parameters.radius 的二十面体(来自 Pyramids-and-Polyhedrons 宏)
  • 一些对于这个问题来说并不重要的面部粘合剂,

下面的 python 脚本打开这个模型,将电子表格中的半径单元格更改为 15,在电子表格上调用 recompute(),在二十面体上调用 touch(),在文档上调用 recompute(),最后对二十面体进行镶嵌。镶嵌网格中索引 11 处顶点的 z 坐标恰好等于二十面体的半径。根据参数更改,我期望它会更改为 15。但它仍然保持在原来的值 50。我做错了什么?

据我了解,应该在重新计算文档期间调用宏的执行方法。

当我用 pudb 跟踪 Document.recompute() 时,我只看到它执行 Facebinder.execute() 而不是 Icosahedron.execute()。从 Document.recompute() 到 Facebinder.execute() 方法的路径在 pudb 中不可见;它立即在 Facebinder.execute() 中停止。

FREECADPATH = '/usr/local/lib' # path to your FreeCAD.so or FreeCAD.dll POLYHEDRONS_PATH = '/home/user/.FreeCAD/Mod/Pyramids-and-Polyhedrons'
import sys
sys.path.append(FREECADPATH)
sys.path.append(POLYHEDRONS_PATH)
import FreeCAD

filename = 'icosahedron.FCStd'
newRadius = 15

doc = FreeCAD.open(filename)
sheet = doc.Spreadsheet
sheet.set('radius', str(newRadius))
sheet.recompute()
print('radius = ' + str(sheet.get('radius')))

icosahedron = doc.getObjectsByLabel('Icosahedron')[0]
print('icosahedron.Radius = '+str(icosahedron.Radius))
icosahedron.touch()
doc.recompute()
print('icosahedron.Radius = '+str(icosahedron.Radius))

(vertices, faces) = icosahedron.Shape.tessellate(1)
z11 = vertices[11][2]
print('z11 = ' + str(z11))
FreeCAD.closeDocument(doc.Name)
4

1 回答 1

0

我想到了。原因Pyramids-and-Polyhedrons毕竟不是进口的。第一个问题是Pyramids-and-Polyhedrons导入(为了安装它的工作台),这取决于在运行脚本之前FreeCADGui需要添加的某些本机库:LD_LIBRARY_PATH

export LD_LIBRARY_PATH=$(echo $(find /usr/local/lib/python3.7/site-packages -maxdepth 2 -mindepth 2 -type f -name *.so* | sed -r 's|/[^/]+$||' | sort -u) | sed -E 's/ /:/g')

现在FreeCADGui可以导入,但缺少调用所需的addCommand方法。Pyramids-and-Polyhedrons我发现只有在被调用FreeCADGui后才会完全初始化。FreeCADGui.showMainWindow()但是,这需要显示,我想将脚本作为 Docker 容器中无头工具链的一部分运行。因此我添加Xvfb到图像中。在运行更新的脚本之前,我在后台启动它并DISPLAY指向Xvfb

FREECADPATH = '/usr/local/lib' # path to your FreeCAD.so or FreeCAD.dll file
POLYHEDRONS_PATH = '/home/user/.FreeCAD/Mod/Pyramids-and-Polyhedrons'
import sys
sys.path.append(FREECADPATH)
sys.path.append(POLYHEDRONS_PATH)
import FreeCAD
import FreeCADGui
FreeCADGui.showMainWindow()

import polyhedrons

filename = 'icosahedron.FCStd'
newRadius = 15

doc = FreeCAD.open(filename)
sheet = doc.Spreadsheet
sheet.set('radius', str(newRadius))
sheet.recompute()
print('radius = ' + str(sheet.get('radius')))

icosahedron = doc.getObjectsByLabel('Icosahedron')[0]
print('icosahedron.Radius = '+str(icosahedron.Radius))
breakpoint()
icosahedron.touch()
doc.recompute()
print('icosahedron.Radius = '+str(icosahedron.Radius))

(vertices, faces) = icosahedron.Shape.tessellate(1)
z11 = vertices[11][2]
print('z11 = ' + str(z11))
FreeCAD.closeDocument(doc.Name)

现在输出是

...
z11 = 15.0

正如预期的那样。

于 2021-03-12T23:58:28.020 回答