Как обновить значения электронных таблиц с помощью модуля FreeCAD python - PullRequest
2 голосов
/ 15 марта 2020

Допустим, у меня есть модель FreeCAD, которая определяет определенную геометрию с размерами высоты, ширины и длины, которые определены в ячейках электронной таблицы модели. Я хочу построить конвейер автоматизации в автономном скрипте Python с использованием модуля FreeCAD, который - считывает эту модель - устанавливает для ячеек электронной таблицы значения, предоставленные клиентом - перекомпилирует модель соответствующим образом - генерирует геометрию путем тесселяции частей модели для дальнейшая обработка вне FreeCAD (не имеет отношения к этому вопросу)

Скрипт работает, за исключением того, что он не может изменить значения параметров, которые используются для вычисления модели. Полученная геометрия всегда отражает исходные значения, которые были сохранены с моделью.

Я добавил команду подтверждения (строка 44). geometry[0][0][2] - это вектор, координата x которого равна значению параметра width в ячейке электронной таблицы A5.

Если один из сценариев вызывается как

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

Пример модели FreeCAD

1 Ответ

1 голос
/ 14 апреля 2020

Наконец я узнал, как заставить это работать: ключ к изменению значений ячеек в электронной таблице, кажется, заключается в использовании

sheet.set("radius", str(radius))
sheet.recompute()

Это отличается от выполнения

sheet.radius = str(radius)
sheet.recompute()

который не влияет на геометрию модели. Эти свойства электронной таблицы являются копиями реальных значений ячеек, доступных только для чтения. Однако при вызове Spreadsheet.recompute () эти свойства также обновляются.

...