明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 916|回复: 3

[图形系统] 在Acad.net的难题

[复制链接]
发表于 2024-10-3 23:39:29 | 显示全部楼层 |阅读模式
本帖最后由 你有种再说一遍 于 2024-10-13 18:56 编辑

# 在Acad.net难题:
在acad中,如果C#出现问题一定是和C++存在同样的问题.
1,官方没有提供接口.
此时只能直接找底层的exe/dll函数签名,通过DllImport载入,麻烦的是函数的参数是不知道的,是需要分析寄存器和入栈信息的(涉及了调用约定).
或者一些万能操作,例如图元数据序列化和反序列化.
如果.net缺少提供一些ARX拥有的接口,也可以通过Hook/DllImport/子类化等方式载入,不过最怕就是函数签名内联之后隐藏了.

2,不知道偏移指针在哪里.
只能通过反汇编工具x32dbg/x64dbg找调用栈,或者windbg.

3,不知道数据结构和修改步骤.
这需要庞大的知识(修改数据库/反编译).用于找到偏移的函数指针或者结构指针之后,需要的修改步骤,通常是写插件注入dll行为.

而avLisp主要是靠com,遇到上面的问题主要是没有指针操作,只能跑FFI,而FFI就要转到其他语言.
com是通过操作系统转发的,所以它在所有语言中支持很好,只是效率太慢了.
C#调用com有两种方式,
1,反射application去调用,需要根据VBA手册的路由指引一直反射.
2,工程上面引入dll,低版本要引入Internal.dll,会限制每个版本的com函数,而高版本cad多了Utils类.
所以说,和com与之相对的是dll动态链接库开发.
其实,都那么多年的累积了,连cad都做不出真的不应该.

## 解析dwg
https://blog.csdn.net/jiangyb999
这个博主解析了04/07dwg,还有一些动态块的文章,带你读一次dwg结构,更好理解dwg,甚至可以通过他文章去参照github开源的dwg库.
例如我们并行句柄,实际上要处理这个句柄无效问题,就需要靠里面的句柄区.
例如我们去掉了教育版.


## OLE生成
虽然在IFox已经实现了读写剪贴板,但是代码中是把OLE片段到剪贴板,也就是com导出wmf转为emf之后设置在剪贴板的meta上面.
粘贴时候要借助剪贴板.还是没有解决如何直接后台生成OLE对象.

创建句柄?就可以创建OleFram?替换句柄:
https://www.cnblogs.com/d1742647821/p/18310874

根据此链接知道了二进制储存在90和310上面,在c#上面也是通过句柄读取:
https://documentation.help/AutoC ... 0ec0a2e719-79f4.htm

其实自己把一个图片在界面显示一点都不难,而符合acad数据库结构的才是困难的,这就是为什么掌握二次开发其实还比较难一点.

## 外部参照的加速方案.
装饰图的立面会放一个小平面,是参照剪块得到的.
如果空间很多个,就需要复制n个平面然后裁剪块,相当于载入n个平面就会非常慢.(想想商场n个面)
为了防止信息熵巨大,卡顿,立面图会按照空间分多个dwg的.
当发现平立面不符时,绘图员会在位编辑这个外部参照,保存时候会刷新全局,也非常慢.
同时,我们是通过局域网共享文件夹,实现工程共享,
(理论上存在并发修改一份平面图的时候,共享打开时候会提示只读打开.但是,客户端1:开图的机子休眠会解除占用,客户端2:就可以打开保存了,客户端1:开启此时保存会跳到只读),
并且存在破坏工程文件的问题,只能通过多次备份.

如果在cad用布局视口旋转虽然也能实现,但是布局毕竟是标注区,不是绘图区,没法模型区直接完成.
1,如果旋转布局视口,用来里面放线,会反复进出视口,这是不可接受的,左右框架需要对照和镜像.
2,模型区直接完成是因为布局有视口数量max限制.
处理max限制如果用分布局就更糟糕了,前后图纸对比存在困难,非常容易违反立面制图0,0水平线对齐的规范.
我非常反对引入另类操作时候,需要靠人工保证规范正确进行,而正确的应该是通过软件提示去保证规范正确进行.
这就是为什么如今仍然采取旋转剪块的方式完成小平面裁剪.

