第三章:几何建模基础
3.1 OpenCascade内核介绍
3.1.1 什么是OpenCascade
OpenCascade Technology(简称OCCT或OCC)是一个开源的3D CAD/CAM/CAE内核,由法国Matra Datavision公司最初开发,后来开源并由OpenCascade公司维护。它是世界上最著名的开源几何建模内核之一,被广泛应用于工业设计、仿真分析、数控加工等领域。
OpenCascade的核心特性包括:
- 边界表示法(B-Rep)建模:采用精确的边界表示法来描述3D几何形状,支持任意复杂的曲面和实体
- 参数化曲线和曲面:支持NURBS曲线、Bezier曲线、圆锥曲线等多种参数化几何元素
- 布尔运算:提供高效可靠的布尔运算算法,包括并集、差集、交集
- 曲面操作:支持曲面偏移、缝合、填充等高级操作
- 数据交换:支持STEP、IGES、BREP等标准格式的导入导出
3.1.2 WebAssembly集成
Chili3D通过Emscripten工具链将OpenCascade编译为WebAssembly(WASM),使其能够在浏览器中高效运行。这种方式具有以下优势:
- 接近原生性能:WebAssembly提供接近原生代码的执行速度
- 无需安装:用户无需安装任何本地软件
- 跨平台兼容:在所有支持WebAssembly的浏览器中都能运行
- 安全沙箱:在浏览器沙箱中运行,安全性更高
WASM初始化流程:
// chili-wasm/src/wasm.ts
export async function initChiliWasm(): Promise<void> {// 加载WASM模块const wasmModule = await import("./chili_wasm.js");// 初始化模块await wasmModule.default();// 注册到全局服务Services.register("wasmModule", wasmModule);
}
3.1.3 C++绑定层
Chili3D使用Embind(Emscripten的C++绑定工具)来暴露OpenCascade的API给JavaScript:
// cpp/src/bindings.cpp
#include <emscripten/bind.h>
#include <BRepPrimAPI_MakeBox.hxx>using namespace emscripten;TopoDS_Shape makeBox(double x, double y, double z, double dx, double dy, double dz) {gp_Pnt origin(x, y, z);TopoDS_Shape box = BRepPrimAPI_MakeBox(origin, dx, dy, dz).Shape();return box;
}EMSCRIPTEN_BINDINGS(chili_wasm) {function("makeBox", &makeBox);// 更多绑定...
}
3.2 形状类型体系
3.2.1 拓扑结构
OpenCascade使用拓扑结构来描述形状的组成关系。在Chili3D中,这些概念被封装到TypeScript接口中:
// chili-core/src/shape/shapeType.ts
export enum ShapeType {Compound = 1, // 复合体:多个形状的集合CompoundSolid = 2, // 复合实体:多个实体的集合Solid = 4, // 实体:封闭的3D体积Shell = 8, // 壳:多个面的集合Face = 16, // 面:有界的曲面Wire = 32, // 线框:多条边的连续序列Edge = 64, // 边:有界的曲线Vertex = 128, // 顶点:空间中的点Shape = 256 // 通用形状类型
}
拓扑层次关系:
Compound(复合体)└── Solid(实体)└── Shell(壳)└── Face(面)└── Wire(线框)└── Edge(边)└── Vertex(顶点)
3.2.2 形状接口
// chili-core/src/shape/shape.ts
export interface IShape {readonly shapeType: ShapeType;readonly isNull: boolean;readonly isValid: boolean;// 获取子形状findSubShapes(type: ShapeType): IShape[];findAncestors(subShape: IShape, ancestorType: ShapeType): IShape[];// 几何信息getBoundingBox(): BoundingBox;getCenter(): XYZ;// 变换transform(matrix: Matrix4): IShape;mirror(plane: Plane): IShape;// 网格化mesh(deflection: number): MeshData;// 序列化toBrep(): string;static fromBrep(brep: string): IShape;
}
3.2.3 形状实现
// chili-wasm/src/shape.ts
export class Shape implements IShape {private _handle: number; // WASM对象句柄private _shapeType?: ShapeType;constructor(handle: number) {this._handle = handle;}get shapeType(): ShapeType {if (this._shapeType === undefined) {this._shapeType = wasm.getShapeType(this._handle);}return this._shapeType;}get isNull(): boolean {return wasm.isShapeNull(this._handle);}get isValid(): boolean {return !this.isNull && wasm.isShapeValid(this._handle);}findSubShapes(type: ShapeType): IShape[] {const handles = wasm.findSubShapes(this._handle, type);return handles.map(h => new Shape(h));}getBoundingBox(): BoundingBox {const [xmin, ymin, zmin, xmax, ymax, zmax] = wasm.getBoundingBox(this._handle);return new BoundingBox(new XYZ(xmin, ymin, zmin),new XYZ(xmax, ymax, zmax));}transform(matrix: Matrix4): IShape {const newHandle = wasm.transformShape(this._handle, matrix.toArray());return new Shape(newHandle);}mesh(deflection: number = 0.1): MeshData {return wasm.meshShape(this._handle, deflection);}// 清理资源dispose(): void {wasm.disposeShape(this._handle);this._handle = 0;}
}
3.3 形状工厂
3.3.1 工厂接口
形状工厂负责创建各种几何形状:
// chili-core/src/shape/shapeFactory.ts
export interface IShapeFactory {// 基本几何体box(origin: XYZ, dx: number, dy: number, dz: number): Result<IShape>;sphere(center: XYZ, radius: number): Result<IShape>;cylinder(axis: Ray, radius: number, height: number): Result<IShape>;cone(axis: Ray, r1: number, r2: number, height: number): Result<IShape>;// 曲线line(start: XYZ, end: XYZ): Result<IEdge>;arc(center: XYZ, start: XYZ, end: XYZ): Result<IEdge>;circle(center: XYZ, normal: XYZ, radius: number): Result<IEdge>;bezier(poles: XYZ[], weights?: number[]): Result<IEdge>;// 线框和面wire(edges: IEdge[]): Result<IWire>;face(wire: IWire): Result<IFace>;// 实体操作extrude(profile: IShape, direction: XYZ, length: number): Result<IShape>;revolve(profile: IShape, axis: Ray, angle: number): Result<IShape>;sweep(profile: IShape, path: IWire): Result<IShape>;loft(sections: IWire[], solid: boolean): Result<IShape>;// 布尔运算booleanUnion(shape1: IShape, shape2: IShape): Result<IShape>;booleanCut(shape1: IShape, shape2: IShape): Result<IShape>;booleanIntersect(shape1: IShape, shape2: IShape): Result<IShape>;// 修改操作fillet(shape: IShape, edges: IEdge[], radius: number): Result<IShape>;chamfer(shape: IShape, edges: IEdge[], distance: number): Result<IShape>;offset(shape: IShape, distance: number): Result<IShape>;
}
3.3.2 工厂实现
// chili-wasm/src/factory.ts
export class ShapeFactory implements IShapeFactory {box(origin: XYZ, dx: number, dy: number, dz: number): Result<IShape> {try {const handle = wasm.makeBox(origin.x, origin.y, origin.z, dx, dy, dz);return Result.ok(new Shape(handle));} catch (e) {return Result.error(`Failed to create box: ${e}`);}}sphere(center: XYZ, radius: number): Result<IShape> {if (radius <= 0) {return Result.error("Radius must be positive");}try {const handle = wasm.makeSphere(center.x, center.y, center.z, radius);return Result.ok(new Shape(handle));} catch (e) {return Result.error(`Failed to create sphere: ${e}`);}}cylinder(axis: Ray, radius: number, height: number): Result<IShape> {if (radius <= 0 || height <= 0) {return Result.error("Radius and height must be positive");}try {const handle = wasm.makeCylinder(axis.origin.x, axis.origin.y, axis.origin.z,axis.direction.x, axis.direction.y, axis.direction.z,radius, height);return Result.ok(new Shape(handle));} catch (e) {return Result.error(`Failed to create cylinder: ${e}`);}}extrude(profile: IShape, direction: XYZ, length: number): Result<IShape> {if (length === 0) {return Result.error("Extrusion length cannot be zero");}try {const normalized = direction.normalize();const handle = wasm.makePrism((profile as Shape).handle,normalized.x * length,normalized.y * length,normalized.z * length);return Result.ok(new Shape(handle));} catch (e) {return Result.error(`Failed to extrude: ${e}`);}}booleanUnion(shape1: IShape, shape2: IShape): Result<IShape> {try {const handle = wasm.booleanFuse((shape1 as Shape).handle,(shape2 as Shape).handle);return Result.ok(new Shape(handle));} catch (e) {return Result.error(`Boolean union failed: ${e}`);}}booleanCut(shape1: IShape, shape2: IShape): Result<IShape> {try {const handle = wasm.booleanCut((shape1 as Shape).handle,(shape2 as Shape).handle);return Result.ok(new Shape(handle));} catch (e) {return Result.error(`Boolean cut failed: ${e}`);}}fillet(shape: IShape, edges: IEdge[], radius: number): Result<IShape> {if (radius <= 0) {return Result.error("Fillet radius must be positive");}try {const edgeHandles = edges.map(e => (e as Shape).handle);const handle = wasm.makeFillet((shape as Shape).handle,edgeHandles,radius);return Result.ok(new Shape(handle));} catch (e) {return Result.error(`Fillet failed: ${e}`);}}
}
3.4 曲线与曲面
3.4.1 曲线类型
Chili3D支持多种曲线类型:
// chili-core/src/shape/curve.ts
export enum CurveType {Line = 0, // 直线Circle = 1, // 圆Ellipse = 2, // 椭圆Hyperbola = 3, // 双曲线Parabola = 4, // 抛物线BezierCurve = 5, // Bezier曲线BSplineCurve = 6, // B样条曲线TrimmedCurve = 7, // 裁剪曲线OffsetCurve = 8, // 偏移曲线OtherCurve = 9 // 其他曲线
}export interface ICurve {readonly curveType: CurveType;readonly isClosed: boolean;readonly isPeriodic: boolean;// 参数化接口parameter(point: XYZ): number;point(parameter: number): XYZ;tangent(parameter: number): XYZ;// 范围firstParameter(): number;lastParameter(): number;// 转换toEdge(): IEdge;trim(u1: number, u2: number): ICurve;reverse(): ICurve;
}
3.4.2 曲线实现
// chili-wasm/src/curve.ts
export class Curve implements ICurve {private _handle: number;constructor(handle: number) {this._handle = handle;}get curveType(): CurveType {return wasm.getCurveType(this._handle);}get isClosed(): boolean {return wasm.isCurveClosed(this._handle);}parameter(point: XYZ): number {return wasm.curveParameter(this._handle, point.x, point.y, point.z);}point(parameter: number): XYZ {const [x, y, z] = wasm.curvePoint(this._handle, parameter);return new XYZ(x, y, z);}tangent(parameter: number): XYZ {const [x, y, z] = wasm.curveTangent(this._handle, parameter);return new XYZ(x, y, z);}trim(u1: number, u2: number): ICurve {const handle = wasm.trimCurve(this._handle, u1, u2);return new Curve(handle);}
}// 具体曲线类型
export class LineCurve extends Curve {get start(): XYZ {return this.point(this.firstParameter());}get end(): XYZ {return this.point(this.lastParameter());}get direction(): XYZ {return this.end.sub(this.start).normalize();}get length(): number {return this.start.distanceTo(this.end);}
}export class CircleCurve extends Curve {get center(): XYZ {const [x, y, z] = wasm.circleCenter(this._handle);return new XYZ(x, y, z);}get radius(): number {return wasm.circleRadius(this._handle);}get normal(): XYZ {const [x, y, z] = wasm.circleNormal(this._handle);return new XYZ(x, y, z);}
}
3.4.3 曲面类型
// chili-core/src/shape/surface.ts
export enum SurfaceType {Plane = 0, // 平面Cylinder = 1, // 圆柱面Cone = 2, // 圆锥面Sphere = 3, // 球面Torus = 4, // 圆环面BezierSurface = 5, // Bezier曲面BSplineSurface = 6, // B样条曲面SurfaceOfRevolution = 7,// 旋转曲面SurfaceOfExtrusion = 8, // 拉伸曲面OffsetSurface = 9, // 偏移曲面OtherSurface = 10 // 其他曲面
}export interface ISurface {readonly surfaceType: SurfaceType;readonly isUClosed: boolean;readonly isVClosed: boolean;// 参数化接口point(u: number, v: number): XYZ;normal(u: number, v: number): XYZ;// 范围uRange(): [number, number];vRange(): [number, number];// 转换toFace(): IFace;
}
3.5 布尔运算
3.5.1 布尔运算类型
export enum BooleanType {Union = 0, // 并集Cut = 1, // 差集Intersect = 2, // 交集Common = 3 // 公共部分
}
3.5.2 布尔运算实现
// chili/src/bodys/boolean.ts
@Serializable("BooleanBody")
export class BooleanBody extends Body {@Property()private _operationType: BooleanType;@Property()private _target: IBody;@Property()private _tool: IBody;constructor(document: IDocument,operationType: BooleanType,target: IBody,tool: IBody) {super(document);this._operationType = operationType;this._target = target;this._tool = tool;}protected generateShape(): Result<IShape> {const targetShape = this._target.shape;const toolShape = this._tool.shape;if (!targetShape || !toolShape) {return Result.error("Invalid input shapes");}const factory = this.document.application.shapeFactory;switch (this._operationType) {case BooleanType.Union:return factory.booleanUnion(targetShape, toolShape);case BooleanType.Cut:return factory.booleanCut(targetShape, toolShape);case BooleanType.Intersect:return factory.booleanIntersect(targetShape, toolShape);default:return Result.error("Unknown boolean type");}}
}
3.5.3 布尔运算命令
// chili/src/commands/boolean.ts
@command({name: "Modify.Boolean.Union",icon: "icon-union",display: "command.union"
})
export class BooleanUnionCommand implements ICommand {async execute(document: IDocument): Promise<void> {// 选择目标对象const targetResult = await document.selection.pickShape({prompt: t("prompt.selectTarget"),filter: ShapeType.Solid | ShapeType.Shell});if (!targetResult.success) return;// 选择工具对象const toolResult = await document.selection.pickShape({prompt: t("prompt.selectTool"),filter: ShapeType.Solid | ShapeType.Shell});if (!toolResult.success) return;// 创建布尔体const body = new BooleanBody(document,BooleanType.Union,targetResult.data.body,toolResult.data.body);// 添加到文档const node = new GeometryNode(document, "Union", body);document.addNode(node);// 隐藏原始对象targetResult.data.node.visible = false;toolResult.data.node.visible = false;}
}
3.6 几何体实现
3.6.1 Body基类
所有几何体都继承自Body基类:
// chili/src/bodys/body.ts
export abstract class Body extends Observable implements IBody {private _shape?: IShape;private _needsUpdate: boolean = true;constructor(readonly document: IDocument) {super();}get shape(): IShape | undefined {if (this._needsUpdate || !this._shape) {const result = this.generateShape();if (result.isOk) {this._shape = result.value;} else {console.error(result.error);this._shape = undefined;}this._needsUpdate = false;}return this._shape;}protected abstract generateShape(): Result<IShape>;protected invalidate(): void {this._needsUpdate = true;this._shape?.dispose();this._shape = undefined;this.notify("shapeChanged");}
}
3.6.2 长方体
// chili/src/bodys/box.ts
@Serializable("BoxBody")
export class BoxBody extends Body {@Property()private _origin: XYZ;@Property()private _dx: number;@Property()private _dy: number;@Property()private _dz: number;constructor(document: IDocument,origin: XYZ,dx: number,dy: number,dz: number) {super(document);this._origin = origin;this._dx = dx;this._dy = dy;this._dz = dz;}get origin(): XYZ { return this._origin; }set origin(value: XYZ) {if (!this._origin.equals(value)) {this._origin = value;this.invalidate();}}get dx(): number { return this._dx; }set dx(value: number) {if (this._dx !== value) {this._dx = value;this.invalidate();}}protected generateShape(): Result<IShape> {return this.document.application.shapeFactory.box(this._origin, this._dx, this._dy, this._dz);}
}
3.6.3 球体
// chili/src/bodys/sphere.ts
@Serializable("SphereBody")
export class SphereBody extends Body {@Property()private _center: XYZ;@Property()private _radius: number;constructor(document: IDocument, center: XYZ, radius: number) {super(document);this._center = center;this._radius = radius;}get center(): XYZ { return this._center; }set center(value: XYZ) {if (!this._center.equals(value)) {this._center = value;this.invalidate();}}get radius(): number { return this._radius; }set radius(value: number) {if (this._radius !== value && value > 0) {this._radius = value;this.invalidate();}}protected generateShape(): Result<IShape> {return this.document.application.shapeFactory.sphere(this._center, this._radius);}
}
3.6.4 拉伸体
// chili/src/bodys/prism.ts
@Serializable("PrismBody")
export class PrismBody extends Body {@Property()private _profile: IBody;@Property()private _direction: XYZ;@Property()private _length: number;constructor(document: IDocument,profile: IBody,direction: XYZ,length: number) {super(document);this._profile = profile;this._direction = direction;this._length = length;// 监听轮廓变化profile.addObserver("shapeChanged", () => this.invalidate());}protected generateShape(): Result<IShape> {const profileShape = this._profile.shape;if (!profileShape) {return Result.error("Invalid profile shape");}return this.document.application.shapeFactory.extrude(profileShape,this._direction,this._length);}
}
3.6.5 旋转体
// chili/src/bodys/revolve.ts
@Serializable("RevolveBody")
export class RevolveBody extends Body {@Property()private _profile: IBody;@Property()private _axis: Ray;@Property()private _angle: number;constructor(document: IDocument,profile: IBody,axis: Ray,angle: number) {super(document);this._profile = profile;this._axis = axis;this._angle = angle;profile.addObserver("shapeChanged", () => this.invalidate());}protected generateShape(): Result<IShape> {const profileShape = this._profile.shape;if (!profileShape) {return Result.error("Invalid profile shape");}return this.document.application.shapeFactory.revolve(profileShape,this._axis,this._angle);}
}
3.7 网格化与显示
3.7.1 网格数据结构
将几何形状转换为可显示的三角网格:
// chili-core/src/shape/meshData.ts
export interface MeshData {// 顶点位置 (x, y, z)positions: Float32Array;// 顶点法向量 (nx, ny, nz)normals: Float32Array;// 顶点UV坐标 (u, v)uvs?: Float32Array;// 三角形索引indices: Uint32Array;// 边数据edges?: EdgeMeshData;
}export interface EdgeMeshData {// 边线顶点positions: Float32Array;// 边线索引 (起点, 终点)indices: Uint32Array;
}
3.7.2 网格生成
// chili-wasm/src/mesher.ts
export class Mesher {/*** 将形状转换为网格* @param shape 输入形状* @param deflection 网格精度(弦偏差)* @param angularDeflection 角度偏差*/static meshShape(shape: IShape,deflection: number = 0.1,angularDeflection: number = 0.5): MeshData {const handle = (shape as Shape).handle;// 调用WASM进行网格化const result = wasm.meshShape(handle, deflection, angularDeflection);return {positions: new Float32Array(result.positions),normals: new Float32Array(result.normals),indices: new Uint32Array(result.indices),edges: result.edges ? {positions: new Float32Array(result.edges.positions),indices: new Uint32Array(result.edges.indices)} : undefined};}
}
3.7.3 与Three.js集成
// chili-three/src/threeGeometry.ts
export class ThreeGeometry {static fromMeshData(meshData: MeshData): THREE.BufferGeometry {const geometry = new THREE.BufferGeometry();// 设置顶点属性geometry.setAttribute("position",new THREE.BufferAttribute(meshData.positions, 3));geometry.setAttribute("normal",new THREE.BufferAttribute(meshData.normals, 3));if (meshData.uvs) {geometry.setAttribute("uv",new THREE.BufferAttribute(meshData.uvs, 2));}// 设置索引geometry.setIndex(new THREE.BufferAttribute(meshData.indices, 1));return geometry;}static createEdgeGeometry(edgeData: EdgeMeshData): THREE.BufferGeometry {const geometry = new THREE.BufferGeometry();geometry.setAttribute("position",new THREE.BufferAttribute(edgeData.positions, 3));geometry.setIndex(new THREE.BufferAttribute(edgeData.indices, 1));return geometry;}
}
3.8 几何计算
3.8.1 交点计算
export class GeometryHelper {/*** 计算两条曲线的交点*/static curveIntersections(curve1: ICurve, curve2: ICurve): XYZ[] {return wasm.curveCurveIntersection((curve1 as Curve).handle,(curve2 as Curve).handle).map(([x, y, z]) => new XYZ(x, y, z));}/*** 计算曲线与曲面的交点*/static curveSurfaceIntersections(curve: ICurve, surface: ISurface): XYZ[] {return wasm.curveSurfaceIntersection((curve as Curve).handle,(surface as Surface).handle).map(([x, y, z]) => new XYZ(x, y, z));}/*** 计算点到曲线的最近点*/static nearestPointOnCurve(point: XYZ, curve: ICurve): XYZ {const [x, y, z] = wasm.nearestPointOnCurve(point.x, point.y, point.z,(curve as Curve).handle);return new XYZ(x, y, z);}/*** 计算点到曲面的最近点*/static nearestPointOnSurface(point: XYZ, surface: ISurface): XYZ {const [x, y, z] = wasm.nearestPointOnSurface(point.x, point.y, point.z,(surface as Surface).handle);return new XYZ(x, y, z);}
}
3.8.2 距离计算
export class DistanceHelper {/*** 计算两个形状之间的最小距离*/static shapeDistance(shape1: IShape, shape2: IShape): number {return wasm.shapeDistance((shape1 as Shape).handle,(shape2 as Shape).handle);}/*** 计算点到形状的最小距离*/static pointShapeDistance(point: XYZ, shape: IShape): number {return wasm.pointShapeDistance(point.x, point.y, point.z,(shape as Shape).handle);}
}
3.8.3 测量工具
// chili/src/commands/measure/measureDistance.ts
@command({name: "Measure.Distance",icon: "icon-measure-distance",display: "command.measureDistance"
})
export class MeasureDistanceCommand implements ICommand {async execute(document: IDocument): Promise<void> {// 选择第一个点const point1Result = await document.selection.pickPoint({prompt: t("prompt.selectFirstPoint")});if (!point1Result.success) return;// 选择第二个点const point2Result = await document.selection.pickPoint({prompt: t("prompt.selectSecondPoint")});if (!point2Result.success) return;// 计算距离const distance = point1Result.data.distanceTo(point2Result.data);// 显示结果Toast.show(`${t("measure.distance")}: ${distance.toFixed(3)}`);}
}
3.9 数据交换
3.9.1 支持的格式
Chili3D支持多种标准CAD格式:
- STEP(.step, .stp):ISO标准格式,最常用的CAD交换格式
- IGES(.iges, .igs):初始图形交换规范,较老但广泛支持
- BREP(.brep):OpenCascade原生格式
3.9.2 导入实现
// chili-builder/src/defaultDataExchange.ts
export class DefaultDataExchange implements IDataExchange {async import(file: File): Promise<Result<IShape[]>> {const extension = file.name.split('.').pop()?.toLowerCase();const buffer = await file.arrayBuffer();switch (extension) {case 'step':case 'stp':return this.importStep(buffer);case 'iges':case 'igs':return this.importIges(buffer);case 'brep':return this.importBrep(buffer);default:return Result.error(`Unsupported format: ${extension}`);}}private importStep(buffer: ArrayBuffer): Result<IShape[]> {try {const shapes = wasm.readStep(new Uint8Array(buffer));return Result.ok(shapes.map(h => new Shape(h)));} catch (e) {return Result.error(`STEP import failed: ${e}`);}}
}
3.9.3 导出实现
export class DefaultDataExchange implements IDataExchange {async export(shapes: IShape[],format: ExportFormat,filename: string): Promise<void> {const handles = shapes.map(s => (s as Shape).handle);let data: Uint8Array;switch (format) {case ExportFormat.STEP:data = wasm.writeStep(handles);break;case ExportFormat.IGES:data = wasm.writeIges(handles);break;case ExportFormat.BREP:data = wasm.writeBrep(handles);break;default:throw new Error(`Unsupported format: ${format}`);}// 创建下载链接const blob = new Blob([data], { type: "application/octet-stream" });const url = URL.createObjectURL(blob);const a = document.createElement("a");a.href = url;a.download = filename;a.click();URL.revokeObjectURL(url);}
}
3.10 本章小结
本章深入介绍了Chili3D的几何建模基础,包括:
- OpenCascade内核:介绍了OCCT的特性和WebAssembly集成方式
- 形状类型体系:详细说明了拓扑结构和形状接口设计
- 形状工厂:展示了各种几何形状的创建方法
- 曲线与曲面:介绍了参数化几何元素的表示和操作
- 布尔运算:说明了并集、差集、交集等布尔操作的实现
- 几何体实现:展示了各种具体几何体的实现方式
- 网格化与显示:介绍了将几何形状转换为可显示网格的过程
- 几何计算:介绍了交点、距离等几何计算功能
- 数据交换:说明了STEP、IGES等格式的导入导出
掌握这些几何建模知识,是进行Chili3D二次开发的重要基础。在下一章中,我们将深入探讨用户界面与交互系统。
下一章预告:第四章将详细介绍Chili3D的用户界面系统,包括UI组件库、功能区设计、视口交互、选择系统等核心内容。