惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

有赞技术团队
有赞技术团队
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
aimingoo的专栏
aimingoo的专栏
IT之家
IT之家
G
Google Developers Blog
爱范儿
爱范儿
博客园 - 司徒正美
Recent Announcements
Recent Announcements
The Register - Security
The Register - Security
J
Java Code Geeks
The Cloudflare Blog
M
MIT News - Artificial intelligence
Apple Machine Learning Research
Apple Machine Learning Research
Microsoft Security Blog
Microsoft Security Blog
博客园 - Franky
雷峰网
雷峰网
酷 壳 – CoolShell
酷 壳 – CoolShell
Blog — PlanetScale
Blog — PlanetScale
Vercel News
Vercel News
宝玉的分享
宝玉的分享
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
B
Blog
小众软件
小众软件
Microsoft Azure Blog
Microsoft Azure Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
WordPress大学
WordPress大学
T
Troy Hunt's Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
H
Hacker News: Front Page
H
Help Net Security
S
Security @ Cisco Blogs
V
V2EX
Security Archives - TechRepublic
Security Archives - TechRepublic
Stack Overflow Blog
Stack Overflow Blog
O
OpenAI News
L
LINUX DO - 最新话题
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
S
Secure Thoughts
Help Net Security
Help Net Security
F
Full Disclosure
博客园 - 叶小钗
The Hacker News
The Hacker News
Spread Privacy
Spread Privacy
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Jina AI
Jina AI
K
Kaspersky official blog
www.infosecurity-magazine.com
www.infosecurity-magazine.com
V
Vulnerabilities – Threatpost
P
Privacy International News Feed
Scott Helme
Scott Helme

博客园 - 我才是银古

第16章:常见问题、排错与最佳实践 第15章:扩展生态、MCAD 与外部集成 第12章:实战案例:机械结构与 3D 打印零件 第14章:构建、测试、调试与贡献流程 第13章:OpenSCAD 源码架构与核心执行流程 第11章:预览、渲染、网格精度与性能优化 第09章:列表推导、递归与算法建模 第08章:参数化零件库与复用设计 第10章:导入导出、命令行与自动化 第06章:CSG 布尔建模方法 第07章:二维图形、拉伸、旋转与投影 第05章:基础几何、坐标系与变换 第04章:参数、变量、函数、模块与作用域 OpenSCAD 教程目录 第03章:OpenSCAD 语言基础 第02章:安装、环境配置与开发工作流 第01章:OpenSCAD 项目全景与学习路线 第02章:源码获取、编译与开发环境配置 第01章:OCCT项目全景与学习路线 第18章:二次开发实战与综合案例 第18章:综合实战案例 第17章:数据交换与协同 第16章:源码架构与二次开发 第15章:插件与自定义工作台开发 第14章:Python脚本宏与自动化 第13章:FEM仿真分析 第12章:CAM数控加工 第11章:SurfaceMesh与逆向工程 第10章:Draft二维绘图与BIM建筑 第09章:工程图TechDraw 第07章:参数化表达式与Spreadsheet 第08章:装配设计Assembly 第06章:Part工作台与几何内核 第05章:PartDesign实体特征建模 第04章:草图Sketcher约束建模 第02章:安装版本与工作环境配置 第03章:界面工作台与基础操作 第01章:项目全景与学习路线 第十二章:插件开发、研究功能与最佳实践 第十章:定时任务与自动化(Cron) 第七章:技能、记忆与自学习闭环 第八章:MCP 集成与上下文文件 第六章:工具系统与终端后端 第五章:模型供应商与配置体系 Hermes Agent 教程目录 第十一章:语音、视觉、浏览器与子代理协作 第四章:CLI/TUI 与会话管理 第十二章:学习路线、实战方案与最佳实践 第十一章:源码结构、开发调试与插件开发 第十章:自动化、远程访问、日志与排障 第九章:Control UI、节点、Canvas 与语音能力 第七章:工具、技能、插件与能力扩展 第八章:安全模型、访问控制与沙箱实践 第六章:Agent 工作区、会话与多智能体路由 第五章:多通道消息接入与聊天平台配置 第四章:配置体系、模型接入与认证管理 第三章:Gateway 架构、协议与运行机制 第二章:安装、环境准备与快速上手 第一章:OpenClaw 项目概览与核心定位 oh-my-openagent 教程目录 09-命令模型回退与配置参考 10-实战案例最佳实践与故障排除 05-工作模式-Ultrawork-Prometheus-Atlas 08-Hooks与MCP系统 06-Category与Skill系统 07-核心工具链 04-智能体全景详解 03-安装与环境配置 02-整体架构与多模型编排机制 01-项目简介与核心理念 01-项目概览与学习路线 02-安装部署与工具适配 03-Skill机制与using-superpowers 05-TDD系统化调试与完成前验证 04-需求澄清方案设计与计划编写 07-并行智能体子智能体与Git-Worktree 第六章:代码审查、反馈处理与分支收尾 08-中国特色Skills与本土团队落地 09-MCP构建工作流执行与自定义Skill 第23章:FreeCAD-Python-API Clipper2 C# 源码解读教程 第19章:PolyTree 多边形树结构 第20章:实际应用与最佳实践 第18章:Minkowski 和与差 第17章:RectClip 矩形裁剪优化 第16章:ClipperOffset 偏移类详解 第15章:填充规则详解 第14章:布尔运算执行流程 第13章:ClipperD 浮点裁剪类 第11章:OutRec 与 OutPt 输出结构 第9章:Active 活动边结构 第10章:Vertex 顶点与 LocalMinima 局部极小值 第12章:Clipper64 裁剪类详解 第7章:高精度运算与128位整数 第8章:ClipperBase 基类详解 第5章:枚举类型与常量定义 第6章:InternalClipper 内部工具类 第2章:核心数据结构 - Point64、PointD 第3章:路径与多边形表示 - Path64、PathD、Paths64、PathsD 第4章:矩形边界 - Rect64、RectD
文件格式与数据交换
我才是银古 · 2026-06-20 · via 博客园 - 我才是银古

