如何使用 FreeCAD python 模块更新电子表格值
how to update Spreadsheet values using FreeCAD python module
假设我有一个 FreeCAD 模型,它定义了一个特定的几何体,其尺寸高度、宽度和长度在模型的电子表格的单元格中定义。
我想使用 FreeCAD 模块在独立 Python 脚本中构建自动化管道
- 阅读那个模型
- 将电子表格单元格设置为客户提供的值
- 相应地重新计算模型
- 通过镶嵌模型的零件来生成几何图形,以便在 FreeCAD 之外进行进一步处理(与此问题无关)
除了无法更改用于计算模型的参数值外,该脚本正在运行。生成的几何图形始终反映与模型一起保存的原始值。
我添加了断言命令(第 44 行)。 geometry[0][0][2]
是一个向量,其 x
坐标恰好等于电子表格单元格 A5 中 width
参数的值。
如果调用脚本为
python so.py so_example.FCStd 10 5 3 6
断言失败,因为几何是根据电子表格的原始值 (width=2
) 而不是覆盖的值 (width=3
) 生成的。
如何有效地覆盖那些电子表格单元格值?
脚本so.py:
FREECADPATH = '/usr/lib/freecad/lib'
import sys
sys.path.append(FREECADPATH)
from collections import defaultdict
def convert_model(filename, arclen, radius, width, height):
try:
import FreeCAD
from FreeCAD import Vector
except ValueError:
print ('import error\n')
else:
FreeCAD.open(filename)
doc = App.ActiveDocument
sheet = doc.Spreadsheet
print("mode = "+str(sheet.getEditorMode("A5")))
sheet.setEditorMode("A5", 0)
print("mode' = "+str(sheet.getEditorMode("A5")))
print("arclen = "+str(sheet.arclen))
print("radius = "+str(sheet.radius))
print("angle = "+str(sheet.angle))
print("width = "+str(sheet.width))
print("height = "+str(sheet.height))
sheet.set("arclen", str(arclen))
sheet.set("radius", str(radius))
sheet.set("width", str(width))
sheet.set("height", str(height))
sheet.recompute()
# verify that the radius and also the dependent angle have changed after the recomputer
print("arclen' = "+str(sheet.arclen))
print("radius' = "+str(sheet.radius))
print("angle' = "+str(sheet.angle))
print("width' = "+str(sheet.width))
print("height' = "+str(sheet.height))
# recompute the model
doc.recompute()
geometry = generate_geometry(doc)
print("generated geometry: "+str(geometry[0][0]))
assert geometry[0][0][2] == Vector(width, 0, 0)
def generate_geometry(doc):
objects = doc.Objects
return [tessellate_shape(shaped) for shaped in objects if shaped.TypeId == 'PartDesign::Body']
def tessellate_shape(shaped):
return shaped.Shape.tessellate(0.1)
def main():
filename=sys.argv[1]
arclen=float(sys.argv[2])
radius=float(sys.argv[3])
width=float(sys.argv[4])
height=float(sys.argv[5])
convert_model(filename, arclen, radius, width, height)
if __name__=='__main__':
main()
终于我找到了如何让它工作:
更改电子表格中单元格值的关键似乎是使用
sheet.set("radius", str(radius))
sheet.recompute()
这与做
不同
sheet.radius = str(radius)
sheet.recompute()
这对模型几何没有影响。这些电子表格属性似乎是实际单元格值的只读副本。但是,通过调用 Spreadsheet.recompute(),这些属性也会更新。
更新:
要在更新电子表格属性后更改实际模型的几何形状,还需要在每个模型对象上调用 touch(),然后调用 doc.recompute()。
假设我有一个 FreeCAD 模型,它定义了一个特定的几何体,其尺寸高度、宽度和长度在模型的电子表格的单元格中定义。 我想使用 FreeCAD 模块在独立 Python 脚本中构建自动化管道 - 阅读那个模型 - 将电子表格单元格设置为客户提供的值 - 相应地重新计算模型 - 通过镶嵌模型的零件来生成几何图形,以便在 FreeCAD 之外进行进一步处理(与此问题无关)
除了无法更改用于计算模型的参数值外,该脚本正在运行。生成的几何图形始终反映与模型一起保存的原始值。
我添加了断言命令(第 44 行)。 geometry[0][0][2]
是一个向量,其 x
坐标恰好等于电子表格单元格 A5 中 width
参数的值。
如果调用脚本为
python so.py so_example.FCStd 10 5 3 6
断言失败,因为几何是根据电子表格的原始值 (width=2
) 而不是覆盖的值 (width=3
) 生成的。
如何有效地覆盖那些电子表格单元格值?
脚本so.py:
FREECADPATH = '/usr/lib/freecad/lib'
import sys
sys.path.append(FREECADPATH)
from collections import defaultdict
def convert_model(filename, arclen, radius, width, height):
try:
import FreeCAD
from FreeCAD import Vector
except ValueError:
print ('import error\n')
else:
FreeCAD.open(filename)
doc = App.ActiveDocument
sheet = doc.Spreadsheet
print("mode = "+str(sheet.getEditorMode("A5")))
sheet.setEditorMode("A5", 0)
print("mode' = "+str(sheet.getEditorMode("A5")))
print("arclen = "+str(sheet.arclen))
print("radius = "+str(sheet.radius))
print("angle = "+str(sheet.angle))
print("width = "+str(sheet.width))
print("height = "+str(sheet.height))
sheet.set("arclen", str(arclen))
sheet.set("radius", str(radius))
sheet.set("width", str(width))
sheet.set("height", str(height))
sheet.recompute()
# verify that the radius and also the dependent angle have changed after the recomputer
print("arclen' = "+str(sheet.arclen))
print("radius' = "+str(sheet.radius))
print("angle' = "+str(sheet.angle))
print("width' = "+str(sheet.width))
print("height' = "+str(sheet.height))
# recompute the model
doc.recompute()
geometry = generate_geometry(doc)
print("generated geometry: "+str(geometry[0][0]))
assert geometry[0][0][2] == Vector(width, 0, 0)
def generate_geometry(doc):
objects = doc.Objects
return [tessellate_shape(shaped) for shaped in objects if shaped.TypeId == 'PartDesign::Body']
def tessellate_shape(shaped):
return shaped.Shape.tessellate(0.1)
def main():
filename=sys.argv[1]
arclen=float(sys.argv[2])
radius=float(sys.argv[3])
width=float(sys.argv[4])
height=float(sys.argv[5])
convert_model(filename, arclen, radius, width, height)
if __name__=='__main__':
main()
终于我找到了如何让它工作: 更改电子表格中单元格值的关键似乎是使用
sheet.set("radius", str(radius))
sheet.recompute()
这与做
不同sheet.radius = str(radius)
sheet.recompute()
这对模型几何没有影响。这些电子表格属性似乎是实际单元格值的只读副本。但是,通过调用 Spreadsheet.recompute(),这些属性也会更新。
更新:
要在更新电子表格属性后更改实际模型的几何形状,还需要在每个模型对象上调用 touch(),然后调用 doc.recompute()。