mynote/freecad/main.md
2024-04-16 17:19:14 +08:00

5.7 KiB
Raw Permalink Blame History

freecad 二次开发文档

freecad 源代码目录结构

**src/**此目录包含 FreeCAD 的核心源代码。

**src/App**包含 FreeCAD 的应用程序对象的实现,如文档、事务管理和撤销/重做系统。

**src/Base**包含一些基本类和函数,如向量、矩阵和几何实体。

**src/Main**包含 FreeCAD 的主程序入口点。

**src/Mod**包含 FreeCAD 的各个模块和工作台的实现,如 Part、Sketcher、FEM 等。

**src/Gui**包含 FreeCAD 的图形用户界面GUI的实现使用 Qt 框架构建。

**src/Tools**包含一些实用工具,如编译和构建脚本。

data/:此目录包含 FreeCAD 的一些资源文件,如图标、模板、样式表等。

**doc/**此目录包含 FreeCAD 的开发文档,包括编码规范、开发指南等。

**ext/**此目录包含 FreeCAD 依赖的外部库,如 Open CASCADE、Eigen 等

fem步骤

  1. 创建或导入一个几何模型。
  2. 转到 FEM 工作台。
  3. 创建一个分析对象Analysis Container
  4. 定义材料属性。
  5. 为模型添加约束,例如固定、力和压力。
  6. 创建一个网格,将几何体划分为有限元。
  7. 选择求解器,如 CalculiX、Elmer 或 Z88。
  8. 运行分析。
  9. 查看和分析结果。

python 自动创建fem分析脚本

#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# vim:fenc=utf-8
#
# Copyright © 2023 veypi <i@veypi.com>
#
# Distributed under terms of the Apache license.
"""

"""

doc = App.newDocument("Scripted_CalculiX_Cantilever3D")
import Part

box_obj = doc.addObject('Part::Box', 'Box')
box_obj.Height = box_obj.Width = 1000
box_obj.Length = 8000

# see how our part looks like
import FreeCADGui

FreeCADGui.ActiveDocument.activeView().viewAxonometric()
FreeCADGui.SendMsgToActiveView("ViewFit")

import ObjectsFem

# analysis
analysis_object = ObjectsFem.makeAnalysis(doc, "Analysis")

# solver (we gone use the well tested CcxTools solver object)
solver_object = ObjectsFem.makeSolverCalculixCcxTools(doc, "CalculiX")
solver_object.GeometricalNonlinearity = 'linear'
solver_object.ThermoMechSteadyState = True
solver_object.MatrixSolverType = 'default'
solver_object.IterationsControlParameterTimeUse = False
analysis_object.addObject(solver_object)

# material
material_object = ObjectsFem.makeMaterialSolid(doc, "SolidMaterial")
mat = material_object.Material
mat['Name'] = "Steel-Generic"
mat['YoungsModulus'] = "210000 MPa"
mat['PoissonRatio'] = "0.30"
mat['Density'] = "7900 kg/m^3"
material_object.Material = mat
analysis_object.addObject(material_object)

# fixed_constraint
fixed_constraint = ObjectsFem.makeConstraintFixed(doc, "FemConstraintFixed")
fixed_constraint.References = [(doc.Box, "Face1")]
analysis_object.addObject(fixed_constraint)

# force_constraint
force_constraint = ObjectsFem.makeConstraintForce(doc, "FemConstraintForce")
force_constraint.References = [(doc.Box, "Face2")]
force_constraint.Force = 9000000.0
force_constraint.Direction = (doc.Box, ["Edge5"])
force_constraint.Reversed = True
analysis_object.addObject(force_constraint)

## fem mesh

femmesh_obj = ObjectsFem.makeMeshGmsh(doc, box_obj.Name + "_Mesh")
femmesh_obj.Part = doc.Box

doc.recompute()

from femmesh.gmshtools import GmshTools as gt

gmsh_mesh = gt(femmesh_obj)
error = gmsh_mesh.create_mesh()
print(error)

analysis_object.addObject(femmesh_obj)

doc.recompute()

# activating analysis

import FemGui

FemGui.setActiveAnalysis(doc.Analysis)

#from femtools import ccxtools
#fea = ccxtools.FemToolsCcx()
#fea.purge_results()
#fea.run()

from femtools import ccxtools

fea = ccxtools.FemToolsCcx()
fea.update_objects()
fea.setup_working_dir()
fea.setup_ccx()
message = fea.check_prerequisites()
if not message:
    fea.purge_results()
    fea.write_inp_file()
    # on error at inp file writing, the inp file path "" was returned (even if the file was written)
    # if we would write the inp file anyway, we need to again set it manually
    # fea.inp_file_name = '/tmp/FEMWB/FEMMeshGmsh.inp'
    fea.ccx_run()
    fea.load_results()
else:
    FreeCAD.Console.PrintError(
        "Houston, we have a problem! {}\n".format(message))  # in report view
    print("Houston, we have a problem! {}\n".format(
        message))  # in Python console

###

# show resutlt
for m in analysis_object.Group:
    if m.isDerivedFrom('Fem::FemResultObject'):
        result_object = m
        break

femmesh_obj.ViewObject.setNodeDisplacementByVectors(
    result_object.NodeNumbers, result_object.DisplacementVectors)
print(result_object.DisplacementVectors[-1])
import time

femmesh_obj.ViewObject.applyDisplacement(20)
import requests

d = requests.get(url="http://192.168.5.172:8015/file/123")
print("|%s|" % (d.text.strip()))
# 每秒请求服务器渲染变形程度
n = 0
data = 0
while 1:
    time.sleep(0.01)
    d = requests.get(url="http://192.168.5.172:8015/file/123")
    data = int(d.text.strip())
    # 更新ui
    FreeCAD.Gui.updateGui()
    #print("%s/%s"%(n, data))
    femmesh_obj.ViewObject.applyDisplacement(n)
    if data > n:
        n = n + 1
    if data < n:
        n = n - 1

添加有限元fem 求解器

参考源码

步骤:

添加mesh导出程序

添加求解器,写入程序,任务程序,约束程序

添加求解器单元测试

添加文档

添加界面参数