Files
envi-code/SourceCode/Code2026/CoreCommand/CoreTools.cpp
T
2026-09-28 15:28:50 +08:00

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 &centroid, 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;
}
}