#include "stdafx.h" #include #include "DimScaleZoneDlg.h" #include "coretools.h" #include "AecDbDimScaleZone.h" #include "KTModelLayoutXData.h" namespace { struct COMPARE_ZONE_AREA { bool operator () (const AecDbDimScaleZone *p1, const AecDbDimScaleZone *p2) const { return p1->GetArea() < p2->GetArea(); } }; } IMPLEMENT_DYNAMIC(CDimScaleZoneDlg, CDialog) CDimScaleZoneDlg::CDimScaleZoneDlg(CWnd* pParent ) : CDialog(IDD_DIM_SCALE_ZONE_DLG, pParent) , m_iNumerator(1) , m_iDenominator(100) , m_iDrawUnits(0) , m_iDimUnits(0) { struct resbuf rb; acedGetVar(_T("INSUNITS"), &rb); m_iDrawUnits = getIdxByUnits((AcDb::UnitsValue)rb.resval.rint); m_iDimUnits = m_iDrawUnits; AecDbObjXDataMap xDataMap; CString scale(_T("1:100")); xDataMap.SetAt(DOC_SCALE, scale); //出图比例 if (KTModelLayoutXData::ReadModelXData(KT_PIPEINIT, xDataMap) && xDataMap.GetAt(DOC_SCALE, scale)) { std::vector ss; CoreTools::SplitString(scale, _T(':'), ss); if (ss.size() == 2) { m_iNumerator = _ttoi(ss[0]); m_iDenominator = _ttoi(ss[1]); } } } CDimScaleZoneDlg::CDimScaleZoneDlg(const int &numerator , const int &denominator , const AcDb::UnitsValue &drawUnits , const AcDb::UnitsValue &dimUnits , CWnd *pParent) : CDialog(IDD_DIM_SCALE_ZONE_DLG, pParent) , m_iNumerator(numerator) , m_iDenominator(denominator) { m_iDrawUnits = getIdxByUnits(drawUnits); m_iDimUnits = getIdxByUnits(dimUnits); } CDimScaleZoneDlg::~CDimScaleZoneDlg() { } void CDimScaleZoneDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); DDX_Text(pDX, IDC_EDT_MOLECULAR, m_iNumerator); DDV_MinMaxInt(pDX, m_iNumerator, 1, INT_MAX); DDX_Text(pDX, IDC_EDT_DENOMINATOR, m_iDenominator); DDV_MinMaxInt(pDX, m_iDenominator, 1, INT_MAX); DDX_CBIndex(pDX, IDC_CMB_DRAW, m_iDrawUnits); DDX_CBIndex(pDX, IDC_CMB_DIM, m_iDimUnits); } BOOL CDimScaleZoneDlg::OnInitDialog() { CDialog::OnInitDialog(); UpdateData(FALSE); return TRUE; } BEGIN_MESSAGE_MAP(CDimScaleZoneDlg, CDialog) ON_BN_CLICKED(IDOK, &CDimScaleZoneDlg::OnBnClickedOk) END_MESSAGE_MAP() AcDb::UnitsValue CDimScaleZoneDlg::getUnitsByIdx(const int &idx) { // 毫米; 米; 厘米; 分米; 公里; 英寸; 英尺; 码; 英里; switch (idx) { case 0: return AcDb::kUnitsMillimeters; case 1: return AcDb::kUnitsMeters; case 2: return AcDb::kUnitsCentimeters; case 3: return AcDb::kUnitsDecimeters; case 4: return AcDb::kUnitsKilometers; case 5: return AcDb::kUnitsInches; case 6: return AcDb::kUnitsFeet; case 7: return AcDb::kUnitsYards; case 8: return AcDb::kUnitsMiles; default: break; } return AcDb::kUnitsUndefined; } int CDimScaleZoneDlg::getIdxByUnits(const AcDb::UnitsValue &un) { switch (un) { case AcDb::kUnitsMillimeters: return 0; case AcDb::kUnitsMeters: return 1; case AcDb::kUnitsCentimeters: return 2; case AcDb::kUnitsDecimeters: return 3; case AcDb::kUnitsKilometers: return 4; case AcDb::kUnitsInches: return 5; case AcDb::kUnitsFeet: return 6; case AcDb::kUnitsYards: return 7; case AcDb::kUnitsMiles: return 8; default: break; } return 0; } void CDimScaleZoneDlg::OnBnClickedOk() { if (!UpdateData(TRUE)) return; CDialog::OnOK(); } int CDimScaleZoneDlg::getNumerator() { return m_iNumerator; } int CDimScaleZoneDlg::getDenominator() { return m_iDenominator; } AcDb::UnitsValue CDimScaleZoneDlg::getDrawUnits() { return getUnitsByIdx(m_iDrawUnits); } AcDb::UnitsValue CDimScaleZoneDlg::getDimUnits() { return getUnitsByIdx(m_iDimUnits); } //////////////////////////////////////////////////////////////////////////////////// void CDimScaleZoneDlg::start() { ads_point adsPtFirst; if (acedGetPoint(NULL, _T("\n选择比例范围的第一个点:"), adsPtFirst) != RTNORM) return; XDimScaleZoneJig jig; jig.m_ptTL = asPnt3d(adsPtFirst); CoreTools::UCS2WCS(jig.m_ptTL, jig.m_ptTL); AcEdJig::DragStatus stat = jig.DoIt(); if (stat != AcEdJig::kNormal) return; CAcModuleResourceOverride myResources; CDimScaleZoneDlg dlg; if (dlg.DoModal() != IDOK) return; AcGePoint3d ptTL(jig.m_ptTL) , ptTR(jig.m_ptTR) , ptBL(jig.m_ptBL) , ptBR(jig.m_ptBR); CoreTools::WCS2UCS(ptTL, ptTL); CoreTools::WCS2UCS(ptTR, ptTR); CoreTools::WCS2UCS(ptBL, ptBL); CoreTools::WCS2UCS(ptBR, ptBR); // 在 UCS下重新排列四个点,按照从左到右,从上到下顺序 std::set xset, yset; xset.insert(ptTL.x); xset.insert(ptTR.x); xset.insert(ptBL.x); xset.insert(ptBR.x); yset.insert(ptTL.y); yset.insert(ptTR.y); yset.insert(ptBL.y); yset.insert(ptBR.y); double xBig(*xset.rbegin()), xSml(*xset.begin()); double yBig(*yset.rbegin()), ySml(*yset.begin()); ptTL.x = xSml; ptTL.y = yBig; ptTR.x = xBig; ptTR.y = yBig; ptBL.x = xSml; ptBL.y = ySml; ptBR.x = xBig; ptBR.y = ySml; CoreTools::UCS2WCS(ptTL, ptTL); CoreTools::UCS2WCS(ptBL, ptBL); CoreTools::UCS2WCS(ptBR, ptBR); CoreTools::UCS2WCS(ptTR, ptTR); AecDbDimScaleZone *pZon(new AecDbDimScaleZone); pZon->SetTopLeftPoint(ptTL); pZon->SetTopRightPoint(ptTR); pZon->SetBottomLeftPoint(ptBL); pZon->SetBottomRightPoint(ptBR); pZon->SetNumerator(dlg.getNumerator()); pZon->SetDenominator(dlg.getDenominator()); pZon->SetDrawUnits(dlg.getDrawUnits()); pZon->SetDimUnits(dlg.getDimUnits()); CoreTools::AddToModelSpace(pZon); } void CDimScaleZoneDlg::dbl() { extern bool GetDoubleClickEnt(LPCTSTR pszCmd, AcDbObjectId& id); AcDbObjectId id; bool bIsOk = GetDoubleClickEnt(_T("DBL_AEC_DIMSCALEZONE"), id); if (!bIsOk || !id.isValid()) return; AcDbObjectPointer ent(id, AcDb::kForWrite); if (ent.openStatus() != Acad::eOk) return; CAcModuleResourceOverride myResources; CDimScaleZoneDlg dlg(ent->GetNumerator() , ent->GetDenominator() , (AcDb::UnitsValue)ent->GetDrawUnits() , (AcDb::UnitsValue)ent->GetDimUnits()); if (dlg.DoModal() != IDOK) return; ent->SetNumerator(dlg.getNumerator()); ent->SetDenominator(dlg.getDenominator()); ent->SetDrawUnits(dlg.getDrawUnits()); ent->SetDimUnits(dlg.getDimUnits()); } bool CDimScaleZoneDlg::hitTest(const AcGePoint3d &pt , double &dScale , AcDb::UnitsValue &drawUnits , AcDb::UnitsValue &dimUnits) { struct resbuf *pRb = acutBuildList(RTDXF0, _T("AEC_DIMSCALEZONE"), 0); ads_name ss, ent; acedSSGet(_T("A"), NULL, NULL, pRb, ss); Adesk::Int32 lLen = 0; acedSSLength(ss, &lLen); AcDbObjectId id; AcDbObjectIdArray arIds; std::set> dszs; for (int i(0); i < lLen; ++i) { acedSSName(ss, i, ent); if (acdbGetObjectId(id, ent) != Acad::eOk) continue; AcDbObjectPointer dsz(id, AcDb::kForRead); if (dsz.openStatus() != Acad::eOk) continue; if (dsz->PointInZone(pt)) arIds.append(id); } acedSSFree(ss); acutRelRb(pRb); if (arIds.isEmpty()) return false; if (arIds.length() == 1) { AcDbObjectPointer dsz(arIds.first(), AcDb::kForRead); if (dsz.openStatus() != Acad::eOk) return false; dScale = dsz->GetScale(); drawUnits = (AcDb::UnitsValue)dsz->GetDrawUnits(); dimUnits = (AcDb::UnitsValue)dsz->GetDimUnits(); return true; } // 分析多个情况 std::set zones; AcDbEntity *pEnt(NULL); // 按照面积排序 for (int i(0); i < arIds.length(); ++i) { if (acdbOpenAcDbEntity(pEnt, arIds[i], AcDb::kForRead) != Acad::eOk) continue; zones.insert((AecDbDimScaleZone*)pEnt); } // 如果面积最小的区域不在第二小的区域里,则存在区域交叉,不能判断 std::set::const_iterator it(zones.begin()) , it1(zones.begin()), it2; it2 = ++it; bool bRel = (*it2)->RectInZone(**it1); if (bRel) { dScale = (*it1)->GetScale(); drawUnits = (AcDb::UnitsValue)(*it1)->GetDrawUnits(); dimUnits = (AcDb::UnitsValue)(*it1)->GetDimUnits(); } for (it = zones.begin(); it != zones.end(); ++it) (*it)->close(); return bRel; }