Teigha中OdGe几何库详解及C#使用

OdGe 是 Teigha (ODA) SDK 中一个核心的几何库命名空间 ,它封装了所有用于描述和操作几何图形的类与函数,是进行任何 CAD 数据底层处理的基础 。

OdGe 命名空间的构成与作用

OdGe 库提供了一套与 AutoCAD 原生几何库高度兼容、但独立于任何特定 CAD 平台或文件格式的纯数学几何对象模型。它的主要作用是:

  1. 几何数据建模:定义了点、向量、矩阵、曲线、曲面等基本几何元素的数据结构。
  2. 几何计算:提供了丰富的数学方法,如求交、投影、变换、求导、长度计算等。
  3. 与数据库实体分离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 方法)。

  1. 环境配置与引用

首先,确保你的项目已正确引用 Teigha.NET 的核心程序集,特别是 Teigha.Geometry.dll

csharp 复制代码
// 在代码文件顶部添加必要的 using 指令
using Teigha.Runtime;
using Teigha.Geometry; // 这是 OdGe 在 C# 中的主要命名空间
using Teigha.DatabaseServices;
  1. 基础类型使用示例

创建点、向量,进行基本运算:

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})");
}
  1. 曲线使用示例:创建并计算 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()}");
}
  1. 从数据库实体 (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();
    }
}

关键注意事项

  1. 命名空间 :在 C# 中,OdGe 的类位于 Teigha.Geometry 命名空间下。类名可能略有不同(如 Point3d 而非 OdGePoint3d),但功能对应。
  2. 对象生命周期OdGe 几何对象是纯粹的 .NET 托管对象,其生命周期由 CLR 管理,无需像 C++ 中那样手动释放。
  3. 性能考量 :虽然 OdGe 提供了强大的几何计算能力,但复杂的运算(如大量曲面求交)可能耗时。在性能敏感的场景中应合理使用。
  4. OdDb 的转换OdDb 实体类(如 OdDbCircle, OdDbSpline)通常提供 GetGeCurve() 或类似的方法来返回其对应的 OdGe 几何对象。反之,也可以通过 OdDb 实体类的构造函数或设置方法,用 OdGe 对象来创建或更新实体。
  5. 错误处理Teigha.NET 中的方法在失败时可能会抛出异常或返回错误状态码,建议在关键操作中添加 try-catch 或检查返回值。

总之,OdGe 是 Teigha 中进行所有底层数学和几何计算的基石。在 C# 中,通过 Teigha.Geometry 命名空间,你可以以面向对象的方式创建、转换和操作这些几何对象,从而实现对 DWG 文件中图形数据的精确控制和复杂分析 。


参考来源

相关推荐
爱喝水的鱼丶1 小时前
SAP-ABAP:变量、常量、结构与内表声明(10篇博客合集) 第六篇:ABAP 7.40+新特性:声明语法的简化写法与兼容注意事项
运维·服务器·开发语言·学习·算法·sap·abap
国科安芯2 小时前
AS32S601商业航天级抗辐照MCU芯片:架构设计与技术特性研究
单片机·嵌入式硬件·算法·安全·架构·risc-v
菜菜的顾清寒2 小时前
力扣HOT100(34)图论-岛屿数量
算法·leetcode·图论
名字不好奇2 小时前
大模型的思考模式:它真的在“想“吗?
人工智能·算法
Run_Teenage2 小时前
算法模板:输入输出,并查集
java·开发语言·算法
高一学习c++会秃头吗2 小时前
操作系统内存块分配算法
算法
洛水水2 小时前
【力扣100题】57.合并区间
算法·leetcode
玉树临风ives2 小时前
atcoder ABC 458 题解
数据结构·c++·算法
如竟没有火炬3 小时前
有序矩阵中第K小的元素
数据结构·线性代数·算法·leetcode·矩阵·深度优先