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

511 lines
13 KiB
C++

#include "stdafx.h"
#include "AcGiViewDraw.h"
#include "AecDbDimScaleZone.h"
#include "MFCDbDwgFiler.h"
#include "CoreTools.h"
#include "compare_double.h"
IMP_XDATA_KEY(AecDbDimScaleZone, _ptTL_);
IMP_XDATA_KEY(AecDbDimScaleZone, _ptTR_);
IMP_XDATA_KEY(AecDbDimScaleZone, _ptBR_);
IMP_XDATA_KEY(AecDbDimScaleZone, _ptBL_);
IMP_XDATA_KEY(AecDbDimScaleZone, _Denominator_);
IMP_XDATA_KEY(AecDbDimScaleZone, _Numerator_);
IMP_XDATA_KEY(AecDbDimScaleZone, _drawunits_);
IMP_XDATA_KEY(AecDbDimScaleZone, _dimunits_);
namespace
{
CString Units2String(const AcDb::UnitsValue &un)
{
switch (un)
{
case AcDb::kUnitsMillimeters: return _T("毫米");
case AcDb::kUnitsMeters: return _T("米");
case AcDb::kUnitsCentimeters: return _T("厘米");
case AcDb::kUnitsDecimeters: return _T("分米");
case AcDb::kUnitsKilometers: return _T("千米");
case AcDb::kUnitsInches: return _T("英寸");
case AcDb::kUnitsFeet: return _T("英尺");
case AcDb::kUnitsYards: return _T("码");
case AcDb::kUnitsMiles: return _T("英里");
default: break;
}
return _T("未知单位");
}
}
ACRX_DXF_DEFINE_MEMBERS(AecDbDimScaleZone, AecDbEntityBase,
AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning,
AEC_DIMSCALEZONE,
"AecXDbCamera"
"|Product Desc: shanghua earthworm app obj"
"|Company: shanghua inc"
"|WEB Address: www.shanghuasoft.com")
// kCurrentVersionNumber->2 --- 增加 m_arSelectionSet
Adesk::UInt32 AecDbDimScaleZone::kCurrentVersionNumber = 1;
AecDbDimScaleZone::AecDbDimScaleZone(void) { }
AecDbDimScaleZone::~AecDbDimScaleZone(void) { }
Acad::ErrorStatus AecDbDimScaleZone::subErase(Adesk::Boolean erasing)
{
return AecDbEntityBase::subErase(erasing);
}
Acad::ErrorStatus AecDbDimScaleZone::copyFrom(const AcRxObject *pSrc)
{
AssertWriteEnabled();
AecDbDimScaleZone *pScale = AecDbDimScaleZone::cast(pSrc);
if (pScale != NULL)
{
m_mapSpecXData.CopyFrom(pScale->GetSpecialtyData(AcDb::kForRead));
}
return Acad::eOk;
}
void AecDbDimScaleZone::subList() const
{
assertReadEnabled();
}
Acad::ErrorStatus AecDbDimScaleZone::subTransformBy(const AcGeMatrix3d &xform)
{
AssertWriteEnabled();
SetTopLeftPoint(GetTopLeftPoint().transformBy(xform));
SetTopRightPoint(GetTopRightPoint().transformBy(xform));
SetBottomRightPoint(GetBottomRightPoint().transformBy(xform));
SetBottomLeftPoint(GetBottomLeftPoint().transformBy(xform));
return Acad::eOk;
}
Acad::ErrorStatus AecDbDimScaleZone::subGetGripPoints(AcGePoint3dArray &gripPoints
, AcDbIntArray &osnapModes
, AcDbIntArray &geomIds) const
{
gripPoints.append(GetBottomLeftPoint());
gripPoints.append(CoreTools::MidPt(GetBottomRightPoint(), GetBottomLeftPoint()));
gripPoints.append(CoreTools::MidPt(GetBottomRightPoint(), GetTopRightPoint()));
gripPoints.append(CoreTools::MidPt(GetTopRightPoint(), GetTopLeftPoint()));
gripPoints.append(CoreTools::MidPt(GetTopLeftPoint(), GetBottomLeftPoint()));
return Acad::ErrorStatus();
}
Acad::ErrorStatus AecDbDimScaleZone::subGetGripPoints(AcDbGripDataPtrArray &grips,
const double curViewUnitSize,
const int gripSize,
const AcGeVector3d &curViewDir,
const int bitflags) const
{
return Acad::eNotImplementedYet;
}
Acad::ErrorStatus AecDbDimScaleZone::subGetOsnapPoints(AcDb::OsnapMode osnapMode
, INT_PTR gsSelectionMark
, const AcGePoint3d &pickPoint
, const AcGePoint3d &lastPoint
, const AcGeMatrix3d &viewXform
, AcGePoint3dArray &snapPoints
, AcDbIntArray &geomIds) const
{
snapPoints.append(GetBottomRightPoint());
snapPoints.append(GetBottomLeftPoint());
snapPoints.append(GetTopRightPoint());
snapPoints.append(GetTopLeftPoint());
return Acad::eOk;
}
Acad::ErrorStatus AecDbDimScaleZone::subMoveGripPointsAt(const AcDbIntArray &indices
, const AcGeVector3d &offset)
{
if (indices.isEmpty()) return Acad::eOk;
AssertWriteEnabled();
AcGeLineSeg3d seg;
AcGeMatrix3d mat;
AcGePoint3d ptDrag, ptIn;
AcGeVector3d vt;
// ptBR 逆时针
switch (indices[0])
{
case 0:
{
mat.setToTranslation(offset);
subTransformBy(mat);
return Acad::eOk;
}
case 1:
{
seg.set(GetBottomRightPoint(), GetBottomLeftPoint());
ptDrag = seg.midPoint() + offset;
ptIn = seg.closestPointTo(ptDrag);
if (COMPARE_DOUBLE::equal_zero(ptIn.distanceTo(ptDrag))) return Acad::eOk;
vt = ptDrag - ptIn;
SetBottomRightPoint(GetBottomRightPoint() + vt);
SetBottomLeftPoint(GetBottomLeftPoint() + vt);
break;
}
case 2:
{
seg.set(GetBottomRightPoint(), GetTopRightPoint());
ptDrag = seg.midPoint() + offset;
ptIn = seg.closestPointTo(ptDrag);
if (COMPARE_DOUBLE::equal_zero(ptIn.distanceTo(ptDrag))) return Acad::eOk;
vt = ptDrag - ptIn;
SetBottomRightPoint(GetBottomRightPoint() + vt);
SetTopRightPoint(GetTopRightPoint() + vt);
break;
}
case 3:
{
seg.set(GetTopRightPoint(), GetTopLeftPoint());
ptDrag = seg.midPoint() + offset;
ptIn = seg.closestPointTo(ptDrag);
if (COMPARE_DOUBLE::equal_zero(ptIn.distanceTo(ptDrag))) return Acad::eOk;
vt = ptDrag - ptIn;
SetTopRightPoint(GetTopRightPoint() + vt);
SetTopLeftPoint(GetTopLeftPoint() + vt);
break;
}
case 4:
{
seg.set(GetTopLeftPoint(), GetBottomLeftPoint());
ptDrag = seg.midPoint() + offset;
ptIn = seg.closestPointTo(ptDrag);
if (COMPARE_DOUBLE::equal_zero(ptIn.distanceTo(ptDrag))) return Acad::eOk;
vt = ptDrag - ptIn;
SetTopLeftPoint(GetTopLeftPoint() + vt);
SetBottomLeftPoint(GetBottomLeftPoint() + vt);
break;
}
default:
return Acad::eOk;
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbDimScaleZone::dwgInFields(AcDbDwgFiler *pFiler)
{
AssertWriteEnabled();
//----- Read parent class information first.
Acad::ErrorStatus es = Acad::eOk;
if (!pFiler->isKindOf(CMFCDbDwgFiler::desc()))
{
es = AecDbEntityBase::dwgInFields(pFiler);
if (es != Acad::eOk)
return (es);
}
//----- Object version number needs to be read first
Adesk::UInt32 version = 0;
if ((es = pFiler->readUInt32(&version)) != Acad::eOk)
return (es);
if (version > AecDbDimScaleZone::kCurrentVersionNumber)
return (Acad::eMakeMeProxy);
m_mapSpecXData.dwgInFields(pFiler);
return (pFiler->filerStatus());
}
Acad::ErrorStatus AecDbDimScaleZone::dwgOutFields(AcDbDwgFiler *pFiler) const
{
assertReadEnabled();
//----- Save parent class information first.
Acad::ErrorStatus es = Acad::eOk;
if (!pFiler->isKindOf(CMFCDbDwgFiler::desc()))
{
es = AecDbEntityBase::dwgOutFields(pFiler);
if (es != Acad::eOk)
return (es);
}
//----- Object version number needs to be saved first
if ((es = pFiler->writeUInt32(AecDbDimScaleZone::kCurrentVersionNumber)) != Acad::eOk)
return (es);
m_mapSpecXData.dwgOutFields(pFiler);
return (pFiler->filerStatus());
}
Acad::ErrorStatus AecDbDimScaleZone::Draw2d(AcGiDraw &dc) const
{
assertReadEnabled();
Adesk::UInt16 oldClr = dc.GetColor();
dc.SetColor(3);
AcGePoint3d ptTL(GetTopLeftPoint())
, ptTR(GetTopRightPoint())
, ptBL(GetBottomLeftPoint())
, ptBR(GetBottomRightPoint());
dc.DrawLine(AcGeLineSeg3d(ptTL, ptTR));
dc.DrawLine(AcGeLineSeg3d(ptTR, ptBR));
dc.DrawLine(AcGeLineSeg3d(ptBR, ptBL));
dc.DrawLine(AcGeLineSeg3d(ptBL, ptTL));
int numerator(GetNumerator()), denominator(GetDenominator());
// 把标高绘制出来
CString sTop;
sTop.Format(_T("出图比例:%d / %d,绘图单位:%s,标注单位:%s")
, numerator
, denominator
, Units2String((AcDb::UnitsValue)GetDrawUnits())
, Units2String((AcDb::UnitsValue)GetDimUnits()));
AcGeVector3d vtY(ptTL - ptBL), vtX(ptBR - ptBL);
vtY.normalize();
vtX.normalize();
double dH(ptBL.distanceTo(ptTL) * .025);
AcGePoint3d ptIns(CoreTools::MidPt(ptBL, ptBR) - vtY * dH * 1.5);
AcDbText txt1;
txt1.setTextString(sTop);
txt1.setPosition(ptIns);
txt1.setHeight(dH);
AcDbExtents ext;
txt1.getGeomExtents(ext);
double dW(ext.maxPoint().x - ext.minPoint().x);
ptIns -= vtX * (dW * .5);
txt1.setPosition(ptIns);
double dAng = AcGeVector3d::kXAxis.angleTo(vtX, AcGeVector3d::kZAxis);
txt1.setRotation(dAng);
dc.DrawEntity(txt1);
dc.SetColor(oldClr);
return Acad::eOk;
}
Acad::ErrorStatus AecDbDimScaleZone::Draw3d(AcGiDraw &dc) const
{
return Draw2d(dc);
}
AecDbObjXDataMap *AecDbDimScaleZone::GetSpecialtyData(AcDb::OpenMode bMode)
{
if (bMode == AcDb::kForWrite)
AssertWriteEnabled();
else
assertReadEnabled();
return &m_mapSpecXData;
}
const AecDbObjXDataMap *AecDbDimScaleZone::GetSpecialtyData() const
{
assertReadEnabled();
return &m_mapSpecXData;
}
double AecDbDimScaleZone::GetScale() const
{
return (double)GetNumerator() / GetDenominator();
}
bool AecDbDimScaleZone::PointInZone(const AcGePoint3d &pt) const
{
AcGePoint3d ptTL(GetTopLeftPoint())
, ptBR(GetBottomRightPoint());
if (pt.x < ptBR.x
&& pt.x > ptTL.x
&& pt.y < ptTL.y
&& pt.y > ptBR.y)
return true;
return false;
}
bool AecDbDimScaleZone::RectInZone(const AecDbDimScaleZone &zone) const
{
return RectInZone(zone.GetTopLeftPoint()
, zone.GetTopRightPoint()
, zone.GetBottomLeftPoint()
, zone.GetBottomRightPoint());
}
bool AecDbDimScaleZone::RectInZone(const AcGePoint3d &ptTL
, const AcGePoint3d &ptTR
, const AcGePoint3d &ptBL
, const AcGePoint3d &ptBR) const
{
if (PointInZone(ptTL)
&& PointInZone(ptTR)
&& PointInZone(ptBL)
&& PointInZone(ptBR))
return true;
return false;
}
bool AecDbDimScaleZone::SameScope(const AecDbDimScaleZone &zone) const
{
return SameScope(zone.GetTopLeftPoint()
, zone.GetTopRightPoint()
, zone.GetBottomLeftPoint()
, zone.GetBottomRightPoint());
}
#define SAME_PT(pt1, pt2, prec) (abs(pt1.x - pt2.x) < prec && abs(pt1.y - pt2.y) < prec && abs(pt1.z - pt2.z) < prec)
bool AecDbDimScaleZone::SameScope(const AcGePoint3d &ptTL
, const AcGePoint3d &ptTR
, const AcGePoint3d &ptBL
, const AcGePoint3d &ptBR) const
{
if (SAME_PT(ptTL, GetTopLeftPoint(), .001)
&& SAME_PT(ptTL, GetTopRightPoint(), .001)
&& SAME_PT(ptTL, GetBottomLeftPoint(), .001)
&& SAME_PT(ptTL, GetBottomRightPoint(), .001))
return true;
return false;
}
double AecDbDimScaleZone::GetArea() const
{
return (GetTopLeftPoint().distanceTo(GetTopRightPoint())
* GetTopLeftPoint().distanceTo(GetBottomLeftPoint()));
}
#define CONVERT_TO_M(d, oper) (d) /= m_to_##oper
#define CONVERT_FROM_M(d, oper) (d) *= m_to_##oper
double AecDbDimScaleZone::ConvertLengthUnits(const double &d
, const AcDb::UnitsValue &from
, const AcDb::UnitsValue &to)
{
static const double m_to_inch = 39.3701;
static const double m_to_foot = 3.28084;
static const double m_to_yard = 1.09361;
static const double m_to_mile = 0.000621371;
static const double m_to_mm = 1000.;
static const double m_to_cm = 100.;
static const double m_to_dm = 10.;
static const double m_to_m = 1.;
static const double m_to_km = .001;
// 单位相同
if (from == to) return d;
// 不管from是什么,都先转到m
double dM(d);
switch (from)
{
case AcDb::kUnitsMillimeters: CONVERT_TO_M(dM, mm); break;
case AcDb::kUnitsCentimeters: CONVERT_TO_M(dM, cm); break;
case AcDb::kUnitsDecimeters: CONVERT_TO_M(dM, dm); break;
case AcDb::kUnitsMeters: CONVERT_TO_M(dM, m); break;
case AcDb::kUnitsKilometers: CONVERT_TO_M(dM, km); break;
case AcDb::kUnitsInches: CONVERT_TO_M(dM, inch); break;
case AcDb::kUnitsFeet: CONVERT_TO_M(dM, foot); break;
case AcDb::kUnitsYards: CONVERT_TO_M(dM, yard); break;
case AcDb::kUnitsMiles: CONVERT_TO_M(dM, mile); break;
default:break;
}
switch (to)
{
case AcDb::kUnitsMillimeters: CONVERT_FROM_M(dM, mm); break;
case AcDb::kUnitsCentimeters: CONVERT_FROM_M(dM, cm); break;
case AcDb::kUnitsDecimeters: CONVERT_FROM_M(dM, dm); break;
case AcDb::kUnitsMeters: CONVERT_FROM_M(dM, m); break;
case AcDb::kUnitsKilometers: CONVERT_FROM_M(dM, km); break;
case AcDb::kUnitsInches: CONVERT_FROM_M(dM, inch); break;
case AcDb::kUnitsFeet: CONVERT_FROM_M(dM, foot); break;
case AcDb::kUnitsYards: CONVERT_FROM_M(dM, yard); break;
case AcDb::kUnitsMiles: CONVERT_FROM_M(dM, mile); break;
default:break;
}
return dM;
}
/////////////////////////////////////////////////////////
#pragma region XDimScaleZoneJig
XDimScaleZoneJig::XDimScaleZoneJig(void): m_pPolyline(NULL)
{
m_pPolyline = new AcDbPolyline;
}
XDimScaleZoneJig::~XDimScaleZoneJig(void)
{
DELETE_PTR(m_pPolyline);
}
AcEdJig::DragStatus XDimScaleZoneJig::DoIt()
{
AcEdJig::DragStatus eStat;
setDispPrompt(_T("\n指定比例范围第二点:"));
return drag();
}
AcEdJig::DragStatus XDimScaleZoneJig::sampler()
{
setUserInputControls((UserInputControls)(AcEdJig::kAccept3dCoordinates
| AcEdJig::kNullResponseAccepted));
AcEdJig::DragStatus eStat;
eStat = acquirePoint(m_ptBR, m_ptTL);
if (eStat == AcEdJig::kNormal)
{
if (m_ptBR == m_ptTL)
return AcEdJig::kNoChange;
CoreTools::WCS2UCS(m_ptTL, m_ptTL);
CoreTools::WCS2UCS(m_ptBR, m_ptBR);
double deltaY(abs(m_ptTL.y - m_ptBR.y)), deltaX(abs(m_ptBR.x - m_ptTL.x));
m_ptBL = m_ptTL;
m_ptBL.y = m_ptBR.y;
m_ptTR = m_ptTL;
m_ptTR.x = m_ptBR.x;
CoreTools::UCS2WCS(m_ptTL, m_ptTL);
CoreTools::UCS2WCS(m_ptBR, m_ptBR);
CoreTools::UCS2WCS(m_ptBL, m_ptBL);
CoreTools::UCS2WCS(m_ptTR, m_ptTR);
}
return eStat;
}
AcDbEntity *XDimScaleZoneJig::entity() const
{
return m_pPolyline;
}
Adesk::Boolean XDimScaleZoneJig::update()
{
m_pPolyline->reset(false, 0);
double dw = CoreTools::PixelToWcs(10);
m_pPolyline->addVertexAt(0, m_ptTL.convert2d(AcGePlane::kXYPlane), .0, dw, dw);
m_pPolyline->addVertexAt(1, m_ptTR.convert2d(AcGePlane::kXYPlane), .0, dw, dw);
m_pPolyline->addVertexAt(2, m_ptBR.convert2d(AcGePlane::kXYPlane), .0, dw, dw);
m_pPolyline->addVertexAt(3, m_ptBL.convert2d(AcGePlane::kXYPlane), .0, dw, dw);
m_pPolyline->addVertexAt(4, m_ptTL.convert2d(AcGePlane::kXYPlane), .0, dw, dw);
return Adesk::kTrue;
}
#pragma endregion