6112 lines
146 KiB
C++
6112 lines
146 KiB
C++
#include "StdAfx.h"
|
|
#include "CoreTools.h"
|
|
#include "filepath.h"
|
|
#include "TypeConvert.h"
|
|
#include "COMPARE_DOUBLE.h"
|
|
#include "initools.h"
|
|
#include "sys/stat.h"
|
|
#include "io.h"
|
|
#include "KTCADUtilityEx.h"
|
|
#include "Base64.h"
|
|
#include <comdef.h>
|
|
#include "KTSetting.h"
|
|
#include "SLTDlg.h"
|
|
#include "NameDlg.h"
|
|
#include "AddBimDlg.h"
|
|
#include "KTModelLayoutXData.h"
|
|
#include "uiiado.h"
|
|
#include "hzip.h"
|
|
#include "_cgal.h"
|
|
#include "SelectBlkDlg.h"
|
|
#include "gpc.h"
|
|
#include "ImpMD5.h"
|
|
#include "breptools.h"
|
|
#include "DimScaleZoneDlg.h"
|
|
#include "simpleProperty.h"
|
|
#include "KTCADSysVar.h"
|
|
#include "KTCadUtility.h"
|
|
|
|
#pragma region object include
|
|
#include "AecDbEarthWorm.h"
|
|
#include "aecdbewpipe.h"
|
|
#include "AecDbShEarthWorm.h"
|
|
#include "AecDbPortRoom.h"
|
|
#include "AecDbVenDoghouse.h"
|
|
#include "AecDbPipeDoghouse.h"
|
|
#include "AecDbCableDoghouse.h"
|
|
#include "AecDbEscapeHatchHouse.h"
|
|
#include "AecDbXXXDoghouse.h"
|
|
#include "AecDbEarthWormFitting.h"
|
|
#include "AecDbBuriedOutletDoghouse.h"
|
|
#include "AecDbEwCable.h"
|
|
#include "AecDbEwFitting.h"
|
|
#include "AecDbEwEquipment.h"
|
|
#include "AecDbConnectDoghouse.h"
|
|
#include "AecDbX3dPartEntity.h"
|
|
#include "AecDbWall.h"
|
|
#include "AecDbSlab.h"
|
|
#include "AecDbColumn.h"
|
|
#include "AecDbBeam.h"
|
|
#include "AecDbFlume.h"
|
|
#include "AecDbSludgePipe.h"
|
|
#include "AecDbRiverGroove.h"
|
|
#include "AecDbParamEquipment.h"
|
|
#include "AecDbX3dPart.h"
|
|
#pragma endregion
|
|
|
|
#define EQU_COMPANY "Beijing shanghua equipment design file"
|
|
#define LAY_PIPE_OUTSIDE _T("PIPE_OUT")
|
|
#define LAY_FITN_DASH _T("FITN_DSH")
|
|
|
|
#define SP_PT TCHAR(0x07) // 响铃 bel 做为分割符
|
|
|
|
extern void AFXAPI AfxTextFloatFormat(CDataExchange* pDX, int nIDC, void* pData, double value, int nSizeGcvt);
|
|
extern void UnZipFile(LPCTSTR pszSrc, LPCTSTR pszDec);
|
|
extern void UnZipFile(LPCTSTR pszSrc, LPCTSTR pszDec,CStringArray& arFiles);
|
|
namespace
|
|
{
|
|
std::map<CString, CString> g_dxf2chs;
|
|
|
|
#define INS_DXF_CHS(dxf, chs) g_dxf2chs.insert(std::make_pair(_T(#dxf), _T(#chs)))
|
|
|
|
int init()
|
|
{
|
|
INS_DXF_CHS(AEC_EARTHWORM, 管廊);
|
|
//INS_DXF_CHS(AEC_PORTROOM, 标准节点);
|
|
INS_DXF_CHS(AEC_VENDOGHOUSE, 通风口);
|
|
INS_DXF_CHS(AEC_PIPEDOGHOUSE, 管类投料口);
|
|
INS_DXF_CHS(AEC_CABLEDOGHOUSE, 线缆类投料口);
|
|
INS_DXF_CHS(AEC_ESCAPEHATCHHOUSE, 逃生口);
|
|
INS_DXF_CHS(AEC_XXXDOGHS, 族节点);
|
|
INS_DXF_CHS(AEC_EWFIT, AEC_EWFIT);
|
|
INS_DXF_CHS(AEC_BODOGHOUSE, 直埋引出);
|
|
//INS_DXF_CHS(AEC_DBEWPIPEBASE, AEC_DBEWPIPEBASE);
|
|
INS_DXF_CHS(AEC_EWPIPE, 管);
|
|
INS_DXF_CHS(AEC_SEARTHWORM, 盾构管廊);
|
|
INS_DXF_CHS(AEC_EWCABLE, 线);
|
|
INS_DXF_CHS(AEC_DBEWFIT, 管件);
|
|
INS_DXF_CHS(AEC_DBWEQUIPMENT, 设备);
|
|
INS_DXF_CHS(AEC_CNTDOGHS, AEC_CNTDOGHS);
|
|
INS_DXF_CHS(AEC_X3DPART, AEC_X3DPART);
|
|
INS_DXF_CHS(AEC_DBWALL, 墙);
|
|
INS_DXF_CHS(AEC_DBSLAB, 板);
|
|
INS_DXF_CHS(AEC_DBCOLMN, 柱);
|
|
INS_DXF_CHS(AEC_DBBEAM, 梁);
|
|
INS_DXF_CHS(AEC_DBPBASIN, 池);
|
|
INS_DXF_CHS(AEC_DBFLUME, 槽);
|
|
INS_DXF_CHS(AEC_SLUDGEPIPE, 排泥管);
|
|
INS_DXF_CHS(AEC_DBPARAEQUI, 参数化设备);
|
|
INS_DXF_CHS(AEC_RIVERGROOVE, 巴氏计量槽);
|
|
return 0;
|
|
}
|
|
|
|
int g_init = init();
|
|
bool createDir(LPCTSTR psz)
|
|
{
|
|
if (!psz) return false;
|
|
// 先判断目录是否存在,如不存在,则新建,如存在,则返回
|
|
struct _stat fstat;
|
|
if ((_tstat(psz, &fstat) == 0) && (fstat.st_mode & _S_IFDIR))
|
|
return true;
|
|
return ::CreateDirectory(psz, NULL) ? true : false;
|
|
}
|
|
|
|
|
|
CString getBitAnswerCodeInfo(unsigned int code)
|
|
{
|
|
switch (code)
|
|
{
|
|
case 0x000: return _T("执行成功");
|
|
case 0x101: return _T("服务应答错误,请检查服务器地址及端口设置 查看解决方案");
|
|
case 0x102: return _T("错误的上下文句柄");
|
|
case 0x103: return _T("不合法的参数输入,请检查参数");
|
|
case 0x104: return _T("分配的存储区域太小");
|
|
case 0x105: return _T("错误的产品识别码(Application Data),请检查所使用的头文件/类文件与连接库是否与产品匹配");
|
|
case 0x106: return _T("心跳线程错误");
|
|
case 0x108: return _T("服务器没有响应,请确认服务器地址和端口配置正确 查看解决方案");
|
|
case 0x109: return _T("服务器返回结果为空");
|
|
case 0x10A: return _T("错误的命令类型");
|
|
case 0x10B: return _T("错误的返回值");
|
|
case 0x10C: return _T("上下文句柄错误,或还没有登陆,请检查参数或重新登陆");
|
|
case 0x10E: return _T("无效的本地许可数据文件");
|
|
case 0x110: return _T("没有找到本地授权码对应的许可数据文件");
|
|
case 0x111: return _T("本地授权许可数据文件签名不正确");
|
|
case 0x112: return _T("运行时错误");
|
|
case 0x113: return _T("线程错误");
|
|
case 0x114: return _T("没有找到相应的本地授权许可数据文件");
|
|
case 0x115: return _T("本地内部错误");
|
|
case 0x116: return _T("许可数据文件获取不完整");
|
|
case 0x117: return _T("授权点数已经用完");
|
|
case 0x118: return _T("内存分配空间不足");
|
|
case 0x119: return _T("获取授权时只能插入一个USB存储器");
|
|
case 0x11A: return _T("请插入存储授权的USB存储器");
|
|
case 0x11B: return _T("获取USB存储器指纹出错");
|
|
case 0x11C: return _T("授权码输入错误,请检查授权码拼写是否正确");
|
|
case 0x11D: return _T("发现本地系统时间篡改。当前时间比最近一次使用时间还要早 查看解决方案");
|
|
case 0x123: return _T("授权码已经从本机迁出 查看解决方案");
|
|
case 0x126: return _T("集团授权的Host设置为空,或未设置集团服务器地址 查看解决方案");
|
|
case 0x127: return _T("服务器类型与配置文件指定的类型或当前的操作类型不匹配");
|
|
case 0x12A: return _T("升级串内容不正确");
|
|
case 0x12B: return _T("不支持的升级串版本");
|
|
case 0x12C: return _T("授权码类型与操作不匹配");
|
|
case 0x12E: return _T("升级串格式不正确,请确认是否拷贝完整");
|
|
case 0x133: return _T("单机授权配置文件格式错误或操作错误");
|
|
case 0x171: return _T("该授权码不支持借出操作");
|
|
case 0x172: return _T("该授权码不支持提前返还操作");
|
|
case 0x173: return _T("授权码已被借出,必须返还后才能再次借出");
|
|
case 0x174: return _T("借出串格式不正确");
|
|
case 0x176: return _T("借出串的类型不正确或不支持");
|
|
case 0x177: return _T("借出串数据不正确");
|
|
case 0x179: return _T("授权码已返还");
|
|
case 0x17A: return _T("没有更多的可借出用户数");
|
|
case 0x17B: return _T("错误的借出时长,必须大于1天并小于最大借出时长限制");
|
|
case 0x17C: return _T("不能对同一台机器上的授权进行借出操作");
|
|
case 0x17E: return _T("当前没有可借出的集团授权码");
|
|
case 0x182: return _T("请插入对应的比特ID硬件");
|
|
case 0x183: return _T("比特ID访问错误,开发商不匹配");
|
|
case 0x184: return _T("比特ID读错误");
|
|
case 0x185: return _T("比特ID写错误");
|
|
case 0x186: return _T("比特ID未初始化");
|
|
case 0x191: return _T("升级或借出的产品不匹配");
|
|
case 0x195: return _T("许可文件数据不匹配");
|
|
case 0x196: return _T("许可文件数据丢失或不存在");
|
|
case 0x197: return _T("许可文件操作错误");
|
|
case 0x201: return _T("客户端会话超时,需要重新登录 查看解决方案");
|
|
case 0x204: return _T("服务器内部异常错误");
|
|
case 0x206: return _T("授权产品已禁用");
|
|
case 0x207: return _T("开发商被禁用");
|
|
case 0x208: return _T("服务器没有响应。请检查服务器地址是否正确,相应的端口是否打开,或与开发商联系");
|
|
case 0x20A: return _T("产品不匹配,SN不属于该应用程序 查看解决方案");
|
|
case 0x212: return _T("该用户被集团服务管理员踢出,几分钟后才能再次登录");
|
|
case 0x213: return _T("授权码由于连接服务器过于频繁被列入黑名单,或集团授权客户端被访问规则禁止 查看解决方案");
|
|
case 0x214: return _T("用户数超出集团服务访问规则限制 查看解决方案");
|
|
case 0x241: return _T("网络或服务器繁忙,请稍后再试");
|
|
case 0x503: return _T("指定的特征项没有找到 查看解决方案");
|
|
case 0x504: return _T("特征项类型不匹配");
|
|
case 0x505: return _T("加解密数据长度超过限制");
|
|
case 0x509: return _T("特征项已过期 查看解决方案");
|
|
case 0x601: return _T("指定的配置项没有找到");
|
|
case 0x602: return _T("配置项索引超过限制");
|
|
case 0x603: return _T("配置项容量超过限制");
|
|
case 0x604: return _T("配置项数量超过限制");
|
|
case 0x701: return _T("授权码已经过期 查看解决方案");
|
|
case 0x702: return _T("在线用户数超过限制 查看解决方案");
|
|
case 0x703: return _T("激活的机器数量已达上限,授权码不能在更多的机器上使用 查看解决方案");
|
|
case 0x704: return _T("授权码使用次数已达上限,不能继续登录 查看解决方案");
|
|
case 0x705: return _T("授权码被禁用 查看解决方案");
|
|
case 0x706: return _T("指定的授权码没有找到,请确认授权码格式、服务器地址是否正确以及授权码与产品是否一致 查看解决方案");
|
|
case 0x707: return _T("同一台客户端登陆次数超过限制");
|
|
case 0x708: return _T("执行命令次数超过限制");
|
|
case 0x709: return _T("授权码连接服务器次数过于频繁,被暂时禁用");
|
|
case 0x70C: return _T("IP地址被禁用,请联系开发商");
|
|
case 0x70D: return _T("请插入存储授权的USB存储器");
|
|
case 0x70E: return _T("无效的授权码格式");
|
|
case 0x70F: return _T("升级授权码次数过于频繁,请过一段时间再进行升级操作");
|
|
case 0x712: return _T("特征项容量已用尽,需要等待其它进程或客户端释放");
|
|
case 0x713: return _T("特征项还没有被使用,无需释放");
|
|
case 0x714: return _T("授权码类型不支持所请求的操作 查看解决方案");
|
|
case 0x716: return _T("请求码错误");
|
|
case 0x717: return _T("请求码已经过期,请重新产生新的请求码");
|
|
case 0x718: return _T("请求码已经成功使用过一次,请重新产生新的请求码");
|
|
case 0x719: return _T("授权码转移的机器数量超过限制");
|
|
case 0x71A: return _T("机器被禁用");
|
|
case 0x71B: return _T("授权码转移的次数超过限制");
|
|
case 0x71C: return _T("授权码不允许转移");
|
|
case 0x71D: return _T("无效的XML格式");
|
|
case 0x71E: return _T("授权码不匹配");
|
|
case 0x71F: return _T("该授权码在多台机器激活");
|
|
case 0x720: return _T("没有找到激活的机器信息");
|
|
case 0x721: return _T("没有找到升级记录");
|
|
case 0x729: return _T("虚拟机授权被禁用");
|
|
case 0x72C: return _T("客户端版本太低,不能支持此授权类型或功能");
|
|
case 0x72D: return _T("机器已被回收");
|
|
case 0x72F: return _T("不支持授权借出,请升级集团服务和扩展模块版本到最新");
|
|
case 0x731: return _T("该IP地址出现异常访问数据,已经被禁止,如需继续访问,请联系比特安索公司");
|
|
case 0x732: return _T("请输入授权码对应的密码");
|
|
case 0x733: return _T("请检查授权码密码是否正确");
|
|
case 0x741: return _T("未找到比特ID硬件 查看解决方案");
|
|
case 0x743: return _T("比特ID硬件不匹配");
|
|
case 0x744: return _T("比特ID硬件未注册");
|
|
case 0x745: return _T("比特ID已被禁用");
|
|
case 0x747: return _T("比特ID已与其它授权码绑定");
|
|
case 0x748: return _T("比特ID安全数据不合法");
|
|
case 0x749: return _T("比特ID的授权类型不匹配");
|
|
case 0x74A: return _T("比特ID还没有和授权码绑定, 无需解除绑定");
|
|
case 0x74B: return _T("该授权码不支持绑定比特ID");
|
|
case 0x74C: return _T("比特ID标签名已经存在");
|
|
case 0x74D: return _T("客户端库版本低,请更新到版本6.4.0及以上版本");
|
|
case 0x751: return _T("自定义终端标识没有找到,请检查该标识是否导入、标识输入是否正确、和授权码是否匹配");
|
|
case 0x753: return _T("该自定义终端标识对应的机器数已经超过限制");
|
|
case 0x754: return _T("该自定义终端标识失效");
|
|
case 0x755: return _T("客户端没有输入自定义终端标识");
|
|
case 0x760: return _T("授权码或终端标识被添加到警告名单");
|
|
case 0x780: return _T("授权码的验证到期,为了正常使用,请再次认证以延长授权码使用期限 查看解决方案");
|
|
case 0x781: return _T("机器硬件信息不匹配,请重新认证 查看解决方案");
|
|
case 0x783: return _T("没有可用的授权码");
|
|
case 0x784: return _T("没有可用的模块");
|
|
case 0x785: return _T("演示授权不支持升级操作");
|
|
case 0x786: return _T("虚拟机被禁止");
|
|
case 0x787: return _T("授权码状态不可用 查看解决方案");
|
|
case 0x788: return _T("不允许通过远程桌面访问");
|
|
case 0x789: return _T("客户终端标识不匹配");
|
|
case 0x801: return _T("该授权码类型不支持升级操作");
|
|
case 0x802: return _T("授权码类型为本地授权");
|
|
case 0x803: return _T("下载次数超过限制");
|
|
case 0x804: return _T("升级码签名验证失败,请检查产品是否匹配");
|
|
case 0x806: return _T("升级码失效,已使用了更新的升级码");
|
|
case 0x807: return _T("本地系统时间错误,请检查系统时间及时区设置");
|
|
case 0x901: return _T("当前产品没有找到,请确认是否已被删除");
|
|
case 0x90F: return _T("E3没有授权,请停止使用");
|
|
case 0x911: return _T("没有可用的授权服务,请检查tomcat是否启动");
|
|
case 0x912: return _T("产生授权码失败,请检查认证中心是否正常工作");
|
|
case 0xA01: return _T("扩展模块签名验证失败,文件可能损坏");
|
|
case 0xA03: return _T("集团服务配置文件错误");
|
|
case 0xA04: return _T("用户名或密码错误");
|
|
case 0xA06: return _T("旧密码错误");
|
|
case 0xA07: return _T("两次输入的密码不匹配");
|
|
case 0xA09: return _T("上传新的扩展模块出错");
|
|
case 0xA11: return _T("加载扩展模块失败");
|
|
case 0xA12: return _T("指定的页面不存在");
|
|
case 0xA15: return _T("不合法的集团服务访问规则设置");
|
|
case 0xA16: return _T("同样的集团服务访问规则已经存在");
|
|
case 0xA21: return _T("客户端借出时长太短");
|
|
case 0xA22: return _T("客户端借出时长超过限制");
|
|
case 0xA23: return _T("集团授权用户数达到保留下限,不能借出");
|
|
case 0xA31: return _T("集团授权客户端版本太低,不能支持所需的操作");
|
|
case 0xA32: return _T("扩展模块版本太低,不能支持所需的操作");
|
|
default:
|
|
break;
|
|
}
|
|
return _T("unknow");
|
|
}
|
|
|
|
bool getPlane(const AcDbVoidPtrArray &ar, AcGePlane &plan)
|
|
{
|
|
for (int i = 0; i < ar.length(); ++i)
|
|
{
|
|
AcDbEntity *pEnt = (AcDbEntity*)ar[i];
|
|
AcDb::Planarity plt;
|
|
pEnt->getPlane(plan, plt);
|
|
if (plt == AcDb::kPlanar)
|
|
return true;
|
|
}
|
|
|
|
// 能走到这里,说明ar里没有平面实体
|
|
|
|
if (ar.length() == 1)
|
|
{
|
|
AcDbLine *pL = AcDbLine::cast((AcDbEntity*)(ar[0]));
|
|
if (!pL) return false;
|
|
|
|
AcGePoint3d ptS(pL->startPoint()), ptE(pL->endPoint());
|
|
AcGePoint3d ptMid(CoreTools::MidPt(ptS, ptE));
|
|
|
|
// 如果水平
|
|
if (EQUAL(ptS.z, ptE.z))
|
|
{
|
|
plan.set(ptMid, AcGeVector3d::kZAxis);
|
|
return true;
|
|
}
|
|
AcGeVector3d vt(ptE - ptS), vtNml;
|
|
vt.normalize();
|
|
|
|
if (vt.isParallelTo(AcGeVector3d::kZAxis))
|
|
{
|
|
plan.set(ptMid, AcGeVector3d::kXAxis);
|
|
return true;
|
|
}
|
|
|
|
vtNml = vt.crossProduct(AcGeVector3d::kZAxis);
|
|
vtNml.rotateBy(PI * .5, vt);
|
|
plan.set(CoreTools::MidPt(pL->startPoint(), pL->endPoint()), vtNml);
|
|
return true;
|
|
}
|
|
|
|
AcGeVector3d vt, vt1, vt2;
|
|
for (int i = 0; i < ar.length() - 1; ++i)
|
|
{
|
|
AcDbLine *pL1 = AcDbLine::cast((AcDbEntity*)(ar[i]));
|
|
AcDbLine *pL2 = AcDbLine::cast((AcDbEntity*)(ar[i + 1]));
|
|
if (!pL1 || !pL2) continue;
|
|
|
|
vt1 = pL1->endPoint() - pL1->startPoint();
|
|
vt2 = pL2->endPoint() - pL2->startPoint();
|
|
|
|
if (vt1.isParallelTo(vt2)) continue;
|
|
|
|
vt = vt1.crossProduct(vt2);
|
|
plan.set(pL1->startPoint(), vt.normalize());
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool isClosed(const AcDbPolyline *pPoly, const double &tol)
|
|
{
|
|
// 如果第一点和最后一点相同,则闭合
|
|
AcGePoint3d pt1, pt2;
|
|
int count = pPoly->numVerts();
|
|
if (count < 2) return false;
|
|
|
|
pPoly->getPointAt(0, pt1);
|
|
pPoly->getPointAt(count - 1, pt2);
|
|
|
|
if ((pt1.x - pt2.x) < tol && (pt1.y - pt2.y) < tol)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool fixPathAndRegionForRevitSweep(AcDbPolyline *pPoly, AcDbRegion *pReg)
|
|
{
|
|
if (!pPoly || !pReg) return false;
|
|
|
|
// 截面圆心,法向
|
|
AcGePoint3d ptRegCen(AcGePoint3d::kOrigin);
|
|
AcGeVector3d vtRegNormal(AcGeVector3d::kIdentity);
|
|
double dArea(.0);
|
|
AcGePlane planReg;
|
|
if (!CoreTools::getRegionInfo(pReg, ptRegCen, dArea, planReg)) return false;
|
|
|
|
// 路径第一点的切线
|
|
AcGePoint3d ptPathStart(AcGePoint3d::kOrigin), ptPathEnd(AcGePoint3d::kOrigin);
|
|
if (pPoly->getStartPoint(ptPathStart) != Acad::eOk) return false;
|
|
if (pPoly->getEndPoint(ptPathEnd) != Acad::eOk) return false;
|
|
AcGeVector3d vtPathTangent(AcGeVector3d::kIdentity);
|
|
if (pPoly->getFirstDeriv(ptPathStart, vtPathTangent) != Acad::eOk) return false;
|
|
vtPathTangent.normalize();
|
|
|
|
AcGeMatrix3d mat(AcGeMatrix3d::kIdentity);
|
|
//CoreTools::CloneAndAddToModelSpace(pPoly, 1);
|
|
//CoreTools::CloneAndAddToModelSpace(pReg, 1);
|
|
|
|
// 先判断 polyline 与 region所在平面相交在哪一点
|
|
// 在revit中,上华的sweept体,默认都从路径的起点开始
|
|
// 直接把路径的起点,移动到plnReg上
|
|
|
|
// 先判断一般情况,一般绘制sweep时,路径会与region相交,可能是起点也可能是终点
|
|
// 如果是起点,不变
|
|
// 如果是终点,反转路径
|
|
AcGe::PointContainment pcS = CoreTools::relationWith(pReg, ptPathStart);
|
|
AcGe::PointContainment pcE = CoreTools::relationWith(pReg, ptPathEnd);
|
|
|
|
if (pcS == AcGe::kOutside && pcE == AcGe::kOutside)
|
|
{ // 起点、终点都不在region上,直接移动路径到region所在plane上面
|
|
|
|
AcGePoint3d ptClosestStart = planReg.closestPointTo(ptPathStart);
|
|
AcGePoint3d ptClosestEnd = planReg.closestPointTo(ptPathEnd);
|
|
// 判断用那个点
|
|
AcGePoint3d ptClosest, ptMove;
|
|
double distStart(ptClosestStart.distanceTo(ptPathStart))
|
|
, distEnd(ptClosestEnd.distanceTo(ptPathEnd));
|
|
|
|
if (COMPARE_DOUBLE::downequal(distStart, distEnd, .0001))
|
|
{
|
|
ptClosest = ptClosestStart;
|
|
ptMove = ptPathStart;
|
|
}
|
|
else
|
|
{
|
|
ptClosest = ptClosestEnd;
|
|
ptMove = ptPathEnd;
|
|
pPoly->reverseCurve();
|
|
}
|
|
|
|
mat.setToTranslation(ptClosest - ptMove);
|
|
pPoly->transformBy(mat);
|
|
}
|
|
else
|
|
{
|
|
if (pcS != AcGe::kOutside) { /*只要起点在region上就什么也不做*/ }
|
|
else if (pcE != AcGe::kOutside)
|
|
{ // 起点不在region上,终点在,反转
|
|
pPoly->reverseCurve();
|
|
}
|
|
}
|
|
|
|
// 判断 ptInter 的切线是否与截面法向平行
|
|
pPoly->getStartPoint(ptPathStart); // 经过上面操作,路径起点与region重合
|
|
pPoly->getFirstDeriv(ptPathStart, vtPathTangent);
|
|
AcGeVector3d vtReg = planReg.normal();
|
|
|
|
//CoreTools::CloneAndAddToModelSpace(pPoly, 2);
|
|
|
|
if (vtPathTangent.isParallelTo(vtReg))//平行,离开,其他的revit处理
|
|
return true;
|
|
else
|
|
{
|
|
AcGeVector3d vtCross = planReg.normal().crossProduct(vtPathTangent);
|
|
double dAngle = planReg.normal().angleTo(vtPathTangent, vtCross);
|
|
mat.setToRotation(dAngle, vtCross);
|
|
pReg->transformBy(mat);
|
|
ptRegCen.transformBy(mat);
|
|
mat.setToTranslation(ptPathStart - ptRegCen);
|
|
pReg->transformBy(mat);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool isLinear(const AcDbPolyline *pPoly)
|
|
{
|
|
if (pPoly->hasBulges()) return false;
|
|
|
|
int numOfVer = pPoly->numVerts();
|
|
|
|
if (numOfVer == 2) return true;
|
|
|
|
int numOfSeg = numOfVer - 1;
|
|
AcGeLineSeg3d seg1, seg2;
|
|
for (int i(0); i < numOfSeg - 1; ++i)
|
|
{
|
|
pPoly->getLineSegAt(i, seg1);
|
|
pPoly->getLineSegAt(i + 1, seg2);
|
|
|
|
if (seg1.direction().isParallelTo(seg2.direction()))
|
|
continue;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// 假设所有点都在有一个平面上,求这个平面
|
|
AcGePlane getPlane(const AcGePoint3dArray &arPts)
|
|
{
|
|
AcGePlane pln(AcGePlane::kXYPlane);
|
|
|
|
AcGePoint3d pt0, pt1, pt2;
|
|
AcGeVector3d vt1, vt2;
|
|
for (int i(2); i < arPts.length(); ++i)
|
|
{
|
|
pt0 = arPts[i-2];
|
|
pt1 = arPts[i-1];
|
|
pt2 = arPts[i];
|
|
vt1 = pt0 - pt1;
|
|
vt2 = pt2 - pt1;
|
|
if (vt1.isParallelTo(vt2))
|
|
continue;
|
|
|
|
pln.set(pt0, pt1, pt2);
|
|
break;
|
|
}
|
|
|
|
return pln;
|
|
}
|
|
|
|
// 拟合不闭合的曲线
|
|
void fittingCurve(AcDbCurve *pCurve, AcDbVoidPtrArray &lines)
|
|
{
|
|
if (pCurve->isClosed()) return;
|
|
|
|
AcGePoint3d ptS, ptE;
|
|
if (pCurve->getStartPoint(ptS) != Acad::eOk
|
|
|| pCurve->getEndPoint(ptE) != Acad::eOk)
|
|
return;
|
|
double dPs(.0), dPe(.0);
|
|
AcGePoint3dArray arpts;
|
|
#if ARX > 18
|
|
AcGeCurve3d *pGeCrv(NULL);
|
|
pCurve->getAcGeCurve(pGeCrv);
|
|
if (!pGeCrv) return;
|
|
|
|
dPs = pGeCrv->paramOf(ptS);
|
|
dPe = pGeCrv->paramOf(ptE);
|
|
|
|
AcGeDoubleArray arparms;
|
|
pGeCrv->getSamplePoints(dPs, dPe, 1., arpts, arparms);
|
|
#else
|
|
AcGePoint3d pt;
|
|
double dLen;
|
|
pCurve->getDistAtPoint(ptE, dLen);
|
|
int nCount(20);
|
|
double dDelta(dLen / nCount);
|
|
dLen = .0;
|
|
|
|
for (int i(0); i < nCount + 1; ++i)
|
|
{
|
|
pCurve->getPointAtDist(dLen, pt);
|
|
arpts.append(pt);
|
|
dLen += dDelta;
|
|
}
|
|
#endif
|
|
for (int i(0); i < arpts.length() - 1; ++i)
|
|
lines.append(new AcDbLine(arpts[i], arpts[i + 1]));
|
|
}
|
|
|
|
// 根据关键字,得到 Plumbing.db 里面 AecValvedata 内的阀门类型
|
|
bool getValveTypes(LPCTSTR pszKey, std::vector<CString> &types)
|
|
{
|
|
if (!pszKey) return false;
|
|
CUIISQLiteServer db;
|
|
if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db")))
|
|
return false;
|
|
std::vector<CString> ss;
|
|
CString sql(_T("select DISTINCT [阀门类型] FROM AecValvedata"));
|
|
db.GetSelData(sql, ss);
|
|
|
|
if (ss.empty()) return false;
|
|
|
|
for (size_t i(0); i < ss.size(); ++i)
|
|
{
|
|
if (ss[i].Find(pszKey) != -1)
|
|
types.push_back(ss[i]);
|
|
}
|
|
|
|
return !types.empty();
|
|
}
|
|
|
|
bool GetIconSize(HICON hIcon, SIZE &size)
|
|
{
|
|
ICONINFO ii = {};
|
|
if (!GetIconInfo(hIcon, &ii))
|
|
return false;
|
|
|
|
BITMAP bm = {};
|
|
if (ii.hbmColor)
|
|
{
|
|
GetObject(ii.hbmColor, sizeof(bm), &bm);
|
|
}
|
|
else if (ii.hbmMask)
|
|
{
|
|
GetObject(ii.hbmMask, sizeof(bm), &bm);
|
|
bm.bmHeight /= 2;
|
|
}
|
|
|
|
size.cx = bm.bmWidth;
|
|
size.cy = bm.bmHeight;
|
|
|
|
if (ii.hbmColor) DeleteObject(ii.hbmColor);
|
|
if (ii.hbmMask) DeleteObject(ii.hbmMask);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// 不可导出,在core工程内部使用
|
|
CString BitAnswerErrCode(unsigned int code) { return getBitAnswerCodeInfo(code); }
|
|
|
|
|
|
#pragma region CoreTools
|
|
|
|
#define JSON_FILE _T("\\paraDesign.json")
|
|
#define VALVE_JSON_PATH _T("\\valveSize.json")
|
|
|
|
double CoreTools::getPScale()
|
|
{
|
|
double dPScale(100.);
|
|
CString sScale(_T("1:100"));
|
|
AecDbObjXDataMap xDataMap;
|
|
if (KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap))
|
|
xDataMap.GetAt(DOC_SCALE, sScale);
|
|
|
|
int idx = sScale.Find(':');
|
|
if (idx != -1)
|
|
{
|
|
sScale = sScale.Right(sScale.GetLength() - idx - 1);
|
|
dPScale = _ttof(sScale);
|
|
}
|
|
|
|
return dPScale;
|
|
}
|
|
|
|
bool CoreTools::initParamValveJsonData(LPCTSTR pszType
|
|
, LPCTSTR pszSrcSection
|
|
, LPCTSTR pszTemplateSection)
|
|
{
|
|
using namespace SHJson;
|
|
CString valveSizeJson(FilePath::GetSysDir() + VALVE_JSON_PATH)
|
|
, paraDesignJson(FilePath::GetSysDir() + JSON_FILE);
|
|
|
|
std::vector<CString> subObjList(0);
|
|
// 先得到子类型列表
|
|
bool bFailed(false);
|
|
if (CString(pszTemplateSection).CompareNoCase(_T("PIPE_VALVE")) == 0)
|
|
{
|
|
if (!getValveTypes(pszType, subObjList))
|
|
{
|
|
AfxMessageBox(CString(_T("没有在等级库内查询到")) + pszType + _T("的相关数据。"));
|
|
bFailed = true;
|
|
}
|
|
}
|
|
if (CString(pszTemplateSection).CompareNoCase(_T("HVAC_VALVE")) == 0 || bFailed)
|
|
{
|
|
WDocument doc;
|
|
if (!SHJson::file2Json(valveSizeJson, doc)) return false;
|
|
|
|
MIt itPipe = doc.FindMember(pszSrcSection);
|
|
if (itPipe == doc.MemberEnd()) return false;
|
|
|
|
MIt itObj = itPipe->value.FindMember(pszType);
|
|
if (itObj == itPipe->value.MemberEnd()) return false;
|
|
|
|
for (MIt itSub = itObj->value.MemberBegin(); itSub != itObj->value.MemberEnd(); ++itSub)
|
|
{
|
|
subObjList.push_back(itSub->name.GetString());
|
|
}
|
|
|
|
if (subObjList.empty())
|
|
subObjList.push_back(CString(_T("通用")) + pszType);
|
|
}
|
|
|
|
WDocument doc;
|
|
if (!SHJson::file2Json(paraDesignJson, doc)) return false;
|
|
|
|
// 如果已经存在
|
|
MIt itPipeVavle = doc.FindMember(pszType);
|
|
if (itPipeVavle != doc.MemberEnd())
|
|
return true;
|
|
|
|
// 如果不存在,从 PIPE_VALVE 拷贝出一个 newType
|
|
itPipeVavle = doc.FindMember(pszTemplateSection);
|
|
if (itPipeVavle == doc.MemberEnd()) return false;
|
|
if (itPipeVavle->value.ObjectEmpty()) return false;
|
|
|
|
WValue newType;
|
|
newType.CopyFrom(itPipeVavle->value, SHJson::getJsonAllocator());
|
|
if (newType.ObjectEmpty()) return false;
|
|
|
|
if (CString(pszTemplateSection).CompareNoCase(_T("HVAC_VALVE")) == 0)
|
|
{
|
|
CString sPath2D(_T("\\tk\\Customer\\图库中心\\图块库\\风阀\\风管阀门阀件.dwg|"));
|
|
if (CString(pszType).Find(_T("调节阀")) != -1)
|
|
{
|
|
sPath2D += _T("上华暖通_防火调节阀");
|
|
}
|
|
else if (CString(pszType).Find(_T("防火阀")) != -1)
|
|
{
|
|
sPath2D += _T("上华暖通_防火阀");
|
|
}
|
|
else if (CString(pszType).Find(_T("止回阀")) != -1)
|
|
{
|
|
sPath2D += _T("上华暖通_止回阀");
|
|
}
|
|
else if (CString(pszType).Find(_T("闸板阀")) != -1)
|
|
{
|
|
sPath2D += _T("上华暖通_插板阀");
|
|
}
|
|
else if (CString(pszType).Find(_T("定风量阀")) != -1)
|
|
{
|
|
sPath2D += _T("上华暖通_排烟阀");
|
|
}
|
|
else if (CString(pszType).Find(_T("蝶阀")) != -1)
|
|
{
|
|
sPath2D += _T("上华暖通_蝶阀");
|
|
}
|
|
else
|
|
sPath2D += _T("上华暖通_防火调节阀");
|
|
|
|
if (newType.HasMember(_T("SUB_VALVE"))
|
|
&& newType[_T("SUB_VALVE")].HasMember(_T("param"))
|
|
&& newType[_T("SUB_VALVE")][_T("param")].IsArray()
|
|
&& newType[_T("SUB_VALVE")][_T("param")].Size() > 4
|
|
&& newType[_T("SUB_VALVE")][_T("param")][3].HasMember(_T("value")))
|
|
{
|
|
newType[_T("SUB_VALVE")][_T("param")][3][_T("value")].SetString(sPath2D, sPath2D.GetLength());
|
|
}
|
|
}
|
|
|
|
MIt itFirst = newType.MemberBegin();
|
|
itFirst->name.SetString(subObjList[0], subObjList[0].GetLength());
|
|
itFirst->value[_T("name")].SetString(subObjList[0], subObjList[0].GetLength());
|
|
|
|
for (size_t i = 1; i < subObjList.size(); ++i)
|
|
{
|
|
// 根据 newType的第一个元素,构成其他类型
|
|
WValue newValue;
|
|
newValue.CopyFrom(itFirst->value, SHJson::getJsonAllocator());
|
|
newValue[_T("name")].SetString(subObjList[i], subObjList[i].GetLength());
|
|
addMember(newType, subObjList[i], newValue);
|
|
}
|
|
addMember(doc, pszType, newType);
|
|
return json2File(paraDesignJson, doc, true);
|
|
|
|
}
|
|
|
|
CString CoreTools::selectBlockByDWG(LPCTSTR pszDWG, LPCTSTR pszBlkPrefix, LPCTSTR pszCurSelet)
|
|
{
|
|
CAcModuleResourceOverride myResources;
|
|
CString str(_T(""));
|
|
if (_taccess(pszDWG, 0x0) != 0x0)
|
|
{
|
|
str.Format(_T("文件%s未找到!"), pszDWG);
|
|
AfxMessageBox(str);
|
|
return _T("");
|
|
}
|
|
|
|
CString sCurSel(_T(""));
|
|
if (pszCurSelet)
|
|
{
|
|
std::vector<CString> vec;
|
|
CoreTools::SplitString(pszCurSelet, _T('|'), vec);
|
|
if (vec.size() > 1)
|
|
sCurSel = vec[1];
|
|
}
|
|
|
|
CSelectBlkDlg dlg(pszDWG, pszBlkPrefix, sCurSel);
|
|
if (dlg.DoModal() != IDOK)
|
|
return pszCurSelet ? pszCurSelet : _T("");
|
|
|
|
// 替换掉pszDWG里面的 FilePath::GetRootDir() 部分
|
|
std::wstring ws(pszDWG);
|
|
CString pathRoot(FilePath::GetRootDir());
|
|
size_t idx = ws.find(pathRoot);
|
|
if (idx != -1)
|
|
ws = ws.substr(idx + pathRoot.GetLength());
|
|
|
|
return CString(ws.c_str()) + _T("|") + dlg.m_sSelectBlkName;
|
|
}
|
|
|
|
AcDbObjectId CoreTools::loadBlockFromDwg(LPCTSTR pszDwg
|
|
, LPCTSTR pszBlkName
|
|
, AcDbDatabase *pDb)
|
|
{
|
|
AcDbObjectId blkId(AcDbObjectId::kNull);
|
|
if (!pszDwg || !pszBlkName) return blkId;
|
|
|
|
if (_taccess(pszDwg, 0x0) != 0x0) return blkId;
|
|
|
|
if (!pDb)
|
|
pDb = acdbHostApplicationServices()->workingDatabase();
|
|
|
|
// 检查是否存在
|
|
{
|
|
AcDbBlockTable *pBT(NULL);
|
|
pDb->getSymbolTable(pBT, AcDb::kForRead);
|
|
if (pBT)
|
|
{
|
|
pBT->getAt(pszBlkName, blkId);
|
|
pBT->close();
|
|
|
|
if (blkId.isValid())
|
|
return blkId;
|
|
}
|
|
}
|
|
|
|
// 插入
|
|
{
|
|
AcDbDatabase *pSrcDb = new AcDbDatabase(false);
|
|
if (pSrcDb->readDwgFile(pszDwg, AcDbDatabase::kForReadAndAllShare) == Acad::eOk)
|
|
{
|
|
AcDbBlockTable *pBT(NULL);
|
|
pSrcDb->getSymbolTable(pBT, AcDb::kForRead);
|
|
if (pBT)
|
|
{
|
|
AcDbObjectId idBlock;
|
|
pBT->getAt(pszBlkName, idBlock);
|
|
pBT->close();
|
|
|
|
AcDbDatabase *pTempDb(NULL);
|
|
pSrcDb->wblock(pTempDb, idBlock);
|
|
if (pTempDb)
|
|
{
|
|
pDb->insert(blkId, pszBlkName, pTempDb);
|
|
DELETE_PTR(pTempDb);
|
|
}
|
|
}
|
|
}
|
|
DELETE_PTR(pSrcDb);
|
|
}
|
|
return blkId;
|
|
}
|
|
|
|
AcGe::PointContainment CoreTools::relationWith(const AcDbRegion *pReg, const AcGePoint3d &pt)
|
|
{
|
|
AcGe::PointContainment pc = AcGe::kOutside;
|
|
BrepTools::relationWith(pReg, pt, pc);
|
|
return pc;
|
|
}
|
|
|
|
AcDbCurve* CoreTools::intersectWith(AcDbPolyline *pPoly, AcDbRegion *pReg, AcGePoint3dArray &ar)
|
|
{
|
|
AcGePlane plnReg;
|
|
pReg->getPlane(plnReg);
|
|
AcGePoint3d pt1, pt2;
|
|
if (isLinear(pPoly)) // 直线于pReg相交
|
|
{
|
|
pPoly->getStartPoint(pt1);
|
|
pPoly->getEndPoint(pt2);
|
|
AcDbLine line(pt1, pt2);
|
|
AcGePoint3d pt;
|
|
if (plnReg.intersectWith(AcGeLineSeg3d(pt1, pt2), pt))
|
|
ar.append(pt);
|
|
}
|
|
else
|
|
{
|
|
AcDb::Planarity pla;
|
|
AcGePlane plnPoly;
|
|
pPoly->getPlane(plnPoly, pla);
|
|
AcGeLine3d l;
|
|
if (plnPoly.intersectWith(plnReg, l))
|
|
{
|
|
AcGePoint3dArray arpts;
|
|
l.getSamplePoints(2, arpts);
|
|
if (arpts.length() > 1)
|
|
{
|
|
AcDbLine line(arpts.first(), arpts.last());
|
|
line.intersectWith(pPoly, AcDb::kExtendThis, ar);
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
// 按照 revit sweep geometry 的要求
|
|
// 1. region 与 path 第一点的切线正交垂直
|
|
// 2. region 的法向 与 path 第一点的切线相同
|
|
AcDbPolyline* CoreTools::fixPathAndRegionForRevitSweep(AcDbPolyline *pPoly
|
|
, AcDbRegion *pReg)
|
|
{
|
|
::fixPathAndRegionForRevitSweep(pPoly, pReg);
|
|
return NULL;
|
|
}
|
|
|
|
int CoreTools::getCurrentSet(AcDbObjectIdArray &ar)
|
|
{
|
|
Adesk::Int32 nLen = 0;
|
|
struct resbuf* pRb = acutBuildList(RTDXF0, _T("*"), 0);
|
|
ads_name ss, ent;
|
|
|
|
acedSSGet(_T("I"), NULL, NULL, pRb, ss);
|
|
acutRelRb(pRb);
|
|
|
|
acedSSLength(ss, &nLen);
|
|
AcDbObjectId id;
|
|
for (int i = 0; i < nLen; ++i)
|
|
{
|
|
acedSSName(ss,i,ent);
|
|
if (acdbGetObjectId(id, ent) == Acad::eOk)
|
|
ar.append(id);
|
|
}
|
|
|
|
acedSSFree(ss);
|
|
return ar.length();
|
|
}
|
|
|
|
int CoreTools::IsPointInPoly(const AcGePoint3d &pt, const AcDbPolyline &pl)
|
|
{
|
|
extern int IsPointInPoly(int nvert, float *vertx, float *verty, float testx, float testy);
|
|
|
|
int num = pl.numVerts();
|
|
// 判断是不是在线上
|
|
AcGePlane pln;
|
|
AcDb::Planarity pla;
|
|
if (pl.getPlane(pln, pla) == Acad::eOk && pla == AcDb::kPlanar)
|
|
{
|
|
AcGePoint3d pt3d = pt.orthoProject(pln);
|
|
AcGePoint2d pt2d(pt.x, pt.y);
|
|
double dParam(.0);
|
|
for (int i = 0; i < num; ++i)
|
|
{
|
|
if (pl.onSegAt(i, pt2d, dParam) == Adesk::kTrue)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
int nPts = 100;
|
|
double dSta = 0.0, dEnd = 0.0;
|
|
|
|
pl.getStartParam(dSta);
|
|
pl.getEndParam(dEnd);
|
|
|
|
double dStep = (dEnd - dSta) / nPts;
|
|
|
|
float* pfPtx = new float[nPts];
|
|
float* pfPty = new float[nPts];
|
|
|
|
AcGePoint3d _pt;
|
|
for (int i = 0; i < nPts; ++i)
|
|
{
|
|
pl.getPointAtParam(dSta + i * dStep, _pt);
|
|
//pl.getPointAt(i, _pt);
|
|
pfPtx[i] = (float)_pt.x;
|
|
pfPty[i] = (float)_pt.y;
|
|
}
|
|
|
|
int bIn = IsPointInPoly(nPts, pfPtx, pfPty, (float)pt.x, (float)pt.y);
|
|
delete[] pfPtx;
|
|
delete[] pfPty;
|
|
if (bIn == 1)
|
|
return bIn;
|
|
return -1;
|
|
}
|
|
|
|
void CoreTools::getBimDatas(const AecDbObjXDataMap & XData, SH_BIM_BLOCK & bim)
|
|
{
|
|
AecDbObjXDataMap::getBimDatas(XData, bim);
|
|
}
|
|
|
|
void CoreTools::setBimDatas(AecDbObjXDataMap & XData, const SH_BIM_BLOCK & bim)
|
|
{
|
|
AecDbObjXDataMap::setBimDatas(XData, bim);
|
|
}
|
|
|
|
bool CoreTools::getBimData(const AecDbObjXDataMap &XData, LPCTSTR pszKey, CString &strValue)
|
|
{
|
|
return AecDbObjXDataMap::getBimData(XData, pszKey, strValue);
|
|
}
|
|
|
|
|
|
bool CoreTools::setBimData(AecDbObjXDataMap &XData, LPCTSTR pszKey, LPCTSTR pszValue)
|
|
{
|
|
return AecDbObjXDataMap::setBimData(XData, pszKey, pszValue);
|
|
}
|
|
|
|
|
|
bool CoreTools::delBimData(AecDbObjXDataMap &XData, LPCTSTR pszKey)
|
|
{
|
|
return AecDbObjXDataMap::delBimData(XData, pszKey);
|
|
}
|
|
|
|
bool CoreTools::getBimData(const AcDbEntity *pEnt, LPCTSTR pszKey, CString &strValue)
|
|
{
|
|
if (!pszKey) return false;
|
|
|
|
AecDbObjXDataMap *pMap(NULL);
|
|
if (pEnt->isKindOf(AecDbCurveBase::desc()))
|
|
{
|
|
AecDbCurveBase *pBase(AecDbCurveBase::cast(pEnt));
|
|
pMap = pBase->GetSpecialtyData(AcDb::kForRead);
|
|
}
|
|
else if (pEnt->isKindOf(AecDbEntityBase::desc()))
|
|
{
|
|
AecDbEntityBase *pBase(AecDbEntityBase::cast(pEnt));
|
|
pMap = pBase->GetSpecialtyData(AcDb::kForRead);
|
|
}
|
|
else
|
|
{
|
|
AecDbObjXDataMap xData;
|
|
if (xData.Read((AcDbObject *)pEnt, _T("SH_BIMS")))
|
|
return AecDbObjXDataMap::getBimData(xData, pszKey, strValue);
|
|
else
|
|
return false;
|
|
}
|
|
if (pMap)
|
|
return getBimData(*pMap, pszKey, strValue);
|
|
return false;
|
|
}
|
|
|
|
bool CoreTools::setBimData(AcDbEntity * pEnt, LPCTSTR pszKey, LPCTSTR pszValue)
|
|
{
|
|
if (!pszKey || !pszValue) return false;
|
|
|
|
AecDbObjXDataMap *pMap(NULL);
|
|
if (pEnt->isKindOf(AecDbCurveBase::desc()))
|
|
{
|
|
AecDbCurveBase *pBase(AecDbCurveBase::cast(pEnt));
|
|
pMap = pBase->GetSpecialtyData(AcDb::kForWrite);
|
|
}
|
|
else if (pEnt->isKindOf(AecDbEntityBase::desc()))
|
|
{
|
|
AecDbEntityBase *pBase(AecDbEntityBase::cast(pEnt));
|
|
pMap = pBase->GetSpecialtyData(AcDb::kForWrite);
|
|
}
|
|
else
|
|
{
|
|
AecDbObjXDataMap xData;
|
|
xData.Read((AcDbObject *)pEnt, _T("SH_BIMS"));
|
|
if (AecDbObjXDataMap::setBimData(xData, pszKey, pszValue))
|
|
return xData.Write(pEnt, _T("SH_BIMS")) ? true : false;
|
|
else
|
|
return false;
|
|
}
|
|
if (pMap)
|
|
return setBimData(*pMap, pszKey, pszValue);
|
|
return false;
|
|
}
|
|
|
|
bool CoreTools::delBimData(AcDbEntity * pEnt, LPCTSTR pszKey)
|
|
{
|
|
if (!pszKey) return false;
|
|
|
|
AecDbObjXDataMap *pMap(NULL);
|
|
if (pEnt->isKindOf(AecDbCurveBase::desc()))
|
|
{
|
|
AecDbCurveBase *pBase(AecDbCurveBase::cast(pEnt));
|
|
pMap = pBase->GetSpecialtyData(AcDb::kForWrite);
|
|
}
|
|
else if (pEnt->isKindOf(AecDbEntityBase::desc()))
|
|
{
|
|
AecDbEntityBase *pBase(AecDbEntityBase::cast(pEnt));
|
|
pMap = pBase->GetSpecialtyData(AcDb::kForWrite);
|
|
}
|
|
else
|
|
{
|
|
AecDbObjXDataMap xData;
|
|
xData.Read((AcDbObject *)pEnt, _T("SH_BIMS"));
|
|
if (AecDbObjXDataMap::delBimData(xData, pszKey))
|
|
return xData.Write(pEnt, _T("SH_BIMS")) ? true : false;
|
|
else
|
|
return false;
|
|
}
|
|
if (pMap)
|
|
return delBimData(*pMap, pszKey);
|
|
return false;
|
|
}
|
|
|
|
void CoreTools::getBimDatas(const AcDbEntity * pEnt, SH_BIM_BLOCK &bimData)
|
|
{
|
|
AecDbObjXDataMap *pMap(NULL);
|
|
if (pEnt->isKindOf(AecDbCurveBase::desc()))
|
|
{
|
|
AecDbCurveBase *pBase(AecDbCurveBase::cast(pEnt));
|
|
pMap = pBase->GetSpecialtyData(AcDb::kForRead);
|
|
}
|
|
else if (pEnt->isKindOf(AecDbEntityBase::desc()))
|
|
{
|
|
AecDbEntityBase *pBase(AecDbEntityBase::cast(pEnt));
|
|
pMap = pBase->GetSpecialtyData(AcDb::kForRead);
|
|
}
|
|
else
|
|
{
|
|
AecDbObjXDataMap xData;
|
|
if (xData.Read((AcDbObject*)pEnt, _T("SH_BIMS")))
|
|
getBimDatas(xData, bimData);
|
|
|
|
return;
|
|
}
|
|
if (pMap)
|
|
getBimDatas(*pMap, bimData);
|
|
}
|
|
|
|
void CoreTools::setBimDatas(AcDbEntity * pEnt, const SH_BIM_BLOCK &bimData)
|
|
{
|
|
AecDbObjXDataMap *pMap(NULL);
|
|
if (pEnt->isKindOf(AecDbCurveBase::desc()))
|
|
{
|
|
AecDbCurveBase *pBase(AecDbCurveBase::cast(pEnt));
|
|
pMap = pBase->GetSpecialtyData(AcDb::kForWrite);
|
|
}
|
|
else if (pEnt->isKindOf(AecDbEntityBase::desc()))
|
|
{
|
|
AecDbEntityBase *pBase(AecDbEntityBase::cast(pEnt));
|
|
pMap = pBase->GetSpecialtyData(AcDb::kForWrite);
|
|
}
|
|
else
|
|
{
|
|
AecDbObjXDataMap xData;
|
|
xData.Read((AcDbObject *)pEnt, _T("SH_BIMS"));
|
|
if (AecDbObjXDataMap::setBimDatas(xData, bimData))
|
|
xData.Write(pEnt, _T("SH_BIMS"));
|
|
|
|
return;
|
|
}
|
|
if (pMap)
|
|
setBimDatas(*pMap, bimData);
|
|
}
|
|
|
|
AcDbArc* CoreTools::geArc2DbArc(const AcGeCircArc3d &geArc)
|
|
{
|
|
AcGePlane plane = AcGePlane(geArc.center(), geArc.normal());
|
|
double ang = geArc.refVec().angleOnPlane(plane);
|
|
return new AcDbArc(geArc.center()
|
|
, geArc.normal()
|
|
, geArc.radius()
|
|
, geArc.startAng() + ang
|
|
, geArc.endAng() + ang);
|
|
}
|
|
|
|
bool CoreTools::sortOfPointByCurve(AcGePoint3dArray &arPts, AcDbCurve *pCurve)
|
|
{
|
|
if (arPts.length() < 2) return false;
|
|
if (!pCurve) return false;
|
|
|
|
std::multimap<double, AcGePoint3d> mm;
|
|
|
|
AcGePoint3d ptOn;
|
|
double dParam;
|
|
for (int i = 0; i < arPts.length(); ++i)
|
|
{
|
|
if (Acad::eOk != pCurve->getClosestPointTo(arPts[i], ptOn)) continue;
|
|
if (Acad::eOk != pCurve->getParamAtPoint(ptOn, dParam)) continue;
|
|
|
|
mm.insert(std::make_pair(dParam, arPts[i]));
|
|
}
|
|
|
|
if (mm.empty()) return false;
|
|
arPts.removeAll();
|
|
|
|
std::multimap<double, AcGePoint3d>::const_iterator it(mm.begin());
|
|
for (; it != mm.end(); ++it)
|
|
{
|
|
arPts.append(it->second);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
extern unsigned int g_lockState;
|
|
void CoreTools::AddCommand(const TCHAR *cmdGroup, const TCHAR *cmdInt, const TCHAR *cmdLoc,
|
|
const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal)
|
|
{
|
|
if (g_lockState != 0) return;
|
|
|
|
TCHAR cmdLocRes[65];
|
|
|
|
if (idLocal != -1)
|
|
{
|
|
::LoadString(_hdllInstance, idLocal, cmdLocRes, 64);
|
|
acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLocRes, cmdFlags, cmdProc);
|
|
}
|
|
else
|
|
{
|
|
acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLoc, cmdFlags, cmdProc);
|
|
}
|
|
}
|
|
|
|
bool CoreTools::hasCSSZ(const bool & bPrompt)
|
|
{
|
|
bool bRel(true);
|
|
AecDbObjXDataMap xdata;
|
|
if (!KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xdata))
|
|
bRel = false;
|
|
|
|
// 额外检查一下 Project 字段,因为这个字段是后加的,涉及到等级
|
|
CString sProject;
|
|
if (!xdata.GetAt(DOC_PIDPROJECT, sProject))
|
|
bRel = false;
|
|
|
|
if (bPrompt && !bRel)
|
|
{
|
|
acedAlert(_T("\n系统没有初始化!请运行初始化命令!"));
|
|
acedPostCommand(_T("pl_cssz "));
|
|
}
|
|
|
|
return bRel;
|
|
}
|
|
|
|
int CoreTools::IsArxAppLoaded(const TCHAR * AppName)
|
|
{
|
|
struct resbuf *rb, *apps;
|
|
TCHAR file[_MAX_FNAME], dir[_MAX_DIR], ext[_MAX_EXT], drive[_MAX_DRIVE];
|
|
int flag = 0;
|
|
apps = ads_arxloaded();
|
|
for (rb = apps; rb != NULL; rb = rb->rbnext)
|
|
{
|
|
_tsplitpath(rb->resval.rstring, drive, dir, file, ext);
|
|
if (_tcsicmp(AppName, file) == 0)
|
|
{
|
|
flag = 1;
|
|
break;
|
|
}
|
|
}
|
|
ads_relrb(apps);
|
|
|
|
return flag;
|
|
}
|
|
|
|
void CoreTools::setPScaleForSHSKernal(double dScale)
|
|
{
|
|
if (!IsArxAppLoaded(_T("wfK")))
|
|
{
|
|
#ifndef ZWCAD
|
|
if (!acrxDynamicLinker->loadModule(_T("wfK.arx"), false)) return;
|
|
#else
|
|
if (!acrxDynamicLinker->loadModule(_T("wfK.zrx"), false)) return;
|
|
#endif
|
|
}
|
|
|
|
typedef BOOL(_cdecl *setps)(double);
|
|
CString str(FilePath::GetArxDir());
|
|
#ifndef ZWCAD
|
|
str += _T("\\wfK.arx");
|
|
#else
|
|
str += _T("\\wfK.zrx");
|
|
#endif
|
|
HINSTANCE hmod(NULL);
|
|
hmod = ::LoadLibrary(str);
|
|
if (hmod)
|
|
{
|
|
setps func(NULL);
|
|
func = (setps)::GetProcAddress(hmod, "SHS_DocSetPScale");
|
|
if (func)
|
|
func(dScale);
|
|
::FreeLibrary(hmod);
|
|
}
|
|
}
|
|
|
|
void CoreTools::setMeterUnitDrawForSHSKernal(bool bMeter)
|
|
{
|
|
if (!IsArxAppLoaded(_T("wfK")))
|
|
{
|
|
#ifndef ZWCAD
|
|
if (!acrxDynamicLinker->loadModule(_T("wfK.arx"), false)) return;
|
|
#else
|
|
if (!acrxDynamicLinker->loadModule(_T("wfK.zrx"), false)) return;
|
|
#endif
|
|
}
|
|
|
|
typedef void(_cdecl *setps)(BOOL);
|
|
CString str(FilePath::GetArxDir());
|
|
#ifndef ZWCAD
|
|
str += _T("\\wfK.arx");
|
|
#else
|
|
str += _T("\\wfK.zrx");
|
|
#endif
|
|
HINSTANCE hmod(NULL);
|
|
hmod = ::LoadLibrary(str);
|
|
if (hmod)
|
|
{
|
|
setps func(NULL);
|
|
func = (setps)::GetProcAddress(hmod, "SHS_DocSetMeterUnitDraw");
|
|
if (func)
|
|
func(bMeter ? TRUE : FALSE);
|
|
::FreeLibrary(hmod);
|
|
}
|
|
}
|
|
|
|
void CoreTools::setMeterUnitDimForSHSKernal(bool bMeter)
|
|
{
|
|
if (!IsArxAppLoaded(_T("wfK")))
|
|
{
|
|
#ifndef ZWCAD
|
|
if (!acrxDynamicLinker->loadModule(_T("wfK.arx"), false)) return;
|
|
#else
|
|
if (!acrxDynamicLinker->loadModule(_T("wfK.zrx"), false)) return;
|
|
#endif
|
|
}
|
|
|
|
typedef void(_cdecl *setps)(BOOL);
|
|
CString str(FilePath::GetArxDir());
|
|
|
|
#ifndef ZWCAD
|
|
str += _T("\\wfK.arx");
|
|
#else
|
|
str += _T("\\wfK.zrx");
|
|
#endif
|
|
|
|
HINSTANCE hmod(NULL);
|
|
hmod = ::LoadLibrary(str);
|
|
if (hmod)
|
|
{
|
|
setps func(NULL);
|
|
func = (setps)::GetProcAddress(hmod, "SHS_DocSetMeterUnitDim");
|
|
if (func)
|
|
func(bMeter ? TRUE : FALSE);
|
|
::FreeLibrary(hmod);
|
|
}
|
|
}
|
|
|
|
int CoreTools::spliteCurve(const AcDbCurve * pCurve, const double & dSpace, AcDbVoidPtrArray &ar)
|
|
{
|
|
Acad::ErrorStatus es;
|
|
|
|
double dMax(100000), dLen(.0), dPrec(10e-4);
|
|
AcGePoint3d ptStart(AcGePoint3d::kOrigin), ptEnd(AcGePoint3d::kOrigin), pt(AcGePoint3d::kOrigin);
|
|
|
|
es = pCurve->getPointAtDist(.0, ptStart);
|
|
if (es != Acad::eOk) return 0;
|
|
|
|
es = pCurve->getEndPoint(ptEnd);
|
|
if (es != Acad::eOk) return 0;
|
|
|
|
es = pCurve->getDistAtPoint(ptEnd, dLen);
|
|
//if (es != Acad::eOk) return 0;
|
|
|
|
int quotient((int)(dLen / dMax));
|
|
double remainder(fmod(dLen, dMax));
|
|
if (remainder < dPrec) quotient -= 1;
|
|
|
|
AcGePoint3dArray arPts;
|
|
|
|
if (dLen - dMax > dPrec)
|
|
{
|
|
for (int i = 0; i < quotient; ++i)
|
|
{
|
|
if (pCurve->getPointAtDist((i + 1) * dMax, pt) != Acad::eOk) continue;
|
|
arPts.append(pt);
|
|
}
|
|
}
|
|
|
|
if (arPts.isEmpty()) return 0;
|
|
|
|
es = pCurve->getSplitCurves(arPts, ar);
|
|
|
|
return ar.length();
|
|
}
|
|
|
|
AcDbPolyline* CoreTools::spliteCurve(AcDbCurve *pCurve, const int &nCount)
|
|
{
|
|
if (!pCurve) return NULL;
|
|
|
|
AcGePoint3d ptStart, pt0, pt1;
|
|
pCurve->getStartPoint(ptStart);
|
|
|
|
double dParamEnd(.0), dLen;
|
|
pCurve->getEndParam(dParamEnd);
|
|
pCurve->getDistAtParam(dParamEnd, dLen);
|
|
|
|
AcDbVoidPtrArray ar;
|
|
double dDist(dLen / nCount);
|
|
pt0 = ptStart;
|
|
for (int i(1); i < nCount; ++i)
|
|
{
|
|
pCurve->getPointAtDist(i * dDist, pt1);
|
|
ar.append(new AcDbLine(pt0, pt1));
|
|
pt0 = pt1;
|
|
}
|
|
|
|
std::vector<AcDbPolyline*> polys;
|
|
MakePolyline(ar, polys);
|
|
deleteArrayVoidPtrs< AcDbEntity>(ar);
|
|
|
|
if (polys.empty()) return NULL;
|
|
|
|
AcDbPolyline *p((AcDbPolyline*)((AcDbPolyline*)polys[0]->clone()));
|
|
|
|
deleteContainerOfStd(polys);
|
|
|
|
return p;
|
|
}
|
|
|
|
double CoreTools::BulgeFromArc(AcDbCurve *c, bool clockwise)
|
|
{
|
|
double bulge = 0.0;
|
|
AcDbArc *a = AcDbArc::cast(c);
|
|
if (a == NULL) return bulge;
|
|
|
|
double newStart =
|
|
(a->startAngle() > a->endAngle()) ?
|
|
(a->startAngle() - 8 * atan(1.0)) :
|
|
(a->startAngle());
|
|
|
|
bulge = tan((a->endAngle() - newStart) / 4.0);
|
|
if (clockwise) bulge = -bulge;
|
|
//// 此处改为由 arc 法向与Z轴关系来判断bulge的正负
|
|
//AcGeVector3d vt = a->normal();
|
|
//vt.normalize();
|
|
//if (vt.dotProduct(AcGeVector3d::kZAxis) < 0)
|
|
// bulge *= -1;
|
|
return bulge;
|
|
}
|
|
|
|
AcDbPolyline* CoreTools::MakePolyline(const AcDbCurve *pCurve)
|
|
{
|
|
AcDbPolyline *pPoly(AcDbPolyline::cast(pCurve));
|
|
|
|
if (pPoly) // 本身就是 polyline,拷贝一份返回
|
|
return (AcDbPolyline*)pPoly->clone();
|
|
|
|
AcDbCircle *pCir(AcDbCircle::cast(pCurve));
|
|
AcDbLine *pLine(AcDbLine::cast(pCurve));
|
|
AcDbEllipse *pEll(AcDbEllipse::cast(pCurve));
|
|
AcDbSpline *pSpl(AcDbSpline::cast(pCurve));
|
|
AcDbVoidPtrArray ar;
|
|
std::vector<AcDbPolyline*> polys;
|
|
if (pCir)
|
|
{
|
|
// 将圆变成两个弧
|
|
AcDbArc arc1(pCir->center(), pCir->normal(), pCir->radius(), 0, PI);
|
|
AcDbArc arc2(pCir->center(), pCir->normal(), pCir->radius(), PI, 2 * PI);
|
|
ar.append(&arc1);
|
|
ar.append(&arc2);
|
|
if (MakePolyline(ar, polys))
|
|
pPoly = polys[0];
|
|
|
|
return pPoly;
|
|
}
|
|
else if (pLine)
|
|
{
|
|
pPoly = new AcDbPolyline;
|
|
pPoly->addVertexAt(0, pLine->startPoint().convert2d(AcGePlane::kXYPlane));
|
|
pPoly->addVertexAt(1, pLine->endPoint().convert2d(AcGePlane::kXYPlane));
|
|
return pPoly;
|
|
}
|
|
else if (pEll)
|
|
{
|
|
AcDbVoidPtrArray lines;
|
|
if (pEll->isClosed()) // 如果闭合,拆开成两个
|
|
{
|
|
AcDbEllipse arc1(pEll->center()
|
|
, pEll->normal()
|
|
, pEll->majorAxis()
|
|
, pEll->radiusRatio()
|
|
, .0
|
|
, PI );
|
|
|
|
fittingCurve(&arc1, lines);
|
|
|
|
AcDbEllipse arc2(pEll->center()
|
|
, pEll->normal()
|
|
, pEll->majorAxis()
|
|
, pEll->radiusRatio()
|
|
, PI
|
|
, 2 * PI );
|
|
fittingCurve(&arc2, lines);
|
|
}
|
|
else
|
|
{
|
|
fittingCurve(pEll, lines);
|
|
}
|
|
|
|
if (MakePolyline(lines, polys))
|
|
pPoly = polys[0];
|
|
|
|
deleteArrayVoidPtrs<AcDbEntity>(lines);
|
|
return pPoly;
|
|
}
|
|
else if (pSpl)
|
|
{
|
|
AcDbCurve *pC(NULL);
|
|
if (pSpl->toPolyline(pC) == Acad::eOk)
|
|
{
|
|
AcDbPolyline *pP(AcDbPolyline::cast(pC));
|
|
AcDb2dPolyline *pP2d(AcDb2dPolyline::cast(pC));
|
|
AcDb3dPolyline *pP3d(AcDb3dPolyline::cast(pC));
|
|
if (pP) return pP;
|
|
if (pP2d) return MakePolyline(pP2d);
|
|
if (pP3d) return MakePolyline(pP3d);
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
AcDbCurve *p((AcDbCurve*)pCurve->clone());
|
|
ar.append(p);
|
|
if (MakePolyline(ar, polys))
|
|
pPoly = polys[0];
|
|
DELETE_PTR(p);
|
|
|
|
return pPoly;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
bool CoreTools::MakePolyline( const AcDbVoidPtrArray &ar
|
|
, std::vector<AcDbPolyline*> &polys
|
|
, const double &tol)
|
|
{
|
|
// ar 保存的是有序曲线集合
|
|
if (ar.isEmpty()) return false;
|
|
AcDbVoidPtrArray crvs(ar);
|
|
|
|
// 检查内容,对圆特殊处理
|
|
AcDbVoidPtrArray circles;
|
|
for (int i = 0; i < crvs.length(); ++i)
|
|
{
|
|
AcDbCurve *pCurve = AcDbCurve::cast((AcDbEntity*)crvs[i]);
|
|
if (!pCurve)
|
|
{
|
|
acutPrintf(_T("\n存在非曲线实体!"));
|
|
return false;
|
|
}
|
|
|
|
AcDbCircle *pCir = AcDbCircle::cast(pCurve);
|
|
if (pCir)
|
|
{
|
|
circles.append(pCir);
|
|
continue;
|
|
}
|
|
|
|
if (pCurve->isClosed())
|
|
{
|
|
acutPrintf(_T("\n存在闭合的曲线!"));
|
|
return false;
|
|
}
|
|
|
|
AcDbLine *pL = AcDbLine::cast(pCurve);
|
|
AcDbArc *pArc = AcDbArc::cast(pCurve);
|
|
if (!pL && !pArc)
|
|
{
|
|
acutPrintf(_T("\n存在除直线、弧线之外的曲线类型!"));
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// 把 AcDbCircle 替换成两个AcDbArc
|
|
AcDbVoidPtrArray arcs;
|
|
for (int i = 0; i < circles.length(); ++i)
|
|
{
|
|
AcDbCircle *pCir = (AcDbCircle*)circles[i];
|
|
crvs.remove(circles[i]);
|
|
AcDbArc *pArc1 = new AcDbArc(pCir->center(), pCir->normal(), pCir->radius(), 0, PI);
|
|
AcDbArc *pArc2 = new AcDbArc(pCir->center(), pCir->normal(), pCir->radius(), PI, 2 * PI);
|
|
crvs.append(pArc1);
|
|
crvs.append(pArc2);
|
|
arcs.append(pArc1);
|
|
arcs.append(pArc2);
|
|
}
|
|
|
|
AcGePlane plan;
|
|
if (!getPlane(ar, plan))
|
|
{
|
|
acutPrintf(_T("\n计算法向、原点失败!"));
|
|
return false;
|
|
}
|
|
AcGePoint3d ptClosed = plan.closestPointTo(AcGePoint3d::kOrigin);
|
|
double ele = ptClosed.distanceTo(AcGePoint3d::kOrigin);
|
|
if (ptClosed.asVector().dotProduct(plan.normal()) < 0)
|
|
ele *= -1;
|
|
plan.set(ptClosed, plan.normal());
|
|
|
|
AcDbPolyline *pPolyline = new AcDbPolyline();
|
|
pPolyline->setNormal(plan.normal());
|
|
pPolyline->setElevation(ele);
|
|
|
|
AcDbCurve *pFirst = (AcDbCurve*)crvs.first();
|
|
AcGePoint3d nextPt = AcGePoint3d::kOrigin;
|
|
AcGePoint3d prevPt = AcGePoint3d::kOrigin;
|
|
|
|
if (pFirst)
|
|
{
|
|
AcGePoint3d ptStart, ptEnd;
|
|
pFirst->getStartPoint(ptStart);
|
|
pFirst->getEndPoint(ptEnd);
|
|
pPolyline->addVertexAt(0, ptStart.convert2d(plan), BulgeFromArc(pFirst, false), 0, 0);
|
|
pPolyline->addVertexAt(1, ptEnd.convert2d(plan), 0, 0, 0);
|
|
nextPt = ptEnd;
|
|
prevPt = ptStart;
|
|
}
|
|
|
|
crvs.remove(pFirst);
|
|
int prevCnt = crvs.length() + 1;
|
|
|
|
while (crvs.length() > 0 && crvs.length() < prevCnt)
|
|
{
|
|
prevCnt = crvs.length();
|
|
for (int i = 0; i < crvs.length(); ++i)
|
|
{
|
|
AcDbCurve *pCrv(AcDbCurve::cast((AcDbEntity*)crvs[i]));
|
|
if (pCrv)
|
|
{
|
|
AcGePoint3d ptStart, ptEnd;
|
|
pCrv->getStartPoint(ptStart);
|
|
pCrv->getEndPoint(ptEnd);
|
|
if (ptStart.distanceTo(nextPt) < tol || ptEnd.distanceTo(nextPt) < tol)
|
|
{
|
|
double bulge = BulgeFromArc(pCrv, ptEnd.distanceTo(nextPt) < tol);
|
|
pPolyline->setBulgeAt(pPolyline->numVerts() - 1, bulge);
|
|
if (ptStart.distanceTo(nextPt) < tol)
|
|
nextPt = ptEnd;
|
|
else
|
|
nextPt = ptStart;
|
|
pPolyline->addVertexAt(pPolyline->numVerts(), nextPt.convert2d(plan), 0, 0, 0);
|
|
crvs.remove(pCrv);
|
|
break;
|
|
}
|
|
else if (ptStart.distanceTo(prevPt) < tol || ptEnd.distanceTo(prevPt) < tol)
|
|
{
|
|
double bulge = BulgeFromArc(pCrv, ptStart.distanceTo(prevPt) < tol);
|
|
if (ptStart.distanceTo(prevPt) < tol)
|
|
prevPt = ptEnd;
|
|
else
|
|
prevPt = ptStart;
|
|
pPolyline->addVertexAt(0, prevPt.convert2d(plan), bulge, 0, 0);
|
|
crvs.remove(pCrv);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (pPolyline->numVerts() == 0)
|
|
{
|
|
DELETE_PTR(pPolyline);
|
|
deleteArrayVoidPtrs< AcDbEntity>(arcs);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
//if (isClosed(pPolyline, tol))
|
|
// pPolyline->setClosed(true);
|
|
|
|
polys.push_back(pPolyline);
|
|
if (!crvs.isEmpty())
|
|
MakePolyline(crvs, polys);
|
|
deleteArrayVoidPtrs< AcDbEntity>(arcs);
|
|
return !polys.empty();
|
|
}
|
|
}
|
|
|
|
bool CoreTools::bimData2IniFile(LPCTSTR pszFile, const std::map<CString,CString>& datas)
|
|
{
|
|
return IniTools::setSectionContent(pszFile, _T("bim_data"), datas);
|
|
}
|
|
|
|
bool CoreTools::iniFile2BimData(LPCTSTR pszFile, std::map<CString,CString>& datas)
|
|
{
|
|
return IniTools::getSectionContent(pszFile, _T("bim_data"), datas);
|
|
return false;
|
|
}
|
|
|
|
bool CoreTools::getBimDataByDlg(bool bAdd
|
|
, CString &sV1
|
|
, CString &sV2
|
|
, LPCTSTR pszTitle
|
|
, LPCTSTR pszName1
|
|
, LPCTSTR pszName2)
|
|
{
|
|
CAcModuleResourceOverride myResources;
|
|
CAddBimDlg dlg(bAdd, sV1, sV2, pszTitle, pszName1, pszName2);
|
|
if (dlg.DoModal() != IDOK)
|
|
return false;
|
|
sV1 = dlg.m_sValue1;
|
|
sV2 = dlg.m_sValue2;
|
|
return true;
|
|
}
|
|
|
|
AcGePoint3d CoreTools::asAcGePoint3d(const AcGePoint2d & pt, const double & z)
|
|
{
|
|
return AcGePoint3d(pt.x, pt.y, z);
|
|
}
|
|
|
|
DWORD CoreTools::AcCmColor2RGB(const AcCmColor & clr)
|
|
{
|
|
COLORREF rgb(0);
|
|
AcCmEntityColor::ColorMethod method = clr.colorMethod();
|
|
if (method == AcCmEntityColor::kByACI
|
|
|| method == AcCmEntityColor::kByLayer
|
|
|| method == AcCmEntityColor::kByBlock )
|
|
rgb = acedGetRGB(clr.colorIndex());
|
|
else
|
|
rgb = RGB(clr.red(), clr.green(), clr.blue());
|
|
return rgb;
|
|
}
|
|
|
|
AcCmColor CoreTools::RGB2AcCmColor(const DWORD & clr)
|
|
{
|
|
AcCmColor cm;
|
|
#if ARX < 24
|
|
cm.setColorMethod(AcCmEntityColor::kByColor);
|
|
cm.setRed(GetRValue(clr));
|
|
cm.setGreen(GetGValue(clr));
|
|
cm.setBlue(GetBValue(clr));
|
|
#else
|
|
cm.setRGB(GetRValue(clr), GetGValue(clr), GetBValue(clr));
|
|
#endif
|
|
return cm;
|
|
}
|
|
|
|
void CoreTools::findCollinear(AcDbCurve* pCurve
|
|
, const AcDbVoidPtrArray& inputs
|
|
, AcDbVoidPtrArray& outputs
|
|
, bool bExtension)
|
|
{
|
|
if (!pCurve) return;
|
|
if (pCurve->isA() != AcDbLine::desc()) return;
|
|
|
|
//if (bExtension)
|
|
|
|
AcDbLine* pLine = (AcDbLine*)pCurve;
|
|
AcGeVector3d vtDir(pLine->endPoint() - pLine->startPoint());
|
|
vtDir.normalize();
|
|
|
|
AcGeLinearEnt3d* pGeLine(NULL);
|
|
if (bExtension)
|
|
pGeLine = new AcGeLineSeg3d(pLine->startPoint(), pLine->endPoint());
|
|
else
|
|
pGeLine = new AcGeRay3d(pLine->startPoint(), pLine->endPoint());
|
|
|
|
outputs.removeAll();
|
|
outputs.append(pCurve);
|
|
|
|
AcDbVoidPtrArray tmps(0);
|
|
AcGeVector3d vt(AcGeVector3d::kIdentity);
|
|
AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin);
|
|
for (int i = 0; i < inputs.length(); ++i)
|
|
{
|
|
AcDbCurve *pC((AcDbCurve*)inputs[i]);
|
|
if (pC->isA() != AcDbLine::desc()) continue;
|
|
|
|
AcDbLine* pL((AcDbLine*)inputs[i]);
|
|
ptS = pL->startPoint();
|
|
ptE = pL->endPoint();
|
|
vt = ptE - ptS;
|
|
vt.normalize();
|
|
|
|
if (vt != vtDir) continue;
|
|
|
|
if (pGeLine->isOn(ptS) && pGeLine->isOn(ptE))
|
|
outputs.append(pL);
|
|
}
|
|
|
|
DELETE_PTR(pGeLine);
|
|
}
|
|
|
|
AcDbCurve* CoreTools::spliteCurve(AcDbCurve* pOrgCurve, const AcDbCurve* pSub)
|
|
{
|
|
AcDbCurve *pCurve(NULL);
|
|
|
|
AcGeTol tol;
|
|
tol.setEqualPoint(.001);
|
|
|
|
if (!pOrgCurve || !pSub) return pCurve;
|
|
|
|
AcGePoint3d ptS(AcGePoint3d::kOrigin)
|
|
, ptE(AcGePoint3d::kOrigin)
|
|
, ptSClosed(AcGePoint3d::kOrigin)
|
|
, ptEClosed(AcGePoint3d::kOrigin)
|
|
, ptOrgS(AcGePoint3d::kOrigin)
|
|
, ptOrgE(AcGePoint3d::kOrigin);
|
|
|
|
if (pSub->getStartPoint(ptS) != Acad::eOk) return pCurve;
|
|
if (pSub->getEndPoint(ptE) != Acad::eOk) return pCurve;
|
|
if (pOrgCurve->getStartPoint(ptOrgS) != Acad::eOk) return pCurve;
|
|
if (pOrgCurve->getEndPoint(ptOrgE) != Acad::eOk) return pCurve;
|
|
|
|
// 一样的线
|
|
if (ptS.isEqualTo(ptOrgS, tol) && ptE.isEqualTo(ptOrgE))
|
|
{
|
|
pCurve = (AcDbCurve*)pOrgCurve->clone();
|
|
return pCurve;
|
|
}
|
|
|
|
if (pOrgCurve->getClosestPointTo(ptS, AcGeVector3d::kZAxis, ptSClosed) != Acad::eOk) return pCurve;
|
|
if (pOrgCurve->getClosestPointTo(ptE, AcGeVector3d::kZAxis, ptEClosed) != Acad::eOk) return pCurve;
|
|
|
|
// 两点相同,不处理,走
|
|
if (ptSClosed.isEqualTo(ptEClosed, tol)) return pCurve;
|
|
|
|
AcGePoint3dArray pts;
|
|
pts.append(ptSClosed);
|
|
pts.append(ptEClosed);
|
|
AcDbVoidPtrArray ptr(0);
|
|
if (pOrgCurve->getSplitCurves(pts, ptr) != Acad::eOk) return pCurve;
|
|
|
|
int count(ptr.length());
|
|
if (count == 1)
|
|
{
|
|
pCurve = (AcDbCurve*)((AcDbCurve*)ptr[0])->clone();
|
|
}
|
|
else if (count > 2)
|
|
{
|
|
pCurve = (AcDbCurve*)((AcDbCurve*)ptr[1])->clone();
|
|
}
|
|
else if (count == 2)
|
|
{ // 如果两点不同,且返回两个结果,说明至少有一点为起点或终点
|
|
if (ptSClosed == ptOrgS || ptEClosed == ptOrgS)
|
|
pCurve = (AcDbCurve*)((AcDbCurve*)ptr[0])->clone();
|
|
if (ptSClosed == ptOrgE || ptEClosed == ptOrgE)
|
|
pCurve = (AcDbCurve*)((AcDbCurve*)ptr[1])->clone();
|
|
}
|
|
|
|
for (int i = 0; i < count; ++i)
|
|
DELETE_PTR(ptr[i]);
|
|
|
|
ptr.removeAll();
|
|
|
|
return pCurve;
|
|
}
|
|
|
|
std::string CoreTools::unicode2Ansii(LPCTSTR psz, const DWORD & codePage)
|
|
{
|
|
return Base64::unicode2Ansii(psz, codePage);
|
|
}
|
|
|
|
std::wstring CoreTools::ansii2Unicode(LPCSTR psz, const DWORD & codePage)
|
|
{
|
|
return Base64::ansii2Unicode(psz, codePage);
|
|
}
|
|
|
|
bool CoreTools::getNameByDialog(LPCTSTR pszTitle, LPCTSTR pszItemName, CString &sName)
|
|
{
|
|
CString str(_T(""));
|
|
if (!pszTitle || !pszItemName) return false;
|
|
|
|
CAcModuleResourceOverride myResources;
|
|
|
|
CNameDlg dlg(pszTitle, pszItemName);
|
|
dlg.m_sName = sName;
|
|
if (dlg.DoModal() != IDOK) return false;
|
|
|
|
sName = dlg.m_sName;
|
|
|
|
return true;
|
|
}
|
|
|
|
CString CoreTools::pointToString(const AcGePoint2d & pt, const int &prec)
|
|
{
|
|
CString x(TypeConvert::f2s((float)pt.x, &prec));
|
|
CString y(TypeConvert::f2s((float)pt.y, &prec));
|
|
return x + SP_PT + y;
|
|
}
|
|
|
|
CString CoreTools::pointToString(const AcGePoint3d & pt, const int &prec)
|
|
{
|
|
CString x(TypeConvert::f2s((float)pt.x, &prec));
|
|
CString y(TypeConvert::f2s((float)pt.y, &prec));
|
|
CString z(TypeConvert::f2s((float)pt.z, &prec));
|
|
return x + SP_PT + y + SP_PT + z;
|
|
}
|
|
|
|
AcGePoint3d CoreTools::stringToPoint3d(LPCTSTR psz)
|
|
{
|
|
AcGePoint3d pt(AcGePoint3d::kOrigin);
|
|
if (!psz) return pt;
|
|
std::vector<CString> ss(0);
|
|
SplitString(psz, SP_PT, ss);
|
|
if (ss.size() < 3) return pt;
|
|
return AcGePoint3d(TypeConvert::s2f(ss[0]), TypeConvert::s2f(ss[1]), TypeConvert::s2f(ss[2]));
|
|
}
|
|
|
|
AcGePoint2d CoreTools::stringToPoint2d(LPCTSTR psz)
|
|
{
|
|
AcGePoint2d pt(AcGePoint2d::kOrigin);
|
|
if (!psz) return pt;
|
|
std::vector<CString> ss(0);
|
|
SplitString(psz, SP_PT, ss);
|
|
if (ss.size() < 2) return pt;
|
|
return AcGePoint2d(TypeConvert::s2f(ss[0]), TypeConvert::s2f(ss[1]));
|
|
}
|
|
|
|
double CoreTools::R2A(const double &R)
|
|
{
|
|
return (180 * R) / PI;
|
|
}
|
|
|
|
double CoreTools::A2R(const double &A)
|
|
{
|
|
return (PI * A) / 180;
|
|
}
|
|
|
|
int CoreTools::getFlume2DStyle()
|
|
{
|
|
// 水槽对象 2维显示方式 0-内径 1-外径
|
|
return 0;
|
|
}
|
|
|
|
void CoreTools::showPictureDlg(LPCTSTR pszPath, CWnd *pParent)
|
|
{
|
|
if (!::IsWindow(g_PictrueDlg::instance().m_hWnd))
|
|
g_PictrueDlg::instance().Create(CSLTDlg::IDD, acedGetAcadFrame());
|
|
|
|
if (g_PictrueDlg::instance().isSamePicture(pszPath) && g_PictrueDlg::instance().IsWindowVisible())
|
|
{
|
|
g_PictrueDlg::instance().ShowWindow(SW_HIDE);
|
|
return;
|
|
}
|
|
|
|
g_PictrueDlg::instance().setPicture(pszPath, pParent);
|
|
g_PictrueDlg::instance().ShowWindow(SW_SHOW);
|
|
}
|
|
|
|
void CoreTools::hidePictureDlg()
|
|
{
|
|
if (::IsWindow(g_PictrueDlg::instance().m_hWnd))
|
|
g_PictrueDlg::instance().ShowWindow(SW_HIDE);
|
|
}
|
|
|
|
bool CoreTools::equipment2File(AcDbObjectId & idEqu, LPCTSTR pszFile, LPCTSTR pszName)
|
|
{
|
|
OPENOBJ_BEGIN(idEqu, AcDb::kForRead, AecDbEwEquipment, pEqu)
|
|
if (pEqu) return equipment2File(pEqu, pszFile, pszName);
|
|
OPENOBJ_END()
|
|
return false;
|
|
}
|
|
|
|
bool CoreTools::equipment2File(AecDbEwEquipment * pEqu, LPCTSTR pszFile, LPCTSTR pszName)
|
|
{
|
|
if (!pEqu) return false;
|
|
if (!pszFile) return false;
|
|
|
|
CMemFile mf;
|
|
if (!equipment2File(pEqu, mf, pszName)) return false;
|
|
|
|
CFile file;
|
|
if (!file.Open(pszFile, CFile::modeCreate | CFile::modeWrite)) return false;
|
|
|
|
byte *pBuf = new byte[mf.GetLength()];
|
|
memset(pBuf, 0, sizeof(byte));
|
|
mf.Read(pBuf, (UINT)mf.GetLength());
|
|
|
|
file.Write(pBuf, (UINT)mf.GetLength());
|
|
file.Close();
|
|
mf.Close();
|
|
DELETE_ARR_(pBuf);
|
|
return true;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
void XPrimData2File(const AecEqui::XPrimData *pData, CMemFile &file, const int &nVer)
|
|
{
|
|
// ver = 3
|
|
if (nVer > 2)
|
|
file.Write(&pData->m_bBoolSubtract, sizeof(bool));
|
|
|
|
// ver = 4
|
|
if (nVer > 3)
|
|
file.Write(&pData->m_iClr, sizeof(Adesk::UInt16));
|
|
|
|
|
|
file.Write(&pData->m_eType, sizeof(short));
|
|
file.Write(&pData->m_nActiveInf, sizeof(short));
|
|
file.Write(&pData->m_nID, sizeof(long));
|
|
|
|
file.Write(&pData->m_vtMove.x, sizeof(double));
|
|
file.Write(&pData->m_vtMove.y, sizeof(double));
|
|
file.Write(&pData->m_vtMove.z, sizeof(double));
|
|
|
|
file.Write(&pData->m_ptRotation.x, sizeof(double));
|
|
file.Write(&pData->m_ptRotation.y, sizeof(double));
|
|
file.Write(&pData->m_ptRotation.z, sizeof(double));
|
|
|
|
//矩阵
|
|
AcGeMatrix3d xform;
|
|
int nLen = pData->m_arMatrix.length();
|
|
file.Write(&nLen, sizeof(int));
|
|
|
|
int nnn = sizeof(AcGeMatrix3d);
|
|
for (int j = 0; j < pData->m_arMatrix.length(); j++)
|
|
{
|
|
xform = pData->m_arMatrix.at(j);
|
|
for (int n = 0; n < 4; n++)
|
|
{
|
|
for (int k = 0; k < 4; k++)
|
|
{
|
|
file.Write(&xform.entry[n][k], sizeof(double));
|
|
}
|
|
}
|
|
}
|
|
|
|
//data
|
|
file.Write(&pData->m_nSize, sizeof(int));
|
|
if (pData->m_nSize > 0)
|
|
{
|
|
file.Write(pData->m_pData, pData->m_nSize);
|
|
}
|
|
|
|
// ver = 5
|
|
if (nVer > 4)
|
|
{
|
|
nLen = pData->m_sName.GetLength();
|
|
file.Write(&nLen, sizeof(int));
|
|
if (nLen > 0)
|
|
file.Write(pData->m_sName.GetString(), sizeof(TCHAR) * nLen);
|
|
|
|
nLen = (int)pData->m_Combins.size();
|
|
file.Write(&nLen, sizeof(int));
|
|
|
|
for (int i(0); i < nLen; ++i)
|
|
{
|
|
XPrimData2File(pData->m_Combins[i], file, nVer);
|
|
}
|
|
}
|
|
}
|
|
|
|
void File2XPrimData(AecEqui::XPrimData *pData, CFile &file, const int &nVer)
|
|
{
|
|
if (nVer > 2)
|
|
file.Read(&pData->m_bBoolSubtract, sizeof(bool));
|
|
if (nVer > 3)
|
|
file.Read(&pData->m_iClr, sizeof(Adesk::UInt16));
|
|
//通用数据
|
|
file.Read(&pData->m_eType, sizeof(short));
|
|
file.Read(&pData->m_nActiveInf, sizeof(short));
|
|
file.Read(&pData->m_nID, sizeof(long));
|
|
|
|
file.Read(&pData->m_vtMove.x, sizeof(double));
|
|
file.Read(&pData->m_vtMove.y, sizeof(double));
|
|
file.Read(&pData->m_vtMove.z, sizeof(double));
|
|
|
|
file.Read(&pData->m_ptRotation.x, sizeof(double));
|
|
file.Read(&pData->m_ptRotation.y, sizeof(double));
|
|
file.Read(&pData->m_ptRotation.z, sizeof(double));
|
|
|
|
//矩阵
|
|
int nLen = 0;
|
|
file.Read(&nLen, sizeof(int));
|
|
|
|
AcGeMatrix3d xform;
|
|
pData->m_arMatrix.setLogicalLength(0);
|
|
for (int j = 0; j < nLen; j++)
|
|
{
|
|
for (int n = 0; n < 4; n++)
|
|
{
|
|
for (int k = 0; k < 4; k++)
|
|
{
|
|
file.Read(&xform.entry[n][k], sizeof(double));
|
|
}
|
|
}
|
|
pData->m_arMatrix.append(xform);
|
|
}
|
|
|
|
//data
|
|
pData->m_nSize = 0;
|
|
file.Read(&pData->m_nSize, sizeof(int));
|
|
|
|
pData->m_pData = NULL;
|
|
if (pData->m_nSize > 0)
|
|
{
|
|
pData->m_pData = new byte[pData->m_nSize];
|
|
file.Read(pData->m_pData, pData->m_nSize);
|
|
}
|
|
|
|
if (nVer > 4)
|
|
{
|
|
pData->m_sName = _T("");
|
|
file.Read(&nLen, sizeof(int));
|
|
if (nLen > 0)
|
|
{
|
|
TCHAR *psz = new TCHAR[nLen + 1];
|
|
::memset(psz, 0, sizeof(TCHAR) * (nLen + 1));
|
|
file.Read(psz, sizeof(TCHAR) * nLen);
|
|
pData->m_sName = psz;
|
|
DELETE_ARR_(psz);
|
|
}
|
|
|
|
file.Read(&nLen, sizeof(int));
|
|
for (int i(0); i < nLen; ++i)
|
|
{
|
|
AecEqui::XPrimData *pSubData = new AecEqui::XPrimData();
|
|
File2XPrimData(pSubData, file, nVer);
|
|
pData->m_Combins.push_back(pSubData);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CoreTools::equipment2File(AecDbEwEquipment * pEqu, CMemFile & file, LPCTSTR pszName)
|
|
{
|
|
if (!pEqu) return false;
|
|
if (!pszName) return false;
|
|
|
|
//0.写入文件标识
|
|
std::string str1, str2;
|
|
str1.append(EQU_COMPANY);
|
|
str2 = Base64::Encode(str1);
|
|
file.Write(str2.c_str(), sizeof(char)* ((UINT)str2.length()));
|
|
|
|
//1.写入名称
|
|
char szName[MAX_PATH];
|
|
memset(szName, 0, sizeof(szName));
|
|
CString sText = pszName ? pszName : _T("equ");
|
|
_bstr_t bst((LPCTSTR)sText);
|
|
strcpy(szName, (const char*)bst);
|
|
file.Write(szName, MAX_PATH);
|
|
|
|
//2.版本
|
|
//int nVer = 1;
|
|
// 由于AecDbEwEquipment内的扩展数据保存了元素的颜色,所以需要保存入文件,文件格式因此升级
|
|
// 由于 XPrimData 增加了名称 和 设备组合 文件格式由4升级5
|
|
int nVer = 5; //old 4
|
|
file.Write(&nVer, sizeof(int));
|
|
|
|
//4.写入定义数据
|
|
AcGeMatrix3d xform;
|
|
int nCount = pEqu->GetSubPrimObjCount();
|
|
|
|
//4.写入数量
|
|
file.Write(&nCount, sizeof(int));
|
|
|
|
int nLen = 0;
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
AecEqui::XPrimData* pData = pEqu->GetSubPrimObj(i);
|
|
if (!pData) continue;
|
|
|
|
XPrimData2File(pData, file, nVer);
|
|
}
|
|
|
|
//5.写入用户数据
|
|
AecDbObjXDataMap *pXDataMap = pEqu->GetSpecialtyData(AcDb::kForRead);
|
|
if (pXDataMap)
|
|
{
|
|
//pXDataMap->Write(&file, TRUE); //写出用户数据USER0~999
|
|
pXDataMap->Write(&file, FALSE); // ver=2 后改为全部写入
|
|
}
|
|
|
|
file.SeekToBegin();
|
|
|
|
return true;
|
|
}
|
|
|
|
CString CoreTools::getEquipmentName(LPCTSTR pszFile)
|
|
{
|
|
if (!pszFile) return _T("");
|
|
if (_taccess(pszFile, 0x00) != 0x00) return _T("");
|
|
|
|
CString sFile(pszFile);
|
|
FilePath f(sFile);
|
|
CString pszSuffix = f._ext;
|
|
CString pszName = f._file_name_without_ext;
|
|
pszSuffix.MakeLower();
|
|
if (pszSuffix == _T(".equ"))
|
|
{
|
|
|
|
CFile file;
|
|
if (!file.Open(pszFile, CFile::modeRead)) return _T("");
|
|
|
|
//0.读入文件标识
|
|
std::string str1, str2;
|
|
str1.append(EQU_COMPANY);
|
|
str2 = Base64::Encode(str1);
|
|
|
|
int nLen = (int)str2.length() + 1;
|
|
char* pszBuf = new char[nLen];
|
|
memset(pszBuf, 0, nLen);
|
|
file.Read(pszBuf, sizeof(char) * (nLen - 1));
|
|
|
|
if (str2.compare(pszBuf) == -1)
|
|
{
|
|
acedAlert(_T("选择的文件不是设备元件设计文件!"));
|
|
file.Close();
|
|
return _T("");
|
|
}
|
|
|
|
//1.写入名称
|
|
char szName[MAX_PATH];
|
|
memset(szName, 0, sizeof(szName));
|
|
file.Read(szName, MAX_PATH);
|
|
|
|
CString sName;
|
|
sName = szName;
|
|
file.Close();
|
|
return sName;
|
|
}
|
|
else if (pszSuffix == _T(".r2p"))
|
|
{
|
|
SHJson::WDocument doc;
|
|
if (!SHJson::file2Json(pszFile, doc))
|
|
return pszName;
|
|
|
|
if (doc.HasParseError())
|
|
return pszName;
|
|
|
|
if (doc.IsArray())
|
|
{ // 旧版本
|
|
return pszName;
|
|
}
|
|
|
|
SHJson::MIt itConfig = doc.FindMember(_T("Config"));
|
|
if (itConfig != doc.MemberEnd())
|
|
{
|
|
SHJson::MIt itTypeName = itConfig->value.FindMember(_T("typeName"));
|
|
if (itTypeName != itConfig->value.MemberEnd())
|
|
return itTypeName->value.GetString();
|
|
}
|
|
return pszName;
|
|
}
|
|
else if (pszSuffix == _T(".zhequ"))
|
|
{
|
|
return pszName;
|
|
}
|
|
return _T("");
|
|
}
|
|
|
|
bool CoreTools::file2Equipment(AecDbEwEquipment *pEqu, LPCTSTR pszFile, CString *pEquName)
|
|
{
|
|
if (!pEqu) return false;
|
|
if (!pszFile) return false;
|
|
if (_taccess(pszFile, 0x00) != 0x00) return false;
|
|
|
|
CFile file;
|
|
if (!file.Open(pszFile, CFile::modeRead)) return false;
|
|
|
|
//0.读入文件标识
|
|
std::string str1, str2;
|
|
str1.append(EQU_COMPANY);
|
|
str2 = Base64::Encode(str1);
|
|
|
|
int nLen = (int)str2.length() + 1;
|
|
char* pszBuf = new char[nLen];
|
|
memset(pszBuf, 0, nLen);
|
|
file.Read(pszBuf, sizeof(char) * (nLen - 1));
|
|
|
|
if (str2.compare(pszBuf) == -1)
|
|
{
|
|
acedAlert(_T("选择的文件不是设备元件设计文件!"));
|
|
file.Close();
|
|
return NULL;
|
|
}
|
|
|
|
//1.写入名称
|
|
char szName[MAX_PATH];
|
|
memset(szName, 0, sizeof(szName));
|
|
file.Read(szName, MAX_PATH);
|
|
|
|
CString sName, sName2;
|
|
sName = szName;
|
|
if (pEquName)
|
|
*pEquName = sName;
|
|
|
|
AecDbObjXDataMap* pXDataMap = pEqu->GetSpecialtyData();
|
|
pXDataMap->SetAt(KEY_NAME, sName);
|
|
pXDataMap->GetAt(KEY_NAME, sName2);
|
|
pXDataMap->SetAt(KEY_FITSRV, KEY_FITWPIPE);
|
|
pXDataMap->SetAt(KEY_RUNTIME, eEquipment);
|
|
|
|
pEqu->setLayer(KTSetting::InitLayer(LAY_PIPE_OUTSIDE));
|
|
AcDbObjectId _id(KTSetting::InitLayer(LAY_FITN_DASH));
|
|
pEqu->SetDashLayer(_id);
|
|
_id = KTSetting::InitLayer(LAY_FITN_CENTER);
|
|
pEqu->SetCenterLayer(_id);
|
|
|
|
//2.版本
|
|
int nVer = 0;
|
|
file.Read(&nVer, sizeof(int));
|
|
|
|
int nCount = 0;
|
|
file.Read(&nCount, sizeof(int));
|
|
|
|
AecEqui::XPrimData XPrimData;
|
|
AecEqui::XPrimData* pData = &XPrimData;
|
|
AcGeMatrix3d xform;
|
|
|
|
if (nVer >= 1)
|
|
{
|
|
for (int i = 0; i < nCount; i++)
|
|
{
|
|
File2XPrimData(pData, file, nVer);
|
|
pEqu->AddSubPrimObj(pData);
|
|
pData->releaseData();
|
|
}
|
|
}
|
|
|
|
// 这里Read的最后一个参数无用,就是把所有的数据全部读取。
|
|
pXDataMap->Read(&file, TRUE);
|
|
|
|
file.Close();
|
|
|
|
pEqu->subDMesh2NewSolid();
|
|
|
|
return true;
|
|
}
|
|
|
|
std::string CoreTools::getEquimentMd5(AcDbObjectId & idEqu)
|
|
{
|
|
OPENOBJ_BEGIN(idEqu, AcDb::kForRead, AecDbEwEquipment, pEqu)
|
|
if (pEqu) return getEquimentMd5(pEqu);
|
|
OPENOBJ_END()
|
|
return "";
|
|
}
|
|
|
|
std::string CoreTools::getEquimentMd5(AecDbEwEquipment * pEqu)
|
|
{
|
|
if (!pEqu) return "";
|
|
|
|
CMemFile mf;
|
|
equipment2File(pEqu, mf, _T("md5"));
|
|
|
|
byte *pBuf = new byte[mf.GetLength()];
|
|
memset(pBuf, 0, sizeof(byte));
|
|
mf.Read(pBuf, (UINT)mf.GetLength());
|
|
|
|
ImpMD5 md5(pBuf, (UINT)mf.GetLength());
|
|
std::string ss = md5.toString();
|
|
|
|
DELETE_ARR_(pBuf);
|
|
return ss;
|
|
}
|
|
|
|
bool CoreTools::isSHObject(AcDbObjectId & id)
|
|
{
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbEntity, pEnt)
|
|
if (pEnt) return isSHObject(pEnt);
|
|
OPENOBJ_END()
|
|
return false;
|
|
}
|
|
|
|
#define CHECK_SHOBJ(ent,type) if (ent->isKindOf(type::desc())) return true
|
|
|
|
bool CoreTools::isSHObject(AcDbEntity * pEnt)
|
|
{
|
|
if (!pEnt) return false;
|
|
|
|
CString dxf = pEnt->isA()->dxfName();
|
|
return dxf.Find(_T("AEC_")) != -1;
|
|
|
|
CHECK_SHOBJ(pEnt, AecDbEarthWorm);
|
|
//CHECK_SHOBJ(pEnt, AecDbPortRoom);
|
|
CHECK_SHOBJ(pEnt, AecDbVenDoghouse);
|
|
CHECK_SHOBJ(pEnt, AecDbPipeDoghouse);
|
|
CHECK_SHOBJ(pEnt, AecDbCableDoghouse);
|
|
CHECK_SHOBJ(pEnt, AecDbEscapeHatchHouse);
|
|
CHECK_SHOBJ(pEnt, AecDbXXXDoghouse);
|
|
CHECK_SHOBJ(pEnt, AecDbEarthWormFitting);
|
|
CHECK_SHOBJ(pEnt, AecDbBuriedOutletDoghouse);
|
|
CHECK_SHOBJ(pEnt, AecDbEwPipeBase);
|
|
CHECK_SHOBJ(pEnt, AecDbEwPipe);
|
|
CHECK_SHOBJ(pEnt, AecDbShEarthWorm);
|
|
CHECK_SHOBJ(pEnt, AecDbEwCable);
|
|
CHECK_SHOBJ(pEnt, AecDbEwFitting);
|
|
CHECK_SHOBJ(pEnt, AecDbEwEquipment);
|
|
CHECK_SHOBJ(pEnt, AecDbConnectDoghouse);
|
|
CHECK_SHOBJ(pEnt, AecDbX3dPartEntity);
|
|
CHECK_SHOBJ(pEnt, AecDbXWall);
|
|
CHECK_SHOBJ(pEnt, AecDbXSlab);
|
|
CHECK_SHOBJ(pEnt, AecDbColumn);
|
|
CHECK_SHOBJ(pEnt, AecDbBeam);
|
|
CHECK_SHOBJ(pEnt, AecDbFlume);
|
|
CHECK_SHOBJ(pEnt, AecDbSludgePipe);
|
|
CHECK_SHOBJ(pEnt, AecDbRiverGroove);
|
|
CHECK_SHOBJ(pEnt, AecDbParamEquipment);
|
|
|
|
return false;
|
|
}
|
|
|
|
CString CoreTools::dxf2Chs(LPCTSTR dxf)
|
|
{
|
|
if (!dxf) return _T("");
|
|
|
|
std::map<CString, CString>::const_iterator it(g_dxf2chs.end());
|
|
it = g_dxf2chs.find(dxf);
|
|
if (it == g_dxf2chs.end()) return dxf;
|
|
return it->second;
|
|
}
|
|
|
|
AcDbObjectId CoreTools::makeTableRecord(const AcDbVoidPtrArray & ar, LPCTSTR pszName, AcDbDatabase *pDb)
|
|
{
|
|
AcDbObjectId bkID(AcDbObjectId::kNull);
|
|
|
|
if (!pDb) pDb = acdbHostApplicationServices()->workingDatabase();
|
|
|
|
if (!pDb) return bkID;
|
|
|
|
AcDbBlockTablePointer tbl(pDb, AcDb::kForWrite);
|
|
if (tbl.openStatus() != Acad::eOk) return bkID;
|
|
|
|
AcDbBlockTableRecord *pRc = new AcDbBlockTableRecord;
|
|
|
|
pRc->setName(pszName ? pszName : _T("*U"));
|
|
|
|
if (tbl->add(bkID, pRc) != Acad::eOk)
|
|
{
|
|
DELETE_PTR(pRc);
|
|
tbl->close();
|
|
return bkID;
|
|
}
|
|
|
|
for (int i = 0; i < ar.length(); ++i)
|
|
{
|
|
AcDbEntity *p = (AcDbEntity*)ar[i];
|
|
pRc->appendAcDbEntity(p);
|
|
p->close();
|
|
}
|
|
|
|
pRc->close();
|
|
|
|
tbl->close();
|
|
|
|
return bkID;
|
|
}
|
|
|
|
AcDbBlockReference * CoreTools::makeBlockReference(const AcDbVoidPtrArray & ar, LPCTSTR pszName, AcDbDatabase *pDb)
|
|
{
|
|
AcDbObjectId id = makeTableRecord(ar, pszName, pDb);
|
|
if (!id.isValid()) return NULL;
|
|
|
|
return new AcDbBlockReference(AcGePoint3d::kOrigin, id);
|
|
}
|
|
|
|
AcDbObjectId CoreTools::findTableRecord(LPCTSTR pszName, AcDbDatabase *pDb)
|
|
{
|
|
AcDbObjectId bkID(AcDbObjectId::kNull);
|
|
|
|
if (!pszName) return bkID;
|
|
|
|
if (!pDb) pDb = acdbHostApplicationServices()->workingDatabase();
|
|
if (!pDb) return bkID;
|
|
|
|
AcDbBlockTable* pTable(NULL);
|
|
pDb->getBlockTable(pTable, AcDb::kForRead);
|
|
if (!pTable) return bkID;
|
|
|
|
pTable->getAt(pszName, bkID);
|
|
|
|
pTable->close();
|
|
|
|
return bkID;
|
|
}
|
|
|
|
AcDbObjectId CoreTools::findTableRecordByPathName(LPCTSTR pszName, AcDbDatabase * pDb)
|
|
{
|
|
AcDbObjectId bkID(AcDbObjectId::kNull);
|
|
|
|
if (!pszName) return bkID;
|
|
|
|
if (!pDb) pDb = acdbHostApplicationServices()->workingDatabase();
|
|
if (!pDb) return bkID;
|
|
|
|
TCHAR *psz(NULL);
|
|
Acad::ErrorStatus es(Acad::eOk);
|
|
AcDbBlockTable* pTable(NULL);
|
|
pDb->getBlockTable(pTable, AcDb::kForRead);
|
|
if (pTable)
|
|
{
|
|
AcDbBlockTableIterator *pIter(NULL);
|
|
pTable->newIterator(pIter);
|
|
if (pIter)
|
|
{
|
|
AcDbBlockTableRecord *pRec(NULL);
|
|
for (pIter->start(); !pIter->done(); pIter->step())
|
|
{
|
|
es = pIter->getRecord(pRec, AcDb::kForRead);
|
|
if (pRec)
|
|
{
|
|
if (pRec->pathName(psz) == Acad::eOk)
|
|
{
|
|
if (CString(psz).Compare(pszName) == 0)
|
|
{
|
|
bkID = pRec->objectId();
|
|
DELETE_PTR(psz);
|
|
pRec->close();
|
|
break;
|
|
}
|
|
}
|
|
DELETE_PTR(psz);
|
|
pRec->close();
|
|
}
|
|
}
|
|
DELETE_PTR(pIter);
|
|
}
|
|
pTable->close();
|
|
}
|
|
|
|
return bkID;
|
|
}
|
|
|
|
bool CoreTools::UCS2WCS(const AcGePoint3d & ptUcs, AcGePoint3d & ptWcs)
|
|
{
|
|
ads_point pt;
|
|
if (acdbUcs2Wcs(asDblArray(ptUcs), pt, false))
|
|
{
|
|
ptWcs = asPnt3d(pt);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CoreTools::WCS2UCS(const AcGePoint3d & ptWcs, AcGePoint3d & ptUcs)
|
|
{
|
|
ads_point pt;
|
|
if (acdbWcs2Ucs(asDblArray(ptWcs), pt, false))
|
|
{
|
|
ptUcs = asPnt3d(pt);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CoreTools::UCS2WCS(const AcGeVector3d & ptUcs, AcGeVector3d & ptWcs)
|
|
{
|
|
ads_point pt;
|
|
if (acdbUcs2Wcs(asDblArray(ptUcs), pt, true))
|
|
{
|
|
ptWcs = asVec3d(pt);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CoreTools::WCS2UCS(const AcGeVector3d & ptWcs, AcGeVector3d & ptUcs)
|
|
{
|
|
ads_point pt;
|
|
if (acdbWcs2Ucs(asDblArray(ptWcs), pt, true))
|
|
{
|
|
ptUcs = asVec3d(pt);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
Acad::ErrorStatus CoreTools::CloneAndAddToModelSpace(const AcDbEntity * pEnt, int clr)
|
|
{
|
|
if (!pEnt) return Acad::eInvalidInput;
|
|
AcDbEntity *p((AcDbEntity*)pEnt->clone());
|
|
p->setColorIndex(clr);
|
|
return AddToModelSpace(p, NULL, true, NULL);
|
|
}
|
|
|
|
Acad::ErrorStatus CoreTools::AddToModelSpace(AcDbEntity* pEnt, AcDbDatabase* pDb, bool bClose, AcDbObjectId *pId)
|
|
{
|
|
if (!pEnt) return Acad::eInvalidInput;
|
|
|
|
if (pDb == NULL)
|
|
pDb = acdbHostApplicationServices()->workingDatabase();
|
|
|
|
Acad::ErrorStatus es;
|
|
|
|
AcDbBlockTable* pTbl = NULL;
|
|
if (Acad::eOk == (es = pDb->getBlockTable(pTbl, AcDb::kForRead)))
|
|
{
|
|
AcDbBlockTableRecord* pBTR = NULL;
|
|
if (Acad::eOk == (es = pTbl->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForWrite)))
|
|
{
|
|
pTbl->close();//调整到此处,便于反应器检测record
|
|
|
|
es = pBTR->appendAcDbEntity(pEnt);
|
|
pBTR->close();//调整到此处,便于反应器检测record
|
|
|
|
if (es == Acad::eOk && pId) *pId = pEnt->objectId();
|
|
if (bClose)
|
|
pEnt->close();
|
|
}
|
|
}
|
|
return es;
|
|
}
|
|
|
|
AcDbObjectId CoreTools::AddToModelSpace(AcDbEntity * pEnt, bool bClose)
|
|
{
|
|
if (!pEnt) return AcDbObjectId::kNull;
|
|
|
|
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
|
|
|
|
AcDbObjectId id(AcDbObjectId::kNull);
|
|
|
|
AcDbBlockTable *pTbl = NULL;
|
|
Acad::ErrorStatus es;
|
|
if (Acad::eOk == (es = pDb->getBlockTable(pTbl, AcDb::kForRead)))
|
|
{
|
|
AcDbBlockTableRecord* pBTR = NULL;
|
|
if (Acad::eOk == (es = pTbl->getAt(ACDB_MODEL_SPACE, pBTR, AcDb::kForWrite)))
|
|
{
|
|
pTbl->close();//调整到此处,便于反应器检测record
|
|
|
|
es = pBTR->appendAcDbEntity(id, pEnt);
|
|
pBTR->close();//调整到此处,便于反应器检测record
|
|
|
|
if (bClose)
|
|
pEnt->close();
|
|
}
|
|
}
|
|
return id;
|
|
}
|
|
|
|
Acad::ErrorStatus CoreTools::generateGroup(LPCTSTR name, AcDbObjectIdArray & ids, AcDbObjectId *pId)
|
|
{
|
|
if (ids.isEmpty()) return Acad::eInvalidInput;
|
|
Acad::ErrorStatus es;
|
|
AcDbGroup *pGroup = new AcDbGroup;
|
|
AcDbObjectId groupObjectId;
|
|
AcDbDictionary *pGroupDict(NULL);
|
|
|
|
es = acdbCurDwg()->getGroupDictionary(pGroupDict, AcDb::kForWrite);
|
|
if (es != Acad::eOk) return es;
|
|
|
|
es = pGroupDict->setAt(_T("*A"), pGroup, groupObjectId);
|
|
if (es != Acad::eOk)
|
|
{
|
|
DELETE_PTR(pGroup);
|
|
return es;
|
|
}
|
|
pGroupDict->close();
|
|
|
|
if (!name)
|
|
pGroup->setAnonymous();
|
|
else
|
|
pGroup->setName(name);
|
|
|
|
pGroup->setSelectable(true);
|
|
if (pId)
|
|
*pId = pGroup->objectId();
|
|
pGroup->append(ids);
|
|
pGroup->close();
|
|
|
|
return es;
|
|
}
|
|
|
|
double CoreTools::PixelToWcs(int nPixel)
|
|
{
|
|
double dGet;
|
|
ads_point ptScreenSize;
|
|
double nViewSize;
|
|
struct resbuf rb1, rb2;
|
|
acedGetVar(_T("ScreenSize"), &rb1);
|
|
acedGetVar(_T("ViewSize"), &rb2);
|
|
nViewSize = rb2.resval.rreal;
|
|
ads_point_set(rb1.resval.rpoint, ptScreenSize);
|
|
|
|
if (ptScreenSize[1] >= 1.0E-6 && nViewSize >= 1.0E-6)
|
|
dGet = (nViewSize / ptScreenSize[Y]) * nPixel;
|
|
|
|
return dGet;
|
|
}
|
|
|
|
AcDbObjectId CoreTools::GetLTypeId(LPCTSTR pszLType, const CString &sLTypeFileName)
|
|
{
|
|
AcDbObjectId id(AcDbObjectId::kNull);
|
|
if (!pszLType) return id;
|
|
|
|
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
|
|
if (pDb == NULL) return id;
|
|
|
|
AcDbLinetypeTable *pLinetypeTable = NULL;
|
|
Acad::ErrorStatus es = pDb->getLinetypeTable(pLinetypeTable, AcDb::kForRead);
|
|
if (es == Acad::eOk)
|
|
{
|
|
es = pLinetypeTable->getAt(pszLType, id);
|
|
pLinetypeTable->close();
|
|
if (es == Acad::eOk) return id;
|
|
}
|
|
|
|
CString path;
|
|
if (CoreTools::FindFile(sLTypeFileName, path))
|
|
{
|
|
if (acdbLoadLineTypeFile(pszLType, path, pDb) == Acad::eOk)
|
|
{
|
|
AcDbLinetypeTable *pLinetypeTable = NULL;
|
|
Acad::ErrorStatus es = pDb->getLinetypeTable(pLinetypeTable, AcDb::kForRead);
|
|
if (es == Acad::eOk)
|
|
{
|
|
es = pLinetypeTable->getAt(pszLType, id);
|
|
pLinetypeTable->close();
|
|
if (es == Acad::eOk) return id;
|
|
}
|
|
}
|
|
}
|
|
return id;
|
|
}
|
|
|
|
int CoreTools::FindFile(const TCHAR *szFile, CString &sFullPath)
|
|
{
|
|
TCHAR pszFullPath[2 * MAX_PATH] = { 0 };
|
|
if (ads_findfile(szFile, pszFullPath) != RTNORM)
|
|
{
|
|
CString path(FilePath::GetSysDir() + _T('\\') + szFile);
|
|
if (_taccess(path, 0x0) == 0x0)
|
|
{
|
|
sFullPath = path;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sFullPath = pszFullPath;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
void CoreTools::ColorToRGB(int nAcadColor, int * nR, int * nG, int * nB)
|
|
{
|
|
DWORD dw = acedGetRGB(nAcadColor);
|
|
*nR = GetRValue(dw);
|
|
*nG = GetGValue(dw);
|
|
*nB = GetBValue(dw);
|
|
}
|
|
|
|
void CoreTools::ColorToRGB(LPCTSTR clr, int * nR, int * nG, int * nB)
|
|
{
|
|
int nClr = _ttoi(clr);
|
|
ColorToRGB(nClr, nR, nG, nB);
|
|
}
|
|
|
|
int CoreTools::SplitString(LPCTSTR psz, LPCTSTR splite, std::vector<CString> &strs)
|
|
{
|
|
if (!psz || !splite) return 0;
|
|
CString Origianl(psz), Separate(splite);
|
|
|
|
if (Origianl.IsEmpty()) return 0;
|
|
if (Separate.IsEmpty())
|
|
{
|
|
strs.push_back(Origianl);
|
|
return (int)strs.size();
|
|
}
|
|
Origianl.TrimLeft(splite);
|
|
Origianl.TrimRight(splite);
|
|
if (Origianl.IsEmpty()) return 0;
|
|
|
|
int start(0), end = Origianl.Find(Separate, start);
|
|
|
|
if (end == -1) // 没有分割符,则全部放入
|
|
{
|
|
strs.push_back(Origianl);
|
|
return (int)strs.size();
|
|
}
|
|
|
|
CString sTemp(_T(""));
|
|
while (end != -1)
|
|
{
|
|
strs.push_back(Origianl.Mid(start, end - start));
|
|
if (end == Origianl.GetLength() - 1) break;
|
|
start = end + Separate.GetLength();
|
|
end = Origianl.Find(Separate, start);
|
|
if (end == -1)
|
|
strs.push_back(Origianl.Mid(start));
|
|
}
|
|
|
|
return (int)strs.size();
|
|
}
|
|
|
|
int CoreTools::SplitString(LPCTSTR psz, const TCHAR &splite, std::vector<CString> &strs)
|
|
{
|
|
if (!psz) return 0;
|
|
|
|
CString Origianl(psz);
|
|
if (Origianl.IsEmpty()) return 0;
|
|
|
|
Origianl.TrimLeft(splite);
|
|
Origianl.TrimRight(splite);
|
|
if (Origianl.IsEmpty()) return 0;
|
|
|
|
int start(0), end = Origianl.Find(splite, start);
|
|
|
|
if (end == -1) // 没有分割符,则全部放入
|
|
{
|
|
strs.push_back(Origianl);
|
|
return (int)strs.size();
|
|
}
|
|
CString sTemp(_T(""));
|
|
while (end != -1)
|
|
{
|
|
strs.push_back(Origianl.Mid(start, end - start));
|
|
if (end == Origianl.GetLength() - 1) break;
|
|
start = end + 1;
|
|
end = Origianl.Find(splite, start);
|
|
if (end == -1)
|
|
strs.push_back(Origianl.Mid(start));
|
|
}
|
|
|
|
return (int)strs.size();
|
|
}
|
|
|
|
int CoreTools::SplitString(LPCTSTR psz, const TCHAR &splite, CStringArray &strs)
|
|
{
|
|
if (!psz) return 0;
|
|
|
|
CString Origianl(psz);
|
|
if (Origianl.IsEmpty()) return 0;
|
|
|
|
Origianl.TrimLeft(splite);
|
|
Origianl.TrimRight(splite);
|
|
if (Origianl.IsEmpty()) return 0;
|
|
|
|
int start(0), end = Origianl.Find(splite, start);
|
|
|
|
if (end == -1) // 没有分割符,则全部放入
|
|
{
|
|
strs.Add(Origianl);
|
|
return (int)strs.GetSize();
|
|
}
|
|
CString sTemp(_T(""));
|
|
while (end != -1)
|
|
{
|
|
strs.Add(Origianl.Mid(start, end - start));
|
|
if (end == Origianl.GetLength() - 1) break;
|
|
start = end + 1;
|
|
end = Origianl.Find(splite, start);
|
|
if (end == -1)
|
|
strs.Add(Origianl.Mid(start));
|
|
}
|
|
|
|
return (int)strs.GetSize();
|
|
}
|
|
|
|
CString CoreTools::ConnectString(const std::vector<CString> &strs, LPCTSTR separate)
|
|
{
|
|
if (!separate) return _T("");
|
|
|
|
CString connect(_T(""));
|
|
for (size_t i = 0; i < strs.size(); ++i)
|
|
{
|
|
connect += strs[i];
|
|
if (i != strs.size() - 1)
|
|
connect += separate;
|
|
}
|
|
return connect;
|
|
}
|
|
|
|
CString CoreTools::merageString(const TCHAR & sp, LPCTSTR pszFormat, const int floatPrec, ...)
|
|
{
|
|
if (!pszFormat) return _T("");
|
|
|
|
CString str(_T(""));
|
|
|
|
va_list vlist;
|
|
va_start(vlist, floatPrec);
|
|
|
|
CString sFormat(pszFormat), sWildCard(_T(""));
|
|
int idx(sFormat.Find(_T('%')));
|
|
CString strItem(_T(""));
|
|
int prec(3);
|
|
while (idx != -1)
|
|
{
|
|
sWildCard = sFormat.Mid(idx, 2);
|
|
|
|
idx = sFormat.Find(_T('%'), idx + 2);
|
|
|
|
if (sWildCard.CompareNoCase(_T("%d")) == 0) // 整数
|
|
strItem =TypeConvert::i2s(va_arg(vlist, int));
|
|
else if (sWildCard.CompareNoCase(_T("%f")) == 0) // 浮点
|
|
strItem =TypeConvert::d2s(va_arg(vlist, double), &floatPrec);
|
|
else if (sWildCard.CompareNoCase(_T("%s")) == 0) // 字符串
|
|
strItem = va_arg(vlist, TCHAR*);
|
|
else
|
|
continue;
|
|
|
|
str += strItem;
|
|
str += sp;
|
|
}
|
|
|
|
va_end(vlist);
|
|
|
|
return str.Left(str.GetLength() - 1);
|
|
}
|
|
|
|
void CoreTools::DDX_Text_Ex(CDataExchange * pDX, int nIDC, double & value, LPCTSTR lpszFormat)
|
|
{
|
|
|
|
if (pDX->m_bSaveAndValidate)
|
|
{
|
|
AfxTextFloatFormat(pDX, nIDC, &value, value, DBL_DIG);
|
|
}
|
|
else
|
|
{
|
|
HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
|
|
CString str;
|
|
str.Format(lpszFormat, value);
|
|
::SetWindowText(hWndCtrl, str);
|
|
}
|
|
}
|
|
|
|
AcDbObjectId CoreTools::findLayerId(LPCTSTR layname, AcDbDatabase * pDb)
|
|
{
|
|
if (!layname) return AcDbObjectId::kNull;
|
|
if (!pDb) pDb = acdbCurDwg();
|
|
|
|
AcDbObjectId id;
|
|
AcDbLayerTable* pLayerTable = NULL;
|
|
Acad::ErrorStatus err = pDb->getLayerTable(pLayerTable, AcDb::kForRead);
|
|
|
|
if (err == Acad::eOk && pLayerTable)
|
|
{
|
|
err = pLayerTable->getAt(layname, id);
|
|
pLayerTable->close();
|
|
}
|
|
return id;
|
|
}
|
|
|
|
AcDbObjectId CoreTools::findLinetypeId(LPCTSTR linetype, AcDbDatabase * pDb)
|
|
{
|
|
if (!linetype) return AcDbObjectId::kNull;
|
|
if (!pDb) pDb = acdbCurDwg();
|
|
|
|
AcDbObjectId id(AcDbObjectId::kNull);
|
|
AcDbLinetypeTable* pLinetypeTable(NULL);
|
|
|
|
Acad::ErrorStatus err = pDb->getLinetypeTable(pLinetypeTable, AcDb::kForRead);
|
|
if (err == Acad::eOk && pLinetypeTable)
|
|
{
|
|
err = pLinetypeTable->getAt(linetype, id);
|
|
pLinetypeTable->close();
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
AcDbObjectId CoreTools::findTextStyleId(LPCTSTR textstyle, AcDbDatabase * pDb)
|
|
{
|
|
if (!textstyle) return AcDbObjectId::kNull;
|
|
if (!pDb) pDb = acdbCurDwg();
|
|
|
|
AcDbObjectId id(AcDbObjectId::kNull);
|
|
AcDbTextStyleTable* pTextStyleTable(NULL);
|
|
|
|
Acad::ErrorStatus err = pDb->getTextStyleTable(pTextStyleTable, AcDb::kForRead);
|
|
if (err == Acad::eOk && pTextStyleTable)
|
|
{
|
|
err = pTextStyleTable->getAt(textstyle, id);
|
|
pTextStyleTable->close();
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
AcGePoint3d CoreTools::MidPt(const AcGePoint3d & pt1, const AcGePoint3d & pt2)
|
|
{
|
|
return AcGePoint3d((pt1.x + pt2.x) * .5, (pt1.y + pt2.y) * .5, (pt1.z + pt2.z) * .5);
|
|
}
|
|
|
|
AcGePoint2d CoreTools::MidPt(const AcGePoint2d & pt1, const AcGePoint2d & pt2)
|
|
{
|
|
return AcGePoint2d((pt1.x + pt2.x) * .5, (pt1.y + pt2.y) * .5);
|
|
}
|
|
|
|
CString CoreTools::guid()
|
|
{
|
|
CString sID = _T("");
|
|
|
|
GUID Guid;
|
|
static TCHAR szGuid[39];
|
|
RPC_WSTR pszGuid = NULL;
|
|
|
|
UuidCreate(&Guid);
|
|
|
|
if (RPC_S_OK != UuidToString(&Guid, &pszGuid))
|
|
{
|
|
return _T("");
|
|
}
|
|
|
|
lstrcpyn(szGuid, (TCHAR *)pszGuid, sizeof(szGuid));
|
|
RpcStringFree(&pszGuid);
|
|
|
|
szGuid[38] = _T('\0');
|
|
sID = szGuid;
|
|
sID.MakeUpper();
|
|
return sID;
|
|
}
|
|
|
|
Acad::ErrorStatus CoreTools::booleanOper(AcDb3dSolid * pSolid, AcDb3dSolid * pSub, AcDb::BoolOperType btype)
|
|
{
|
|
AcDb3dSolid *pClone((AcDb3dSolid*)pSub->clone());
|
|
Acad::ErrorStatus es = pSolid->booleanOper(btype, pClone);
|
|
DELETE_PTR(pClone);
|
|
return es;
|
|
}
|
|
|
|
AcDbRegion* CoreTools::createRegion(const AcDbVoidPtrArray & curveSegments)
|
|
{
|
|
Acad::ErrorStatus es;
|
|
AcDbVoidPtrArray regions;
|
|
if ( (es = AcDbRegion::createFromCurves(curveSegments, regions) )!= Acad::eOk)
|
|
{
|
|
acutPrintf(_T("\n createFromCurves failed."));
|
|
|
|
AcDbVoidPtrArray arRes;
|
|
AcDbCurve* pCurveT = KTCADUtilityEx::ConvertBoundCurve(curveSegments,arRes);
|
|
if (pCurveT != NULL)
|
|
{
|
|
AcDbPolyline* pPl = AcDbPolyline::cast(pCurveT);
|
|
if (pPl != NULL)
|
|
{
|
|
pPl->setClosed(Adesk::kTrue);
|
|
}
|
|
arRes.removeAll();
|
|
arRes.append(pCurveT);
|
|
|
|
es = AcDbRegion::createFromCurves(arRes,regions);
|
|
|
|
if (es == Acad::eOk)
|
|
acutPrintf(_T("\n re createFromCurves success."));
|
|
}
|
|
}
|
|
|
|
if (regions.isEmpty())
|
|
{
|
|
acutPrintf(_T("\n result is empty."));
|
|
return NULL;
|
|
}
|
|
|
|
AcDbRegion *pReg = (AcDbRegion *)(((AcDbEntity*)regions.first())->clone());
|
|
|
|
deleteArrayVoidPtrs< AcDbEntity>(regions);
|
|
|
|
return pReg;
|
|
}
|
|
|
|
bool CoreTools::createRegion(const AcDbVoidPtrArray& curveSegments, AcDbVoidPtrArray& regions)
|
|
{
|
|
Acad::ErrorStatus es;
|
|
if ( (es = AcDbRegion::createFromCurves(curveSegments, regions) ) != Acad::eOk)
|
|
{
|
|
acutPrintf(_T("\n createFromCurves failed."));
|
|
|
|
AcDbVoidPtrArray arRes;
|
|
AcDbCurve* pCurveT = KTCADUtilityEx::ConvertBoundCurve(curveSegments,arRes);
|
|
if (pCurveT != NULL)
|
|
{
|
|
AcDbPolyline* pPl = AcDbPolyline::cast(pCurveT);
|
|
if (pPl != NULL)
|
|
{
|
|
pPl->setClosed(Adesk::kTrue);
|
|
}
|
|
arRes.removeAll();
|
|
arRes.append(pCurveT);
|
|
|
|
es = AcDbRegion::createFromCurves(arRes,regions);
|
|
|
|
if (es == Acad::eOk)
|
|
acutPrintf(_T("\n re createFromCurves success."));
|
|
}
|
|
}
|
|
|
|
if (regions.isEmpty())
|
|
{
|
|
acutPrintf(_T("\n result is empty."));
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
AcDbRegion* CoreTools::createRegion(AcDbEntity *pEnt)
|
|
{
|
|
AcDbVoidPtrArray arr, segs;
|
|
arr.append(pEnt);
|
|
if (!createRegion(arr, segs)) return NULL;
|
|
return (AcDbRegion*)segs[0];
|
|
}
|
|
|
|
Adesk::UInt64 CoreTools::RegionToString(const AcDbRegion *pReg, char *& pszTxt)
|
|
{
|
|
Adesk::UInt64 dwFileLength = 0;
|
|
pszTxt = NULL;
|
|
|
|
CString sFullPath = FilePath::getSystemTemporaryFolder();
|
|
sFullPath.MakeLower();
|
|
sFullPath += _T("\\Region121.sat");
|
|
|
|
CString sLine;
|
|
AcDbVoidPtrArray arBodyPtrs;
|
|
arBodyPtrs.append((void *)pReg);
|
|
|
|
Acad::ErrorStatus es(AcDbBody::acisOut(sFullPath, arBodyPtrs));
|
|
|
|
if (Acad::eOk == es)
|
|
{
|
|
CFile file;
|
|
if (file.Open(sFullPath, CFile::modeRead))
|
|
{
|
|
dwFileLength = file.GetLength();
|
|
pszTxt = new char[dwFileLength];
|
|
::memset(pszTxt, 0, sizeof(char) * dwFileLength);
|
|
|
|
file.Read(pszTxt, (UINT)dwFileLength);
|
|
|
|
file.Close();
|
|
}
|
|
else
|
|
{
|
|
acutPrintf(_T("\nCoreTools::RegionToString read file failure."));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
acutPrintf(_T("\nCoreTools::RegionToString::acisOut failure. ERRNO %d."), es);
|
|
}
|
|
return dwFileLength;
|
|
}
|
|
|
|
bool CoreTools::RegionToString(const AcDbRegion * pReg, CString & sRegionScrp)
|
|
{
|
|
CString sFullPath = FilePath::getSystemTemporaryFolder();
|
|
sFullPath.MakeLower();
|
|
sFullPath += _T("\\Region1.sat");
|
|
|
|
CString sLine;
|
|
AcDbVoidPtrArray arBodyPtrs;
|
|
arBodyPtrs.append((void*)pReg);
|
|
|
|
Acad::ErrorStatus es(AcDbBody::acisOut(sFullPath, arBodyPtrs));
|
|
|
|
if (Acad::eOk == es)
|
|
{
|
|
CFile file;
|
|
if (file.Open(sFullPath, CFile::modeRead))
|
|
{
|
|
ULONGLONG dwFileLength = file.GetLength();
|
|
char* pszTxt = new char[dwFileLength];
|
|
::memset(pszTxt, 0, sizeof(char) * dwFileLength);
|
|
|
|
file.Read(pszTxt, (UINT)dwFileLength);
|
|
|
|
sRegionScrp = pszTxt;
|
|
delete[] pszTxt;
|
|
|
|
file.Close();
|
|
}
|
|
else
|
|
{
|
|
acutPrintf(_T("\nCoreTools::RegionToString read file failure."));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
acutPrintf(_T("\nCoreTools::RegionToString::acisOut failure. ERRNO %d."), es);
|
|
}
|
|
return sRegionScrp.IsEmpty() ? false : true;
|
|
}
|
|
|
|
bool CoreTools::PolylineToString(AcDbPolyline * pPl, CString & sPoints, bool bMakeSureClosed)
|
|
{
|
|
if (!pPl != NULL) return false;
|
|
|
|
double dBulge = 0.0;
|
|
sPoints = _T("");
|
|
|
|
CString sText;
|
|
AcGePoint2d pt2d;
|
|
AcGePoint3d pt3d;
|
|
AcGePoint2dArray arPt2ds;
|
|
for (int i = 0; i < pPl->numVerts(); i++)
|
|
{
|
|
pPl->getPointAt(i, pt2d);
|
|
pPl->getPointAt(i, pt3d);
|
|
pPl->getBulgeAt(i, dBulge);
|
|
|
|
arPt2ds.append(pt2d);
|
|
sText.Format(_T("%.9f,%.9f@%.9f,"), pt2d.x, pt2d.y, dBulge);
|
|
sPoints += sText;
|
|
}
|
|
if (arPt2ds.isEmpty()) return false;
|
|
|
|
// 如果是闭合曲线,把第一点加入
|
|
if (pPl->isClosed())
|
|
{
|
|
pt2d = arPt2ds.first();
|
|
sText.Format(_T("%.9f,%.9f@%.9f,"), pt2d.x, pt2d.y, dBulge);
|
|
sPoints += sText;
|
|
}
|
|
else
|
|
{
|
|
// 如果不是,且 bMakeSureClosed 为真,说明需要强制闭合
|
|
if (bMakeSureClosed && pPl->numVerts() > 2)
|
|
{
|
|
if (arPt2ds.last().distanceTo(arPt2ds.first()) > 1.e-2)
|
|
{
|
|
pt2d = arPt2ds.first();
|
|
sText.Format(_T("%.9f,%.9f@0.0,"), pt2d.x, pt2d.y);
|
|
sPoints += sText;
|
|
}
|
|
}
|
|
}
|
|
|
|
sText.Format(_T("[%.9f;%.9f;%.9f;%.9f]"), pPl->elevation(), pPl->normal().x, pPl->normal().y, pPl->normal().z);
|
|
sPoints += sText;
|
|
|
|
return true;
|
|
}
|
|
|
|
#define CLASS_CONVER(type, dist, src) type *dist = type::cast((src))
|
|
#include "geometry2json.h"
|
|
bool CoreTools::AcDbCurveToString(AcDbCurve *pPl, CString &str)
|
|
{
|
|
str.Empty();
|
|
using namespace GEO2JSON;
|
|
_geo *pGeo(NULL);
|
|
CLASS_CONVER(AcDbLine, pLine, pPl);
|
|
if (pLine)
|
|
{
|
|
str = _T("AcDbLine");
|
|
pGeo = _geo::makeGeoPtr<line>(pPl);
|
|
}
|
|
CLASS_CONVER(AcDbCircle, pCir, pPl);
|
|
if (pCir)
|
|
{
|
|
str = _T("AcDbCircle");
|
|
pGeo = _geo::makeGeoPtr<circle>(pPl);
|
|
}
|
|
CLASS_CONVER(AcDbArc, pArc, pPl);
|
|
if (pArc)
|
|
{
|
|
str = _T("AcDbArc");
|
|
pGeo = _geo::makeGeoPtr<arc>(pPl);
|
|
}
|
|
|
|
// AcDbPolyline 单独处理
|
|
CLASS_CONVER(AcDbPolyline, pPline, pPl);
|
|
if (pPline)
|
|
{
|
|
str = _T("AcDbPolyline");
|
|
CString cs;
|
|
CoreTools::PolylineToString(pPline, cs, false);
|
|
str += cs;
|
|
return true;
|
|
}
|
|
|
|
CLASS_CONVER(AcDbEllipse, pEll, pPl);
|
|
if (pEll)
|
|
{
|
|
str = _T("AcDbEllipse");
|
|
pGeo = _geo::makeGeoPtr<ellipse>(pPl);
|
|
}
|
|
CLASS_CONVER(AcDbSpline, pSp, pPl);
|
|
if (pSp)
|
|
{
|
|
str = _T("AcDbSpline");
|
|
pGeo = _geo::makeGeoPtr<spline>(pPl);
|
|
}
|
|
|
|
if (pGeo)
|
|
{
|
|
byte *p = pGeo->toBinary();
|
|
unsigned long memlen = pGeo->memLen();
|
|
if (p)
|
|
{
|
|
std::string ss = Base64::Encode((char *)p, memlen);
|
|
delete[] p;
|
|
str += Base64::ansii2Unicode(ss.c_str(), CP_UTF8).c_str();
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
CString cutHead(LPCTSTR pszPoint2ds, LPCTSTR pszHead)
|
|
{
|
|
if (!pszPoint2ds) return _T("");
|
|
CString s(pszPoint2ds);
|
|
int idx(-1);
|
|
CString sType(pszHead);
|
|
if ((idx = s.Find(sType)) != -1)
|
|
return s.Mid(idx + sType.GetLength());
|
|
|
|
return _T("");
|
|
}
|
|
|
|
char* StringToAcDbCurve(LPCTSTR pszPoint2ds, LPCTSTR pszType)
|
|
{
|
|
CString s(cutHead(pszPoint2ds, pszType));
|
|
if (s.IsEmpty()) return NULL;
|
|
|
|
std::string ss = Base64::unicode2Ansii(s, CP_UTF8);
|
|
|
|
char *pBuffer(NULL);
|
|
Base64::Decode(ss, pBuffer);
|
|
|
|
return pBuffer;
|
|
}
|
|
}
|
|
|
|
AcDbCurve *CoreTools::StringToAcDbCurve(LPCTSTR pszPoint2ds)
|
|
{
|
|
if (!pszPoint2ds) return NULL;
|
|
CString s(pszPoint2ds);
|
|
int idx(-1);
|
|
AcDbCurve *pCurve(NULL);
|
|
|
|
GEO2JSON::_geo *pGeo(NULL);
|
|
char *pBuffer(NULL);
|
|
|
|
if (s.Find(_T("AcDbPolyline")) != -1)
|
|
{
|
|
s = cutHead(pszPoint2ds, _T("AcDbPolyline"));
|
|
return CoreTools::StringToPolyline(s);
|
|
}
|
|
|
|
if ((pBuffer = ::StringToAcDbCurve(pszPoint2ds, _T("AcDbLine"))))
|
|
pGeo = new GEO2JSON::line;
|
|
else if ((pBuffer = ::StringToAcDbCurve(pszPoint2ds, _T("AcDbCircle"))))
|
|
pGeo = new GEO2JSON::circle;
|
|
else if ((pBuffer = ::StringToAcDbCurve(pszPoint2ds, _T("AcDbArc"))))
|
|
pGeo = new GEO2JSON::arc;
|
|
else if ((pBuffer = ::StringToAcDbCurve(pszPoint2ds, _T("AcDbEllipse"))))
|
|
pGeo = new GEO2JSON::ellipse;
|
|
else if ((pBuffer = ::StringToAcDbCurve(pszPoint2ds, _T("AcDbSpline"))))
|
|
pGeo = new GEO2JSON::spline;
|
|
else
|
|
{ // 都没有找到,大概率是 CoreTools::PolylineToString()生成的
|
|
return CoreTools::StringToPolyline(pszPoint2ds);
|
|
}
|
|
|
|
pGeo->byBinary((byte*)pBuffer);
|
|
DELETE_ARR_(pBuffer);
|
|
pCurve = pGeo->asDbCurve();
|
|
DELETE_PTR(pGeo);
|
|
|
|
return pCurve;
|
|
|
|
}
|
|
|
|
AcDbPolyline * CoreTools::StringToPolyline(LPCTSTR pszPoint2ds)
|
|
{
|
|
if (!pszPoint2ds) return NULL;
|
|
|
|
if (CString(pszPoint2ds).IsEmpty()) return NULL;
|
|
|
|
CString sPlane,sTemp;
|
|
CString sAll = pszPoint2ds;
|
|
int nPos = sAll.Find(_T("plane="));
|
|
if (nPos != -1)
|
|
{
|
|
sPlane = sAll.Mid(nPos);
|
|
sTemp = sAll.Mid(0,nPos);
|
|
sAll = sTemp;
|
|
}
|
|
|
|
CStringArray arXYs;
|
|
SplitStrintToArray(sAll, arXYs, _T(','));
|
|
// 字符串格式为 "x,y@bulge" 列如: "%.9f,%.9f@%.9f, ..."
|
|
if (arXYs.GetCount() < 2) // 说明没有一个完整的点
|
|
return NULL;
|
|
|
|
double dEl = 0.0;
|
|
AcGeVector3d vtNorm = AcGeVector3d::kZAxis;
|
|
|
|
CString sLast;
|
|
if (arXYs.GetSize() > 0)
|
|
{
|
|
sLast = arXYs.GetAt(arXYs.GetSize() - 1);
|
|
if (sLast.Find(_T('[')) != -1)
|
|
{
|
|
sLast.TrimLeft(_T('['));
|
|
sLast.TrimRight(_T(']'));
|
|
}
|
|
|
|
CStringArray arVals;
|
|
SplitStrintToArray(sLast, arVals, _T(';'));
|
|
|
|
if (arVals.GetSize() >= 4)
|
|
{
|
|
dEl = _ttof(arVals.GetAt(0));
|
|
vtNorm.set(_ttof(arVals.GetAt(1)), _ttof(arVals.GetAt(2)), _ttof(arVals.GetAt(3)));
|
|
}
|
|
}
|
|
|
|
CString sX, sYB, sBulge, sY;
|
|
double dBulge = 0.0;
|
|
int nFind = -1;
|
|
AcGePoint2d pt;
|
|
AcDbPolyline pl;
|
|
|
|
AcDbPolyline* pPl = new AcDbPolyline;
|
|
|
|
if (!sPlane.IsEmpty())
|
|
{
|
|
sPlane.TrimLeft(_T("plane="));
|
|
sPlane.TrimLeft(_T('('));
|
|
sPlane.TrimRight(_T(')'));
|
|
|
|
CStringArray arVals;
|
|
CoreTools::SplitStrintToArray(sPlane,arVals,_T(','));
|
|
|
|
if (arVals.GetSize() >= 4)
|
|
{
|
|
vtNorm.set(_ttof(arVals.GetAt(0)),_ttof(arVals.GetAt(1)),_ttof(arVals.GetAt(2)));
|
|
dEl = _ttof(arVals.GetAt(3));
|
|
|
|
pPl->setNormal(vtNorm);
|
|
pPl->setElevation(dEl);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pPl->setNormal(vtNorm);
|
|
pPl->setElevation(dEl);
|
|
}
|
|
|
|
for (int i = 0; i < arXYs.GetSize() / 2; i++)
|
|
{
|
|
sX = arXYs.GetAt(2 * i);
|
|
sYB = arXYs.GetAt(2 * i + 1);
|
|
sY = sYB;
|
|
dBulge = 0.0;
|
|
|
|
nFind = sYB.Find(_T('@'));
|
|
if (nFind != -1)
|
|
{
|
|
sBulge = sYB.Mid(nFind + 1);
|
|
dBulge = _ttof(sBulge);
|
|
sY = sYB.Mid(0, nFind);
|
|
}
|
|
|
|
pt.set(_ttof(sX), _ttof(sY));
|
|
pPl->addVertexAt(i, pt, dBulge);
|
|
}
|
|
|
|
return pPl;
|
|
}
|
|
|
|
bool CoreTools::CurveToString(const AcDbCurve * pCurve, CString & sScr2)
|
|
{
|
|
AcDbCircle* pCir = AcDbCircle::cast(pCurve);
|
|
AcDbEllipse* pEllipse = AcDbEllipse::cast(pCurve);
|
|
AcDbPolyline* pPl = AcDbPolyline::cast(pCurve);
|
|
|
|
//法向量均为Z
|
|
if (pCir != NULL)
|
|
{
|
|
sScr2.Format(_T("%d:%.9f,%.9f,%.9f,%.9f"), eCircle, pCir->radius(), pCir->center().x, pCir->center().y, pCir->center().z);
|
|
return true;
|
|
}
|
|
|
|
if (pEllipse != NULL)
|
|
{
|
|
sScr2.Format(_T("%d:%.9f,%.9f,%.9f,%.9f"), eEllispe, pEllipse->radiusRatio(), pEllipse->majorAxis().x, pEllipse->majorAxis().y, pEllipse->majorAxis().z);
|
|
return true;
|
|
}
|
|
|
|
if (pPl != NULL)
|
|
{
|
|
return PolylineToString(pPl, sScr2);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
size_t find_nth_occurrence_reverse(const std::string &str, char target, size_t n)
|
|
{
|
|
size_t pos = str.size();
|
|
size_t count = 0;
|
|
|
|
while (pos > 0)
|
|
{
|
|
pos = str.rfind(target, pos - 1); // 从 pos-1 开始反向查找
|
|
if (pos == std::string::npos) break;
|
|
count++;
|
|
if (count == n) return pos;
|
|
}
|
|
|
|
return std::string::npos;
|
|
}
|
|
|
|
// 整理sat文件格式,使其符合规范
|
|
bool fixACISFormat(const char *pszReg, std::string &sOut)
|
|
{
|
|
// 先取第一行,得到data record 的数量
|
|
std::string ss;
|
|
std::stringstream eam(pszReg);
|
|
std::getline(eam, ss);
|
|
if (ss.empty()) return false;
|
|
|
|
std::vector<CString> nums;
|
|
CoreTools::SplitString(CString(ss.c_str()), _T(" "), nums);
|
|
if (nums.size() < 2) return false;
|
|
int countOfRecord = _ttoi((LPCTSTR)nums[1]);
|
|
|
|
ss = pszReg;
|
|
int sharpCount = std::count(ss.begin() ,ss.end(), '#');
|
|
|
|
size_t pos(std::string::npos);
|
|
if (sharpCount > countOfRecord)
|
|
{
|
|
// 如果 sharpCount 大于 countOfRecord,从头部取到第sharpCount个‘#’位置
|
|
pos = find_nth_occurrence_reverse(ss, '#', (sharpCount - countOfRecord + 1));
|
|
}
|
|
else // <=
|
|
{
|
|
// 如果 sharpCount 小于等于 countOfRecord,直接从头部取到最后一个‘#’位置
|
|
pos = ss.rfind('#');
|
|
}
|
|
sOut = ss.substr(0, pos + 1);
|
|
sOut += "\n\r";
|
|
return true;
|
|
}
|
|
}
|
|
|
|
AcDbRegion* CoreTools::StringToRegion(const CString & sRegionScrp)
|
|
{
|
|
std::string sUtf8 = CoreTools::unicode2Ansii((LPCTSTR)sRegionScrp, CP_UTF8);
|
|
std::string sNewSrc;
|
|
if (!fixACISFormat(sUtf8.c_str(), sNewSrc)) return NULL;
|
|
|
|
CFile file;
|
|
CString sFullPath = FilePath::getSystemTemporaryFolder();
|
|
sFullPath.MakeLower();
|
|
sFullPath += _T("\\Region2.sat");
|
|
if (file.Open(sFullPath, CFile::modeCreate | CFile::modeWrite))
|
|
{
|
|
file.Write(sNewSrc.c_str(), sizeof(char) * (UINT)sNewSrc.size());
|
|
file.Close();
|
|
}
|
|
else
|
|
{
|
|
acutPrintf(_T("\nCoreTools::StringToRegion write file failure."));
|
|
return NULL;
|
|
}
|
|
|
|
AcDbRegion *pReg(NULL);
|
|
AcDbVoidPtrArray arBodyPtrs;
|
|
Acad::ErrorStatus es(AcDbBody::acisIn(sFullPath, arBodyPtrs));
|
|
if (Acad::eOk == es)
|
|
{
|
|
if (arBodyPtrs.length() > 0)
|
|
{
|
|
AcDbEntity* pEnt = (AcDbEntity*)arBodyPtrs.first();
|
|
AcDbRegion* pRegion = AcDbRegion::cast(pEnt);
|
|
if (pRegion != NULL)
|
|
{
|
|
pReg = pRegion;
|
|
arBodyPtrs.removeFirst();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
acutPrintf(_T("\nCoreTools::StringToRegion acisIn failure."));
|
|
}
|
|
|
|
for (int i = 0; i < arBodyPtrs.length(); ++i)
|
|
DELETE_PTR(arBodyPtrs[i]);
|
|
|
|
return pReg;
|
|
}
|
|
|
|
AcDbRegion *CoreTools::StringToRegion(Adesk::UInt64 nLen, char *pszReg)
|
|
{
|
|
std::string sNewSrc;
|
|
if (!fixACISFormat(pszReg, sNewSrc)) return NULL;
|
|
|
|
AcDbRegion *pReg(NULL);
|
|
CString sFullPath = FilePath::getSystemTemporaryFolder();
|
|
sFullPath.MakeLower();
|
|
sFullPath += _T("\\Region212.sat");
|
|
|
|
CFile file;
|
|
if (file.Open(sFullPath, CFile::modeCreate | CFile::modeWrite))
|
|
{
|
|
file.Write(sNewSrc.c_str(), sizeof(char) * (UINT)sNewSrc.size());
|
|
file.Close();
|
|
}
|
|
else
|
|
{
|
|
acutPrintf(_T("\nCoreTools::StringToRegion write file failure."));
|
|
return NULL;
|
|
}
|
|
|
|
AcDbVoidPtrArray arBodyPtrs;
|
|
Acad::ErrorStatus es(AcDbBody::acisIn(sFullPath, arBodyPtrs));
|
|
if (Acad::eOk == es)
|
|
{
|
|
if (arBodyPtrs.length() > 0)
|
|
{
|
|
AcDbEntity *pEnt = (AcDbEntity *)arBodyPtrs.first();
|
|
AcDbRegion *pRegion = AcDbRegion::cast(pEnt);
|
|
if (pRegion != NULL)
|
|
{
|
|
pReg = pRegion;
|
|
arBodyPtrs.removeFirst();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
acutPrintf(_T("\n CoreTools::StringToRegion::acisIn failure ERRNO %d."), es);
|
|
}
|
|
|
|
for (int i = 0; i < arBodyPtrs.length(); ++i)
|
|
DELETE_PTR(arBodyPtrs[i]);
|
|
|
|
return pReg;
|
|
}
|
|
|
|
Adesk::UInt64 CoreTools::BodyToString(const AcDbBody *pBody, char *&pszOut)
|
|
{
|
|
Adesk::UInt64 dwFileLength = 0;
|
|
pszOut = NULL;
|
|
|
|
CString sFullPath = FilePath::getSystemTemporaryFolder();
|
|
sFullPath.MakeLower();
|
|
sFullPath += _T("\\Region121.sat");
|
|
|
|
CString sLine;
|
|
AcDbVoidPtrArray arBodyPtrs;
|
|
arBodyPtrs.append((void *)pBody);
|
|
|
|
Acad::ErrorStatus es(AcDbBody::acisOut(sFullPath, arBodyPtrs));
|
|
|
|
if (Acad::eOk == es)
|
|
{
|
|
CFile file;
|
|
if (file.Open(sFullPath, CFile::modeRead))
|
|
{
|
|
dwFileLength = file.GetLength();
|
|
pszOut = new char[dwFileLength];
|
|
::memset(pszOut, 0, sizeof(char) * dwFileLength);
|
|
|
|
file.Read(pszOut, (UINT)dwFileLength);
|
|
|
|
file.Close();
|
|
}
|
|
else
|
|
{
|
|
acutPrintf(_T("\nCoreTools::BodyToString read file failure."));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
acutPrintf(_T("\nCoreTools::BodyToString::acisOut failure. ERRNO %d."), es);
|
|
}
|
|
return dwFileLength;
|
|
}
|
|
|
|
AcDbSurface *CoreTools::StringToFace(Adesk::UInt64 nLen, char *pszBody)
|
|
{
|
|
AcDbSurface *pFace(NULL);
|
|
CString sFullPath = FilePath::getSystemTemporaryFolder();
|
|
sFullPath.MakeLower();
|
|
sFullPath += _T("\\Region312.sat");
|
|
|
|
CFile file;
|
|
if (file.Open(sFullPath, CFile::modeCreate | CFile::modeWrite))
|
|
{
|
|
file.Write(pszBody, nLen);
|
|
file.Close();
|
|
}
|
|
else
|
|
{
|
|
acutPrintf(_T("\nCoreTools::StringToBody write file failure."));
|
|
return NULL;
|
|
}
|
|
|
|
AcDbVoidPtrArray arBodyPtrs;
|
|
Acad::ErrorStatus es(AcDbBody::acisIn(sFullPath, arBodyPtrs));
|
|
if (Acad::eOk == es)
|
|
{
|
|
if (arBodyPtrs.length() > 0)
|
|
{
|
|
AcDbEntity *pEnt = (AcDbEntity *)arBodyPtrs.first();
|
|
//if (pEnt != NULL)
|
|
//{
|
|
// acutPrintf(_T("\nStringToBody classname : %s"), pEnt->isA()->name());
|
|
//}
|
|
|
|
AcDbSurface *pFaceT = AcDbSurface::cast(pEnt);
|
|
if (pFaceT != NULL)
|
|
{
|
|
pFace = pFaceT;
|
|
arBodyPtrs.removeFirst();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
|
|
#ifndef NDEBUG
|
|
static int nAdd = 1;
|
|
//copy file to
|
|
CString sFileName;
|
|
CString sFullPath2 = FilePath::GetRootDir();
|
|
sFullPath2 += _T("\\temp\\");
|
|
sFileName.Format(_T("Region312-%d.sat"), nAdd++);
|
|
sFullPath2 += sFileName;
|
|
|
|
CopyFile(sFullPath, sFullPath2, FALSE);
|
|
#endif // ! NDEBUG
|
|
|
|
acutPrintf(_T("\n CoreTools::StringToBody::acisIn failure ERRNO %d."), es);
|
|
}
|
|
|
|
for (int i = 0; i < arBodyPtrs.length(); ++i)
|
|
DELETE_PTR(arBodyPtrs[i]);
|
|
|
|
return pFace;
|
|
}
|
|
|
|
void CoreTools::SplitStrintToArray(LPCTSTR pszDescr, CStringArray & arInfo, TCHAR tcSpace)
|
|
{
|
|
if (pszDescr == NULL) return;
|
|
|
|
CString sDescr = pszDescr;
|
|
int nLen = sDescr.GetLength();
|
|
int i = 0;
|
|
CString sText = _T("");
|
|
TCHAR tchar = _T('\0');
|
|
|
|
for (i = 0; i < nLen; i++)
|
|
{
|
|
tchar = sDescr.GetAt(i);
|
|
if (tchar == tcSpace)
|
|
{
|
|
arInfo.Add(sText);
|
|
sText = _T("");
|
|
}
|
|
else
|
|
{
|
|
sText += tchar;
|
|
}
|
|
|
|
if (i == nLen - 1 && !sText.IsEmpty())
|
|
{
|
|
arInfo.Add(sText);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CoreTools::SplitStrintToArray(LPCTSTR pszDescr, std::vector<CString>& arInfo, TCHAR tcSpace)
|
|
{
|
|
if (pszDescr == NULL) return;
|
|
|
|
arInfo.clear();
|
|
CString sDescr = pszDescr;
|
|
int nLen = sDescr.GetLength();
|
|
int i = 0;
|
|
CString sText = _T("");
|
|
TCHAR tchar = _T('\0');
|
|
|
|
for (i = 0; i < nLen; i++)
|
|
{
|
|
tchar = sDescr.GetAt(i);
|
|
if (tchar == tcSpace)
|
|
{
|
|
arInfo.push_back(sText);
|
|
sText = _T("");
|
|
}
|
|
else
|
|
{
|
|
sText += tchar;
|
|
}
|
|
|
|
if (i == nLen - 1 && !sText.IsEmpty())
|
|
{
|
|
arInfo.push_back(sText);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CoreTools::isBuildingJs(LPCTSTR psz)
|
|
{
|
|
if (!psz) return false;
|
|
|
|
CString rType(psz);
|
|
rType.MakeLower();
|
|
|
|
if (
|
|
rType.Find(_T("walls")) != -1
|
|
|| rType.Find(_T("floors")) != -1
|
|
|| rType.Find(_T("columns")) != -1
|
|
|| rType.Find(_T("framing")) != -1
|
|
|| rType.Find(_T("doors")) != -1
|
|
|| rType.Find(_T("windows")) != -1
|
|
)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CoreTools::getFilesInFolder(LPCTSTR sPath
|
|
, LPCTSTR filter
|
|
, std::vector<CString>& vs
|
|
, const bool &bOnlyName
|
|
, const bool &bRecursive)
|
|
{
|
|
if (!sPath) return;
|
|
|
|
CString filename(_T(""));
|
|
CFileFind finder;
|
|
|
|
// 先把自己目录下的文件找出来
|
|
BOOL isNotEmpty = finder.FindFile(CString(sPath) + _T("\\") + filter);
|
|
while (isNotEmpty)
|
|
{
|
|
isNotEmpty = finder.FindNextFile();
|
|
filename = bOnlyName ? finder.GetFileTitle() : finder.GetFilePath();
|
|
if (!finder.IsDirectory() && !finder.IsHidden() && !finder.IsDots())
|
|
{
|
|
vs.push_back(filename);
|
|
}
|
|
else
|
|
continue;
|
|
}
|
|
finder.Close();
|
|
|
|
// 如果需要遍历子目录
|
|
if (bRecursive)
|
|
{
|
|
std::vector<CString> paths;
|
|
getSubFolderByPath(sPath, paths, false);
|
|
for (int i(0); i < paths.size(); ++i)
|
|
{
|
|
// 只找当下目录的
|
|
getFilesInFolder(paths[i], filter, vs, bOnlyName, true);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void CoreTools::getSubFolderByPath(LPCTSTR sPath, std::vector<CString>& subFolders, const bool &bOnlyName)
|
|
{
|
|
if (!sPath) return;
|
|
|
|
CString sName(_T(""));
|
|
CFileFind finder;
|
|
BOOL isNotEmpty = finder.FindFile(CString(sPath) + _T("\\*.*"));
|
|
while (isNotEmpty)
|
|
{
|
|
isNotEmpty = finder.FindNextFile();
|
|
if (!finder.IsDots() && finder.IsDirectory())
|
|
{
|
|
sName = finder.GetFilePath();
|
|
if (bOnlyName)
|
|
sName = sName.Right(sName.GetLength() - sName.ReverseFind(_T('\\')) - 1);
|
|
subFolders.push_back(sName);
|
|
}
|
|
}
|
|
finder.Close();
|
|
}
|
|
|
|
//pszSrc d:\xxx\zzz.dwg--> pszDec d:\xxx\zzz.zip
|
|
bool CoreTools::ZipFile(LPCTSTR pszSrc, LPCTSTR pszDec)
|
|
{
|
|
if (!pszSrc || !pszDec) return false;
|
|
if (_taccess(pszSrc, 0x0) != 0x0) return false;
|
|
|
|
CString sFullFile = pszSrc;
|
|
sFullFile.MakeLower();
|
|
|
|
CString sFileName;
|
|
int nPos = sFullFile.ReverseFind(_T('\\'));
|
|
if (nPos != -1)
|
|
{
|
|
sFileName = sFullFile.Mid(nPos + 1);
|
|
|
|
}
|
|
|
|
HZIP hz = CreateZip(pszDec,NULL);
|
|
ZipAdd(hz,sFileName, pszSrc);//? 乱码
|
|
CloseZip(hz);
|
|
|
|
CFileFind m_FileFind;
|
|
if (m_FileFind.FindFile(pszDec)) //路径不存在则创建该路径
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
|
|
static int SplitDirSegments(LPCTSTR pszFullDir,CStringArray& arFields)
|
|
{
|
|
//_T("e:\\mydwgdir\\mydwgdir\\sample\\");
|
|
CString sText = pszFullDir;
|
|
sText.TrimLeft();
|
|
sText.TrimRight();
|
|
sText.MakeLower();
|
|
sText.Replace(_T('/'),_T('\\'));
|
|
|
|
CString sTmp = sText;
|
|
int nPos = sTmp.ReverseFind(_T('.'));
|
|
if (nPos != -1)
|
|
{
|
|
nPos = sTmp.ReverseFind(_T('\\'));
|
|
sText = sTmp.Mid(0,nPos);
|
|
}
|
|
|
|
CString sTemp;
|
|
for (int i = 0;i < sText.GetLength();i++)
|
|
{
|
|
if (sText.GetAt(i) == _T('\\') )
|
|
{
|
|
arFields.Add(sTemp);
|
|
sTemp = _T("");
|
|
}
|
|
else
|
|
{
|
|
sTemp += sText.GetAt(i);
|
|
if (i == sText.GetLength() - 1)
|
|
{
|
|
arFields.Add(sTemp);
|
|
}
|
|
}
|
|
}
|
|
return (int)arFields.GetSize();
|
|
}
|
|
|
|
static DWORD CreateFolder(LPCTSTR pszFullDir)
|
|
{
|
|
//create comp info global data
|
|
PSECURITY_DESCRIPTOR pSec = (PSECURITY_DESCRIPTOR)::LocalAlloc(LMEM_FIXED, SECURITY_DESCRIPTOR_MIN_LENGTH);
|
|
if(pSec == NULL)
|
|
{
|
|
return GetLastError();
|
|
}
|
|
|
|
if(!::InitializeSecurityDescriptor(pSec, SECURITY_DESCRIPTOR_REVISION))
|
|
{
|
|
LocalFree(pSec);
|
|
return GetLastError();
|
|
}
|
|
|
|
if(!::SetSecurityDescriptorDacl(pSec, TRUE, NULL, TRUE))
|
|
{
|
|
LocalFree(pSec);
|
|
return GetLastError();
|
|
}
|
|
|
|
SECURITY_ATTRIBUTES attr;
|
|
attr.bInheritHandle = FALSE;
|
|
attr.lpSecurityDescriptor = pSec;
|
|
attr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
|
|
|
CStringArray arFields;
|
|
SplitDirSegments(pszFullDir,arFields);
|
|
|
|
CString sDir,sFullDir;
|
|
for(int i = 0;i < arFields.GetSize();i++)
|
|
{
|
|
sDir = arFields.GetAt(i);
|
|
sFullDir += sDir;
|
|
sFullDir += _T("\\");
|
|
|
|
if (i > 0)
|
|
{
|
|
::CreateDirectory(sFullDir,&attr);
|
|
}
|
|
}
|
|
LocalFree(pSec);
|
|
return 0;
|
|
}
|
|
|
|
//d:\xx\xx\abc.zip->d:\xx\xx
|
|
void CoreTools::unZipFile(LPCTSTR pszSrc, LPCTSTR pszDec)
|
|
{
|
|
if (!pszSrc || !pszDec) return;
|
|
if (_taccess(pszSrc, 0x0) != 0x0) return;
|
|
|
|
//判断路径是否存在
|
|
//::CreateDirectory(pszDec, NULL);
|
|
|
|
//d:\xx\xx\abc.zip->d:\xx\xx\
|
|
|
|
CreateFolder(pszDec);
|
|
|
|
//只是把zip解压到指定目录下
|
|
UnZipFile(pszSrc, pszDec);
|
|
}
|
|
|
|
void CoreTools::unZipFile(LPCTSTR pszSrc, LPCTSTR pszDec,CStringArray& arGetFiles)
|
|
{
|
|
if (!pszSrc || !pszDec) return;
|
|
if (_taccess(pszSrc, 0x0) != 0x0) return;
|
|
|
|
//判断路径是否存在
|
|
//::CreateDirectory(pszDec, NULL);
|
|
|
|
//d:\xx\xx\abc.zip->d:\xx\xx\
|
|
|
|
CreateFolder(pszDec);
|
|
|
|
//只是把zip解压到指定目录下
|
|
UnZipFile(pszSrc, pszDec,arGetFiles);
|
|
}
|
|
|
|
AcDbObjectId CoreTools::AecInitLayerEx(LPCTSTR pszLayer
|
|
, LPCTSTR pszSys
|
|
, int nColorIndex
|
|
, LPCTSTR pszLineType
|
|
, AcDbDatabase * pDb)
|
|
{
|
|
CString sLayerInit = pszLayer;
|
|
CString sLineTypeinit = pszLineType;
|
|
int nLineWidth = AcDb::kLnWt000;
|
|
|
|
if (pDb == NULL)
|
|
pDb = acdbCurDwg();
|
|
|
|
|
|
//映射到系统图层
|
|
CString dbPath = FilePath::GetSysDir();
|
|
dbPath += _T("\\Plumbing.db");
|
|
|
|
CUIISQLiteServer *pDbSrv = new CUIISQLiteServer;
|
|
pDbSrv->InitADOServer(dbPath);
|
|
if (pDbSrv)
|
|
{
|
|
CString sSQL, sTablename, sCurrSys;
|
|
sCurrSys = pszSys;
|
|
|
|
sTablename = CoreTools::getCurrentPipeSysTblName();
|
|
|
|
//sSQL = _T("select tablename from wpipecfg where currstd=1");
|
|
//if (pDbSrv->GetSelData(sSQL, sTablename))
|
|
if (!sTablename.IsEmpty())
|
|
{
|
|
//LAYKEY LAYNAME PIPESYS SYSTEM COLOR LINETYPE LINEWIDTH
|
|
//11 废水管线中心线 管线中心线 废水 4 Continuous:________ 0
|
|
sSQL.Format(_T("select layname,pipesys,color,linetype,linewidth from [%s] where system='%s'"), sTablename, sCurrSys);
|
|
|
|
CUIIValueTable table;
|
|
pDbSrv->GetSelData(sSQL, table);
|
|
|
|
DELETE_PTR(pDbSrv);
|
|
|
|
CStringArray arVals;
|
|
CString sLayName, sPipeSys, sColor, sLineType, sLineWidth, sTemp;
|
|
|
|
for (int i = 0; i < table.GetTableLogicSize(); i++)
|
|
{
|
|
arVals.RemoveAll();
|
|
table.GetValueRecord(i, arVals);
|
|
|
|
sLayName = arVals.GetAt(0);
|
|
sPipeSys = arVals.GetAt(1);
|
|
sColor = arVals.GetAt(2);
|
|
sLineType = arVals.GetAt(3);
|
|
|
|
//管线中心线
|
|
if (_tcscmp(pszLayer, LAY_PIPE_CENTER) == 0)
|
|
{
|
|
sLayerInit = sLayName;
|
|
sLineTypeinit = sLineType;
|
|
nColorIndex = _ttoi(sColor);
|
|
nLineWidth = _ttoi(sLineWidth);
|
|
break;
|
|
}
|
|
|
|
//管线边线
|
|
if (_tcscmp(pszLayer, LAY_PIPE_OUTSIDE) == 0)
|
|
{
|
|
//sLayerInit = sLayName;
|
|
|
|
sLayerInit.Format(_T("%s-%s"), pszSys, pszLayer);
|
|
sLineTypeinit = sLineType;
|
|
nColorIndex = KTSetting::GetLayerColor(pszLayer);
|
|
|
|
nLineWidth = _ttoi(sLineWidth);
|
|
break;
|
|
}
|
|
|
|
//管线中心线 单线
|
|
if (_tcscmp(pszLayer, PIPE_SINGLE_SYS) == 0)
|
|
{
|
|
//sLayerInit = sLayName;
|
|
sLayerInit.Format(_T("%s-%s"), pszSys, pszLayer);
|
|
sLineTypeinit = sLineType;
|
|
nColorIndex = _ttoi(sColor);
|
|
nLineWidth = _ttoi(sLineWidth);
|
|
break;
|
|
}
|
|
|
|
//FITN_CENTER_SYS
|
|
if (_tcscmp(pszLayer, LAY_FITN_CENTER) == 0)
|
|
{
|
|
sLayerInit = sLayName;
|
|
sLineTypeinit = sLineType;
|
|
nColorIndex = _ttoi(sColor);
|
|
nLineWidth = _ttoi(sLineWidth);
|
|
break;
|
|
}
|
|
|
|
if (_tcscmp(pszLayer, LAY_FITN_OUTSIDE) == 0)
|
|
{
|
|
//sLayerInit = sLayName;
|
|
sLayerInit.Format(_T("%s-%s"), pszSys, pszLayer);
|
|
sLineTypeinit = sLineType;
|
|
nColorIndex = KTSetting::GetLayerColor(pszLayer);
|
|
nLineWidth = _ttoi(sLineWidth);
|
|
break;
|
|
}
|
|
|
|
if (_tcscmp(pszLayer, LAY_FITN_SINGLE) == 0)
|
|
{
|
|
//sLayerInit = sLayName;
|
|
sLayerInit.Format(_T("%s-%s"), pszSys, pszLayer);
|
|
sLineTypeinit = sLineType;
|
|
nColorIndex = _ttoi(sColor);
|
|
nLineWidth = _ttoi(sLineWidth);
|
|
break;
|
|
}
|
|
|
|
if (_tcscmp(pszLayer, LAY_EQU) == 0)
|
|
{
|
|
//sLayerInit = sLayName;
|
|
sLayerInit.Format(_T("%s-%s"), pszSys, pszLayer);
|
|
|
|
sLineTypeinit = sLineType;
|
|
nColorIndex = _ttoi(sColor);
|
|
nLineWidth = _ttoi(sLineWidth);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
AcDbObjectId id;
|
|
AcDbLayerTable* pLayTbl = NULL;
|
|
if (Acad::eOk == pDb->getLayerTable(pLayTbl, AcDb::kForWrite))
|
|
{
|
|
if (Acad::eOk == pLayTbl->getAt(sLayerInit, id))
|
|
{
|
|
//如果找到
|
|
pLayTbl->close();
|
|
return id;
|
|
}
|
|
|
|
AcCmColor color;
|
|
color.setColorIndex(nColorIndex);
|
|
AcDbLayerTableRecord* pRec = new AcDbLayerTableRecord;
|
|
pRec->setColor(color);
|
|
pRec->setLineWeight((AcDb::LineWeight)nLineWidth);
|
|
|
|
//首先判断是否有此线型
|
|
bool bFind = false;
|
|
AcDbObjectId idLt;
|
|
AcDbLinetypeTable* pLTbl = NULL;
|
|
|
|
if (Acad::eOk == pDb->getLinetypeTable(pLTbl, AcDb::kForRead))
|
|
{
|
|
if (Acad::eOk == pLTbl->getAt(sLineTypeinit, idLt))
|
|
{
|
|
bFind = true;
|
|
}
|
|
pLTbl->close();
|
|
}
|
|
if (!bFind)
|
|
{
|
|
//加载线型
|
|
//D:\Program Files\AutoCAD 2008\acad.exe
|
|
TCHAR szFileName[MAX_PATH];
|
|
::GetModuleFileName(acedGetAcadWinApp()->m_hInstance, szFileName, MAX_PATH);
|
|
|
|
//
|
|
CString sLtFile = szFileName;
|
|
sLtFile.MakeLower();
|
|
#ifndef ZWCAD
|
|
sLtFile.Replace(_T("acad.exe"), _T("support\\acad.lin"));
|
|
#else
|
|
sLtFile.Replace(_T("zwcad.exe"), _T("support\\acad.lin"));
|
|
#endif
|
|
|
|
CFileFind find;
|
|
if (find.FindFile(sLtFile))
|
|
{
|
|
acdbLoadLineTypeFile(sLineTypeinit, sLtFile, pDb);
|
|
|
|
if (Acad::eOk == pDb->getLinetypeTable(pLTbl, AcDb::kForRead))
|
|
{
|
|
pLTbl->getAt(sLineTypeinit, idLt);
|
|
pLTbl->close();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (CoreTools::FindFile(_T("acad.lin"), sLtFile))
|
|
{
|
|
acdbLoadLineTypeFile(sLineTypeinit, sLtFile, pDb);
|
|
|
|
if (Acad::eOk == pDb->getLinetypeTable(pLTbl, AcDb::kForRead))
|
|
{
|
|
pLTbl->getAt(sLineTypeinit, idLt);
|
|
pLTbl->close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pRec->setName(sLayerInit);
|
|
pRec->setLinetypeObjectId(idLt);
|
|
pLayTbl->add(id, pRec);
|
|
pRec->close();
|
|
pLayTbl->close();
|
|
}
|
|
return id;
|
|
}
|
|
|
|
int CoreTools::getPipeColorBySystem(LPCTSTR pszSys)
|
|
{
|
|
//return getColorByPipeSys(pszSys, !CoreTools::IsUsePipeOutClrFor3DRender());
|
|
CString dbPath = FilePath::GetSysDir();
|
|
dbPath += _T("\\Plumbing.db");
|
|
|
|
CUIISQLiteServer DbSrv;
|
|
DbSrv.InitADOServer(dbPath);
|
|
|
|
CStringArray arVals;
|
|
CString sSQL, sTablename(CoreTools::getCurrentPipeSysTblName());
|
|
//sSQL = _T("select tablename from wpipecfg where currstd=1");
|
|
|
|
//if (DbSrv.GetSelData(sSQL, sTablename))
|
|
if (!sTablename.IsEmpty())
|
|
{
|
|
//LAYKEY LAYNAME PIPESYS SYSTEM COLOR LINETYPE LINEWIDTH
|
|
//11 废水管线中心线 管线中心线 废水 4 Continuous:________ 0
|
|
sSQL.Format(_T("select layname,pipesys,color,linetype,linewidth from [%s] where system='%s'"), sTablename, pszSys);
|
|
|
|
DbSrv.GetSelData(sSQL, arVals);
|
|
}
|
|
if (arVals.GetSize() > 2) return _ttoi(arVals.GetAt(2));
|
|
return 0;
|
|
}
|
|
|
|
bool CoreTools::sameSystemForPipe(AecDbEwPipe * pPipe1, AecDbEwPipe * pPipe2)
|
|
{
|
|
CString sys1(_T("")), sys2(_T(""));
|
|
pPipe1->GetSpecialtyData()->GetAt(PIPE_SYS, sys1);
|
|
pPipe2->GetSpecialtyData()->GetAt(PIPE_SYS, sys2);
|
|
return sys1 == sys2;
|
|
}
|
|
|
|
void CoreTools::getInnerTypeList(std::vector<CString>& list)
|
|
{
|
|
list.push_back("墙");
|
|
list.push_back("板");
|
|
list.push_back("柱");
|
|
list.push_back("梁");
|
|
list.push_back("洞");
|
|
list.push_back("其它");
|
|
}
|
|
|
|
int CoreTools::getIdxForInnerTypeList(LPCTSTR psz)
|
|
{
|
|
std::vector<CString> list;
|
|
getInnerTypeList(list);
|
|
if (list.empty()) return -1;
|
|
|
|
std::vector<CString>::iterator it = std::find(list.begin(), list.end(), psz);
|
|
return (int)std::distance(list.begin(), it);
|
|
}
|
|
|
|
bool CoreTools::collectHolesForDTYG(AcDbObjectId id, std::vector<HoleData> &holes)
|
|
{
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbBDPipeBase, pEnt)
|
|
{
|
|
if (!pEnt) return false;
|
|
CString dtygType(_T("")), value(_T(""));
|
|
std::vector<CString> vec;
|
|
HoleData hole;
|
|
for (int i = 0; i < pEnt->GetX3dPartCount(); ++i)
|
|
{
|
|
AecDbX3dPart *pPart = pEnt->GetX3dPart(i);
|
|
if (!pPart) continue;
|
|
if (!pPart->GetSpecialtyData()->GetAt(_T("DTYG_TYPE"), dtygType)) continue;
|
|
if (!pPart->GetSpecialtyData()->GetAt(_T("user3"), value)) continue;
|
|
CoreTools::SplitString(value, _T(':'), vec);
|
|
if (vec.size() != 2) continue;
|
|
if (vec[0] != _T("统计类型")) continue;
|
|
if (vec[1] != _T("洞")) continue;
|
|
::memset(&hole, 0, sizeof(HoleData));
|
|
hole.bHasPipe = FALSE;
|
|
hole.eShape = eXShape;
|
|
hole.dSize[0] = .0;
|
|
hole.dSize[1] = .0;
|
|
hole.ptPos = pPart->GetOrgPoint();
|
|
_tcscpy(hole.szRem, _T("开洞"));
|
|
holes.push_back(hole);
|
|
}
|
|
|
|
}
|
|
OPENOBJ_END()
|
|
return true;
|
|
}
|
|
|
|
bool CoreTools::checkFileName(LPCTSTR sFile)
|
|
{
|
|
DWORD dw = ::GetFileAttributes(sFile);
|
|
if (dw == INVALID_FILE_ATTRIBUTES)
|
|
{
|
|
if (::GetLastError()== ERROR_INVALID_NAME)
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
void CoreTools::sendKeyToWindow(HWND handle, UINT key)
|
|
{
|
|
UINT scan(MapVirtualKey(key, 0));
|
|
LPARAM lparam(0);
|
|
lparam = 0x00000001 | (LPARAM)(scan << 16);
|
|
::SendMessage(handle, WM_KEYDOWN, key, lparam);
|
|
::SendMessage(handle, WM_CHAR, key, lparam);
|
|
LPARAM tmp(1);
|
|
lparam |= (tmp << 30);
|
|
lparam |= (tmp << 31);
|
|
::SendMessage(handle, WM_KEYUP, key, lparam);
|
|
}
|
|
|
|
void CoreTools::sendKeyToCADView(UINT key)
|
|
{
|
|
CView *pView = acedGetAcadDwgView();
|
|
sendKeyToWindow(pView->GetSafeHwnd(), key);
|
|
}
|
|
|
|
void AcDbPolyline2GePolygon2d(const AcDbPolyline &poly, Geometry::GePwh2d &pwh)
|
|
{
|
|
pwh.outer_boundary.vertexs.clear();
|
|
pwh.inner_holes.clear();
|
|
//AcGePoint2d pt(AcGePoint2d::kOrigin);
|
|
AcGePlane pln;
|
|
AcDb::Planarity pla;
|
|
poly.getPlane(pln, pla);
|
|
AcGePoint3d pt(AcGePoint3d::kOrigin);
|
|
for (int i = 0; i < poly.numVerts(); ++i)
|
|
{
|
|
poly.getPointAt(i, pt);
|
|
//poly.getPointAt(i, pt);
|
|
pwh.outer_boundary.vertexs.push_back(pt.convert2d(pln));
|
|
}
|
|
|
|
if (!Geometry::is_counterclockwise(pwh))
|
|
{
|
|
std::reverse(pwh.outer_boundary.vertexs.begin(), pwh.outer_boundary.vertexs.end());
|
|
}
|
|
}
|
|
|
|
bool CoreTools::getRegionInfo(AcDbRegion *pReg, AcGePoint3d ¢roid, double &area, AcGePlane &pln)
|
|
{
|
|
if (!pReg) return false;
|
|
|
|
if (pReg->getPlane(pln) != Acad::eOk) return false;
|
|
|
|
AcDbExtents ext;
|
|
pReg->getGeomExtents(ext);
|
|
centroid = CoreTools::MidPt(ext.maxPoint(), ext.minPoint());
|
|
|
|
AcGePoint3d ptOrg;
|
|
AcGeVector3d vtX, vtY;
|
|
pln.getCoordSystem(ptOrg, vtX, vtY);
|
|
AcGePoint2d pt2d;
|
|
double d(.0), ds[2];
|
|
AcGeVector2d vt2ds[2];
|
|
if (pReg->getAreaProp(ptOrg, vtX, vtY, d, area, pt2d, ds, d, ds, vt2ds, ds, pt2d, pt2d) == Acad::eOk)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
int CoreTools::ptInRegion(const AcGePoint2d &pt, AcDbRegion *pReg)
|
|
{
|
|
if (!pReg) return Geometry::eOutside;
|
|
|
|
AcGePlane pln;
|
|
if (pReg->getPlane(pln) != Acad::eOk) return Geometry::eOutside;
|
|
|
|
AcDbVoidPtrArray ptrs;
|
|
if (pReg->explode(ptrs) != Acad::eOk) return Geometry::eOutside;
|
|
if (ptrs.isEmpty()) return Geometry::eOutside;
|
|
|
|
std::vector<AcDbPolyline*> polys;
|
|
MakePolyline(ptrs, polys);
|
|
if (polys.empty()) return Geometry::eOutside;
|
|
|
|
AcDbPolyline *pPoly = (AcDbPolyline*)((AcDbEntity*)polys[0])->clone();
|
|
deleteContainerOfStd(polys);
|
|
|
|
AcDbPolyline *pNewPoly = CoreTools::spliteCurve((AcDbCurve*)pPoly, 100);
|
|
DELETE_PTR(pPoly);
|
|
|
|
if (!pNewPoly) return Geometry::eOutside;
|
|
|
|
Geometry::GePwh2d gepoly;
|
|
AcDbPolyline2GePolygon2d(*pNewPoly, gepoly);
|
|
|
|
DELETE_PTR(pNewPoly);
|
|
|
|
return Geometry::boundary_check(pt, gepoly);
|
|
}
|
|
|
|
struct resbuf* CoreTools::MakeFence(const std::vector<AcGePoint3d> &pts)
|
|
{
|
|
struct resbuf resF;
|
|
resF.restype = RT3DPOINT;
|
|
|
|
struct resbuf *pHead = NULL;
|
|
struct resbuf *pHeadT = NULL;
|
|
struct resbuf *pTemp = NULL; acutNewRb(RT3DPOINT);
|
|
|
|
for (size_t i(0); i < pts.size(); i++)
|
|
{
|
|
const AcGePoint3d &pt(pts[i]);
|
|
|
|
pTemp = acutNewRb(RT3DPOINT);
|
|
pTemp->resval.rpoint[0] = pt.x;
|
|
pTemp->resval.rpoint[1] = pt.y;
|
|
pTemp->resval.rpoint[2] = 0;
|
|
pTemp->restype = RT3DPOINT;//make sure
|
|
pTemp->rbnext = NULL;
|
|
|
|
if (pHead == NULL)
|
|
{
|
|
pHead = pTemp;
|
|
pHeadT = pHead;
|
|
}
|
|
else
|
|
{
|
|
pHead->rbnext = pTemp;
|
|
pHead = pTemp;
|
|
pHead->rbnext = NULL;
|
|
}
|
|
}
|
|
return pHeadT;
|
|
}
|
|
|
|
bool CoreTools::IsMetersUnit()
|
|
{
|
|
struct resbuf rb;
|
|
acedGetVar(_T("INSUNITS"), &rb);
|
|
return rb.resval.rint == AcDb::kUnitsMeters;
|
|
}
|
|
|
|
Adesk::Int32 CoreTools::addNozzForEqu(AecDbEwEquipment *pEqu
|
|
, const AcGeVector3d &vtDir
|
|
, const AcGePoint3d &ptIns
|
|
, AecEqui::XPrimData &data)
|
|
{
|
|
// data 由外部释放
|
|
if (data.m_nActiveInf == -1) return -1;
|
|
AcGePoint3d ptGeThis0, ptGeThis1;
|
|
AcGeVector3d vtDir0, vtDir1;
|
|
|
|
pEqu->GetInfFaceInf(&data, vtDir0, ptGeThis0, 0);
|
|
pEqu->GetInfFaceInf(&data, vtDir1, ptGeThis1, 1);
|
|
|
|
|
|
// 在这里计算一下方向
|
|
// 取 activeInf = 0 时的点 与 activeInf = 1 时的点,即是管嘴的最低点(=0)和最高点(=1)
|
|
// 两点相减得到方向为管嘴的真正方向,指向最高点
|
|
AcGeVector3d vtNozz(AcGeVector3d::kZAxis);
|
|
|
|
AcGeVector3d vtNorm = vtNozz.crossProduct(vtDir);
|
|
AcGeMatrix3d xform1 = vtNozz.rotateTo(vtDir, vtNorm);
|
|
|
|
AcGeVector3d vtMove = ptIns - ptGeThis0;
|
|
AcGeMatrix3d xform2;
|
|
xform2.setToTranslation(vtMove);
|
|
|
|
data.m_arMatrix.append(xform1);
|
|
data.m_arMatrix.append(xform2);
|
|
data.m_nActiveInf = -1;
|
|
pEqu->AddSubPrimObj(&data);
|
|
return data.m_nID;
|
|
}
|
|
|
|
Adesk::Int32 CoreTools::addNozzForEqu_Rect(AecDbEwEquipment *pEqu
|
|
, const AcGeVector3d &vtDir
|
|
, const AcGePoint3d &ptIns
|
|
, const double &dFL // 长
|
|
, const double &dFW // 宽
|
|
, const double &dFH // 高
|
|
, const double &dO // 卷边
|
|
, const double &dT // 法兰厚度
|
|
, const int &nFlangType // 0 单法兰 1 双法兰 2 无法兰
|
|
, const bool &bHvacCircle // 圆口?
|
|
, const bool &bPipeSys // 水管系统?
|
|
)
|
|
{
|
|
AecEqui::XPrimData data;
|
|
data.m_eType = AecEqui::kNozz;
|
|
data.m_nActiveInf = 0;
|
|
data.m_nID = ::GetTickCount();
|
|
|
|
AecEqui::XNozz nozz;
|
|
nozz.bTwoFlags = nFlangType;
|
|
nozz.nType = bHvacCircle ? 2 : 1;
|
|
nozz.dVal1 = dFL;
|
|
nozz.dVal2 = dFW;
|
|
nozz.dVal3 = dFH;
|
|
nozz.dVal4 = dO;
|
|
nozz.dVal5 = dT;
|
|
|
|
if (bHvacCircle)
|
|
{
|
|
nozz.nType = 2;
|
|
nozz.nCmd = 1;
|
|
}
|
|
else
|
|
{
|
|
nozz.nCmd = bPipeSys ? 0 : 1;
|
|
nozz.nType = 1;
|
|
}
|
|
|
|
data.m_nSize = sizeof(AecEqui::XNozz);
|
|
data.m_pData = new char[data.m_nSize];
|
|
|
|
::memcpy(data.m_pData, &nozz, sizeof(AecEqui::XNozz));
|
|
|
|
Adesk::Int32 res = addNozzForEqu(pEqu, vtDir, ptIns, data);
|
|
data.releaseData();
|
|
return res;
|
|
}
|
|
|
|
double CoreTools::MakeSureMMUnit(double& dDn)
|
|
{
|
|
if (dDn < 5.0 && dDn > 0)//最小公程直径 6
|
|
{
|
|
dDn *= 1000.0;
|
|
return 1000.0;
|
|
}
|
|
return 1.0;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
void getNozzInfo(const double &dDN, LPCTSTR sPN, double &dWD, double &dC, double &dYh, double &dN)
|
|
{
|
|
CUIISQLiteServer db;
|
|
db.InitADOServer(FilePath::GetSysDir() + _T("\\plumbing.db"));
|
|
double dPre(1.);
|
|
if (sPN)
|
|
dPre = _ttof(sPN);;
|
|
CoreTools::QueryFlangData(&db, dDN, dPre, dWD, dC, dYh, dN);
|
|
}
|
|
}
|
|
|
|
Adesk::Int32 CoreTools::addNozzForEqu_Circle(AecDbEwEquipment *pEqu
|
|
, const AcGeVector3d &vtDir
|
|
, const AcGePoint3d &ptIns
|
|
, const double &dDN // 公称
|
|
, LPCTSTR sPress // 压力
|
|
, const int &nFlangType // 0 单法兰 1 双法兰 2 无法兰
|
|
, const bool &bPipeSys // 水管系统?
|
|
, const bool &bHvacCircle // 风管圆口?
|
|
, const bool &bUseDB // 根据 公称和压力搜索数据库,得到数据,不使用 dH, dFlangH
|
|
, const double &dH // 总高度
|
|
, const double &dFlangH // 法兰高度
|
|
)
|
|
{
|
|
double _dYMinh(.0), _dYH(.0);
|
|
|
|
double nD(.0), nN(.0), nC(.0), dYMinh(.0);
|
|
getNozzInfo(dDN, sPress, nD, nC, dYMinh, nN);
|
|
if (bUseDB)
|
|
{
|
|
_dYMinh = dYMinh;
|
|
_dYH = 2 * _dYMinh;
|
|
}
|
|
else
|
|
{
|
|
_dYMinh = dFlangH;
|
|
_dYH = dH;
|
|
}
|
|
|
|
AecEqui::XPrimData data;
|
|
data.m_eType = AecEqui::kNozz;
|
|
data.m_nActiveInf = 0;
|
|
data.m_nID = ::GetTickCount();
|
|
|
|
AecEqui::XNozz nozz;
|
|
nozz.bTwoFlags = nFlangType;
|
|
if (bHvacCircle)
|
|
{
|
|
nozz.nType = 2;
|
|
nozz.nCmd = 1;
|
|
}
|
|
else
|
|
{
|
|
if (bPipeSys)
|
|
{
|
|
nozz.nCmd = 0;
|
|
nozz.nType = 0;
|
|
}
|
|
else
|
|
{
|
|
nozz.nType = 2;
|
|
nozz.nCmd = 1;
|
|
}
|
|
}
|
|
|
|
nozz.dVal1 = 1.0 * int(dDN);
|
|
nozz.dVal2 = 1.0 * nD;
|
|
nozz.dVal3 = 1.0 * nN;
|
|
nozz.dVal4 = 1.0 * (nC = nC > _dYMinh ? _dYMinh : nC);
|
|
nozz.dVal5 = _dYH;
|
|
|
|
//兼容之前的,放到szResvr中
|
|
sprintf(nozz.szResvr, "N=%d;P=%g;H=%d;", (int)nN, _ttof(sPress), (int)dYMinh);
|
|
|
|
|
|
data.m_nSize = sizeof(AecEqui::XNozz);
|
|
data.m_pData = new char[data.m_nSize];
|
|
::memcpy(data.m_pData, &nozz, sizeof(AecEqui::XNozz));
|
|
|
|
Adesk::Int32 res = addNozzForEqu(pEqu, vtDir, ptIns, data);
|
|
data.releaseData();
|
|
return res;
|
|
}
|
|
|
|
void CoreTools::enumBlockByDWG(LPCTSTR pszDWG
|
|
, std::vector<CString> &vec
|
|
, LPCTSTR pszFilter
|
|
, AcDbObjectIdArray *pIds)
|
|
{
|
|
vec.clear();
|
|
if (_taccess(pszDWG, 0x0) != 0x0) return;
|
|
AcDbDatabase *pSrcDb = new AcDbDatabase(false);
|
|
if (pSrcDb->readDwgFile(pszDWG, AcDbDatabase::kForReadAndAllShare) == Acad::eOk)
|
|
{
|
|
enumBlockByDWG(pSrcDb, vec, pszFilter, pIds);
|
|
}
|
|
DELETE_PTR(pSrcDb);
|
|
}
|
|
|
|
void CoreTools::enumBlockByDWG(AcDbDatabase *pDb
|
|
, std::vector<CString> &vec
|
|
, LPCTSTR pszFilter
|
|
, AcDbObjectIdArray *pIds)
|
|
{
|
|
if (!pDb) return;
|
|
vec.clear();
|
|
AcDbBlockTable *pTbl(NULL);
|
|
pDb->getBlockTable(pTbl, AcDb::kForRead);
|
|
if (pTbl)
|
|
{
|
|
AcDbBlockTableIterator *pItr(NULL);
|
|
AcDbBlockTableRecord *pRcd(NULL);
|
|
pTbl->newIterator(pItr);
|
|
if (pItr)
|
|
{
|
|
for (pItr->start(); !pItr->done(); pItr->step())
|
|
{
|
|
if (pItr->getRecord(pRcd, AcDb::kForRead) == Acad::eOk)
|
|
{
|
|
AcString StyleName(_T(""));
|
|
pRcd->getName(StyleName);
|
|
if (!StyleName.isEmpty() && StyleName.constPtr()[0] != _T('*'))
|
|
{
|
|
if (pszFilter)
|
|
{
|
|
if (StyleName.find(pszFilter) != -1)
|
|
{
|
|
vec.push_back((LPCTSTR)StyleName);
|
|
if (pIds) pIds->append(pRcd->objectId());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
vec.push_back((LPCTSTR)StyleName);
|
|
if (pIds) pIds->append(pRcd->objectId());
|
|
}
|
|
}
|
|
pRcd->close();
|
|
}
|
|
}
|
|
DELETE_PTR(pItr);
|
|
}
|
|
pTbl->close();
|
|
}
|
|
}
|
|
|
|
int CoreTools::encryptionType()
|
|
{
|
|
// 根据product.ini里面的[startapp]的"bal"来判断是
|
|
std::map<CString, CString> mm;
|
|
CString iniFile(FilePath::GetSysDir() + _T("\\product.ini"));
|
|
IniTools::getSectionContent(iniFile, _T("STARTAPP"), mm);
|
|
if (mm.empty())
|
|
{
|
|
#if defined (BAL_LOCAL)
|
|
return 0;
|
|
#else
|
|
return 1;
|
|
#endif
|
|
}
|
|
|
|
std::map<CString, CString>::const_iterator it = mm.find(_T("bal"));
|
|
|
|
// 如果没有bal字段,说明是试用版
|
|
if (it == mm.end())
|
|
return -1;
|
|
|
|
if (it->second.CompareNoCase(_T("local")) == 0) return 0;
|
|
if (it->second.CompareNoCase(_T("remote")) == 0) return 1;
|
|
|
|
return -1;
|
|
}
|
|
double CoreTools::getPScaleForSymb()
|
|
{
|
|
typedef double(_cdecl *_func_)();
|
|
CString str(FilePath::GetArxDir());
|
|
#ifndef ZWCAD
|
|
str += _T("\\Dimension.arx");
|
|
#else
|
|
str += _T("\\Dimension.zrx");
|
|
#endif
|
|
double dRel(100);
|
|
HINSTANCE hmod(NULL);
|
|
hmod = ::LoadLibrary(str);
|
|
if (hmod)
|
|
{
|
|
_func_ func(NULL);
|
|
func = (_func_)::GetProcAddress(hmod, "getPScaleForSymb");
|
|
if (func)
|
|
dRel = func();
|
|
::FreeLibrary(hmod);
|
|
}
|
|
return dRel;
|
|
}
|
|
|
|
bool CoreTools::IsMeterUnitForPipeElevDim()
|
|
{
|
|
typedef bool(_cdecl *_func_)();
|
|
CString str(FilePath::GetArxDir());
|
|
#ifndef ZWCAD
|
|
str += _T("\\Dimension.arx");
|
|
#else
|
|
str += _T("\\Dimension.zrx");
|
|
#endif
|
|
bool bRel(false);
|
|
HINSTANCE hmod(NULL);
|
|
hmod = ::LoadLibrary(str);
|
|
if (hmod)
|
|
{
|
|
_func_ func(NULL);
|
|
func = (_func_)::GetProcAddress(hmod, "IsMeterUnitForPipeElevDim");
|
|
if (func)
|
|
bRel = func();
|
|
::FreeLibrary(hmod);
|
|
}
|
|
return bRel;
|
|
}
|
|
|
|
bool CoreTools::IsMeterUnitForHoleElevDim()
|
|
{
|
|
typedef bool(_cdecl *_func_)();
|
|
CString str(FilePath::GetArxDir());
|
|
#ifndef ZWCAD
|
|
str += _T("\\Dimension.arx");
|
|
#else
|
|
str += _T("\\Dimension.zrx");
|
|
#endif
|
|
bool bRel(true);
|
|
HINSTANCE hmod(NULL);
|
|
hmod = ::LoadLibrary(str);
|
|
if (hmod)
|
|
{
|
|
_func_ func(NULL);
|
|
func = (_func_)::GetProcAddress(hmod, "IsMeterUnitForHoleElevDim");
|
|
if (func)
|
|
bRel = func();
|
|
::FreeLibrary(hmod);
|
|
}
|
|
return bRel;
|
|
}
|
|
|
|
int CoreTools::getPrecForPipeElevDim()
|
|
{
|
|
typedef int(_cdecl *_func_)();
|
|
CString str(FilePath::GetArxDir());
|
|
#ifndef ZWCAD
|
|
str += _T("\\Dimension.arx");
|
|
#else
|
|
str += _T("\\Dimension.zrx");
|
|
#endif
|
|
int nRel(0);
|
|
HINSTANCE hmod(NULL);
|
|
hmod = ::LoadLibrary(str);
|
|
if (hmod)
|
|
{
|
|
_func_ func(NULL);
|
|
func = (_func_)::GetProcAddress(hmod, "getPrecForPipeElevDim");
|
|
if (func)
|
|
nRel = func();
|
|
::FreeLibrary(hmod);
|
|
}
|
|
return nRel;
|
|
}
|
|
|
|
int CoreTools::getPrecForHoleElevDim()
|
|
{
|
|
typedef int(_cdecl *_func_)();
|
|
CString str(FilePath::GetArxDir());
|
|
#ifndef ZWCAD
|
|
str += _T("\\Dimension.arx");
|
|
#else
|
|
str += _T("\\Dimension.zrx");
|
|
#endif
|
|
int nRel(0);
|
|
HINSTANCE hmod(NULL);
|
|
hmod = ::LoadLibrary(str);
|
|
if (hmod)
|
|
{
|
|
_func_ func(NULL);
|
|
func = (_func_)::GetProcAddress(hmod, "getPrecForHoleElevDim");
|
|
if (func)
|
|
nRel = func();
|
|
::FreeLibrary(hmod);
|
|
}
|
|
return nRel;
|
|
}
|
|
|
|
void CoreTools::refreshGraphics()
|
|
{
|
|
acedUpdateDisplay();
|
|
actrTransactionManager->flushGraphics();
|
|
}
|
|
|
|
CString CoreTools::GetCurrentProject()
|
|
{
|
|
CString sProj(_T("KT-1"));
|
|
AecDbObjXDataMap xDataMap;
|
|
if (GetPipeInitConfig(xDataMap))
|
|
{
|
|
xDataMap.GetAt(DOC_PROJECT, sProj);
|
|
}
|
|
return sProj;
|
|
}
|
|
|
|
bool CoreTools::GetDimScaleZone(const AcGePoint3d &ptHit
|
|
, double &dScale
|
|
, AcDb::UnitsValue &drawUnits
|
|
, AcDb::UnitsValue &dimUnits)
|
|
{
|
|
return CDimScaleZoneDlg::hitTest(ptHit, dScale, drawUnits, dimUnits);
|
|
}
|
|
|
|
int CoreTools::getCurrentTrade()
|
|
{
|
|
int nRel(WPipe::eCivial);
|
|
|
|
AecDbObjXDataMap xDataMap;
|
|
if (KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap))
|
|
{
|
|
if (xDataMap.GetAt(DOC_TRADE, nRel))
|
|
return nRel;
|
|
}
|
|
|
|
return nRel;
|
|
}
|
|
|
|
CString CoreTools::getCurrentPipeSysTblName()
|
|
{
|
|
int nTrade = getCurrentTrade();
|
|
CString sRel(_T("WConfig_CN"));
|
|
CUIISQLiteServer db;
|
|
if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db"))) return sRel;
|
|
|
|
CString sql(_T(""));
|
|
if (nTrade == 6) // 冶金
|
|
sql.Format(_T("SELECT [TABLENAME] FROM WPipeCfg WHERE [STDNAME]='冶金'"));
|
|
else
|
|
sql.Format(_T("SELECT [TABLENAME] FROM WPipeCfg WHERE [STDNAME]='默认'"));
|
|
|
|
|
|
db.GetSelData(sql, sRel);
|
|
return sRel;
|
|
}
|
|
|
|
int CoreTools::getColorByPipeSys(LPCTSTR sys, bool bCenter)
|
|
{
|
|
CUIISQLiteServer db;
|
|
if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db"))) return 256;
|
|
|
|
CString sTable(CoreTools::getCurrentPipeSysTblName());
|
|
|
|
CString pipesys = bCenter ? _T("管线中心线") : _T("管线外边线");
|
|
CString sql;
|
|
sql.Format(_T("SELECT [COLOR] FROM %s WHERE [SYSTEM]='%s' AND [PIPESYS]='%s'"), sTable, sys, pipesys);
|
|
CString sClr(_T("256"));
|
|
db.GetSelData(sql, sClr);
|
|
return _ttoi(sClr);
|
|
}
|
|
|
|
AcDbObjectId CoreTools::getLtByPipeSys(LPCTSTR sys, bool bCenter)
|
|
{
|
|
AcDbObjectId id(AcDbObjectId::kNull);
|
|
CUIISQLiteServer db;
|
|
if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db"))) return id;
|
|
|
|
CString sTable(CoreTools::getCurrentPipeSysTblName());
|
|
CString pipesys = bCenter ? _T("管线中心线") : _T("管线外边线");
|
|
CString sql;
|
|
sql.Format(_T("SELECT [LINETYPE] FROM %s WHERE [SYSTEM]='%s' AND [PIPESYS]='%s'"), sTable, sys, pipesys);
|
|
CString sLt(_T("Continuous"));
|
|
db.GetSelData(sql, sLt);
|
|
|
|
AcDbDatabase *pDb = acdbCurDwg();
|
|
if (!pDb) return id;
|
|
|
|
AcDbLinetypeTable *pTable(NULL);
|
|
pDb->getLinetypeTable(pTable, AcDb::kForRead);
|
|
ACHAR *psz(NULL);
|
|
if (pTable)
|
|
{
|
|
pTable->getAt(sLt, id);
|
|
pTable->close();
|
|
}
|
|
|
|
if (!id.isValid())
|
|
{
|
|
id = CoreTools::loadLineType(FilePath::GetSysDir(), sLt);
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
double CoreTools::getLwByPipeSys(LPCTSTR sys, bool bCenter)
|
|
{
|
|
CUIISQLiteServer db;
|
|
if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db"))) return 0;
|
|
|
|
CString sTable(CoreTools::getCurrentPipeSysTblName());
|
|
CString pipesys = bCenter ? _T("管线中心线") : _T("管线外边线");
|
|
CString sql;
|
|
sql.Format(_T("SELECT [LINEWIDTH] FROM %s WHERE [SYSTEM]='%s' AND [PIPESYS]='%s'"), sTable, sys, pipesys);
|
|
CString sLw(_T("0"));
|
|
db.GetSelData(sql, sLw);
|
|
|
|
AecDbObjXDataMap xdata;
|
|
if (KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xdata))
|
|
{
|
|
CString sScale(_T("1:100"));
|
|
xdata.GetAt(DOC_SCALE, sScale);
|
|
int nIndex = sScale.Find(':', 0);
|
|
double dDocScale = 1.0;
|
|
if (nIndex != -1)
|
|
{
|
|
dDocScale = _ttof(sScale.Mid(nIndex + 1)) / _ttof(sScale.Mid(0, nIndex));
|
|
}
|
|
return _ttof(sLw) * dDocScale;
|
|
}
|
|
|
|
return _ttof(sLw);
|
|
}
|
|
|
|
AcDbObjectId CoreTools::getLyByPipeSys(LPCTSTR sys, bool bCenter, bool bUpdate)
|
|
{
|
|
AcDbObjectId id;
|
|
CUIISQLiteServer db;
|
|
if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db"))) return id;
|
|
|
|
CString sTable(CoreTools::getCurrentPipeSysTblName());
|
|
CString pipesys = bCenter ? _T("管线中心线") : _T("管线外边线");
|
|
CString sql;
|
|
sql.Format(_T("SELECT [LAYNAME] FROM %s WHERE [SYSTEM]='%s' AND [PIPESYS]='%s'"), sTable, sys, pipesys);
|
|
CString sLy(_T("0"));
|
|
db.GetSelData(sql, sLy);
|
|
|
|
AcDbDatabase *pDb = acdbCurDwg();
|
|
if (!pDb) return id;
|
|
|
|
|
|
AcDbLayerTable *pTable(NULL);
|
|
pDb->getLayerTable(pTable, AcDb::kForWrite);
|
|
ACHAR *psz(NULL);
|
|
if (pTable)
|
|
{
|
|
if (!pTable->has(sLy))
|
|
{ // 没有则新建
|
|
AcDbLayerTableRecord *pRec = new AcDbLayerTableRecord();
|
|
|
|
AcDbObjectId idLt = CoreTools::getLtByPipeSys(sys, bCenter);
|
|
if (idLt.isValid())
|
|
pRec->setLinetypeObjectId(idLt);
|
|
|
|
int clr = CoreTools::getColorByPipeSys(sys, bCenter);
|
|
AcCmColor aclr;
|
|
aclr.setColorIndex(clr);
|
|
pRec->setColor(aclr);
|
|
|
|
pRec->setName(sLy);
|
|
pTable->add(id, pRec);
|
|
pRec->close();
|
|
}
|
|
else
|
|
pTable->getAt(sLy, id);
|
|
pTable->close();
|
|
}
|
|
|
|
if (!bUpdate) return id;
|
|
|
|
OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbLayerTableRecord, pRec)
|
|
if (pRec)
|
|
{
|
|
AcDbObjectId idLt = CoreTools::getLtByPipeSys(sys, bCenter);
|
|
|
|
int clr = CoreTools::getColorByPipeSys(sys, bCenter);
|
|
AcCmColor aclr;
|
|
aclr.setColorIndex(clr);
|
|
|
|
pRec->setLinetypeObjectId(idLt);
|
|
pRec->setColor(aclr);
|
|
}
|
|
OPENOBJ_END()
|
|
|
|
return id;
|
|
}
|
|
|
|
AcDbObjectId CoreTools::getLyForPipe(LPCTSTR sys, bool bUpdate)
|
|
{
|
|
CString sName(CString(sys) + _T("管线系统"));
|
|
AcDbObjectId idPipeLayer;
|
|
|
|
AcDbDatabase *pDb = acdbCurDwg();
|
|
if (!pDb) return idPipeLayer;
|
|
|
|
AcDbLayerTable *pTable(NULL);
|
|
if (Acad::eOk == pDb->getLayerTable(pTable, AcDb::kForRead))
|
|
{
|
|
pTable->getAt(sName, idPipeLayer);
|
|
pTable->close();
|
|
}
|
|
|
|
if (idPipeLayer.isValid())
|
|
{
|
|
if (!bUpdate) return idPipeLayer;
|
|
|
|
OPENOBJ_BEGIN(idPipeLayer, AcDb::kForWrite, AcDbLayerTableRecord, pRec)
|
|
if (pRec)
|
|
{
|
|
AcDbObjectId idLt = CoreTools::getLtByPipeSys(sys, true);
|
|
|
|
int clr = CoreTools::getColorByPipeSys(sys, !IsUsePipeOutClrFor3DRender());
|
|
AcCmColor aclr;
|
|
aclr.setColorIndex(clr);
|
|
|
|
pRec->setLinetypeObjectId(idLt);
|
|
pRec->setColor(aclr);
|
|
}
|
|
OPENOBJ_END()
|
|
return idPipeLayer;
|
|
}
|
|
|
|
AcDbObjectId idLy = CoreTools::getLyByPipeSys(sys, true, bUpdate);
|
|
OPENOBJ_BEGIN(idLy, AcDb::kForRead, AcDbLayerTableRecord, pRec)
|
|
if (pRec)
|
|
{
|
|
AcDbLayerTableRecord *pNew = (AcDbLayerTableRecord *)pRec->clone();
|
|
pNew->setName(sName);
|
|
int clr = CoreTools::getColorByPipeSys(sys, !IsUsePipeOutClrFor3DRender());
|
|
AcCmColor aclr;
|
|
aclr.setColorIndex(clr);
|
|
pNew->setColor(aclr);
|
|
AcDbDatabase *pDb = acdbCurDwg();
|
|
if (pDb)
|
|
{
|
|
AcDbLayerTable *pT(NULL);
|
|
if (pDb->getLayerTable(pT, AcDb::kForWrite) == Acad::eOk)
|
|
{
|
|
if (pT->add(idPipeLayer, pNew) == Acad::eOk)
|
|
pNew->close();
|
|
pT->close();
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END()
|
|
|
|
return idPipeLayer;
|
|
}
|
|
|
|
void CoreTools::SetUsePipeOutClrFor3DRender(const BOOL &b)
|
|
{
|
|
AecDbObjXDataMap xDataMap;
|
|
if (KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap))
|
|
{
|
|
xDataMap.SetAt(_T("PIPESYS_USE_OUTER_COLOR_FOR_3D"), b);
|
|
KTModelLayoutXData::WriteModelXData(KT_PIPEINIT, xDataMap);
|
|
}
|
|
}
|
|
|
|
bool CoreTools::IsUsePipeOutClrFor3DRender()
|
|
{
|
|
BOOL bRel(TRUE);
|
|
AecDbObjXDataMap xDataMap;
|
|
if (KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap))
|
|
{
|
|
xDataMap.GetAt(_T("PIPESYS_USE_OUTER_COLOR_FOR_3D"), bRel);
|
|
}
|
|
return bRel == FALSE ? false : true;
|
|
}
|
|
|
|
AcDbObjectId CoreTools::loadLineType(LPCTSTR pszDir, LPCTSTR pszName)
|
|
{
|
|
AcDbDatabase *pDb(NULL);
|
|
if (pDb == NULL) pDb = acdbCurDwg();
|
|
|
|
AcDbObjectId idLt;
|
|
|
|
std::vector<CString> files;
|
|
CoreTools::getFilesInFolder(pszDir, _T("*.lin"), files, false);
|
|
for (size_t i(0); i < files.size(); ++i)
|
|
{
|
|
if (acdbLoadLineTypeFile(pszName, files[i], pDb) == Acad::eOk)
|
|
{
|
|
AcDbLinetypeTable *pLTbl(NULL);
|
|
if (Acad::eOk == pDb->getLinetypeTable(pLTbl, AcDb::kForRead))
|
|
{
|
|
pLTbl->getAt(pszName, idLt);
|
|
pLTbl->close();
|
|
return idLt;
|
|
}
|
|
}
|
|
}
|
|
return idLt;
|
|
}
|
|
|
|
CString CoreTools::LineWeight2String(const AcDb::LineWeight &lw)
|
|
{
|
|
switch (lw)
|
|
{
|
|
case AcDb::kLnWt000:
|
|
return _T("0.00mm");
|
|
case AcDb::kLnWt005:
|
|
return _T("0.05mm");
|
|
case AcDb::kLnWt009:
|
|
return _T("0.09mm");
|
|
case AcDb::kLnWt013:
|
|
return _T("0.13mm");
|
|
case AcDb::kLnWt015:
|
|
return _T("0.15mm");
|
|
case AcDb::kLnWt018:
|
|
return _T("0.18mm");
|
|
case AcDb::kLnWt020:
|
|
return _T("0.20mm");
|
|
case AcDb::kLnWt025:
|
|
return _T("0.25mm");
|
|
case AcDb::kLnWt030:
|
|
return _T("0.30mm");
|
|
case AcDb::kLnWt035:
|
|
return _T("0.35mm");
|
|
case AcDb::kLnWt040:
|
|
return _T("0.40mm");
|
|
case AcDb::kLnWt050:
|
|
return _T("0.50mm");
|
|
case AcDb::kLnWt053:
|
|
return _T("0.53mm");
|
|
case AcDb::kLnWt060:
|
|
return _T("0.60mm");
|
|
case AcDb::kLnWt070:
|
|
return _T("0.70mm");
|
|
case AcDb::kLnWt080:
|
|
return _T("0.80mm");
|
|
case AcDb::kLnWt090:
|
|
return _T("0.90mm");
|
|
case AcDb::kLnWt100:
|
|
return _T("1.00mm");
|
|
case AcDb::kLnWt106:
|
|
return _T("1.06mm");
|
|
case AcDb::kLnWt120:
|
|
return _T("1.20mm");
|
|
case AcDb::kLnWt140:
|
|
return _T("1.40mm");
|
|
case AcDb::kLnWt158:
|
|
return _T("1.58mm");
|
|
case AcDb::kLnWt200:
|
|
return _T("2.00mm");
|
|
case AcDb::kLnWt211:
|
|
return _T("2.11mm");
|
|
default:
|
|
break;
|
|
}
|
|
return _T("0.00mm");
|
|
}
|
|
|
|
AcDb::LineWeight CoreTools::String2LineWeight(LPCTSTR psz)
|
|
{
|
|
if (!psz) return AcDb::kLnWt000;
|
|
CString s(psz);
|
|
if (s == _T("0.00mm")) return AcDb::kLnWt000;
|
|
if (s == _T("0.05mm")) return AcDb::kLnWt005;
|
|
if (s == _T("0.09mm")) return AcDb::kLnWt009;
|
|
if (s == _T("0.13mm")) return AcDb::kLnWt013;
|
|
if (s == _T("0.15mm")) return AcDb::kLnWt015;
|
|
if (s == _T("0.18mm")) return AcDb::kLnWt018;
|
|
if (s == _T("0.20mm")) return AcDb::kLnWt020;
|
|
if (s == _T("0.25mm")) return AcDb::kLnWt025;
|
|
if (s == _T("0.30mm")) return AcDb::kLnWt030;
|
|
if (s == _T("0.35mm")) return AcDb::kLnWt035;
|
|
if (s == _T("0.40mm")) return AcDb::kLnWt040;
|
|
if (s == _T("0.50mm")) return AcDb::kLnWt050;
|
|
if (s == _T("0.53mm")) return AcDb::kLnWt053;
|
|
if (s == _T("0.60mm")) return AcDb::kLnWt060;
|
|
if (s == _T("0.70mm")) return AcDb::kLnWt070;
|
|
if (s == _T("0.80mm")) return AcDb::kLnWt080;
|
|
if (s == _T("0.90mm")) return AcDb::kLnWt090;
|
|
if (s == _T("1.00mm")) return AcDb::kLnWt100;
|
|
if (s == _T("1.06mm")) return AcDb::kLnWt106;
|
|
if (s == _T("1.20mm")) return AcDb::kLnWt120;
|
|
if (s == _T("1.40mm")) return AcDb::kLnWt140;
|
|
if (s == _T("1.58mm")) return AcDb::kLnWt158;
|
|
if (s == _T("2.00mm")) return AcDb::kLnWt200;
|
|
if (s == _T("2.11mm")) return AcDb::kLnWt211;
|
|
return AcDb::kLnWt000;
|
|
}
|
|
|
|
namespace
|
|
{
|
|
void BuildVertex(const AcGePoint3d &pt, gpc_vertex &vertex)
|
|
{
|
|
vertex.x = pt.x;
|
|
vertex.y = pt.y;
|
|
}
|
|
|
|
void BuildVertexList(const AcDbPolyline *pl, gpc_vertex_list &list)
|
|
{
|
|
AcGePoint3d pt;
|
|
int len(pl->numVerts());
|
|
|
|
gpc_vertex *pArPts = new gpc_vertex[len];
|
|
::memset(pArPts, 0, sizeof(gpc_vertex) * len);
|
|
|
|
gpc_vertex verPt;
|
|
for (int i(0); i < len; ++i)
|
|
{
|
|
pl->getPointAt(i, pt);
|
|
BuildVertex(pt, verPt);
|
|
::memcpy(&pArPts[i], &verPt, sizeof(gpc_vertex));
|
|
}
|
|
list.num_vertices = len;
|
|
list.vertex = pArPts;
|
|
}
|
|
|
|
AcDbPolyline *BuildPolyline(const gpc_vertex_list &list)
|
|
{
|
|
AcDbPolyline *pNew = new AcDbPolyline();
|
|
pNew->setElevation(.0);
|
|
for (int i(0); i < list.num_vertices; ++i)
|
|
{
|
|
pNew->addVertexAt(i, AcGePoint2d(list.vertex[i].x, list.vertex[i].y));
|
|
}
|
|
pNew->setClosed(1);
|
|
return pNew;
|
|
}
|
|
|
|
void BuildPolyline(const gpc_polygon &polygon
|
|
, std::vector<AcDbPolyline*> &pls
|
|
, std::vector<int> &holds )
|
|
{
|
|
if (!polygon.contour || !polygon.hole) return;
|
|
|
|
for (int i(0); i < polygon.num_contours; ++i)
|
|
{
|
|
AcDbPolyline *pNew = BuildPolyline(polygon.contour[i]);
|
|
pls.push_back(pNew);
|
|
holds.push_back(polygon.hole[i]);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CoreTools::gpcBoolean(int _op
|
|
, const AcDbPolyline &poly
|
|
, const AcDbPolyline &polyClip
|
|
, std::vector<AcDbPolyline*> &outPolys
|
|
, std::vector<int> &outHolds)
|
|
{
|
|
gpc_op op((gpc_op)_op);
|
|
gpc_vertex_list list, list_clip;
|
|
BuildVertexList(&poly, list);
|
|
BuildVertexList(&polyClip, list_clip);
|
|
|
|
gpc_polygon *polygon(new gpc_polygon)
|
|
, *polygon_clip(new gpc_polygon)
|
|
, *polygon_out(new gpc_polygon);
|
|
|
|
::memset(polygon, 0, sizeof(gpc_polygon));
|
|
::memset(polygon_clip, 0, sizeof(gpc_polygon));
|
|
::memset(polygon_out, 0, sizeof(gpc_polygon));
|
|
|
|
gpc_add_contour(polygon, &list, 0);
|
|
gpc_add_contour(polygon_clip, &list_clip, 0);
|
|
|
|
gpc_polygon_clip(op, polygon, polygon_clip, polygon_out);
|
|
|
|
BuildPolyline(*polygon_out, outPolys, outHolds);
|
|
|
|
gpc_free_polygon(polygon);
|
|
gpc_free_polygon(polygon_clip);
|
|
gpc_free_polygon(polygon_out);
|
|
|
|
}
|
|
|
|
AecDbEwEquipment* CoreTools::selectEquipment(LPCTSTR pszPath, LPCTSTR pszFile)
|
|
{
|
|
typedef AecDbEwEquipment *(_cdecl *func_selectSingleEqu) (LPCTSTR, LPCTSTR);
|
|
#ifndef ZWCAD
|
|
HINSTANCE hmod = ::LoadLibrary(FilePath::GetArxDir() + _T("\\pipelinecmd.arx"));
|
|
#else
|
|
HINSTANCE hmod = ::LoadLibrary(FilePath::GetArxDir() + _T("\\pipelinecmd.zrx"));
|
|
#endif
|
|
if (!hmod) return NULL;
|
|
|
|
func_selectSingleEqu proc = (func_selectSingleEqu)::GetProcAddress(hmod, "selectSingleEqu");
|
|
if (!proc)
|
|
{
|
|
::FreeLibrary(hmod);
|
|
return NULL;
|
|
}
|
|
|
|
AecDbEwEquipment *pEnt = proc(pszPath, pszFile);
|
|
|
|
::FreeLibrary(hmod);
|
|
|
|
return pEnt;
|
|
}
|
|
|
|
|
|
void CoreTools::projectToXOY(AcDbVoidPtrArray &arEntPtrs)
|
|
{
|
|
//投影到XY面 竖线为点
|
|
AcGeVector3d vt;
|
|
AcGePoint3d pt, pt2;
|
|
AcGeMatrix3d xform;
|
|
|
|
AcDbEntity *pEnt(NULL);
|
|
AcGePoint3dArray arPts;
|
|
for (int i = 0; i < arEntPtrs.length(); i++)
|
|
{
|
|
pEnt = (AcDbEntity *)arEntPtrs.at(i);
|
|
AcDbLine *pLn = AcDbLine::cast(pEnt);
|
|
if (pLn != NULL)
|
|
{
|
|
vt = pLn->endPoint() - pLn->startPoint();
|
|
if (vt.isParallelTo(AcGeVector3d::kZAxis))
|
|
{
|
|
pt = pLn->startPoint();
|
|
pt.z = 0.0;
|
|
AcDbPoint *pPt = new AcDbPoint;
|
|
pPt->setPosition(pt);
|
|
pPt->setLayer(pLn->layerId());
|
|
arEntPtrs.setAt(i, pPt);
|
|
delete pLn;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
AcDbIntArray osnapModes, geomIds;
|
|
arPts.removeAll();
|
|
pEnt->getGripPoints(arPts, osnapModes, geomIds);
|
|
|
|
if (arPts.length() > 0)
|
|
{
|
|
pt = arPts.first();
|
|
pt2 = pt.orthoProject(AcGePlane::kXYPlane);
|
|
vt = pt2 - pt;
|
|
xform.setToTranslation(vt);
|
|
pEnt->transformBy(xform);
|
|
}
|
|
}
|
|
}
|
|
|
|
#define HLR_DBX L"AsdkHlrApi##ARX.dbx"
|
|
|
|
BOOL CoreTools::FindSHHLrDll(CString &SHHlrDLL, CString &sDbx)
|
|
{
|
|
#ifndef ZWCAD
|
|
struct resbuf rb;
|
|
acedGetVar(_T("ACADVER"), &rb);//Acadver = 18.2s (LMS Tech)
|
|
double dVer = _ttof(rb.resval.rstring);
|
|
int nVer = (int)(dVer + 0.2);
|
|
|
|
#if ARX < 24
|
|
sDbx.Format(_T("%s\\AsdkHlrDbx\\sys%.1fx64\\AsdkHlrApi%d.dbx")
|
|
, FilePath::GetRootDir(), dVer, nVer);
|
|
#else
|
|
sDbx.Format(_T("AsdkHlrApi%d.dbx"), nVer);
|
|
#endif
|
|
|
|
//SHHlrDLL.Format(_T("%s\\SHHlr%.1f.dll"), FilePath::GetArxDir(), dVer);
|
|
SHHlrDLL.Format(_T("%s\\SHHlr.dll"), FilePath::GetArxDir());
|
|
if (_taccess(sDbx, 0x00) != 0x00)
|
|
return FALSE;
|
|
|
|
if (!acrxServiceIsRegistered(_T("ASDK_HLR_API_SERVICES")))
|
|
{
|
|
acrxLoadModule(sDbx, false, true);
|
|
}
|
|
acrxLoadModule(sDbx, false, false);
|
|
|
|
if (_taccess(SHHlrDLL, 0x00) != 0x00)
|
|
return FALSE;
|
|
return TRUE;
|
|
#else
|
|
|
|
TCHAR dllPath[MAX_PATH] = { 0 };
|
|
if (::GetModuleFileName(NULL, dllPath, MAX_PATH))
|
|
{
|
|
FilePath _path(dllPath);
|
|
sDbx = _path._directory;// +_T("\\zwhlr.dll");
|
|
}
|
|
|
|
//#if defined(R24)
|
|
// sDbx.Format(_T("%s\\ZwHlrDll\\2024\\zwhlr.dll"), FilePath::GetRootDir());
|
|
//#else
|
|
// sDbx.Format(_T("%s\\ZwHlrDll\\2025\\zwhlr.dll"), FilePath::GetRootDir());
|
|
//#endif
|
|
SHHlrDLL.Format(_T("%s\\SHHlr.dll"), FilePath::GetArxDir());
|
|
return TRUE;
|
|
#endif
|
|
}
|
|
|
|
BOOL CoreTools::GetPipeInitConfig(AecDbObjXDataMap &xdata)
|
|
{
|
|
return KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xdata);
|
|
}
|
|
|
|
BOOL CoreTools::QueryFlangSpecs(CUIISQLiteServer *pDb
|
|
, double dDN
|
|
, WPipe::Trade &eTrade
|
|
, CString &sStd
|
|
, CString &sTyp
|
|
, LPCTSTR pszProName
|
|
, LPCTSTR pszPreSpecName)
|
|
{
|
|
CString sSQL, sTip;
|
|
//行业 全局
|
|
int nTrade = CoreTools::getCurrentTrade();
|
|
|
|
eTrade = (WPipe::Trade)nTrade;
|
|
if (eTrade == WPipe::eCivial || pszPreSpecName == NULL)//市政 不考虑等级 Z系列 暂 A
|
|
{
|
|
//暂时默认---库中没有市政法兰数据
|
|
sStd = _T("HG/T 20592-2009");
|
|
sTyp = _T("WN");//WN>=1.0压力 PL<=1.0压力
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
if (pszProName == NULL || pszPreSpecName == NULL)
|
|
{
|
|
CStringArray arVals;
|
|
bool bFind = false;
|
|
|
|
sSQL.Format(_T("select distinct [标准号],[法兰类型] from [AecFlangeData] where [公称直径]=%d"), (int)(dDN + 0.5));
|
|
pDb->GetSelData(sSQL, arVals);
|
|
|
|
if (arVals.GetSize() >= 2)
|
|
{
|
|
sStd = arVals.GetAt(0);
|
|
sTyp = arVals.GetAt(1);
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
sTip.Format(_T("缺少 DN=%d 的法兰选型数据!\n"), (int)(dDN + 0.5));
|
|
AfxMessageBox(sTip);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CStringArray arVals;
|
|
bool bFind = false;
|
|
if (pszProName != NULL && pszPreSpecName != NULL)
|
|
{
|
|
sSQL.Format(_T("select distinct [标准号],[类型] from AecSpecFlange where [项目名称]='%s' and [等级名称]='%s' and [公称直径]=%d"),
|
|
pszProName, pszPreSpecName, (int)(dDN+0.5));
|
|
pDb->GetSelData(sSQL, arVals);
|
|
|
|
if (arVals.GetSize() >= 2)
|
|
{
|
|
sStd = arVals.GetAt(0);
|
|
sTyp = arVals.GetAt(1);
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
sTip.Format(_T("缺少项目名称=%s 和 等级名称=%s DN=%d的法兰选型数据!\n请设置该项目和等级需要的法兰数据!\n参见 KTSpeEdit\\等级生成器\\法兰设置!"), pszProName, pszPreSpecName, (int)(dDN + 0.5));
|
|
AfxMessageBox(sTip);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CoreTools::QueryFlangDataEx(CUIISQLiteServer *pDb
|
|
, const double dDN
|
|
, const double dPre
|
|
, std::vector<CString> &ss // 内容顺序参考 Plumbing.db/AecFlangeData 表格字段
|
|
, LPCTSTR pszProName
|
|
, LPCTSTR pszPreSpecName
|
|
, LPCTSTR pszODNo)
|
|
{
|
|
if (pDb == NULL)
|
|
return FALSE;
|
|
|
|
CString sSQL, sSNo, sTip, sStd = _T("HG/T 20592-2009"), sTyp;
|
|
CStringArray arValues;
|
|
|
|
//查询等级试用的 类型 标准号
|
|
WPipe::Trade eTrade = WPipe::eCivial;
|
|
if (!QueryFlangSpecs(pDb, dDN, eTrade, sStd, sTyp, pszProName, pszPreSpecName))
|
|
{
|
|
//无等级
|
|
eTrade = WPipe::eCivial;
|
|
}
|
|
|
|
//塑料管,标准号按材质过度
|
|
bool bIsPlastic = false;
|
|
if (pszODNo != NULL)
|
|
{
|
|
const CString sPlastic = _T("PE PP PS U-PVC UPVC CPVC PET NY PC PF UF ABS");
|
|
|
|
CStringArray arNos;
|
|
SplitStrintToArray(sPlastic, arNos,_T(' '));
|
|
for(int i = 0;i < arNos.GetSize();i++)
|
|
{
|
|
if (arNos.GetAt(i).CompareNoCase(pszODNo) == 0)
|
|
{
|
|
sStd = pszODNo;
|
|
bIsPlastic = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//按标准号 有交集 等级中 HG/T 20592(A) 和 原始库中 HG/T 20592-2009 处理未知 改为暂时去掉标准号
|
|
if (!bIsPlastic)
|
|
{
|
|
sSQL.Format(_T("select [标准号] from aecflangedata where [公称直径]=%d and [压力]>%.2f and [压力]<%.2f and [法兰类型]='%s'"),
|
|
(int)(dDN + 0.5), dPre - 0.01, dPre + 0.01, sTyp);
|
|
|
|
int iPos = -1;
|
|
CStringArray arVls;
|
|
pDb->GetSelData(sSQL, arVls);
|
|
for (int i = 0;i < arVls.GetSize();i++)
|
|
{
|
|
//判读字符串有交集
|
|
if ((iPos = arVls.GetAt(i).FindOneOf(sStd)) == 0)
|
|
{
|
|
sStd = arVls.GetAt(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
sSQL.Format(_T("select * from aecflangedata where \
|
|
[公称直径]=%d and [压力]>%.2f and [压力]<%.2f and [法兰类型]='%s' and [标准号]='%s' order by [法兰厚度]"),
|
|
(int)(dDN+0.5), dPre-0.01, dPre+0.01, sTyp, sStd);
|
|
|
|
pDb->GetSelData(sSQL, ss);
|
|
|
|
if (ss.size() >= 8)
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
//查不到再查
|
|
if (eTrade == WPipe::eCivial)
|
|
{
|
|
//没有找到,按照1.0查找
|
|
sSQL.Format(_T("select * from aecflangedata where \
|
|
[公称直径]=%d and [压力]>%.2f and [压力]<%.2f and [法兰类型]='%s' and [标准号]='%s'"),
|
|
(int)(dDN + 0.5), 1.-0.05, 1.+0.05, sTyp, sStd);
|
|
|
|
pDb->GetSelData(sSQL, ss);
|
|
if (ss.size() >= 8)
|
|
{
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
sTip.Format(_T("\n缺少公称直径:%d 压力%.2f [法兰类型]='%s' [标准号]:%s 的法兰参数!"), (int)(dDN+0.5), dPre, sTyp,sStd);
|
|
AfxMessageBox(sTip);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sTip.Format(_T("缺少项目名称=%s 等级名称=%s 公称直径=%d的法兰选型数据!\n请设置该项目和等级需要的法兰数据!\n参见 KTSpeEdit\\等级生成器\\法兰设置!"),
|
|
pszProName, pszPreSpecName, (int)(dDN+0.5));
|
|
AfxMessageBox(sTip);
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL CoreTools::QueryFlangData(CUIISQLiteServer *pDb
|
|
, const double _dDN
|
|
, const double dPre
|
|
, double &dWD
|
|
, double &dWh
|
|
, double &dThk
|
|
, double &dN
|
|
, LPCTSTR pszProName
|
|
, LPCTSTR pszPreSpecName
|
|
, LPCTSTR pszODNo)
|
|
{
|
|
if (pDb == NULL)
|
|
return FALSE;
|
|
|
|
double dDN(_dDN);
|
|
double dUnit = MakeSureMMUnit(dDN);
|
|
|
|
std::vector<CString> ss;
|
|
if (!CoreTools::QueryFlangDataEx(pDb, dDN, dPre, ss, pszProName, pszPreSpecName,pszODNo))
|
|
return FALSE;
|
|
|
|
if (ss.size() < 8) return FALSE;
|
|
|
|
dWD = _ttof(ss[5]); // 法兰外经
|
|
dWh = _ttof(ss[7]); // 法兰厚度
|
|
dThk = _ttof(ss[6]);// 法兰高度
|
|
dN = _ttof(ss[8]); // 法兰颈
|
|
|
|
dWD /= dUnit;
|
|
dWh /= dUnit;
|
|
dThk /= dUnit;
|
|
dN /= dUnit;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
double CoreTools::GetDPIScale(HWND hWnd)
|
|
{
|
|
static bool bFirstGetDPI = true;
|
|
|
|
if (!hWnd)
|
|
hWnd = acedGetAcadFrame()->m_hWnd;
|
|
|
|
static double dScale(1.);
|
|
|
|
if (bFirstGetDPI == false)
|
|
return dScale;
|
|
|
|
if (!hWnd) return dScale;
|
|
|
|
UINT dpi = 96;
|
|
|
|
HMODULE hShcore = LoadLibraryA("shcore.dll");
|
|
if (hShcore)
|
|
{
|
|
HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
|
|
UINT dpiX = 0, dpiY = 0;
|
|
typedef HRESULT(WINAPI *GetDpiForMonitorFunc)(HMONITOR hmonitor, int dpiType, UINT *dpiX, UINT *dpiY);
|
|
GetDpiForMonitorFunc pGetDpiForMonitorFunc = (GetDpiForMonitorFunc)GetProcAddress(hShcore, "GetDpiForMonitor");
|
|
if (pGetDpiForMonitorFunc
|
|
&& pGetDpiForMonitorFunc(hMonitor, 0, &dpiX, &dpiY) == S_OK)
|
|
{
|
|
dpi = dpiX;
|
|
}
|
|
FreeLibrary(hShcore);
|
|
}
|
|
else // 没有 shcore.dll 可能是win7系统,用 GetDpiForWindow 获取 DPI
|
|
{
|
|
HMODULE hUser32 = LoadLibraryW(L"user32.dll");
|
|
if (hUser32)
|
|
{
|
|
// 多显示器时,GetDpiForWindow好像不太准确
|
|
typedef UINT(WINAPI *GetDpiForWindowFunc)(HWND hwnd);
|
|
GetDpiForWindowFunc pGetDpiForWindow = (GetDpiForWindowFunc)GetProcAddress(hUser32, "GetDpiForWindow");
|
|
|
|
if (pGetDpiForWindow)
|
|
UINT dpi = pGetDpiForWindow(hWnd);
|
|
FreeLibrary(hUser32);
|
|
}
|
|
else // 最后用 GetDeviceCaps 获取 DPI
|
|
{
|
|
HDC hdc = GetDC(hWnd);
|
|
dpi = GetDeviceCaps(hdc, LOGPIXELSX);
|
|
ReleaseDC(hWnd, hdc);
|
|
}
|
|
}
|
|
|
|
dScale = dpi / 96.0;
|
|
|
|
bFirstGetDPI = false;
|
|
|
|
return dScale;
|
|
|
|
}
|
|
|
|
void CoreTools::createFont(CFont *pFont, LPCTSTR faceName, const int &fontSize, CDC *_pDC)
|
|
{
|
|
if (!faceName || !pFont) return;
|
|
|
|
int dpiY;
|
|
if (_pDC == NULL)
|
|
{
|
|
CWnd *pWnd = acedGetAcadFrame();
|
|
if (!pWnd) return;
|
|
|
|
CDC *pDC = pWnd->GetDC();
|
|
if (!pDC) return;
|
|
|
|
dpiY = GetDeviceCaps(pDC->m_hDC, LOGPIXELSY);
|
|
pWnd->ReleaseDC(pDC);
|
|
}
|
|
else
|
|
{
|
|
dpiY = GetDeviceCaps(_pDC->m_hDC, LOGPIXELSY);
|
|
}
|
|
|
|
LOGFONT lf;
|
|
::GetObject((HFONT)GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
|
|
_tcscpy(lf.lfFaceName, faceName);
|
|
lf.lfHeight = -MulDiv(fontSize, dpiY, 72);
|
|
pFont->CreateFontIndirect(&lf);
|
|
}
|
|
|
|
bool CoreTools::drawIcon(HICON hIcon, HDC hDC, CPoint pt, UINT ustyle)
|
|
{
|
|
if (!hIcon) return false;
|
|
SIZE sz;
|
|
if (!GetIconSize(hIcon, sz)) return false;
|
|
|
|
double scale = GetDPIScale();
|
|
|
|
int drawCx = (int)(sz.cx * scale);
|
|
int drawCy = (int)(sz.cy * scale);
|
|
|
|
DrawIconEx(hDC
|
|
, pt.x
|
|
, pt.y
|
|
, hIcon
|
|
, drawCx // 想画多大都可以
|
|
, drawCy
|
|
, 0
|
|
, NULL
|
|
, DI_NORMAL);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CoreTools::drawIcon(HIMAGELIST hImgList, int iImage, HDC hDC, CPoint pt, UINT ustyle)
|
|
{
|
|
CImageList *pImgList = CImageList::FromHandle(hImgList);
|
|
if (!pImgList) return false;
|
|
|
|
HICON hIcon = pImgList->ExtractIcon(iImage);
|
|
if (!hIcon) return false;
|
|
|
|
bool bRel = drawIcon(hIcon, hDC, pt, ustyle);
|
|
DestroyIcon(hIcon);
|
|
|
|
return bRel;
|
|
}
|
|
|
|
SIZE CoreTools::getStringSZ(HDC hDc, LPCTSTR lpszLong)
|
|
{
|
|
SIZE sz = { 0,0 };
|
|
if (hDc && lpszLong)
|
|
{
|
|
CString str(lpszLong);
|
|
::GetTextExtentPoint32(hDc, str, str.GetLength(), &sz);
|
|
}
|
|
return sz;
|
|
}
|
|
|
|
void CoreTools::getAllLayers(std::vector<CString> &layers)
|
|
{
|
|
// 1. 良好的习惯:先清空容器
|
|
layers.clear();
|
|
|
|
// 2. 获取当前工作的数据库
|
|
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
|
|
if (pDb == NULL) return;
|
|
|
|
// 3. 打开图层表 (Layer Table)
|
|
// 使用 kForRead 模式即可,因为我们只读不改
|
|
AcDbLayerTable *pLayerTbl = NULL;
|
|
if (pDb->getLayerTable(pLayerTbl, AcDb::kForRead) != Acad::eOk)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// 4. 创建迭代器遍历图层表
|
|
// 这里也可以使用 newIterator(pIter, true) 来跳过被删除的图层(虽然通常不需要)
|
|
AcDbLayerTableIterator *pIter = NULL;
|
|
if (pLayerTbl->newIterator(pIter) != Acad::eOk)
|
|
{
|
|
pLayerTbl->close();
|
|
return;
|
|
}
|
|
|
|
// 5. 开始遍历
|
|
for (; !pIter->done(); pIter->step())
|
|
{
|
|
AcDbLayerTableRecord *pRec = NULL;
|
|
// 获取当前迭代器指向的记录 (打开模式为只读)
|
|
if (pIter->getRecord(pRec, AcDb::kForRead) == Acad::eOk)
|
|
{
|
|
ACHAR *pszName = NULL;
|
|
// 获取图层名称
|
|
// 注意:getName 会分配内存,需要我们需要手动释放
|
|
if (pRec->getName(pszName) == Acad::eOk)
|
|
{
|
|
if (pszName != NULL)
|
|
{
|
|
layers.push_back(pszName);
|
|
|
|
// 【关键点】 ObjectARX 规定:getName 返回的字符串必须用 acutDelString 释放
|
|
acutDelString(pszName);
|
|
}
|
|
}
|
|
|
|
// 记得关闭记录,否则会导致图层被锁定无法编辑
|
|
pRec->close();
|
|
}
|
|
}
|
|
|
|
// 6. 清理资源
|
|
// 迭代器是用 new 创建的,必须 delete
|
|
delete pIter;
|
|
|
|
// 关闭图层表
|
|
pLayerTbl->close();
|
|
}
|
|
|
|
void CoreTools::getAllSubSystems(std::vector<CString>& ss)
|
|
{
|
|
CString dbPath = FilePath::GetSysDir();
|
|
dbPath += _T("\\Plumbing.db");
|
|
|
|
CUIISQLiteServer ADOServer;
|
|
if (!ADOServer.InitADOServer(dbPath))
|
|
{
|
|
AfxMessageBox(_T("数据库驱动加载数据库Plumbing.db失败!"));
|
|
return;
|
|
}
|
|
CString sSQL(_T("select distinct system from ")), sStd(CoreTools::getCurrentPipeSysTblName());
|
|
sSQL += sStd;
|
|
ADOServer.GetSelData(sSQL, ss);
|
|
}
|
|
|
|
void CoreTools::setLayerPorperty(SimpleProperty::PropertySetByIndex &propertys)
|
|
{
|
|
using namespace SimpleProperty;
|
|
PropertySetByIndex::SetType::iterator it(propertys.m_set.begin());
|
|
SimpleProperty::Property prop;
|
|
for (; it != propertys.m_set.end(); ++it)
|
|
{
|
|
prop = *it;
|
|
if (prop.m_sPropertyName == _T("图层"))
|
|
{
|
|
prop.m_bCanModify = true;
|
|
prop.m_arOptions.clear();
|
|
getAllLayers(prop.m_arOptions);
|
|
propertys.m_set.erase(it);
|
|
propertys.m_set.insert(prop);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CoreTools::setSubSystemPorperty(SimpleProperty::PropertySetByIndex &propertys)
|
|
{
|
|
using namespace SimpleProperty;
|
|
PropertySetByIndex::SetType::const_iterator it(propertys.m_set.begin());
|
|
SimpleProperty::Property prop;
|
|
for (; it != propertys.m_set.end(); ++it)
|
|
{
|
|
prop = *it;
|
|
if (prop.m_sPropertyName == _T("分系统"))
|
|
{
|
|
prop.m_bCanModify = true;
|
|
prop.m_arOptions.clear();
|
|
getAllSubSystems(prop.m_arOptions);
|
|
propertys.m_set.erase(it);
|
|
propertys.m_set.insert(prop);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CoreTools::isPolylineSelfCollinear(AcDbPolyline * pPoly)
|
|
{
|
|
unsigned int numVerts = pPoly->numVerts();
|
|
double dBulge(.0);
|
|
|
|
// 1. 点数过少处理
|
|
// 如果只有0或1个点,或者只有2个点,视作直线特性,符合“共线”定义
|
|
// (通常我们会剔除这种退化实体)
|
|
if (numVerts < 3)
|
|
{
|
|
// 即使只有2个点,也要检查有没有圆弧
|
|
pPoly->getBulgeAt(0, dBulge);
|
|
if (numVerts == 2 && fabs(dBulge) > 1.0e-6)
|
|
return false; // 有圆弧,保留
|
|
return true; // 视作共线/直线
|
|
}
|
|
|
|
// 2. 检查圆弧 (Bulge)
|
|
// 只要有任意一段包含凸度,就绝对不是“共直线”
|
|
for (unsigned int i = 0; i < numVerts; i++)
|
|
{
|
|
pPoly->getBulgeAt(i, dBulge);
|
|
if (fabs(dBulge) > 1.0e-6)
|
|
return false;
|
|
}
|
|
|
|
// 3. 几何共线检查
|
|
AcGePoint3d ptStart;
|
|
pPoly->getPointAt(0, ptStart);
|
|
|
|
AcGeVector3d vecBase;
|
|
bool bBaseFound = false;
|
|
|
|
// 3.1 寻找基准向量 (起点到第一个不重合的点的向量)
|
|
for (unsigned int i = 1; i < numVerts; i++)
|
|
{
|
|
AcGePoint3d ptNext;
|
|
pPoly->getPointAt(i, ptNext);
|
|
AcGeVector3d vecRaw = ptNext - ptStart;
|
|
|
|
// 忽略重合点
|
|
if (!vecRaw.isZeroLength())
|
|
{
|
|
vecBase = vecRaw;
|
|
bBaseFound = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 如果所有点都重合(即实际上只是一个点),视作共线
|
|
if (!bBaseFound)
|
|
return true;
|
|
|
|
// 3.2 检查剩余所有点
|
|
// 我们只需要检查: (当前点 - 起点) 是否平行于 (基准向量)
|
|
for (unsigned int i = 1; i < numVerts; i++)
|
|
{
|
|
AcGePoint3d ptCurrent;
|
|
pPoly->getPointAt(i, ptCurrent);
|
|
AcGeVector3d vecCurrent = ptCurrent - ptStart;
|
|
|
|
// 忽略重合点
|
|
if (vecCurrent.isZeroLength())
|
|
continue;
|
|
|
|
// 使用 ObjectARX 的全局公差进行平行判断
|
|
// 如果不平行,说明有拐角,不是共线
|
|
if (!vecCurrent.isParallelTo(vecBase, AcGeContext::gTol))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// 所有检查通过,说明所有点都在一条直线上
|
|
return true;
|
|
}
|
|
|
|
AcDbPolyline * CoreTools::getOuterContour(const AcDbVoidPtrArray &arInput)
|
|
{
|
|
AcDbVoidPtrArray arRegions;
|
|
|
|
AcDbRegion::createFromCurves(arInput, arRegions);
|
|
|
|
if (arRegions.isEmpty()) return NULL;
|
|
|
|
AcDbRegion *pRegMax(NULL);
|
|
do
|
|
{
|
|
// 保险起见,得到最大region
|
|
pRegMax = ((AcDbRegion *)arRegions[0]);
|
|
if (!pRegMax) break;
|
|
|
|
double dAreaBig(.0), dArea(.0);
|
|
pRegMax->getArea(dAreaBig);
|
|
|
|
pRegMax = NULL;
|
|
|
|
int idxMaxArea(0);
|
|
for (int i(1); i < arRegions.length(); ++i)
|
|
{
|
|
AcDbRegion *p((AcDbRegion *)arRegions[i]);
|
|
|
|
if (!p) continue;
|
|
|
|
if (p->getArea(dArea) != Acad::eOk) continue;
|
|
|
|
if (dAreaBig < dArea)
|
|
{
|
|
idxMaxArea = i;
|
|
dAreaBig = dArea;
|
|
}
|
|
}
|
|
|
|
// 如果最大region还是很小,直接离开
|
|
if (dAreaBig <= 1e-3)
|
|
break;
|
|
|
|
// 根据最大region的索引克隆出最大的region,并从数组中移除
|
|
pRegMax = ((AcDbRegion *)((AcDbEntity *)arRegions[idxMaxArea])->clone());
|
|
arRegions.removeAt(idxMaxArea);
|
|
|
|
// 用clone出的最大的region和剩余的region进行布尔运算,合并成一个完整的region
|
|
for (int i(0); i < arRegions.length(); ++i)
|
|
{
|
|
if (pRegMax->booleanOper(AcDb::kBoolUnite, (AcDbRegion *)arRegions[i]) != Acad::eOk)
|
|
continue;
|
|
}
|
|
} while (false);
|
|
|
|
deleteArrayVoidPtrs<AcDbEntity>(arRegions);
|
|
|
|
if (!pRegMax) return NULL;
|
|
|
|
AcDbVoidPtrArray arCrv;
|
|
pRegMax->explode(arCrv);
|
|
delete pRegMax;
|
|
|
|
if (arCrv.isEmpty()) return NULL;
|
|
|
|
std::vector<AcDbPolyline *> pls;
|
|
CoreTools::MakePolyline(arCrv, pls);
|
|
|
|
if (pls.empty()) return NULL;
|
|
|
|
AcDbPolyline *pOuter = (AcDbPolyline*)(pls[0]->clone());
|
|
|
|
deleteContainerOfStd(pls);
|
|
|
|
return pOuter;
|
|
}
|
|
|
|
#pragma endregion
|
|
|
|
|
|
extern "C"
|
|
{
|
|
__declspec(dllexport) AcDbRegion *GetColumnRegion(const ColumnParam &ColParam)
|
|
{
|
|
KTCADSysVar<int> vOsMode(_T("OSMODE"), 679);
|
|
|
|
KTSetting::InitLayer(_T("LAY_COLU"));
|
|
CString sLayCol, sTemp;
|
|
KTSetting::GetLayerName(_T("LAY_COLU"), sLayCol, sTemp);
|
|
|
|
KTCADSysVar<LPCTSTR, TRUE> clayer(_T("CLAYER"), sLayCol);
|
|
|
|
CString sText;
|
|
sText = _T("\n请点击鼠标开始插入柱子<退出>:");
|
|
|
|
ads_point pt, ptIns;
|
|
pt[X] = 0.0; pt[Y] = 0.0; pt[Z] = 0.0;
|
|
|
|
double dAngle = 0.0;
|
|
AcGePoint3d ptOffset(ColParam.m_dXExtend, ColParam.m_dYExtend, 0.0);
|
|
ptOffset.rotateBy(CKTCadUtility::Wcs2Ucs(dAngle), CKTCadUtility::GetUcsZAxis());
|
|
|
|
ptIns[X] = pt[X];// + ptOffset.x;
|
|
ptIns[Y] = pt[Y];// + ptOffset.y;
|
|
ptIns[Z] = pt[Z];// + ptOffset.z;
|
|
|
|
AcGePoint3d ptGe;
|
|
ptGe = CKTCadUtility::Ucs2Wcs(asPnt3d(ptIns));
|
|
|
|
ptGe[X] += ptOffset.x;
|
|
ptGe[Y] += ptOffset.y;
|
|
ptGe[Z] += ptOffset.z;
|
|
|
|
ptIns[0] = ptGe.x;
|
|
ptIns[1] = ptGe.y;
|
|
ptIns[2] = ptGe.z;
|
|
|
|
dAngle += ColParam.m_dRotAngle * PI / 180.0;
|
|
//dAngle = CKTCadUtility::Ucs2Wcs(dAngle);
|
|
|
|
AcDbObjectId idBlk;
|
|
if (ColParam.m_nShape <= 2)
|
|
{
|
|
if (ColParam.m_idRec.isValid())
|
|
{
|
|
idBlk = ColParam.m_idRec;
|
|
}
|
|
else
|
|
{
|
|
idBlk = KTCADUtilityEx::InsertBlock(ColParam.m_sBlockName);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
idBlk = ColParam.m_idRec;
|
|
}
|
|
if (!idBlk.isValid())
|
|
return FALSE;
|
|
|
|
AcGeScale3d scScale(ColParam.m_dXScale, ColParam.m_dYScale, 1.0);
|
|
|
|
AcDbBlockReference *pRef = new AcDbBlockReference(asPnt3d(ptIns), idBlk);
|
|
ASSERT(pRef != NULL);
|
|
|
|
pRef->setLayer(sLayCol);
|
|
pRef->setScaleFactors(scScale);
|
|
pRef->setRotation(dAngle);
|
|
|
|
AcDbRegion *pRegAll = NULL, *pRegTmp = NULL;
|
|
if (pRef != NULL)
|
|
{
|
|
AcDbVoidPtrArray arCurPtrs;
|
|
pRef->explode(arCurPtrs);
|
|
|
|
AcGePoint3d ptPos = pRef->position();
|
|
|
|
AcDbVoidPtrArray arRegPtrs;
|
|
AcDbRegion::createFromCurves(arCurPtrs, arRegPtrs);
|
|
|
|
if (!arRegPtrs.isEmpty())
|
|
{
|
|
for (int i = 0; i < arRegPtrs.length(); i++)
|
|
{
|
|
if (pRegAll == NULL)
|
|
{
|
|
pRegAll = (AcDbRegion *)arRegPtrs.at(i);
|
|
continue;
|
|
}
|
|
|
|
pRegTmp = (AcDbRegion *)arRegPtrs.at(i);
|
|
if (pRegAll != NULL)
|
|
{
|
|
pRegAll->booleanOper(AcDb::kBoolUnite, pRegTmp);
|
|
}
|
|
}
|
|
}
|
|
deleteArrayVoidPtrs< AcDbEntity>(arCurPtrs);
|
|
}
|
|
delete pRef;
|
|
return pRegAll;
|
|
}
|
|
}
|