Files
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

301 lines
7.7 KiB
C++

#include "stdafx.h"
#include <set>
#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<CString> 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<double> 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<AecDbDimScaleZone> 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<AcDbObjectPointer<AecDbDimScaleZone>> dszs;
for (int i(0); i < lLen; ++i)
{
acedSSName(ss, i, ent);
if (acdbGetObjectId(id, ent) != Acad::eOk) continue;
AcDbObjectPointer<AecDbDimScaleZone> 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<AecDbDimScaleZone> 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<AecDbDimScaleZone*, COMPARE_ZONE_AREA> 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<AecDbDimScaleZone*, COMPARE_ZONE_AREA>::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;
}