第十四章:文件格式与数据交换

14.1 文件格式支持概述

14.1.1 LightCAD支持的格式

格式 读取 写入 说明
LightCAD原生格式 完整保留所有数据
DWG AutoCAD绘图格式(通过ODA SDK)
DXF AutoCAD交换格式(通过netDxf)
SketchUp (.skp) SketchUp模型格式
SVG - 可缩放矢量图形

14.1.2 模块结构

LightCAD.ImportAndExport/
├── DwgImporter.cs           # DWG导入
├── DwgExporter.cs           # DWG导出
├── DxfImporter.cs           # DXF导入
├── DxfExporter.cs           # DXF导出
├── SketchUpImporter.cs      # SketchUp导入
├── SketchUpExporter.cs      # SketchUp导出
└── FormatConverter.cs       # 格式转换器

src/Libs/
├── LightCAD.DwgReaderWrite/ # DWG读写库
└── ODA SDK DLLs             # Open Design Alliance SDK

src/netDxf/                  # DXF处理库(源码)
├── DxfDocument.cs           # DXF文档
├── DxfReader.cs             # DXF读取器
├── DxfWriter.cs             # DXF写入器
└── Entities/                # DXF实体映射

14.2 DWG格式支持

14.2.1 DWG格式概述

DWG(Drawing)是AutoCAD的原生文件格式,也是CAD行业最广泛使用的文件格式。LightCAD通过ODA(Open Design Alliance)SDK实现了对DWG格式的读写支持。

14.2.2 DWG导入

