#include "stdafx.h" #include "HlrCutOptionDlg.h" #include "CoreTools.h" #include "hlrcutoption.h" #include "KTSetting.h" #include "COMPARE_DOUBLE.h" #include #include "UIHistory.h" #include "AecDbJoggedCamera.h" #include "quickmodifydlg.h" namespace { void getEntitiesExtents(AcDbObjectIdArray &ar, AcDbExtents &all) { AcGePoint3d ptmax, ptmin; AcDbExtents ext; for (int i(0); i < ar.length(); ++i) { AcDbEntityPointer ent(ar[i], AcDb::kForRead); if (ent.openStatus() != Acad::eOk) continue; if (ent->getGeomExtents(ext) != Acad::eOk) continue; ptmax = ext.maxPoint(); ptmin = ext.minPoint(); if (ptmax.x < ptmin.x || ptmax.y < ptmin.y || ptmax.z < ptmin.z) continue; all.addExt(ext); } } bool selectPoint(ads_real *pPrevPt, LPCTSTR pszPrompts, AcGePoint3d &pt) { ads_point adspt; if (acedGetPoint(pPrevPt, pszPrompts, adspt) != RTNORM) return false; pt = asPnt3d(adspt); CoreTools::UCS2WCS(pt, pt); return true; } AcGePoint3d getClosestPoint(const AcGePoint3d &ptOn, const AcGeVector3d &vt, const AcGePoint3d &ptOut) { return AecDbJoggedCamera::getClosestPoint(ptOn, vt, ptOut); } bool getStartPoint(AcGePoint3d &ptStart, AecDbJoggedCamera *pJogged) { if (!pJogged) return false; int count = pJogged->getCameraCount(); if (count == 0) return true; const AecDbJoggedCamera::Camera *pCam = pJogged->getCamera(count - 1); if (!pCam) return true; CString sPrompts; AcGePoint3d ptClosed; AcGeVector3d vt(pCam->getJoggedDir()); sPrompts.Format(_T("\n输入第%d个剖切线的起点:"), count + 1); while (true) { // 取点失败,直接离开 if (!selectPoint(asDblArray(pCam->m_ptEnd), sPrompts, ptStart)) return false; if (!pJogged->judgeSegmentCanInsert(ptStart, ptStart + vt * 100, ptClosed)) { acutPrintf(_T("\n剖切线的起点不能和已有的剖切线区域重叠,请重新拾取!")); continue; } return true; } return false; } bool getEndPoint(AcGePoint3d &ptEnd, const AcGePoint3d &ptStart, AecDbJoggedCamera *pJogged) { if (!pJogged) return false; int count = pJogged->getCameraCount(); if (count == 0) return true; const AecDbJoggedCamera::Camera *pCam = pJogged->getCamera(count - 1); if (!pCam) return true; CString sPrompts; AcGePoint3d ptClosed; AcGeVector3d vt(pCam->getJoggedDir()); sPrompts.Format(_T("\n输入第%d个剖切线的终点:"), count + 1); while (true) { // 取点失败,直接离开 if (!selectPoint(asDblArray(ptStart), sPrompts, ptEnd)) return false; if (!pJogged->judgeSegmentCanInsert(ptStart, ptEnd, ptClosed)) { acutPrintf(_T("\n剖切线的终点必须在上个剖切线终点和当前剖切线起点的延长线上,请重新拾取!")); continue; } ptEnd = ptClosed; return true; } return false; } } #pragma region CCameraDlg CCameraDlg::CCameraDlg(CWnd *pParent) : CDialog(IDD_CAMERA_DLG, pParent) , m_dHorizTop(.25) , m_dHorizBottom(.25) { GET_CACHE(CCameraDlg , %f%f , &m_dHorizTop , &m_dHorizBottom); } CCameraDlg::~CCameraDlg() { } void CCameraDlg::DoDataExchange(CDataExchange *pDX) { CDialog::DoDataExchange(pDX); if (!pDX->m_bSaveAndValidate) { if (!CoreTools::IsMetersUnit()) { m_dHorizTop = (int)m_dHorizTop; m_dHorizBottom = (int)m_dHorizBottom; } else { CString ss; ss.Format(_T("%.3f"), m_dHorizTop); m_dHorizTop = TypeConvert::s2d(ss); ss.Format(_T("%.3f"), m_dHorizBottom); m_dHorizBottom = TypeConvert::s2d(ss); } } DDX_Text(pDX, IDC_EDT_HORIZ_TOP, m_dHorizTop); DDX_Text(pDX, IDC_EDT_HORIZ_BOTTOM, m_dHorizBottom); } BOOL CCameraDlg::OnInitDialog() { CDialog::OnInitDialog(); UpdateData(FALSE); return TRUE; } void CCameraDlg::OnBnClickedOk() { if (!UpdateData(TRUE)) return; if (COMPARE_DOUBLE::equal(m_dHorizBottom, m_dHorizTop, .001)) { AfxMessageBox(_T("上下标高不能相等!")); return; } SET_CACHE(CCameraDlg , %f%f , m_dHorizTop , m_dHorizBottom); OnOK(); } IMPLEMENT_DYNAMIC(CCameraDlg, CDialog) BEGIN_MESSAGE_MAP(CCameraDlg, CDialog) ON_BN_CLICKED(IDOK, &CCameraDlg::OnBnClickedOk) END_MESSAGE_MAP() void CCameraDlg::cctv() { ads_point adsPtFirst; if (acedGetPoint(NULL, _T("\n选择第一个点:"), adsPtFirst) != RTNORM) return; XCameraJig_V jig; jig.m_ptStart = asPnt3d(adsPtFirst); CoreTools::UCS2WCS(jig.m_ptStart, jig.m_ptStart); jig.m_ptStart.z = .0; jig.m_nStep = 0; AcEdJig::DragStatus stat = jig.DoIt(); if (stat != AcEdJig::kNormal) return; jig.m_nStep = 1; stat = jig.DoIt(); if (stat != AcEdJig::kNormal) return; jig.m_nStep = 2; stat = jig.DoIt(); if (stat != AcEdJig::kNormal) return; AcGePoint3d ptEye(jig.m_ptEye), ptOutput(jig.m_ptOutput); AcGeVector3d vtEye(jig.m_vtEye); AecDbXCamera *pCam = new AecDbXCamera(); pCam->SetUsageMode(AecDbXCamera::eVerti); pCam->SetEyeDirect(vtEye); pCam->SetEyePoint(ptEye); pCam->SetWidth(jig.m_ptStart.distanceTo(jig.m_ptEnd)); pCam->SetOutputPoint(ptOutput); pCam->setLayer(KTSetting::InitLayer(_T("LAY_CAMERA"))); // 在计算之前,取得实体的标高范围 double dMax, dMin; pCam->calcRangeOfElev(dMax, dMin); CAcModuleResourceOverride myResources; CCameraDlg dlg; dlg.m_dHorizTop = dMax; dlg.m_dHorizBottom = dMin; if (dlg.DoModal() != IDOK) { DELETE_PTR(pCam); return; } pCam->SetHorizTop(dlg.m_dHorizTop); pCam->SetHorizBottom(dlg.m_dHorizBottom); CoreTools::AddToModelSpace(pCam, false); pCam->refresh(true); pCam->close(); } void CCameraDlg::ccth() { ads_point adsPtFirst; if (acedGetPoint(NULL, _T("\n选择切面范围的第一个点:"), adsPtFirst) != RTNORM) return; XCameraJig_H jig; jig.m_ptLT = asPnt3d(adsPtFirst); CoreTools::UCS2WCS(jig.m_ptLT, jig.m_ptLT); jig.m_ptLT.z = .0; jig.m_nStep = 0; AcEdJig::DragStatus stat = jig.DoIt(); if (stat != AcEdJig::kNormal) return; jig.m_nStep = 1; stat = jig.DoIt(); if (stat != AcEdJig::kNormal) return; struct resbuf *selArea = acutBuildList(RTPOINT, jig.m_ptLT , RTPOINT, jig.m_ptRT , RTPOINT, jig.m_ptRB , RTPOINT, jig.m_ptLB , RTPOINT, jig.m_ptLT , 0); AcDbObjectIdArray arIds; AecDbXCamera::collectEnities(AecDbXCamera::getSelectTypeResbuf(), selArea, arIds); acutRelRb(selArea); double dMaxZ(.0), dMinZ(.0); AcDbExtents ext; getEntitiesExtents(arIds, ext); if (!arIds.isEmpty()) { dMaxZ = ext.maxPoint().z; dMinZ = ext.minPoint().z; } AecDbXCamera *pCam = new AecDbXCamera(); pCam->SetUsageMode(AecDbXCamera::eHoriz); pCam->SetOutputPoint(jig.m_ptOutput); pCam->SetWidth(jig.m_ptLT.distanceTo(jig.m_ptRT)); pCam->SetHeight(jig.m_ptLT.distanceTo(jig.m_ptLB)); pCam->setLayer(KTSetting::InitLayer(_T("LAY_CAMERA"))); pCam->calcRangeOfElev(dMaxZ, dMinZ); CAcModuleResourceOverride myResources; CCameraDlg dlg; dlg.m_dHorizTop = dMaxZ; dlg.m_dHorizBottom = dMinZ; if (dlg.DoModal() != IDOK) { DELETE_PTR(pCam); return; } pCam->SetEyeDirect(-AcGeVector3d::kZAxis * (dlg.m_dHorizTop - dlg.m_dHorizBottom)); pCam->SetHorizTop(dlg.m_dHorizTop); pCam->SetHorizBottom(dlg.m_dHorizBottom); AcGePoint3d ptEye(jig.m_ptEye); ptEye.z = dlg.m_dHorizTop; pCam->SetEyePoint(ptEye); CoreTools::AddToModelSpace(pCam, false); pCam->refresh(true); pCam->close(); } void CCameraDlg::dbl() { extern bool GetDoubleClickEnt(LPCTSTR pszCmd, AcDbObjectId& id); AcDbObjectId id; bool bIsOk = GetDoubleClickEnt(_T("DBL_AEC_XCAMERA"), id); if (!bIsOk || !id.isValid()) return; AcDbObjectPointer ent(id, AcDb::kForWrite); if (ent.openStatus() != Acad::eOk) return; CAcModuleResourceOverride myResources; CCameraDlg dlg; dlg.m_dHorizTop = ent->GetHorizTop(); dlg.m_dHorizBottom = ent->GetHorizBottom(); if (ent->GetUsageMode() == AecDbXCamera::eHoriz) { if (dlg.DoModal() == IDOK) { AcGePoint3d ptEye(ent->GetEyePoint()); AcGeVector3d vtEye(ent->GetEyeDirect()); ent->SetHorizTop(dlg.m_dHorizTop); ptEye.z = dlg.m_dHorizTop; ent->SetEyePoint(ptEye); ent->SetHorizBottom(dlg.m_dHorizBottom); vtEye = -AcGeVector3d::kZAxis * (ent->GetHorizTop() - ent->GetHorizBottom()); ent->SetEyeDirect(vtEye); ent->refresh(true); } } else if (ent->GetUsageMode() == AecDbXCamera::eVerti) { if (dlg.DoModal() == IDOK) { ent->SetHorizTop(dlg.m_dHorizTop); ent->SetHorizBottom(dlg.m_dHorizBottom); ent->refresh(true); } } else { if (AfxMessageBox(_T("是否刷新结果?"), MB_YESNO) != IDYES) return; ent->refresh(true); } } void CCameraDlg::resetAecDraw3d() { struct resbuf *pRb = acutBuildList( RTDXF0, _T("AEC_DBWEQUIPMENT,AEC_DBOPENING"), 0); ads_name ss, ent; int nRes = acedSSGet(NULL, NULL, NULL, pRb, ss); acutRelRb(pRb); if (nRes != RTNORM) return; Adesk::Int32 lLen = 0; acedSSLength(ss, &lLen); AcDbObjectId id; for (int i = 0; i < lLen; i++) { acedSSName(ss, i, ent); acdbGetObjectId(id, ent); if (!id.isValid()) continue; AcDbEntityPointer ent(id, AcDb::kForWrite); AecDbEntityBase *pBase(AecDbEntityBase::cast(ent)); if (!pBase) continue; AecDbObjXDataMap *pXData = pBase->GetSpecialtyData(AcDb::kForWrite); if (!pXData) continue; pXData->SetAt(HLR_CALC, FALSE); } acedSSFree(ss); } void CCameraDlg::jogged_dbl() { extern bool GetDoubleClickEnt(LPCTSTR pszCmd, AcDbObjectId& id); AcDbObjectId id; bool bIsOk = GetDoubleClickEnt(_T("DBL_AEC_JOGGEDCAMERA"), id); if (!bIsOk || !id.isValid()) return; AcDbObjectPointer ent(id, AcDb::kForWrite); if (ent.openStatus() != Acad::eOk) return; if (AfxMessageBox(_T("是否刷新结果?"), MB_YESNO) != IDYES) return; ent->refresh(); } void CCameraDlg::joggedCamera() { AecDbJoggedCamera *pJoggedCam = new AecDbJoggedCamera(); if (!pJoggedCam) return; AcDbObjectId id = CoreTools::AddToModelSpace(pJoggedCam); int loop(0); while (loop < 30) { AcDbObjectPointer jogged(id, AcDb::kForWrite); if (jogged.openStatus() != Acad::eOk) break; CJoggedCameraJig jig(pJoggedCam); AcEdJig::DragStatus stat = jig.DoIt(); if (stat == AcEdJig::kNull || stat == AcEdJig::kCancel) break; jogged->addCamera(jig.m_ptStart, jig.m_ptEnd, jig.m_vtEye); ++loop; jogged->close(); } AcDbObjectPointer jogged(id, AcDb::kForWrite); if (jogged.openStatus() != Acad::eOk) return; // 没有剖切线,清理 if (jogged->getCameraCount() == 0) { jogged->erase(); return; } ads_point pt; acedGetPoint(NULL, _T("\n选择生成剖切结果的位置:"), pt); AcGePoint3d ptOutput(asPnt3d(pt)); CoreTools::UCS2WCS(ptOutput, ptOutput); jogged->setOutputPoint(ptOutput); jogged->close(); AcDbObjectIdArray ar; ar.append(id); CQuickModifyDlg::start(ar); } void CCameraDlg::joggedCamera1() { AcDbObjectId id, subid; AcGeVector3d vtDir; AcGePoint3d pt1, pt2; AcDbLine *pLine(NULL); if (!selectPoint(NULL, _T("\n选择第1条剖切线的起点:"), pt1)) return; if (!selectPoint(asDblArray(pt1), _T("\n选择第1条剖切线的终点:"), pt2)) return; vtDir = pt2 - pt1; vtDir.rotateBy(PI * .5, AcGeVector3d::kZAxis); AecDbJoggedCamera *pJoggedCam = new AecDbJoggedCamera(); if (!pJoggedCam) return; if (!pJoggedCam->addCamera(pt1, pt2, vtDir)) { acutPrintf(_T("\n插入折线剖切失败!")); DELETE_PTR(pJoggedCam); return; } id = CoreTools::AddToModelSpace(pJoggedCam); AcGePoint3d ptS, ptE, ptLast; AcGeVector3d vtLine(pt2 - pt1); int loop(0); while (loop < 30) { AcDbObjectPointer jogged(id, AcDb::kForWrite); if (jogged.openStatus() != Acad::eOk) continue; ptLast = jogged->getLastPoint(); if (!getStartPoint(ptS, jogged)) break; AcDbLine *pLine = new AcDbLine(ptS, ptLast); pLine->setColorIndex(9); subid = CoreTools::AddToModelSpace(pLine, true); if (!getEndPoint(ptE, ptS, jogged)) { AcDbEntityPointer entLine(subid, AcDb::kForWrite); if (entLine.openStatus() == Acad::eOk) entLine->erase(); break; } jogged->addCamera(ptS, ptE, vtDir); jogged->close(); AcDbEntityPointer entLine(subid, AcDb::kForWrite); if (entLine.openStatus() == Acad::eOk) entLine->erase(); ++loop; } // 如果没有折线 AcDbObjectPointer jogged(id, AcDb::kForWrite); if (jogged.openStatus() != Acad::eOk) { AfxMessageBox(_T("生成剖切线出错!")); return; } pt1 = CoreTools::MidPt(ptE, ptS); CString sPrompts(_T("\n选取一个点,来确定剖切方向和范围:")); if (!selectPoint(asDblArray(pt1), sPrompts, pt2)) acutPrintf(_T("\n采用默认剖切方向和范围.")); // 获得标高 CCameraDlg dlg; dlg.m_dHorizTop = 3000.; dlg.m_dHorizBottom = -3000.; dlg.DoModal(); if (COMPARE_DOUBLE::equal(dlg.m_dHorizTop, dlg.m_dHorizBottom)) { dlg.m_dHorizTop = 3000.; dlg.m_dHorizBottom = -3000.; } // 一个循环,设置范围,方向,高度 for (int i(0); i < jogged->getCameraCount(); ++i) { jogged->setCameraWidth(i, pt2); jogged->setCameraHeight(i, dlg.m_dHorizTop, dlg.m_dHorizBottom); } // 结果对齐点 pt2 = AcGePoint3d::kOrigin; if (!selectPoint(asDblArray(pt1), _T("\n选取结果对齐点<默认为原点>:"), pt2)) acutPrintf(_T("\n设置结果对齐点在原点.")); jogged->setOutputPoint(pt2); jogged->close(); } namespace { // 辅助函数:使用射线法判断一个点是否在闭合曲线上 bool IsPointInsideBoundary(AcDbCurve *pBoundary, const AcGePoint3d &testPt) { if (pBoundary == NULL) { return false; } // 1. 优先判定:点是否在边界曲线上 AcGePoint3d closestPt; if (pBoundary->getClosestPointTo(testPt, closestPt) == Acad::eOk) { // 如果测试点到边界最近点的距离小于容差,认为点在边界上 if (testPt.distanceTo(closestPt) < 1e-6) { return true; // 视为在内部,予以保留 } } // 2. 获取边界的外包围盒,用于快速排除并构建射线长度 AcDbExtents extents; if (pBoundary->getGeomExtents(extents) != Acad::eOk) { return false; } // 粗略判断:如果点在外包围盒之外,肯定在外部 if (testPt.x < extents.minPoint().x || testPt.x > extents.maxPoint().x || testPt.y < extents.minPoint().y || testPt.y > extents.maxPoint().y) { return false; } // 3. 构造一条射线,从测试点射向包围盒外的一个极远点 // 使用非标准角度的向量,尽量避免穿过顶点或与边重合 AcGeVector3d rayDir(1.0, 0.314159, 0.0); double dist = extents.maxPoint().distanceTo(extents.minPoint()) * 2.0; AcGePoint3d farPt = testPt + rayDir * dist; AcDbLine rayLine(testPt, farPt); AcGePoint3dArray intPts; // 4. 求交 if (pBoundary->intersectWith(&rayLine, AcDb::kOnBothOperands, intPts) != Acad::eOk) { return false; } // 5. 过滤重复交点 (容差处理,防止同一个交点被重复计算) int validIntersectionCount = 0; for (int i = 0; i < intPts.length(); ++i) { bool isDuplicate = false; for (int j = 0; j < i; ++j) { if (intPts[i].distanceTo(intPts[j]) < 1e-6) { isDuplicate = true; break; } } if (!isDuplicate) { validIntersectionCount++; } } // 6. 射线法核心:交点个数为奇数则在内部,偶数则在外部 return (validIntersectionCount % 2) != 0; } void ClipCurvesByBoundary(AcDbObjectId boundaryId, const AcDbObjectIdArray &targetCurveIds) { AcDbObjectPointer pBoundary(boundaryId, AcDb::kForRead); if (pBoundary.openStatus() != Acad::eOk) { return; } for (int i = 0; i < targetCurveIds.length(); ++i) { AcDbObjectPointer pTargetCurve(targetCurveIds[i], AcDb::kForWrite); if (pTargetCurve.openStatus() != Acad::eOk) { continue; } AcGePoint3dArray intPts; // 1. 获取目标曲线与边界的所有交点 if (pTargetCurve->intersectWith(pBoundary.object(), AcDb::kOnBothOperands, intPts) == Acad::eOk && intPts.length() > 0) { AcGeDoubleArray splitParams; std::vector vecParams; // 2. 将交点转换为曲线上的参数 for (int j = 0; j < intPts.length(); ++j) { double param = 0.0; AcGePoint3d projPt; if (pTargetCurve->getClosestPointTo(intPts[j], projPt) == Acad::eOk) { if (pTargetCurve->getParamAtPoint(projPt, param) == Acad::eOk) { vecParams.push_back(param); } } } // 3. 对参数进行排序和去重 if (!vecParams.empty()) { std::sort(vecParams.begin(), vecParams.end()); vecParams.erase(std::unique(vecParams.begin(), vecParams.end()), vecParams.end()); for (size_t k = 0; k < vecParams.size(); ++k) { splitParams.append(vecParams[k]); } // 4. 打断曲线 AcDbVoidPtrArray curveFragments; if (pTargetCurve->getSplitCurves(splitParams, curveFragments) == Acad::eOk) { // 遍历打断后的碎片 for (int f = 0; f < curveFragments.length(); ++f) { AcDbCurve *pFragment = static_cast(curveFragments[f]); if (pFragment != NULL) { double startParam = 0.0; double endParam = 0.0; pFragment->getStartParam(startParam); pFragment->getEndParam(endParam); double midParam = (startParam + endParam) / 2.0; AcGePoint3d midPt; if (pFragment->getPointAtParam(midParam, midPt) == Acad::eOk) { // 恢复正确的逻辑:框内保留,框外剔除 if (IsPointInsideBoundary(pBoundary.object(), midPt)) { // 内部保留:加入模型空间 CoreTools::AddToModelSpace(pFragment); } else { // 外部剔除:直接在内存销毁 delete pFragment; } } else { delete pFragment; } } } // 删除打断前的原始线条 pTargetCurve->erase(true); } } } else { // 【核心修复点】: // 如果与边界完全没有交点(不管它是在红框外面十万八千里,还是在红框正中间) // 我们什么都不做! // 智能指针 pTargetCurve 会在离开作用域时自动 close(),实体原样安全保留。 } } } } void CCameraDlg::cfix() { // 1. 选择裁剪边界 (使用 acedEntSel,因为通常边界只选一个) ads_name boundaryEnt; ads_point pt; int res = acedEntSel(_T("\n请选择作为裁剪边界的闭合多段线: "), boundaryEnt, pt); if (res != RTNORM) { acutPrintf(_T("\n未选择边界,命令取消。")); return; } AcDbObjectId boundaryId; if (acdbGetObjectId(boundaryId, boundaryEnt) != Acad::eOk) { return; } // 简单校验一下选中的边界是不是一条曲线 (AcDbCurve) { AcDbObjectPointer pBoundary(boundaryId, AcDb::kForRead); if (pBoundary.openStatus() != Acad::eOk) { acutPrintf(_T("\n错误:所选边界不是有效的曲线实体!")); return; } // 可选:你甚至可以在这里检查 pBoundary->isClosed() 确保它是闭合的 } // 2. 批量选择需要被裁剪的目标曲线 (使用 acedSSGet 配合 DXF 过滤) acutPrintf(_T("\n请框选需要被裁剪的曲线 (将自动过滤非曲线实体): ")); // 构建过滤器:0 代表图元类型,后面的字符串涵盖了绝大多数 AcDbCurve 派生类 // "*POLYLINE" 是通配符,能同时匹配 LWPOLYLINE(轻量多段线) 和 POLYLINE(二维/三维多段线) struct resbuf *pFilter = acutBuildList(0, _T("LINE,ARC,CIRCLE,ELLIPSE,SPLINE,*POLYLINE"), 0); ads_name ssName; // 第一个参数 NULL 表示允许用户进行常规框选/点选 res = acedSSGet(NULL, NULL, NULL, pFilter, ssName); // 过滤器用完必须立刻释放,避免内存泄漏 acutRelRb(pFilter); if (res != RTNORM) { acutPrintf(_T("\n未选中任何有效的曲线,命令结束。")); return; } // 3. 解析选择集,提取 ObjectId Adesk::Int32 length = 0; acedSSLength(ssName, &length); AcDbObjectIdArray targetCurveIds; for (long i = 0; i < length; ++i) { ads_name en; if (acedSSName(ssName, i, en) == RTNORM) { AcDbObjectId objId; if (acdbGetObjectId(objId, en) == Acad::eOk) { // 确保不要把边界本身也作为被裁剪的目标传进去 if (objId != boundaryId) { targetCurveIds.append(objId); } } } } // 释放选择集内存 acedSSFree(ssName); // 4. 调用核心裁剪算法 if (targetCurveIds.length() > 0) { acutPrintf(_T("\n成功提取了 %d 条曲线,开始执行裁剪算法..."), targetCurveIds.length()); // 调用之前写好的算法 ClipCurvesByBoundary(boundaryId, targetCurveIds); acutPrintf(_T("\n裁剪完成!")); } else { acutPrintf(_T("\n未找到符合条件的裁剪目标。")); } } void CCameraDlg::test_static() { //struct resbuf *pRb= acutBuildList( // -4, _T("") // , -4, _T("") // , -4, _T("") // , -4, _T("or>") // , 0); } #pragma endregion #pragma region HlrCutOptionDlg #define SET_BY_OPT_VALUE(func, name)\ m_bSet##func####name = HlrCutOption::getHlr##func##_##name(m_n##func####name) #define SET_OPT_VALUE(func, name)\ if (m_bSet##func####name) \ HlrCutOption::setHlr##func##_##name(m_n##func####name);\ else \ HlrCutOption::removeHlr##func##_##name() #define SET_BY_OPT_CHECK(func, name)\ m_bSet##func####name = HlrCutOption::getHlr##func##_##name() #define SET_OPT_CHECK(func, name)\ HlrCutOption::setHlr##func##_##name(m_bSet##func####name);\ IMPLEMENT_DYNAMIC(HlrCutOptionDlg, CDialog) HlrCutOptionDlg::HlrCutOptionDlg(CWnd *pParent) : CDialog(IDD_HLR_OPTION_DLG, pParent) , m_bSetBLKSTAIR(TRUE) , m_bSetBLKFITTING(TRUE) , m_bSetBLKOPEN(TRUE) , m_bSetBLKEQU(TRUE) , m_bSetBLKPARAEQU(TRUE) , m_bSetBLKYGDT(TRUE) , m_bSetSTYLE2DOPEN(TRUE) , m_bSetSTYLE2DVALVE(TRUE) , m_bSetSTYLE2DHOLE(TRUE) , m_bSetLWWall(FALSE) , m_bSetLWBeam(FALSE) , m_bSetLWSlab(FALSE) , m_bSetLWColumn(TRUE) , m_bSetZXSameDir(FALSE) , m_bSetZXParallel(FALSE) , m_bSetLWPipeSys(FALSE) , m_bSetLWElecSys(FALSE) , m_bSetLWHvacSys(FALSE) //, m_bSetMERGEEnvelope(TRUE) , m_bSetLWEnvCut(TRUE) , m_bSetMERGEWall(TRUE) , m_bSetMERGEBeam(TRUE) , m_bSetMERGESlab(TRUE) , m_bSetMERGEColumn(FALSE) , m_bSetLWEnvelope(FALSE) , m_bSetLYEnvelope(FALSE) , m_bSetLTEnvelope(FALSE) , m_bSetCLEnvelope(FALSE) , m_nLWWall(.5) , m_nLWBeam(.5) , m_nLWSlab(.5) , m_nLWColumn(.5) , m_nLWPipeSys(.5) , m_nLWElecSys(.5) , m_nLWHvacSys(.5) , m_nLWEnvelope(.5) , m_nLWEnvCut(5) , m_nLYEnvelope(AcDbObjectId::kNull) , m_nLTEnvelope(AcDbObjectId::kNull) , m_nCLEnvelope(256) { HlrCutOption::init(); // 构筑物线宽 SET_BY_OPT_VALUE(LW, Wall); SET_BY_OPT_VALUE(LW, Beam); SET_BY_OPT_VALUE(LW, Slab); SET_BY_OPT_VALUE(LW, Column); SET_BY_OPT_VALUE(LW, PipeSys); SET_BY_OPT_VALUE(LW, ElecSys); SET_BY_OPT_VALUE(LW, HvacSys); SET_BY_OPT_VALUE(LW, EnvCut); SET_BY_OPT_CHECK(BLK, OPEN); SET_BY_OPT_CHECK(BLK, FITTING); SET_BY_OPT_CHECK(BLK, EQU); SET_BY_OPT_CHECK(BLK, PARAEQU); SET_BY_OPT_CHECK(BLK, YGDT); SET_BY_OPT_CHECK(BLK, STAIR); SET_BY_OPT_CHECK(STYLE2D, OPEN); SET_BY_OPT_CHECK(STYLE2D, VALVE); SET_BY_OPT_CHECK(STYLE2D, HOLE); //SET_BY_OPT_CHECK(MERGE, Envelope); // 构筑物融合 SET_BY_OPT_CHECK(MERGE, Wall); SET_BY_OPT_CHECK(MERGE, Beam); SET_BY_OPT_CHECK(MERGE, Slab); SET_BY_OPT_CHECK(MERGE, Column); // 构筑物融合后使用的属性 SET_BY_OPT_VALUE(LW, Envelope); SET_BY_OPT_VALUE(LY, Envelope); SET_BY_OPT_VALUE(LT, Envelope); SET_BY_OPT_VALUE(CL, Envelope); // 折线剖切 SET_BY_OPT_CHECK(ZX, SameDir); SET_BY_OPT_CHECK(ZX, Parallel); } HlrCutOptionDlg::~HlrCutOptionDlg() { } void HlrCutOptionDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Control(pDX, IDC_EDT_WALL, m_edtWall); DDX_Control(pDX, IDC_EDT_BEAM, m_edtBeam); DDX_Control(pDX, IDC_EDT_SLAB, m_edtSlab); DDX_Control(pDX, IDC_EDT_COLUMN, m_edtColumn); DDX_Control(pDX, IDC_EDT_PIPE, m_edtPipe); DDX_Control(pDX, IDC_EDT_PIPE_FIT, m_edtPipeFit); DDX_Control(pDX, IDC_EDT_EC, m_edtEc); DDX_Control(pDX, IDC_EDT_EC_FIT, m_edtEcFit); DDX_Control(pDX, IDC_EDT_HVAC, m_edtHvac); DDX_Control(pDX, IDC_EDT_HVAC_FIT, m_edtHvacFit); DDX_Control(pDX, IDC_EDT_ENVCUT, m_edtEnvCut); DDX_Control(pDX, IDC_CHK_WALL, m_chkWall); DDX_Control(pDX, IDC_CHK_BEAM, m_chkBeam); DDX_Control(pDX, IDC_CHK_SLAB, m_chkSlab); DDX_Control(pDX, IDC_CHK_COLUMN, m_chkColumn); DDX_Control(pDX, IDC_CHK_ENVE_WEIGTH, m_chkEnvelopeLW); DDX_Control(pDX, IDC_CHK_ENVE_LINETYPE, m_chkEnvelopeLT); DDX_Control(pDX, IDC_CHK_ENVE_LAYER, m_chkEnvelopeLY); DDX_Control(pDX, IDC_CHK_ENVE_COLOR, m_chkEnvelopeCL); DDX_Control(pDX, IDC_EDT_ENVE_WEIGTH, m_edtEnvelopeLW); DDX_Control(pDX, IDC_CMB_ENVE_LINETYPE, m_cmbEnvelopeLT); DDX_Control(pDX, IDC_CMB_ENVE_LAYER, m_cmbEnvelopeLY); DDX_Control(pDX, IDC_BTN_ENVE_COLOR, m_btnEnvelopeCL); DDX_Check(pDX, IDC_CHK_WALL, m_bSetLWWall); DDX_Check(pDX, IDC_CHK_BEAM, m_bSetLWBeam); DDX_Check(pDX, IDC_CHK_SLAB, m_bSetLWSlab); DDX_Check(pDX, IDC_CHK_COLUMN, m_bSetLWColumn); DDX_Check(pDX, IDC_CHK_ENVCUT, m_bSetLWEnvCut); DDX_Check(pDX, IDC_CHK_PIPE, m_bSetLWPipeSys); DDX_Check(pDX, IDC_CHK_EC, m_bSetLWElecSys); DDX_Check(pDX, IDC_CHK_HVAC, m_bSetLWHvacSys); DDX_Check(pDX, IDC_CHK_BLK_YGDT, m_bSetBLKYGDT); DDX_Check(pDX, IDC_CHK_BLK_EQU, m_bSetBLKEQU); DDX_Check(pDX, IDC_CHK_BLK_PARAEQU, m_bSetBLKPARAEQU); DDX_Check(pDX, IDC_CHK_BLK_OPEN, m_bSetBLKOPEN); DDX_Check(pDX, IDC_CHK_BLK_FITTING, m_bSetBLKFITTING); DDX_Check(pDX, IDC_CHK_BLK_STAIR, m_bSetBLKSTAIR); DDX_Check(pDX, IDC_CHK_2D_VALVE, m_bSetSTYLE2DVALVE); DDX_Check(pDX, IDC_CHK_2D_OPEN, m_bSetSTYLE2DOPEN); DDX_Check(pDX, IDC_CHK_2D_HOLE, m_bSetSTYLE2DHOLE); //DDX_Check(pDX, IDC_CHK_ENVELOPE_MERGE, m_bSetMERGEEnvelope); DDX_Check(pDX, IDC_CHK_MERGE_WALL, m_bSetMERGEWall); DDX_Check(pDX, IDC_CHK_MERGE_BEAM, m_bSetMERGEBeam); DDX_Check(pDX, IDC_CHK_MERGE_SLAB, m_bSetMERGESlab); DDX_Check(pDX, IDC_CHK_MERGE_COLUMN, m_bSetMERGEColumn); DDX_Check(pDX, IDC_CHK_ENVE_WEIGTH, m_bSetLWEnvelope); DDX_Check(pDX, IDC_CHK_ENVE_LAYER, m_bSetLYEnvelope); DDX_Check(pDX, IDC_CHK_ENVE_LINETYPE, m_bSetLTEnvelope); DDX_Check(pDX, IDC_CHK_ENVE_COLOR, m_bSetCLEnvelope); DDX_Check(pDX, IDC_CHK_ZX_SAME_DIR, m_bSetZXSameDir); DDX_Check(pDX, IDC_CHK_ZX_PARALLEL, m_bSetZXParallel); DDX_Text(pDX, IDC_EDT_WALL, m_nLWWall); DDX_Text(pDX, IDC_EDT_BEAM, m_nLWBeam); DDX_Text(pDX, IDC_EDT_SLAB, m_nLWSlab); DDX_Text(pDX, IDC_EDT_COLUMN, m_nLWColumn); DDX_Text(pDX, IDC_EDT_PIPE, m_nLWPipeSys); DDX_Text(pDX, IDC_EDT_HVAC, m_nLWHvacSys); DDX_Text(pDX, IDC_EDT_EC, m_nLWElecSys); DDX_Text(pDX, IDC_EDT_ENVCUT, m_nLWEnvCut); DDX_Text(pDX, IDC_EDT_ENVE_WEIGTH, m_nLWEnvelope); DDV_MinMaxDouble(pDX, m_nLWWall, .01, 100); DDV_MinMaxDouble(pDX, m_nLWBeam, .01, 100); DDV_MinMaxDouble(pDX, m_nLWSlab, .01, 100); DDV_MinMaxDouble(pDX, m_nLWColumn, .01, 100); DDV_MinMaxDouble(pDX, m_nLWEnvCut, .01, 100); DDV_MinMaxDouble(pDX, m_nLWPipeSys, .01, 100); DDV_MinMaxDouble(pDX, m_nLWHvacSys, .01, 100); DDV_MinMaxDouble(pDX, m_nLWElecSys, .01, 100); DDV_MinMaxDouble(pDX, m_nLWEnvelope, .01, 100); } BOOL HlrCutOptionDlg::OnInitDialog() { CDialog::OnInitDialog(); UpdateData(FALSE); OnBnClickedEnvelopeMerage(); OnBnClickedChk(); initCombobox(); return TRUE; } #define getSymbolRecords(symboltable, type)\ {\ TCHAR *name(NULL);\ int nCurIdx(-1);\ AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();\ if (pDb)\ {\ AcDb##symboltable##TablePointer table(pDb, AcDb::kForRead);\ AcDb##symboltable##TableIterator *pIter;\ table->newIterator(pIter);\ AcDbObjectId id;\ int idx(-1);\ for (int i(0); !pIter->done(); pIter->step(), ++i)\ {\ pIter->getRecordId(id);\ AcDb##symboltable##TableRecordPointer rec(id, AcDb::kForRead);\ rec->getName(name);\ idx = m_cmbEnvelope##type.AddString(name);\ m_cmbEnvelope##type.SetItemData(idx, id.asOldId());\ acutDelString(name);\ if (m_n##type##Envelope == id)\ nCurIdx = idx;\ }\ delete pIter;\ }\ if (m_cmbEnvelope##type.GetCount() != 0)\ m_cmbEnvelope##type.SetCurSel(nCurIdx == -1 ? 0 : nCurIdx);\ } void HlrCutOptionDlg::initCombobox() { getSymbolRecords(Layer, LY); getSymbolRecords(Linetype, LT); } BEGIN_MESSAGE_MAP(HlrCutOptionDlg, CDialog) ON_BN_CLICKED(IDOK, &HlrCutOptionDlg::OnBnClickedOk) ON_BN_CLICKED(IDC_CHK_WALL, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_BEAM, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_SLAB, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_COLUMN, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_ENVCUT, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_PIPE, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_PIPE_FIT, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_EC, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_EC_FIT, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_HVAC, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_HVAC_FIT, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_ENVE_WEIGTH, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_ENVE_LAYER, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_ENVE_LINETYPE, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_ENVE_COLOR, &HlrCutOptionDlg::OnBnClickedChk) ON_BN_CLICKED(IDC_CHK_MERGE_WALL, &HlrCutOptionDlg::OnBnClickedEnvelopeMerage) ON_BN_CLICKED(IDC_CHK_MERGE_BEAM, &HlrCutOptionDlg::OnBnClickedEnvelopeMerage) ON_BN_CLICKED(IDC_CHK_MERGE_SLAB, &HlrCutOptionDlg::OnBnClickedEnvelopeMerage) ON_BN_CLICKED(IDC_CHK_MERGE_COLUMN, &HlrCutOptionDlg::OnBnClickedEnvelopeMerage) ON_BN_CLICKED(IDC_BTN_ENV_COLOR, &HlrCutOptionDlg::OnBnClickedEnvelopeColor) ON_WM_CTLCOLOR() ON_CBN_SELCHANGE(IDC_CMB_ENVE_LAYER, &HlrCutOptionDlg::OnComboBoxSelChangeLayer) ON_CBN_SELCHANGE(IDC_CMB_ENVE_LINETYPE, &HlrCutOptionDlg::OnComboBoxSelChangeLinetype) END_MESSAGE_MAP() void HlrCutOptionDlg::OnBnClickedOk() { if (!UpdateData(TRUE)) return; SET_OPT_VALUE(LW, Wall); SET_OPT_VALUE(LW, Beam); SET_OPT_VALUE(LW, Slab); SET_OPT_VALUE(LW, Column); // 2025.10.29 管道+配件+阀门 变为统一线宽 SET_OPT_VALUE(LW, PipeSys); SET_OPT_VALUE(LW, ElecSys); SET_OPT_VALUE(LW, HvacSys); SET_OPT_VALUE(LW, EnvCut); SET_OPT_CHECK(BLK, OPEN); SET_OPT_CHECK(BLK, FITTING); SET_OPT_CHECK(BLK, EQU); SET_OPT_CHECK(BLK, PARAEQU); SET_OPT_CHECK(BLK, YGDT); SET_OPT_CHECK(BLK, STAIR); SET_OPT_CHECK(STYLE2D, OPEN); SET_OPT_CHECK(STYLE2D, VALVE); SET_OPT_CHECK(STYLE2D, HOLE); //SET_OPT_CHECK(MERGE, Envelope); SET_OPT_CHECK(MERGE, Wall); SET_OPT_CHECK(MERGE, Beam); SET_OPT_CHECK(MERGE, Slab); SET_OPT_CHECK(MERGE, Column); SET_OPT_VALUE(LW, Envelope); SET_OPT_VALUE(LT, Envelope); SET_OPT_VALUE(LY, Envelope); SET_OPT_VALUE(CL, Envelope); SET_OPT_CHECK(ZX, SameDir); SET_OPT_CHECK(ZX, Parallel); CDialog::OnOK(); } bool HlrCutOptionDlg::isMerageEnvelope() { int count(0); if (m_bSetMERGEWall) ++count; if (m_bSetMERGEBeam) ++count; if (m_bSetMERGESlab) ++count; if (m_bSetMERGEColumn) ++count; return count >= 2; } void HlrCutOptionDlg::OnBnClickedChk() { UpdateData(TRUE); bool bMerge(isMerageEnvelope()); // 不融合,只要线宽设置的check被选上,线宽edit就可用 if (!bMerge) { m_edtWall.EnableWindow(m_bSetLWWall); m_edtBeam.EnableWindow(m_bSetLWBeam); m_edtSlab.EnableWindow(m_bSetLWSlab); m_edtColumn.EnableWindow(m_bSetLWColumn); } // 融合情况下,哪种类型 !没有! 参与融合,哪种类型的线宽check被选上,线宽edit就可用 else { if (!m_bSetMERGEWall) { m_edtWall.EnableWindow(m_bSetLWWall); m_chkWall.EnableWindow(TRUE); } else { m_edtWall.EnableWindow(FALSE); m_chkWall.EnableWindow(FALSE); } if (!m_bSetMERGEBeam) { m_edtBeam.EnableWindow(m_bSetLWBeam); m_chkBeam.EnableWindow(TRUE); } else { m_edtBeam.EnableWindow(FALSE); m_chkBeam.EnableWindow(FALSE); } if (!m_bSetMERGESlab) { m_edtSlab.EnableWindow(m_bSetLWSlab); m_chkSlab.EnableWindow(TRUE); } else { m_edtSlab.EnableWindow(FALSE); m_chkSlab.EnableWindow(FALSE); } if (!m_bSetMERGEColumn) { m_edtColumn.EnableWindow(m_bSetLWColumn); m_chkColumn.EnableWindow(TRUE); } else { m_edtColumn.EnableWindow(FALSE); m_chkColumn.EnableWindow(FALSE); } } //m_edtWall.EnableWindow(bMerge ? FALSE : m_bSetLWWall); //m_edtBeam.EnableWindow(bMerge ? FALSE : m_bSetLWBeam); //m_edtSlab.EnableWindow(bMerge ? FALSE : m_bSetLWSlab); //m_edtColumn.EnableWindow(bMerge ? FALSE : m_bSetLWColumn); m_edtEnvCut.EnableWindow(m_bSetLWEnvCut); m_edtPipe.EnableWindow(m_bSetLWPipeSys); m_edtEc.EnableWindow(m_bSetLWElecSys); m_edtHvac.EnableWindow(m_bSetLWHvacSys); m_edtEnvelopeLW.EnableWindow(!bMerge ? FALSE : m_bSetLWEnvelope); m_cmbEnvelopeLT.EnableWindow(!bMerge ? FALSE : m_bSetLTEnvelope); m_cmbEnvelopeLY.EnableWindow(!bMerge ? FALSE : m_bSetLYEnvelope); m_btnEnvelopeCL.EnableWindow(!bMerge ? FALSE : m_bSetCLEnvelope); } void HlrCutOptionDlg::OnBnClickedEnvelopeMerage() { UpdateData(TRUE); bool bMerge(isMerageEnvelope()); if (bMerge) { m_chkWall.EnableWindow(!m_bSetMERGEWall); m_chkBeam.EnableWindow(!m_bSetMERGEBeam); m_chkSlab.EnableWindow(!m_bSetMERGESlab); m_chkColumn.EnableWindow(!m_bSetMERGEColumn); } else { m_chkWall.EnableWindow(TRUE); m_chkBeam.EnableWindow(TRUE); m_chkSlab.EnableWindow(TRUE); m_chkColumn.EnableWindow(TRUE); } m_chkEnvelopeLW.EnableWindow(bMerge); m_chkEnvelopeLT.EnableWindow(bMerge); m_chkEnvelopeLY.EnableWindow(bMerge); m_chkEnvelopeCL.EnableWindow(bMerge); m_edtEnvelopeLW.EnableWindow(!bMerge ? FALSE : m_bSetLWEnvelope); m_cmbEnvelopeLT.EnableWindow(!bMerge ? FALSE : m_bSetLTEnvelope); m_cmbEnvelopeLY.EnableWindow(!bMerge ? FALSE : m_bSetLYEnvelope); m_btnEnvelopeCL.EnableWindow(!bMerge ? FALSE : m_bSetCLEnvelope); } void HlrCutOptionDlg::OnBnClickedEnvelopeColor() { if (acedSetColorDialog(m_nCLEnvelope, Adesk::kTrue, 0) != Adesk::kTrue) return; m_btnEnvelopeCL.RedrawWindow(); } HBRUSH HlrCutOptionDlg::OnCtlColor(CDC *pDC, CWnd *pWnd, UINT nCtlColor) { HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor); if (nCtlColor == CTLCOLOR_BTN) { if (pWnd != NULL && pWnd->GetDlgCtrlID() == IDC_BTN_ENVE_COLOR) { CRect rc; pWnd->GetClientRect(rc); pDC->FillSolidRect(rc, acedGetRGB(m_nCLEnvelope)); } } return hbr; } void HlrCutOptionDlg::OnComboBoxSelChangeLayer() { int idx = m_cmbEnvelopeLY.GetCurSel(); if (idx == -1) return; Adesk::IntDbId dbid = m_cmbEnvelopeLY.GetItemData(idx); m_nLYEnvelope.setFromOldId(dbid); } void HlrCutOptionDlg::OnComboBoxSelChangeLinetype() { int idx = m_cmbEnvelopeLT.GetCurSel(); if (idx == -1) return; Adesk::IntDbId dbid = m_cmbEnvelopeLT.GetItemData(idx); m_nLTEnvelope.setFromOldId(dbid); } void HlrCutOptionDlg::hlrOption() { CAcModuleResourceOverride myResources; HlrCutOptionDlg dlg; dlg.DoModal(); } #pragma endregion