OdGe 是 Teigha (ODA) SDK 中一个核心的几何库命名空间 ,它封装了所有用于描述和操作几何图形的类与函数,是进行任何 CAD 数据底层处理的基础 。
OdGe 命名空间的构成与作用
OdGe 库提供了一套与 AutoCAD 原生几何库高度兼容、但独立于任何特定 CAD 平台或文件格式的纯数学几何对象模型。它的主要作用是:
- 几何数据建模:定义了点、向量、矩阵、曲线、曲面等基本几何元素的数据结构。
- 几何计算:提供了丰富的数学方法,如求交、投影、变换、求导、长度计算等。
- 与数据库实体分离 :
OdGe对象是纯粹的几何定义,不包含图层、颜色、线型等数据库属性。它们通常由OdDb(数据库实体)对象生成,用于进行复杂的几何运算。
OdGe 的核心类可按功能分类如下表所示:
| 类别 | 代表性类 | 说明 |
|---|---|---|
| 基础类型 | OdGePoint2d, OdGePoint3d OdGeVector2d, OdGeVector3d OdGeMatrix2d, OdGeMatrix3d |
表示二维/三维点、向量和变换矩阵。是所有几何计算的基础 。 |
| 曲线 (Curve) | OdGeCurve2d, OdGeCurve3d (抽象基类) OdGeLineSeg2d, OdGeLineSeg3d OdGeCircArc2d, OdGeCircArc3d OdGeEllipArc2d, OdGeEllipArc3d OdGeNurbCurve2d, **OdGeNurbCurve3d** |
定义各种二维和三维曲线。OdGeCurve3d 是抽象基类,OdGeNurbCurve3d 等是其具体实现,用于参数化曲线计算 。 |
| 曲面 (Surface) | OdGeSurface (抽象基类) OdGePlane, OdGeCylinder, OdGeCone, OdGeSphere OdGeNurbSurface |
定义各种三维曲面。 |
| 其他 | OdGeInterval, OdGeBoundBlock2d, OdGeBoundBlock3d |
表示参数区间、二维/三维边界框等。 |
在 C# (Teigha.NET) 中使用 OdGe
在 C# 项目中,你需要引用 Teigha.NET 的程序集,并通过 Teigha.Geometry 命名空间来访问 OdGe 的托管封装类。这些类的名称通常与 C++ 版本对应,但遵循 .NET 的命名规范(如使用属性而非 get/set 方法)。
- 环境配置与引用
首先,确保你的项目已正确引用 Teigha.NET 的核心程序集,特别是 Teigha.Geometry.dll。
csharp
// 在代码文件顶部添加必要的 using 指令
using Teigha.Runtime;
using Teigha.Geometry; // 这是 OdGe 在 C# 中的主要命名空间
using Teigha.DatabaseServices;
- 基础类型使用示例
创建点、向量,进行基本运算:
csharp
using Teigha.Geometry;
public void BasicGeometricOperations()
{
// 1. 创建三维点
Point3d pointA = new Point3d(10.0, 20.0, 0.0);
Point3d pointB = new Point3d(30.0, 40.0, 5.0);
// 2. 创建向量
Vector3d vectorAB = pointB - pointA; // 从A指向B的向量
Console.WriteLine($"向量 AB: ({vectorAB.X}, {vectorAB.Y}, {vectorAB.Z})");
// 3. 向量标准化(单位化)
if (!vectorAB.IsZeroLength())
{
Vector3d unitVector = vectorAB.GetNormal();
Console.WriteLine($"单位向量: ({unitVector.X}, {unitVector.Y}, {unitVector.Z})");
}
// 4. 点与向量运算
Point3d pointC = pointA + vectorAB * 0.5; // A 到 B 的中点
Console.WriteLine($"中点 C: ({pointC.X}, {pointC.Y}, {pointC.Z})");
// 5. 使用矩阵进行变换(平移)
Matrix3d translationMatrix = Matrix3d.Translation(new Vector3d(5, 10, 0));
Point3d translatedPoint = pointA.TransformBy(translationMatrix);
Console.WriteLine($"平移后的点: ({translatedPoint.X}, {translatedPoint.Y}, {translatedPoint.Z})");
}
- 曲线使用示例:创建并计算 NURBS 曲线 (
OdGeNurbCurve3d)
以下示例演示如何创建一个简单的三次 NURBS 曲线(由四个控制点定义),并在其上采样计算点的位置。
csharp
using Teigha.Geometry;
using System.Collections.Generic;
public void CreateAndEvaluateNurbCurve()
{
// 1. 定义 NURBS 曲线的控制点
List<Point3d> controlPoints = new List<Point3d>
{
new Point3d(0, 0, 0),
new Point3d(10, 20, 5),
new Point3d(30, 10, -5),
new Point3d(40, 0, 0)
};
// 2. 定义节点向量 (Knot Vector)
// 对于有4个控制点、阶数(p)为3的曲线,节点数 = 控制点数 + p + 1 = 8
// 这里使用一个均匀的、非周期性的节点向量 [0,0,0,0,1,1,1,1]
List<double> knots = new List<double> { 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0 };
// 3. 定义权值 (Weights),默认为1
List<double> weights = new List<double> { 1.0, 1.0, 1.0, 1.0 };
// 4. 创建 OdGeNurbCurve3d 对象
// 参数:阶数(degree)=3, 控制点, 节点向量, 权值, 是否为有理曲线(false)
NurbCurve3d nurbCurve = new NurbCurve3d(
3, // degree (阶数 = order - 1)
controlPoints.ToArray(),
knots.ToArray(),
weights.ToArray(),
false // 非有理曲线(所有权值为1时)
);
// 5. 使用 evaluatePoint 方法计算曲线上特定参数位置的点
// 这是从 OdGeCurve3d 基类继承的核心方法
double parameter = 0.5; // 参数范围通常在节点向量定义的有效区间内,此处为[0,1]
Point3d evaluatedPoint;
Vector3d firstDerivative;
// 调用 Evaluate 方法。参数:参数值、求导阶数(1表示同时计算一阶导)、输出点、输出导数
nurbCurve.Evaluate(parameter, 1, out evaluatedPoint, out firstDerivative);
Console.WriteLine($"在参数 t={parameter} 处:");
Console.WriteLine($" 点坐标: ({evaluatedPoint.X:F2}, {evaluatedPoint.Y:F2}, {evaluatedPoint.Z:F2})");
Console.WriteLine($" 一阶导数(切向量): ({firstDerivative.X:F2}, {firstDerivative.Y:F2}, {firstDerivative.Z:F2})");
// 6. 获取曲线的其他信息
double startParam, endParam;
nurbCurve.GetInterval(out startParam, out endParam);
Console.WriteLine($"曲线参数区间: [{startParam}, {endParam}]");
Console.WriteLine($"曲线是否闭合: {nurbCurve.IsClosed()}");
}
- 从数据库实体 (
OdDbEntity) 获取OdGe几何对象
这是最常见的应用场景:从 DWG 文件读取一个实体,提取其几何定义进行计算或修改。
csharp
using Teigha.DatabaseServices;
using Teigha.Geometry;
public void GetGeometryFromEntity(OdDbDatabase db)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// 假设我们有一个块表记录和模型空间块表记录
BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
foreach (ObjectId entityId in btr)
{
Entity ent = tr.GetObject(entityId, OpenMode.ForRead) as Entity;
if (ent == null) continue;
// 示例1:处理圆弧 (OdDbArc -> OdGeCircArc3d)
if (ent is Arc arcEntity)
{
// 获取圆弧的几何定义
CircularArc3d geArc = arcEntity.GetGeCurve() as CircularArc3d;
if (geArc != null)
{
Point3d center = geArc.Center;
double radius = geArc.Radius;
// 使用 geArc 进行几何计算...
}
}
// 示例2:处理样条曲线 (OdDbSpline -> OdGeNurbCurve3d)
if (ent is Spline splineEntity)
{
// 获取样条曲线的 NURBS 几何表示
NurbCurve3d geSpline = splineEntity.GetGeCurve() as NurbCurve3d;
if (geSpline != null)
{
// 现在可以使用 NurbCurve3d 的所有方法进行分析
// 例如,采样一系列点
List<Point3d> samplePoints = new List<Point3d>();
double start, end;
geSpline.GetInterval(out start, out end);
for (double t = start; t <= end; t += 0.1)
{
Point3d pt;
geSpline.Evaluate(t, 0, out pt);
samplePoints.Add(pt);
}
}
}
}
tr.Commit();
}
}
关键注意事项
- 命名空间 :在 C# 中,
OdGe的类位于Teigha.Geometry命名空间下。类名可能略有不同(如Point3d而非OdGePoint3d),但功能对应。 - 对象生命周期 :
OdGe几何对象是纯粹的 .NET 托管对象,其生命周期由 CLR 管理,无需像 C++ 中那样手动释放。 - 性能考量 :虽然
OdGe提供了强大的几何计算能力,但复杂的运算(如大量曲面求交)可能耗时。在性能敏感的场景中应合理使用。 - 与
OdDb的转换 :OdDb实体类(如OdDbCircle,OdDbSpline)通常提供GetGeCurve()或类似的方法来返回其对应的OdGe几何对象。反之,也可以通过OdDb实体类的构造函数或设置方法,用OdGe对象来创建或更新实体。 - 错误处理 :Teigha.NET 中的方法在失败时可能会抛出异常或返回错误状态码,建议在关键操作中添加
try-catch或检查返回值。
总之,OdGe 是 Teigha 中进行所有底层数学和几何计算的基石。在 C# 中,通过 Teigha.Geometry 命名空间,你可以以面向对象的方式创建、转换和操作这些几何对象,从而实现对 DWG 文件中图形数据的精确控制和复杂分析 。