#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 #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 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 &types) { if (!pszKey) return false; CUIISQLiteServer db; if (!db.InitADOServer(FilePath::GetSysDir() + _T("\\Plumbing.db"))) return false; std::vector 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 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 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 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::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 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 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(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 &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& datas) { return IniTools::setSectionContent(pszFile, _T("bim_data"), datas); } bool CoreTools::iniFile2BimData(LPCTSTR pszFile, std::map& 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 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 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::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 &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 &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 &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(pPl); } CLASS_CONVER(AcDbCircle, pCir, pPl); if (pCir) { str = _T("AcDbCircle"); pGeo = _geo::makeGeoPtr(pPl); } CLASS_CONVER(AcDbArc, pArc, pPl); if (pArc) { str = _T("AcDbArc"); pGeo = _geo::makeGeoPtr(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(pPl); } CLASS_CONVER(AcDbSpline, pSp, pPl); if (pSp) { str = _T("AcDbSpline"); pGeo = _geo::makeGeoPtr(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 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& 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& 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 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& 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& 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 list; getInnerTypeList(list); if (list.empty()) return -1; std::vector::iterator it = std::find(list.begin(), list.end(), psz); return (int)std::distance(list.begin(), it); } bool CoreTools::collectHolesForDTYG(AcDbObjectId id, std::vector &holes) { OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbBDPipeBase, pEnt) { if (!pEnt) return false; CString dtygType(_T("")), value(_T("")); std::vector vec; HoleData hole; for (int i = 0; i < pEnt->GetX3dPartCount(); ++i) { AecDbX3dPart *pPart = pEnt->GetX3dPart(i); if (!pPart) continue; if (!pPart->GetSpecialtyData()->GetAt(_T("DTYG_TYPE"), dtygType)) continue; if (!pPart->GetSpecialtyData()->GetAt(_T("user3"), value)) continue; CoreTools::SplitString(value, _T(':'), vec); if (vec.size() != 2) continue; if (vec[0] != _T("统计类型")) continue; if (vec[1] != _T("洞")) continue; ::memset(&hole, 0, sizeof(HoleData)); hole.bHasPipe = FALSE; hole.eShape = eXShape; hole.dSize[0] = .0; hole.dSize[1] = .0; hole.ptPos = pPart->GetOrgPoint(); _tcscpy(hole.szRem, _T("开洞")); holes.push_back(hole); } } OPENOBJ_END() return true; } bool CoreTools::checkFileName(LPCTSTR sFile) { DWORD dw = ::GetFileAttributes(sFile); if (dw == INVALID_FILE_ATTRIBUTES) { if (::GetLastError()== ERROR_INVALID_NAME) return false; } return true; } void CoreTools::sendKeyToWindow(HWND handle, UINT key) { UINT scan(MapVirtualKey(key, 0)); LPARAM lparam(0); lparam = 0x00000001 | (LPARAM)(scan << 16); ::SendMessage(handle, WM_KEYDOWN, key, lparam); ::SendMessage(handle, WM_CHAR, key, lparam); LPARAM tmp(1); lparam |= (tmp << 30); lparam |= (tmp << 31); ::SendMessage(handle, WM_KEYUP, key, lparam); } void CoreTools::sendKeyToCADView(UINT key) { CView *pView = acedGetAcadDwgView(); sendKeyToWindow(pView->GetSafeHwnd(), key); } void AcDbPolyline2GePolygon2d(const AcDbPolyline &poly, Geometry::GePwh2d &pwh) { pwh.outer_boundary.vertexs.clear(); pwh.inner_holes.clear(); //AcGePoint2d pt(AcGePoint2d::kOrigin); AcGePlane pln; AcDb::Planarity pla; poly.getPlane(pln, pla); AcGePoint3d pt(AcGePoint3d::kOrigin); for (int i = 0; i < poly.numVerts(); ++i) { poly.getPointAt(i, pt); //poly.getPointAt(i, pt); pwh.outer_boundary.vertexs.push_back(pt.convert2d(pln)); } if (!Geometry::is_counterclockwise(pwh)) { std::reverse(pwh.outer_boundary.vertexs.begin(), pwh.outer_boundary.vertexs.end()); } } bool CoreTools::getRegionInfo(AcDbRegion *pReg, AcGePoint3d ¢roid, double &area, AcGePlane &pln) { if (!pReg) return false; if (pReg->getPlane(pln) != Acad::eOk) return false; AcDbExtents ext; pReg->getGeomExtents(ext); centroid = CoreTools::MidPt(ext.maxPoint(), ext.minPoint()); AcGePoint3d ptOrg; AcGeVector3d vtX, vtY; pln.getCoordSystem(ptOrg, vtX, vtY); AcGePoint2d pt2d; double d(.0), ds[2]; AcGeVector2d vt2ds[2]; if (pReg->getAreaProp(ptOrg, vtX, vtY, d, area, pt2d, ds, d, ds, vt2ds, ds, pt2d, pt2d) == Acad::eOk) return true; return false; } int CoreTools::ptInRegion(const AcGePoint2d &pt, AcDbRegion *pReg) { if (!pReg) return Geometry::eOutside; AcGePlane pln; if (pReg->getPlane(pln) != Acad::eOk) return Geometry::eOutside; AcDbVoidPtrArray ptrs; if (pReg->explode(ptrs) != Acad::eOk) return Geometry::eOutside; if (ptrs.isEmpty()) return Geometry::eOutside; std::vector 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 &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 &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 &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 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::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 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 &pls , std::vector &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 &outPolys , std::vector &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 &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 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 &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& 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(arRegions); if (!pRegMax) return NULL; AcDbVoidPtrArray arCrv; pRegMax->explode(arCrv); delete pRegMax; if (arCrv.isEmpty()) return NULL; std::vector 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 vOsMode(_T("OSMODE"), 679); KTSetting::InitLayer(_T("LAY_COLU")); CString sLayCol, sTemp; KTSetting::GetLayerName(_T("LAY_COLU"), sLayCol, sTemp); KTCADSysVar 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; } }