如果模型支持摄像机(视口引用)就好了,可以将摄像机和布局视口绑定,这样只用一个大平面(甚至可以跨图引用),进行视口平移和旋转摄像机,布局视口可见就一直跟踪摄像机,视口边界改动的话,模型的摄像机边界也联动.

不过制图上面仍然需要对齐才可以放线...
Revit倒是能非常好解决这个问题,它主要是通过三维模型+三维视口裁剪实现,令图纸信息熵不大...
不过它是建模出图,一堵墙就从4个Point3d变大成8个了...

这个时候想,如果让cad变得不是那么通用,在室内设计上面仅仅采用4个float表达墙体+1个float角度,是不是能够更快速...现在只能说性能不是很好,但是能跑,不过我已经不在乎了,又没有国产厂商去追求这个性能优化.

## 文字渲染.
因为acad的文字卡顿实在不太喜欢.
感觉可以做一个预渲染功能,直接将文字通过辅助进程来进行,通过内存共享直接使用.但是操作是动态渲染的,对于文字的处理还是存在难题.
1,是屏蔽原生字体显示.
2,是根据文字样式,读取ttf/shx文件,处理贝塞尔曲线什么的还是挺简单的,有现有开源库.
3,利用定点数在GUI绘制和仿射变换.
4,文字编辑器重写.
5,查找文本功能重写,利用分词+倒序索引,还是SIMD暴力搜索呢?

## 标注关联
https://www.cnblogs.com/ztcad/p/14107353.html
C++有提供接口,不知道为什么C#没有.
根据这个文章的链接可知,其实也不知道怎么进行纯C#实现.
是要找相关接口dllimport?
还是说通过图形序列化?
或者参考DXF动态块生成方案?

## 动态块生成
1,acad06不支持动态块,并且不支持.net
2,acad08不支持拉伸填充

测试方式:
那么我们在低版本上面是可以模拟实验高版本功能,从而探索实现原理.
既然06不支持.net,那么用ARX嵌入mono实现JIT环境,或者直接AOT实现不一样的C#支持.
不过cad.net用的是C++ FFI to .net所以并非那么简单.我们可以把高版本放进低版本里面,不就是跟嵌入mono一样吗?

如果通过ARX读取动态块信息,实现自己驱动,驱动上面可以利用自定义图元绘制夹点等等,这可以验证很多信息.
遍历句柄是否得到高版本保留的动态块信息,否则需要读取文件.
写入动态块信息,官方论坛讨论了此问题
https://forums.autodesk.com/t5/o ... %20with%20help%20of

只是说了没有公开的API.
不过,在DXF上面拥有完整的数据库信息,因此我们直接对DXF读写.
这里有人做了解析动态块:
https://blog.csdn.net/jiangyb999/article/details/128725215

方案一:
读取动态块
通过句柄获取全部的DXF组码,包括动态块的参数和动作.
https://www.cnblogs.com/JJBox/p/12489648.html
写入动态块
entmake可以创建DXF内容,具体我也没有尝试,可能存在结构写入不正确.

方案二:
序列化接口修改图元
https://www.cnblogs.com/JJBox/p/11614714.html

保存:
通过application server保存为高版本dwg.
这样大家会不会吃惊...
用户一看,06居然可以保存一个13版本dwg...
发表于 2024-10-8 21:28:56 | 显示全部楼层
标注关联AssocDimDependencyBody,约束Assoc2dConstraintGroup
 楼主| 发表于 2024-10-8 23:05:37 | 显示全部楼层
本帖最后由 你有种再说一遍 于 2024-10-8 23:06 编辑
d1742647821 发表于 2024-10-8 21:28
标注关联AssocDimDependencyBody,约束Assoc2dConstraintGroup

啥版本开始有的,写个demo看看
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-28 22:19 , Processed in 0.251347 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表