public class DwgImporter
{
    /// <summary>
    /// 导入DWG文件
    /// </summary>
    public LcDocument Import(string filePath)
    {
        var document = new LcDocument();

        using (var database = new OdDatabase())
        {
            // 读取DWG文件
            database.ReadDwgFile(filePath);

            // 导入图层
            ImportLayers(database, document);

            // 导入线型
            ImportLineTypes(database, document);

            // 导入文字样式
            ImportTextStyles(database, document);

            // 导入标注样式
            ImportDimStyles(database, document);

            // 导入块定义
            ImportBlocks(database, document);

            // 导入模型空间中的实体
            ImportEntities(database, document);
        }

        return document;
    }

    /// <summary>
    /// 导入图层
    /// </summary>
    private void ImportLayers(OdDatabase database, LcDocument document)
    {
        var layerTable = database.LayerTable;

        foreach (var layerId in layerTable)
        {
            var layer = layerId.GetObject() as OdLayerTableRecord;
            if (layer != null)
            {
                document.Layers.Create(layer.Name);
                var lcLayer = document.Layers.Get(layer.Name);
                lcLayer.Color = ConvertColor(layer.Color);
                lcLayer.IsVisible = !layer.IsFrozen && !layer.IsOff;
                lcLayer.IsLocked = layer.IsLocked;
                lcLayer.LineType = layer.LinetypeName;
            }
        }
    }

    /// <summary>
    /// 导入实体
    /// </summary>
    private void ImportEntities(OdDatabase database, LcDocument document)
    {
        var modelSpace = database.ModelSpace;

        foreach (var entityId in modelSpace)
        {
            var entity = entityId.GetObject();
            var lcEntity = ConvertEntity(entity);

            if (lcEntity != null)
            {
                lcEntity.LayerName = entity.Layer;
                lcEntity.Color = ConvertColor(entity.Color);
                document.Entities.Add(lcEntity);
            }
        }
    }

    /// <summary>
    /// 转换DWG实体为LightCAD实体
    /// </summary>
    private LcEntity ConvertEntity(OdEntity odEntity)
    {
        return odEntity switch
        {
            OdLine line => new LcLine
            {
                StartPoint = ConvertPoint(line.StartPoint),
                EndPoint = ConvertPoint(line.EndPoint)
            },
            OdCircle circle => new LcCircle
            {
                Center = ConvertPoint(circle.Center).ToPoint2d(),
                Radius = circle.Radius
            },
            OdArc arc => new LcArc
            {
                Center = ConvertPoint(arc.Center).ToPoint2d(),
                Radius = arc.Radius,
                StartAngle = arc.StartAngle,
                EndAngle = arc.EndAngle
            },
            OdPolyline polyline => ConvertPolyline(polyline),
            OdText text => ConvertText(text),
            OdDimension dim => ConvertDimension(dim),
            OdBlockReference blockRef => ConvertBlockReference(blockRef),
            _ => null
        };
    }
}

14.2.3 DWG导出

public class DwgExporter
{
    /// <summary>
    /// 导出为DWG文件
    /// </summary>
    public void Export(LcDocument document, string filePath,
                       DwgVersion version = DwgVersion.AC1032)
    {
        using (var database = new OdDatabase())
        {
            // 设置DWG版本
            database.DwgFileVersion = version;

            // 导出图层
            ExportLayers(document, database);

            // 导出实体
            ExportEntities(document, database);

            // 导出块定义
            ExportBlocks(document, database);

            // 写入文件
            database.SaveAs(filePath, version);
        }
    }

    /// <summary>
    /// 转换LightCAD实体为DWG实体
    /// </summary>
    private OdEntity ConvertToOdEntity(LcEntity entity)
    {
        return entity switch
        {
            LcLine line => new OdLine
            {
                StartPoint = ConvertToOdPoint(line.StartPoint),
                EndPoint = ConvertToOdPoint(line.EndPoint)
            },
            LcCircle circle => new OdCircle
            {
                Center = ConvertToOdPoint3d(circle.Center),
                Radius = circle.Radius
            },
            LcArc arc => new OdArc
            {
                Center = ConvertToOdPoint3d(arc.Center),
                Radius = arc.Radius,
                StartAngle = arc.StartAngle,
                EndAngle = arc.EndAngle
            },
            _ => null
        };
    }
}

