diff --git a/freecad/main.md b/freecad/main.md new file mode 100644 index 0000000..7d14d82 --- /dev/null +++ b/freecad/main.md @@ -0,0 +1,211 @@ +# 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分析脚本 + +```python +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2023 veypi +# +# 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 求解器 + +[参考源码](https://github.com/FreeCAD/FreeCAD/compare/a03eb6b9625ba...dfc01ec949525) + +步骤: + + +[添加mesh导出程序](https://github.com/FreeCAD/FreeCAD/commit/e100971fa0a0c17b5e4906ac540fa31ac0d11766) + +[添加求解器,写入程序,任务程序,约束程序](https://github.com/FreeCAD/FreeCAD/commit/cdcd271b4c97a27431dc28d852f6ed7e171dba67) + +[添加求解器单元测试](https://github.com/FreeCAD/FreeCAD/commit/005c66f4ecc7fb1690a54592a00ec490146b985d) + +[添加文档](https://github.com/FreeCAD/FreeCAD/commit/cfc08b811ff09628b1468e21e9e823587efc799a) + +[添加界面参数](https://github.com/FreeCAD/FreeCAD/commit/dfc01ec949525162c70648ea6d6d93c818907f1f) +