解锁FreeCAD Python API:从自动化建模到工程仿真的全流程实践指南
在现代工程设计领域,3D建模软件已成为不可或缺的工具。然而,传统的手动建模方式往往面临效率低下、重复性高、参数调整困难等挑战。FreeCAD作为一款开源的参数化3D建模软件,其强大的Python API为解决这些痛点提供了全新可能。本文将通过"问题导向-核心价值-分层实践-场景拓展"的四象限框架,帮助你系统掌握FreeCAD Python API的应用,实现从手动操作到自动化设计的效率跃迁。
一、问题导向:工程设计中的效率瓶颈与解决方案
1.1 重复建模的时间消耗问题
痛点描述:在机械设计中,经常需要创建多个结构相似但尺寸不同的零部件,手动重复建模不仅耗时,还容易引入人为错误。
解决方案:利用FreeCAD Python API实现参数化建模,通过调整参数自动生成系列化零件。
代码示例:参数化创建螺栓系列
import FreeCAD as App
import Part
def create_bolt_assembly(bolt_params):
"""
创建参数化螺栓组件
参数:
bolt_params: 包含螺栓参数的字典,格式如下:
{
"diameter": 10.0, # 螺栓直径(mm)
"length": 50.0, # 螺栓长度(mm)
"head_diameter": 16.0, # 螺栓头直径(mm)
"head_height": 6.0, # 螺栓头高度(mm)
"thread_pitch": 1.5 # 螺纹螺距(mm)
}
"""
# 创建新文档
doc = App.newDocument("BoltGenerator")
# 创建螺栓杆
bolt_shaft = Part.makeCylinder(
bolt_params["diameter"] / 2,
bolt_params["length"] - bolt_params["head_height"]
)
# 创建螺栓头(六边形)
bolt_head = Part.makePolygon([
App.Vector(bolt_params["head_diameter"]/2, 0, bolt_params["length"] - bolt_params["head_height"]),
App.Vector(bolt_params["head_diameter"]/2 * 0.866, bolt_params["head_diameter"]/2 * 0.5, bolt_params["length"] - bolt_params["head_height"]),
App.Vector(-bolt_params["head_diameter"]/2 * 0.866, bolt_params["head_diameter"]/2 * 0.5, bolt_params["length"] - bolt_params["head_height"]),
App.Vector(-bolt_params["head_diameter"]/2, 0, bolt_params["length"] - bolt_params["head_height"]),
App.Vector(-bolt_params["head_diameter"]/2 * 0.866, -bolt_params["head_diameter"]/2 * 0.5, bolt_params["length"] - bolt_params["head_height"]),
App.Vector(bolt_params["head_diameter"]/2 * 0.866, -bolt_params["head_diameter"]/2 * 0.5, bolt_params["length"] - bolt_params["head_height"]),
App.Vector(bolt_params["head_diameter"]/2, 0, bolt_params["length"] - bolt_params["head_height"])
])
bolt_head_face = Part.Face(bolt_head)
bolt_head_solid = bolt_head_face.extrude(App.Vector(0, 0, bolt_params["head_height"]))
# 合并螺栓头和螺栓杆
bolt = bolt_shaft.fuse(bolt_head_solid)
# 添加到文档
obj = doc.addObject("Part::Feature", "Bolt")
obj.Shape = bolt
doc.recompute()
return doc
# 创建M10和M12两种规格的螺栓
m10_bolt = create_bolt_assembly({
"diameter": 10.0, "length": 50.0,
"head_diameter": 16.0, "head_height": 6.0,
"thread_pitch": 1.5
})
m12_bolt = create_bolt_assembly({
"diameter": 12.0, "length": 60.0,
"head_diameter": 19.0, "head_height": 7.5,
"thread_pitch": 1.75
})
应用场景:标准件库创建、系列化产品设计、快速原型迭代。
适用场景:当需要创建多个尺寸不同但结构相似的零件时,参数化建模能显著减少重复劳动。
常见误区:过度参数化导致模型复杂度过高,应只对关键尺寸进行参数化控制。
优化建议:将常用参数保存到配置文件或数据库,实现参数的集中管理和快速调用。
1.2 复杂装配体的定位与约束挑战
痛点描述:手动装配多个零件时,精确调整零件位置和添加约束关系耗时且困难,尤其在包含数十个零件的复杂装配体中。
解决方案:使用Python API自动化装配过程,通过代码精确控制零件位置和添加约束关系。
代码示例:自动化装配机械臂组件
import FreeCAD as App
import FreeCADGui as Gui
import Assembly
def assemble_mechanical_arm():
"""自动化装配机械臂组件"""
# 创建新文档
doc = App.newDocument("MechanicalArmAssembly")
# 创建基础部件
base = Part.makeBox(100, 80, 20)
base_obj = doc.addObject("Part::Feature", "Base")
base_obj.Shape = base
# 创建大臂
boom = Part.makeBox(150, 30, 25)
boom_obj = doc.addObject("Part::Feature", "Boom")
boom_obj.Shape = boom
# 设置大臂位置
boom_placement = App.Placement()
boom_placement.Base = App.Vector(40, 25, 15) # 定位到大臂连接点
boom_obj.Placement = boom_placement
# 创建小臂
stick = Part.makeBox(120, 25, 20)
stick_obj = doc.addObject("Part::Feature", "Stick")
stick_obj.Shape = stick
# 设置小臂位置
stick_placement = App.Placement()
stick_placement.Base = App.Vector(190, 30, 15) # 定位到小臂连接点
stick_obj.Placement = stick_placement
# 创建铲斗
bucket = Part.makeBox(80, 40, 30)
bucket_obj = doc.addObject("Part::Feature", "Bucket")
bucket_obj.Shape = bucket
# 设置铲斗位置
bucket_placement = App.Placement()
bucket_placement.Base = App.Vector(310, 35, 15) # 定位到铲斗连接点
bucket_obj.Placement = bucket_placement
# 创建旋转关节
def create_joint(name, position):
joint = Part.makeCylinder(10, 30)
joint_obj = doc.addObject("Part::Feature", name)
joint_obj.Shape = joint
joint_placement = App.Placement()
joint_placement.Base = position
joint_obj.Placement = joint_placement
return joint_obj
# 添加关节
base_boom_joint = create_joint("BaseBoomJoint", App.Vector(40, 40, 15))
boom_stick_joint = create_joint("BoomStickJoint", App.Vector(190, 40, 15))
stick_bucket_joint = create_joint("StickBucketJoint", App.Vector(310, 40, 15))
# 添加装配约束
Assembly.addConstraint(doc, base, base_boom_joint, "Coincident",
{"firstElement": (base, ["Face1"]), "secondElement": (base_boom_joint, ["Face1"])})
doc.recompute()
return doc
# 执行装配
arm_assembly = assemble_mechanical_arm()
# 切换到装配工作台
Gui.activateWorkbench("AssemblyWorkbench")
应用场景:机械装置装配、机器人结构搭建、复杂机电产品设计。
适用场景:当装配体包含多个零件且需要精确相对位置关系时,API装配能提高效率和准确性。
常见误区:忽略零件之间的干涉检查,应在装配过程中加入碰撞检测。
优化建议:使用坐标系变换和矩阵运算实现复杂运动关系的精确控制。
二、核心价值:FreeCAD Python API的技术优势
2.1 设计流程的自动化与标准化
FreeCAD Python API的核心价值在于将设计流程从手动操作转变为程序化控制,实现了以下关键优势:
- 自动化重复任务:通过脚本自动执行重复性高的建模操作,如阵列特征、标准化零件创建等。
- 设计过程标准化:确保团队成员使用统一的设计标准和参数设置,减少设计差异。
- 版本控制集成:将设计参数和脚本纳入版本控制系统,实现设计过程的可追溯性。
- 跨平台一致性:在不同操作系统上保持设计流程和结果的一致性。
2.2 与同类工具的技术对比
| 特性 | FreeCAD Python API | 商业CAD软件API | 开源CAD工具 |
|---|---|---|---|
| 成本 | 完全免费 | 高昂许可费用 | 免费但功能有限 |
| 定制自由度 | 极高,可访问源代码 | 有限,受厂商限制 | 中等,扩展能力有限 |
| 社区支持 | 活跃的开源社区 | 厂商提供的技术支持 | 小型社区,支持有限 |
| 学习曲线 | 中等,需Python基础 | 陡峭,专有API学习成本高 | 平缓但功能简单 |
| 集成能力 | 高,可与各类Python库集成 | 中等,主要与厂商生态集成 | 低,集成选项有限 |
三、分层实践:从基础应用到创新实践
3.1 基础应用:API核心模块与基础操作
痛点描述:初学者面对FreeCAD复杂的API体系往往不知从何入手,难以掌握核心功能模块的使用方法。
解决方案:系统学习FreeCAD核心API模块,通过基础示例掌握关键操作。
代码示例:FreeCAD核心模块基础操作
import FreeCAD as App
import Part
import Draft
import Sketcher
def api_fundamentals_demo():
"""FreeCAD API核心功能演示"""
# 1. 文档管理
doc = App.newDocument("APIDemo")
doc.Label = "FreeCAD API基础演示"
# 2. 基础几何体创建 (Part模块)
# 创建立方体
cube = Part.makeBox(50, 30, 20)
cube_obj = doc.addObject("Part::Feature", "Cube")
cube_obj.Shape = cube
# 创建圆柱体
cylinder = Part.makeCylinder(15, 40)
cylinder_obj = doc.addObject("Part::Feature", "Cylinder")
cylinder_obj.Shape = cylinder
cylinder_obj.Placement = App.Placement(App.Vector(70, 0, 0), App.Rotation())
# 3. 草图绘制 (Sketcher模块)
sketch = doc.addObject('Sketcher::SketchObject', 'Sketch')
sketch.Placement = App.Placement(App.Vector(0, 70, 0), App.Rotation())
# 选择草图平面
sketch.Support = (doc.getObject("XY_Plane"), [""])
sketch.MapMode = "FlatFace"
# 添加几何元素
sketch.addGeometry(Sketcher.GeometryOfType('Circle', False), False)
sketch.setGeometry(0, Sketcher.Circle(App.Vector(0, 0, 0), App.Vector(0, 0, 1), 25))
# 添加约束
sketch.addConstraint(Sketcher.Constraint('Radius', 0, 20)) # 半径约束
sketch.addConstraint(Sketcher.Constraint('DistanceX', 0, 3, 0, 1, 0)) # X坐标约束
sketch.addConstraint(Sketcher.Constraint('DistanceY', 0, 3, 0, 1, 0)) # Y坐标约束
# 4. 2D到3D转换 (Draft模块)
# 创建多边形
polygon_points = [
App.Vector(0, 120, 0), App.Vector(30, 150, 0),
App.Vector(60, 120, 0), App.Vector(30, 90, 0), App.Vector(0, 120, 0)
]
polygon = Draft.make_polygon(polygon_points, closed=True)
# 拉伸为3D形状
extruded = Draft.make_extrusion(polygon, 15)
extruded.Label = "ExtrudedPolygon"
doc.recompute()
return doc
# 执行演示
demo_doc = api_fundamentals_demo()
应用场景:快速原型设计、基础零件创建、API入门学习。
适用场景:适合FreeCAD API初学者了解核心模块功能和基本操作方法。
常见误区:忽略文档重组(recompute)操作,导致模型无法正确显示。
优化建议:使用try-except结构捕获API调用可能出现的异常,提高脚本健壮性。
3.2 进阶技巧:参数化设计与批量处理
痛点描述:随着模型复杂度增加,手动修改多个关联参数变得困难,且难以实现设计方案的快速迭代。
解决方案:实现全参数化模型,通过外部数据驱动设计变更,实现批量处理和快速迭代。
代码示例:基于CSV数据的参数化零件批量生成
import FreeCAD as App
import Part
import csv
from pathlib import Path
class ParametricPartGenerator:
"""参数化零件生成器"""
def __init__(self, template_file):
"""
初始化生成器
参数:
template_file: CSV参数模板文件路径
"""
self.template_file = template_file
self.parameters = []
self.load_parameters()
def load_parameters(self):
"""从CSV文件加载参数"""
try:
with open(self.template_file, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f)
self.parameters = list(reader)
print(f"成功加载 {len(self.parameters)} 组参数")
except Exception as e:
print(f"加载参数失败: {str(e)}")
def create_part_from_params(self, params):
"""根据参数创建单个零件"""
# 创建文档
doc_name = f"Part_{params['id']}"
doc = App.newDocument(doc_name)
# 创建基础形状
length = float(params['length'])
width = float(params['width'])
height = float(params['height'])
hole_diameter = float(params['hole_diameter'])
hole_count = int(params['hole_count'])
# 创建主体
body = Part.makeBox(length, width, height)
# 添加孔特征
hole_spacing = (length - 20) / (hole_count - 1) if hole_count > 1 else 0
for i in range(hole_count):
x_pos = 10 + i * hole_spacing
hole = Part.makeCylinder(hole_diameter/2, height)
hole_placement = App.Placement(App.Vector(x_pos, width/2, 0), App.Rotation())
hole.transformShape(hole_placement.Matrix)
body = body.cut(hole)
# 添加到文档
part_obj = doc.addObject("Part::Feature", f"Part_{params['id']}")
part_obj.Shape = body
part_obj.Label = params['name']
doc.recompute()
return doc
def batch_generate(self, output_dir="generated_parts"):
"""批量生成零件"""
# 创建输出目录
Path(output_dir).mkdir(exist_ok=True)
for param_set in self.parameters:
try:
doc = self.create_part_from_params(param_set)
# 保存零件
file_path = Path(output_dir) / f"{param_set['name']}.FCStd"
doc.saveAs(str(file_path))
print(f"成功生成零件: {param_set['name']}")
App.closeDocument(doc.Name)
except Exception as e:
print(f"生成零件 {param_set['name']} 失败: {str(e)}")
# 使用示例
if __name__ == "__main__":
# 假设CSV文件格式: id,name,length,width,height,hole_diameter,hole_count
generator = ParametricPartGenerator("part_parameters.csv")
generator.batch_generate()
应用场景:系列化产品设计、根据外部数据自动生成模型、批量零件库创建。
适用场景:当需要根据外部数据(如Excel、数据库)生成大量相似零件时特别有效。
常见误区:参数验证不足导致模型生成失败,应在创建前验证参数有效性。
优化建议:结合多线程处理提高批量生成效率,尤其在处理大量零件时。
3.3 创新实践:工程仿真与数据可视化
痛点描述:传统CAD设计与工程仿真往往是分离的流程,需要在不同软件间切换,导致效率低下和数据传递错误。
解决方案:利用FreeCAD API将建模与有限元分析(FEA)集成,实现设计-分析一体化流程。
代码示例:参数化建模与有限元分析集成
import FreeCAD as App
import Part
import Fem
import ObjectsFem
import femmesh.gmshtools as gmsh_tools
import numpy as np
import matplotlib.pyplot as plt
def parametric_fea_analysis(beam_length=100, beam_width=10, beam_height=20, load=1000):
"""
参数化梁结构有限元分析
参数:
beam_length: 梁长度(mm)
beam_width: 梁宽度(mm)
beam_height: 梁高度(mm)
load: 施加的载荷(N)
"""
# 创建新文档
doc = App.newDocument("FEAAnalysis")
# 1. 创建几何模型
beam = Part.makeBox(beam_length, beam_width, beam_height)
beam_obj = doc.addObject("Part::Feature", "Beam")
beam_obj.Shape = beam
# 2. 设置有限元分析
analysis = ObjectsFem.makeAnalysis(doc, "Analysis")
# 添加材料
material = ObjectsFem.makeMaterialSolid(doc, "Material")
material.Material = {
"Name": "Steel",
"YoungsModulus": "200000 MPa",
"PoissonRatio": "0.3",
"Density": "7800 kg/m^3"
}
analysis.addObject(material)
# 添加固定约束
fixed_constraint = ObjectsFem.makeConstraintFixed(doc, "FixedConstraint")
fixed_face = beam_obj.Shape.Faces[0] # 选择梁的一个端面
fixed_constraint.References = [(beam_obj, "Face" + str(beam_obj.Shape.Faces.index(fixed_face) + 1))]
analysis.addObject(fixed_constraint)
# 添加载荷
force_constraint = ObjectsFem.makeConstraintForce(doc, "ForceConstraint")
free_face = beam_obj.Shape.Faces[1] # 选择梁的另一个端面
force_constraint.References = [(beam_obj, "Face" + str(beam_obj.Shape.Faces.index(free_face) + 1))]
force_constraint.Force = (0, 0, -load) # 向下施加力
analysis.addObject(force_constraint)
# 3. 网格划分
mesh = ObjectsFem.makeMeshGmsh(doc, "Mesh")
mesh.Part = beam_obj
mesh.ElementDimension = "3D"
mesh.CharacteristicLengthMax = 5.0 # 网格最大尺寸
# 生成网格
gmsh_mesh = gmsh_tools.GmshTools(mesh)
gmsh_mesh.create_mesh()
analysis.addObject(mesh)
# 4. 求解设置
solver = ObjectsFem.makeSolverCalculiX(doc, "Solver")
solver.AnalysisType = "static"
solver.GeometricalNonlinearity = "linear"
solver.MaterialNonlinearity = "linear"
analysis.addObject(solver)
# 运行求解
doc.recompute()
solver.Run()
# 5. 结果可视化
displacement_result = ObjectsFem.makeResultMechanical(doc, "DisplacementResult")
displacement_result.Mesh = mesh
displacement_result.ResultType = "Displacement"
displacement_result.Solver = solver
analysis.addObject(displacement_result)
# 获取位移数据并可视化
displacement_data = displacement_result.DisplacementLengths
if displacement_data:
# 这里简化处理,实际应用中需要更复杂的数据提取
max_displacement = max(displacement_data)
print(f"最大位移: {max_displacement:.4f} mm")
# 绘制简单的位移分布图
plt.figure(figsize=(10, 4))
plt.plot(displacement_data)
plt.title(f"梁结构位移分布 (载荷: {load}N)")
plt.xlabel("节点编号")
plt.ylabel("位移 (mm)")
plt.grid(True)
plt.savefig("displacement_distribution.png")
plt.close()
return doc
# 执行分析
fea_doc = parametric_fea_analysis(beam_length=150, beam_width=15, beam_height=25, load=1500)
应用场景:结构强度分析、产品优化设计、多物理场仿真、工程参数敏感性分析。
适用场景:在产品设计阶段进行快速结构验证,减少物理原型制作成本。
常见误区:网格划分质量不足导致分析结果不准确,应确保适当的网格密度。
优化建议:结合参数优化算法,自动寻找最优设计参数组合。
四、场景拓展:API底层原理与性能优化
4.1 API底层原理:FreeCAD内部工作机制
FreeCAD Python API建立在C++核心之上,通过SWIG(Simplified Wrapper and Interface Generator)实现Python与C++代码的交互。了解其底层工作机制有助于编写更高效的代码:
-
对象模型:FreeCAD中的所有实体(文档、零件、特征等)都是基于C++的
App::DocumentObject类,Python API提供了这些对象的包装器。 -
延迟计算:FreeCAD采用延迟计算机制,修改对象属性后需要调用
recompute()方法触发更新。 -
几何内核:FreeCAD使用OpenCASCADE作为几何内核,Part模块中的许多功能直接映射到底层几何库函数。
-
事务系统:FreeCAD具有完善的事务管理系统,支持操作的撤销和重做,通过
App.ActiveDocument.openTransaction()和App.ActiveDocument.commitTransaction()控制。
4.2 性能优化:提升大型模型处理效率
处理复杂模型时,API脚本可能面临性能挑战,以下是一些优化建议:
-
减少文档重组次数:多次修改后集中调用
recompute(),而非每次修改后都调用。 -
使用批量操作:优先使用支持批量处理的API方法,减少循环次数。
-
几何缓存:对于重复使用的几何形状,缓存其结果避免重复计算。
-
禁用视图更新:在批量处理时,通过
Gui.ActiveDocument.ActiveView.setEnable(False)暂时禁用视图更新。 -
使用低精度模式:在草稿阶段降低几何精度以提高处理速度。
代码示例:性能优化技术应用
import FreeCAD as App
import FreeCADGui as Gui
import Part
import time
def optimized_large_model_creation(feature_count=1000):
"""优化大型模型创建性能的示例"""
start_time = time.time()
# 创建文档
doc = App.newDocument("OptimizedModel")
# 禁用视图更新以提高性能
view = Gui.ActiveDocument.ActiveView
view.setEnable(False)
# 开始事务
doc.openTransaction("Create large model")
# 创建多个特征
for i in range(feature_count):
# 创建基础立方体
box = Part.makeBox(10, 10, 10)
# 设置位置
placement = App.Placement()
placement.Base = App.Vector(i % 10 * 15, i // 10 * 15, 0)
box.transformShape(placement.Matrix)
# 添加到文档
obj = doc.addObject("Part::Feature", f"Box_{i}")
obj.Shape = box
# 每100个特征重组一次,平衡性能和内存使用
if i % 100 == 0 and i > 0:
doc.recompute()
# 完成事务
doc.commitTransaction()
# 最后一次重组
doc.recompute()
# 重新启用视图更新
view.setEnable(True)
view.redraw()
end_time = time.time()
print(f"创建 {feature_count} 个特征耗时: {end_time - start_time:.2f} 秒")
return doc
# 测试优化效果
optimized_doc = optimized_large_model_creation(1000)
五、技术选型决策树:选择适合的API应用方式
在使用FreeCAD Python API时,根据不同的应用场景选择合适的实现方式至关重要:
-
快速原型设计
- 需求:快速创建简单模型
- 推荐:使用Draft和Part模块的高层API
- 示例:
Draft.make_cube()、Part.makeCylinder()
-
参数化零件库
- 需求:创建可配置的标准零件
- 推荐:面向对象设计+参数验证
- 示例:创建
ParametricBolt、ParametricGear类
-
批量数据处理
- 需求:从外部数据源生成模型
- 推荐:CSV/Excel导入+批量处理函数
- 示例:使用
csv模块读取参数,批量生成零件
-
工程分析集成
- 需求:将建模与仿真分析结合
- 推荐:FEM模块+结果可视化
- 示例:参数化建模+自动网格划分+有限元分析
-
复杂装配自动化
- 需求:创建包含大量零件的装配体
- 推荐:装配约束API+位置矩阵计算
- 示例:使用
Assembly模块添加约束关系
六、拓展思考题
-
参数化设计挑战:如何设计一个参数化齿轮生成器,使其能够处理不同模数、齿数和压力角的齿轮,并自动计算齿形曲线?
-
数据集成实践:如何从CAD模型中自动提取关键尺寸信息,并生成BOM(物料清单)表格,实现设计与生产数据的无缝对接?
-
性能优化探索:在处理包含10,000个以上零件的大型装配体时,如何进一步优化API脚本性能,减少内存占用和处理时间?
通过这些实践问题,你可以深入探索FreeCAD Python API的高级应用,进一步提升自动化设计能力。
七、总结
FreeCAD Python API为工程设计提供了强大的自动化工具,通过本文介绍的"问题导向-核心价值-分层实践-场景拓展"框架,你可以系统掌握从基础操作到高级应用的全流程技能。无论是参数化建模、批量处理还是工程仿真集成,FreeCAD API都能显著提升设计效率和质量。
随着开源社区的不断发展,FreeCAD的功能持续增强,其Python API也将提供更多可能性。通过持续学习和实践,你可以将这些技术应用到实际工程问题中,实现从手动设计到自动化设计的转变,成为高效的现代工程设计师。
记住,最好的学习方法是动手实践。选择一个实际项目,应用本文介绍的技术,逐步构建你的自动化设计工具箱。随着经验的积累,你将能够应对更复杂的设计挑战,释放FreeCAD Python API的全部潜力。
GLM-5智谱 AI 正式发布 GLM-5,旨在应对复杂系统工程和长时域智能体任务。Jinja00
GLM-5-w4a8GLM-5-w4a8基于混合专家架构,专为复杂系统工程与长周期智能体任务设计。支持单/多节点部署,适配Atlas 800T A3,采用w4a8量化技术,结合vLLM推理优化,高效平衡性能与精度,助力智能应用开发Jinja00
jiuwenclawJiuwenClaw 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。Python0214- QQwen3.5-397B-A17BQwen3.5 实现了重大飞跃,整合了多模态学习、架构效率、强化学习规模以及全球可访问性等方面的突破性进展,旨在为开发者和企业赋予前所未有的能力与效率。Jinja00
AtomGit城市坐标计划AtomGit 城市坐标计划开启!让开源有坐标,让城市有星火。致力于与城市合伙人共同构建并长期运营一个健康、活跃的本地开发者生态。01
OpenDeepWikiOpenDeepWiki 是 DeepWiki 项目的开源版本,旨在提供一个强大的知识管理和协作平台。该项目主要使用 C# 和 TypeScript 开发,支持模块化设计,易于扩展和定制。C#00