public enum DwgVersion
{
    AC1015,  // AutoCAD 2000
    AC1018,  // AutoCAD 2004
    AC1021,  // AutoCAD 2007
    AC1024,  // AutoCAD 2010
    AC1027,  // AutoCAD 2013
    AC1032   // AutoCAD 2018+
}

14.3 DXF格式支持

14.3.1 DXF格式概述

DXF(Drawing Exchange Format)是AutoCAD的文本交换格式。相比DWG,DXF是开放的文本格式,更容易解析和生成。LightCAD使用netDxf库来处理DXF文件。

14.3.2 DXF导入

public class DxfImporter
{
    /// <summary>
    /// 导入DXF文件
    /// </summary>
    public LcDocument Import(string filePath)
    {
        var dxfDoc = netDxf.DxfDocument.Load(filePath);
        var document = new LcDocument();

        // 导入图层
        foreach (var layer in dxfDoc.Layers)
        {
            var lcLayer = document.Layers.Create(layer.Name);
            lcLayer.Color = ConvertDxfColor(layer.Color);
            lcLayer.IsVisible = layer.IsVisible;
        }

        // 导入实体
        ImportLines(dxfDoc, document);
        ImportCircles(dxfDoc, document);
        ImportArcs(dxfDoc, document);
        ImportPolylines(dxfDoc, document);
        ImportTexts(dxfDoc, document);
        ImportDimensions(dxfDoc, document);
        ImportInserts(dxfDoc, document);

        return document;
    }

    private void ImportLines(netDxf.DxfDocument dxfDoc, LcDocument document)
    {
        foreach (var dxfLine in dxfDoc.Entities.Lines)
        {
            var line = new LcLine
            {
                StartPoint = new Point2d(
                    dxfLine.StartPoint.X, dxfLine.StartPoint.Y),
                EndPoint = new Point2d(
                    dxfLine.EndPoint.X, dxfLine.EndPoint.Y),
                LayerName = dxfLine.Layer.Name,
                Color = ConvertDxfColor(dxfLine.Color)
            };
            document.Entities.Add(line);
        }
    }

    private void ImportPolylines(netDxf.DxfDocument dxfDoc,
                                  LcDocument document)
    {
        foreach (var dxfPoly in dxfDoc.Entities.LightWeightPolylines)
        {
            var polyline = new LcPolyline
            {
                IsClosed = dxfPoly.IsClosed,
                LayerName = dxfPoly.Layer.Name
            };

            foreach (var vertex in dxfPoly.Vertexes)
            {
                polyline.AddVertex(
                    new Point2d(vertex.Position.X, vertex.Position.Y),
                    vertex.Bulge);
            }

            document.Entities.Add(polyline);
        }
    }
}

14.3.3 DXF导出

public class DxfExporter
{
    /// <summary>
    /// 导出为DXF文件
    /// </summary>
    public void Export(LcDocument document, string filePath,
                       DxfVersion version = DxfVersion.AutoCad2018)
    {
        var dxfDoc = new netDxf.DxfDocument(
            (netDxf.Header.DxfVersion)version);

        // 导出图层
        foreach (var layerName in document.Layers.AllLayerNames)
        {
            var lcLayer = document.Layers.Get(layerName);
            var dxfLayer = new netDxf.Tables.Layer(layerName)
            {
                Color = ConvertToAciColor(lcLayer.Color),
                IsVisible = lcLayer.IsVisible
            };
            dxfDoc.Layers.Add(dxfLayer);
        }

        // 导出实体
        foreach (var entity in document.Entities)
        {
            var dxfEntity = ConvertToDxfEntity(entity);
            if (dxfEntity != null)
            {
                dxfDoc.Entities.Add(dxfEntity);
            }
        }

        // 保存文件
        dxfDoc.Save(filePath);
    }
}

14.4 SketchUp格式支持

14.4.1 SketchUp导入

public class SketchUpImporter
{
    /// <summary>
    /// 导入SketchUp文件
    /// </summary>
    public LcDocument Import(string filePath)
    {
        var document = new LcDocument();

        // 解析SKP文件
        using (var reader = new SkpReader(filePath))
        {
            // 导入材质
            foreach (var material in reader.Materials)
            {
                ImportMaterial(material, document);
            }

            // 导入组件定义
            foreach (var component in reader.ComponentDefinitions)
            {
                ImportComponent(component, document);
            }

            // 导入几何体
            foreach (var face in reader.Faces)
            {
                ImportFace(face, document);
            }

            foreach (var edge in reader.Edges)
            {
                ImportEdge(edge, document);
            }
        }

        return document;
    }

    /// <summary>
    /// 导入SketchUp面(转换为网格体)
    /// </summary>
    private void ImportFace(SkpFace face, LcDocument document)
    {
        var mesh = new LcMesh3d();

        // 转换顶点
        foreach (var vertex in face.Vertices)
        {
            mesh.Vertices.Add(new Point3d(
                vertex.X, vertex.Y, vertex.Z));
        }

        // 转换三角面
        var triangulated = face.Triangulate();
        foreach (var tri in triangulated)
        {
            mesh.FaceIndices.Add(tri.Index0);
            mesh.FaceIndices.Add(tri.Index1);
            mesh.FaceIndices.Add(tri.Index2);
        }

        mesh.RecalculateNormals();

        if (face.Material != null)
        {
            mesh.Material = new MaterialInfo
            {
                Name = face.Material.Name,
                DiffuseColor = ConvertSkpColor(face.Material.Color)
            };
        }

        document.Entities.Add(mesh);
    }
}

14.5 原生格式

14.5.1 LightCAD文件格式设计

LightCAD的原生文件格式采用二进制格式,能够完整保存所有CAD数据:

public class NativeFormatSerializer
{
    private const string MAGIC = "LCAD";
    private const int VERSION = 1;

    /// <summary>
    /// 保存文档
    /// </summary>
    public void Save(LcDocument document, string filePath)
    {
        using var stream = File.Create(filePath);
        using var writer = new BinaryWriter(stream);

        // 文件头
        writer.Write(MAGIC.ToCharArray());
        writer.Write(VERSION);
        writer.Write(DateTime.UtcNow.ToBinary());

        // 文档元数据
        writer.Write(document.Name ?? "");
        writer.Write(document.Guid.ToString());

        // 单位设置
        WriteUnitSettings(writer, document.Units);

        // 图层表
        var layers = document.Layers.GetAll();
        writer.Write(layers.Count);
        foreach (var layer in layers)
        {
            WriteLayer(writer, layer);
        }

        // 块定义
        var blocks = document.Blocks.GetAll();
        writer.Write(blocks.Count);
        foreach (var block in blocks)
        {
            WriteBlock(writer, block);
        }

        // 实体
        var entities = document.Entities.ToList();
        writer.Write(entities.Count);
        foreach (var entity in entities)
        {
            WriteEntity(writer, entity);
        }
    }

    /// <summary>
    /// 加载文档
    /// </summary>
    public LcDocument Load(string filePath)
    {
        using var stream = File.OpenRead(filePath);
        using var reader = new BinaryReader(stream);

        // 验证文件头
        var magic = new string(reader.ReadChars(4));
        if (magic != MAGIC)
            throw new InvalidDataException("无效的LightCAD文件");

        var version = reader.ReadInt32();
        var timestamp = DateTime.FromBinary(reader.ReadInt64());

        var document = new LcDocument
        {
            Name = reader.ReadString(),
            Guid = new LcGuid(reader.ReadString())
        };

        // 读取单位设置
        document.Units = ReadUnitSettings(reader);

        // 读取图层
        var layerCount = reader.ReadInt32();
        for (int i = 0; i < layerCount; i++)
        {
            ReadLayer(reader, document);
        }

        // 读取块定义
        var blockCount = reader.ReadInt32();
        for (int i = 0; i < blockCount; i++)
        {
            ReadBlock(reader, document);
        }

        // 读取实体
        var entityCount = reader.ReadInt32();
        for (int i = 0; i < entityCount; i++)
        {
            var entity = ReadEntity(reader);
            if (entity != null)
            {
                document.Entities.Add(entity);
            }
        }

        return document;
    }

    /// <summary>
    /// 写入实体(带类型标识)
    /// </summary>
    private void WriteEntity(BinaryWriter writer, LcEntity entity)
    {
        // 写入类型标识
        writer.Write(entity.TypeName);

        // 写入通用属性
        writer.Write(entity.Handle);
        writer.Write(entity.Guid.ToString());
        writer.Write(entity.LayerName);
        WriteColor(writer, entity.Color);
        writer.Write(entity.LineType ?? "");
        writer.Write(entity.LineWeight);
        writer.Write(entity.IsVisible);

        // 写入特定属性
        switch (entity)
        {
            case LcLine line:
                WritePoint2d(writer, line.StartPoint);
                WritePoint2d(writer, line.EndPoint);
                break;
            case LcCircle circle:
                WritePoint2d(writer, circle.Center);
                writer.Write(circle.Radius);
                break;
            case LcArc arc:
                WritePoint2d(writer, arc.Center);
                writer.Write(arc.Radius);
                writer.Write(arc.StartAngle);
                writer.Write(arc.EndAngle);
                writer.Write(arc.IsCounterClockwise);
                break;
            // ... 其他实体类型
        }
    }
}

14.6 格式转换工具

14.6.1 统一转换接口

public class FormatConverter
{
    /// <summary>
    /// 通用文件导入
    /// </summary>
    public LcDocument Import(string filePath)
    {
        var extension = Path.GetExtension(filePath).ToLower();

        return extension switch
        {
            ".dwg" => new DwgImporter().Import(filePath),
            ".dxf" => new DxfImporter().Import(filePath),
            ".skp" => new SketchUpImporter().Import(filePath),
            ".lcad" => new NativeFormatSerializer().Load(filePath),
            _ => throw new NotSupportedException(
                $"不支持的文件格式:{extension}")
        };
    }

    /// <summary>
    /// 通用文件导出
    /// </summary>
    public void Export(LcDocument document, string filePath)
    {
        var extension = Path.GetExtension(filePath).ToLower();

        switch (extension)
        {
            case ".dwg":
                new DwgExporter().Export(document, filePath);
                break;
            case ".dxf":
                new DxfExporter().Export(document, filePath);
                break;
            case ".lcad":
                new NativeFormatSerializer().Save(document, filePath);
                break;
            default:
                throw new NotSupportedException(
                    $"不支持的导出格式:{extension}");
        }
    }

    /// <summary>
    /// 批量格式转换
    /// </summary>
    public void BatchConvert(string inputDir, string outputDir,
                              string inputFormat, string outputFormat)
    {
        var files = Directory.GetFiles(inputDir, $"*.{inputFormat}");

        foreach (var file in files)
        {
            var document = Import(file);
            var outputPath = Path.Combine(outputDir,
                Path.ChangeExtension(
                    Path.GetFileName(file), outputFormat));
            Export(document, outputPath);
        }
    }
}

14.7 本章小结

本章详细介绍了LightCAD的文件格式支持和数据交换能力。LightCAD通过ODA SDK实现了DWG格式的完整读写,通过netDxf库支持DXF格式,还支持SketchUp格式的导入导出。原生的LightCAD文件格式采用高效的二进制编码,能够完整保存所有CAD数据。统一的格式转换接口为用户提供了便捷的文件操作体验。


上一章第十三章:用户界面框架

下一章第十五章:插件系统与扩展开发