Files
envi-code/SourceCode/Code2026/tg_shs/shs_kernal/dbDimension.cpp
T
2026-09-28 15:28:50 +08:00

8134 lines
228 KiB
C++
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
extern AcDbObjectId DimStyleAcad2Tch(AcDbObjectId idAcad, double &nScale);
extern AcDbObjectId DimStyleTch2Acad(AcDbObjectId idTch, double nScale, BOOL bAngular, AcDbDatabase *pDb, double dTxtHeight);
//extern BOOL g_bMakeBlock;
extern XPoint GetTextExtend(AcDbObjectId idTextStyle, const TCHAR *pszText, double nHeight, BOOL penups);
//extern XString GetSymbolName(AcDbObjectId idSymbolRec);
//extern double g_nAcadVer;
static BOOL g_bDisableQuickMode=FALSE;
// 不能重载cloneMeForDragging
//问题:由于不断的读取dimstyle导致显示速度很慢
int TDimTextPos::CompareByIndexForFind(const TDimTextPos * p1, const void *p2)
{
int idx=*(const int *)p2;
return (p1->nIndex!=idx);
}
int TDimTextContent::CompareByIndexForFind(const TDimTextContent * p1, const void *p2)
{
int idx=*(const int *)p2;
return (p1->nIndex!=idx);
}
/////////////////////////////////////////////////////////////
// 尺寸对象类
/////////////////////////////////////////////////////////////
const Adesk::UInt8 TDbDimension::g_nVersion = 3;
ACRX_DXF_DEFINE_MEMBERS(ATSDimension, ATSEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_DIMENSION, "ATS_DIMENSION图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbDimension);
//BOOL TDbDimension::g_bExplAcadDim=TRUE;
TDbDimension::TDbDimension()
{
m_nRotation=0; //旋转角度
m_nDist2DimLine=0; //定位点到尺寸线的距离, 可以为负值
m_nDimRadius=0; //夹角,可以为负
m_nObjRadius=0;
}
TDbDimension::~TDbDimension()
{
}
BOOL TDbDimension::IsValid() const
{
BOOL bRet=TDbEntity::IsValid();
if(!bRet)
return bRet;
bRet=m_lstSegment.Length()>=1;
return bRet;
}
BOOL TDbDimension::IsValidSegment(double nVal, BOOL bDist) const
{
double nPrec=IsAngular()? _angSnap : _DIST_SNAP;
if(IsAngular() && bDist) {
ASSERT(m_nDimRadius>_DIST_SNAP);
nVal = nVal/m_nDimRadius;
}
return (nVal>nPrec);
}
void TDbDimension::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
double nOldScale=GetPScale();
double nDimDist=GetDist2DimLine(FALSE);
TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbDimension *pSrc=TDbDimension::cast(pSrcEntity);
if(pSrc) {
if(database()==NULL||
pSrcEntity->database()==NULL||
database()==pSrcEntity->database())//add by whl on 060317
{
m_idDimStyle=pSrc->m_idDimStyle; //尺寸标注类型
}
UseDimStyleScale(pSrc->IsUseDimStyleScale());
}
double nNewScale=GetPScale();
if(fabs(nNewScale-nOldScale)>1.0E-3 && IsAngular()) {
SetDist2DimLine(nDimDist, FALSE);
}
}
// 从DWG读入数据:
Acad::ErrorStatus TDbDimension::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbEntity::dwgInFields(pFiler);
if(es != Acad::eOk) return es;
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
if(nVer>g_nVersion) {// Version is too new
return Acad::eMakeMeProxy;
}
pFiler->readItem((AcGePoint3d *)&m_ptLocation); //定位点--即不动点
m_ptLocation.z=0; //必须是二维
pFiler->readItem(&m_nRotation); //旋转角度
pFiler->readItem(&m_nDist2DimLine); //定位点到尺寸线的距离, 可以为负值
if(nVer<2)
pFiler->readItem(&m_nDimRadius); //夹角,可以为负
pFiler->readItem(&m_idDimStyle); //尺寸标注类型
m_lstSegment.Reset();
Adesk::UInt16 nSeg=0;
pFiler->readItem(&nSeg);
for(Adesk::UInt16 i=0; i<nSeg; i++) {
double nVal=0;
pFiler->readItem(&nVal);
m_lstSegment.Append(new double(nVal));
}
if(nVer>1) {
pFiler->readItem(&m_nDimFlag);
} else m_nDimFlag=0;
m_lstTextPos.Reset();
if(nVer==1 || (m_nDimFlag&DF_POSITION)) {
m_lstTextPos.Reset();
Adesk::UInt16 nTextSeg=0;
pFiler->readItem(&nTextSeg);
for(i=0; i<nTextSeg; i++) {
AcGePoint2d ptPos;
Adesk::UInt16 nIndex;
pFiler->readItem(&nIndex);
pFiler->readItem(&ptPos);
m_lstTextPos.Append(new TDimTextPos(nIndex, XPoint(ptPos[0], ptPos[1])));
}
}
m_lstTextContent.Reset();
if(nVer>1) {
if(m_nDimFlag&DF_TEXT) {
Adesk::UInt16 nTextSeg=0;
pFiler->readItem(&nTextSeg);
for(i=0; i<nTextSeg; i++) {
XString sText;
Adesk::UInt16 nIndex;
pFiler->readItem(&nIndex);
ReadString(pFiler, sText);
m_lstTextContent.Append(new TDimTextContent(nIndex, sText));
}
}
if(m_nDimFlag&DF_BIND)
pFiler->readItem(&m_idBind);
if(nVer>2 && IsAngular()) {
pFiler->readItem(&m_nDimRadius);
pFiler->readItem(&m_nObjRadius);
}
}
es=pFiler->filerStatus();
return es;
}
Acad::ErrorStatus TDbDimension::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem((const AcGePoint3d &)m_ptLocation); //定位点--即不动点
pFiler->writeItem(m_nRotation); //旋转角度
pFiler->writeItem(m_nDist2DimLine); //定位点到尺寸线的距离, 可以为负值
pFiler->writeItem(m_idDimStyle); //尺寸标注类型
Adesk::UInt16 nSeg=m_lstSegment.Length();
pFiler->writeItem(nSeg);
for(Adesk::UInt16 i=0; i<nSeg; i++) {
double nVal=m_lstSegment[i];
pFiler->writeItem(nVal);
}
pFiler->writeItem(m_nDimFlag);
if(m_nDimFlag&DF_POSITION) {
Adesk::UInt16 nTextSeg=m_lstTextPos.Length();
pFiler->writeItem(nTextSeg);
for(i=0; i<nTextSeg; i++) {
const TDimTextPos &pTextPos=m_lstTextPos[i];
pFiler->writeItem(pTextPos.nIndex);
pFiler->writeItem((const AcGePoint2d &)pTextPos.ptPos);
}
}
if(m_nDimFlag&DF_TEXT) {
Adesk::UInt16 nTextSeg=m_lstTextContent.Length();
pFiler->writeItem(nTextSeg);
for(i=0; i<nTextSeg; i++) {
const TDimTextContent &text=m_lstTextContent[i];
pFiler->writeItem(text.nIndex);
pFiler->writeString(text.sText);
}
}
if(IsBind()) {
pFiler->writeItem(m_idBind);
}
if(IsAngular()) {
pFiler->writeItem(m_nDimRadius); //夹角,可以为负
pFiler->writeItem(m_nObjRadius);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbDimension::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbEntity::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbDimension"))) {
return Acad::eBadDxfSequence;
}
return pFiler->filerStatus();
// 不读入任何数据
}
Acad::ErrorStatus TDbDimension::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es=TDbEntity::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbDimension"));
assert(es == Acad::eOk);
return es;
}
// -----------------------------------------------------------------------
Acad::ErrorStatus
TDbDimension::subGetOsnapPoints(AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
Acad::ErrorStatus es = Acad::eOk;
switch (osnapMode) {
case AcDb::kOsModeNode:
case AcDb::kOsModeIns: {
double nOffDist=m_nDist2DimLine*GetPScale();
XCurveSegment cv=GetDimCurve();
XCurveSegment cvFix=cv.Offset(nOffDist, LS_FINITE);
XPoly2D poly;
GetPolySegOnDimLine(poly);
if(osnapMode==AcDb::kOsModeNode) {
int nVertNum=poly.Length();
for(int i=0; i<nVertNum; i++) {
XPoint ptFix;
cvFix.ProjectToMe(*poly[i], ptFix);
snapPoints.append(*poly[i]);
snapPoints.append(ptFix);
}
} else {
int nSeg=poly.TotalSegments();
for(int i=0; i<nSeg; i++) {
XPoint ptText = GetTextPos(i);
snapPoints.append(ptText);
}
}
}
break;
default: {
//XPushMemVar<BOOL> vTemp(g_bExplAcadDim, FALSE);
TDbEntity::subGetOsnapPoints(osnapMode, gsSelectionMark, pickPoint,
lastPoint, viewXform, snapPoints,
geomIds);
}
return Acad::eOk;
}
return es;
}
// Overriden functions for edit
// to do:
// 允许通过夹点改变边界
Acad::ErrorStatus TDbDimension::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
double nOffDist=m_nDist2DimLine*GetPScale();
XCurveSegment cv=GetDimCurve();
XCurveSegment cvFix=cv.Offset(nOffDist, LS_FINITE);
XCurveSegment cvObj;
if(IsAngular()) {
double nDist2Obj=cv.GetArc().GetRadius()-m_nObjRadius;
cvObj=cv.Offset(-nDist2Obj, LS_FINITE);
}
XPoly2D poly;
GetPolySegOnDimLine(poly);
int nVertNum=poly.Length();
gripPoints.append(*poly.Head()); //0
gripPoints.append(*poly.Tail()); //1
for(int i=0; i<nVertNum; i++) {
XPoint ptFix;
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
cvObj.ProjectToMe(*poly[i], ptFix);
else cvFix.ProjectToMe(*poly[i], ptFix);
gripPoints.append(ptFix);
}
int nSeg=poly.TotalSegments();
for(i=0; i<nSeg; i++) {
XPoint ptText = GetTextPos(i);
gripPoints.append(ptText);
}
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
gripPoints.append(m_ptLocation);
return Acad::eOk;
}
// stretch points is diffrent from grep points, with no midpoint included
Acad::ErrorStatus TDbDimension::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
assertReadEnabled();
AcDbIntArray osnapModes;
AcDbIntArray geomIds;
return subGetGripPoints(stretchPoints, osnapModes, geomIds);
}
// Active when being rotated, scaled, moved, etc.
// Scale is disabled here
Acad::ErrorStatus TDbDimension::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
TDbEntity::subTransformBy(xform);
ads_matrix mat;
AsAdsMatrix(xform, mat);
for(int i=0; i<m_lstTextPos.Length(); i++) {
m_lstTextPos[i]->ptPos.TransformBy(mat);
}
if(IsAngular()) {
XCurveSegment cv=GetDimCurve();
cv.TransformBy(mat);
m_nRotation=cv.IDirection(0);
ads_polar(cv.StartPoint(), m_nRotation-PI/2, GetDist2DimLine(FALSE), m_ptLocation);
if(IsMirrorMatrix(mat)) {
m_lstTextPos.Reverse();
m_lstTextContent.Reverse();
m_lstSegment.Reverse();
}
} else {
m_ptLocation.TransformBy(mat);
m_ptLocation.z=0;
XVector3D vt(cos(m_nRotation), sin(m_nRotation));
((AcGeVector3d &)vt).transformBy(xform);
m_nRotation = ads_angle(XPoint(), vt);
if(IsMirrorMatrix(mat)) {
m_nDist2DimLine=-m_nDist2DimLine;
}
}
return Acad::eOk;
}
//设置尺寸线位置
BOOL TDbDimension::SetDimLinePos(XPoint pt)
{
assertWriteEnabled();
BOOL bRet=FALSE;
XCurveSegment seg=GetDimCurve();
XPoint ptOnSeg;
if(seg.ProjectToMe(pt, ptOnSeg)==RTNORM) {
double nDistMove=pt.Distance2d(ptOnSeg);
int nSideLoc=seg.OnWhichSide(GetLocation());
int nSide=seg.OnWhichSide(pt);
double nDist2Dim=GetDist2DimLine(FALSE);
if(fabs(nDist2Dim)>1.0E-6) {
double nFactor=nDist2Dim/fabs(nDist2Dim);
if(nSide!=nSideLoc)
nDistMove *= nFactor;
else
nDistMove *= -nFactor;
} else {
if(nSideLoc=OFFSET_LEFT) nDistMove=-nDistMove;
}
if(IsAngular()) {
nDist2Dim += nDistMove;
double nDistRad= GetDimRadius();
nDistRad -= nDistMove;
if(nDistRad>_DIST_SNAP) {
SetDimRadius(nDistRad);
SetDist2DimLine(nDist2Dim, FALSE);
}
} else {
nDist2Dim += nDistMove;
SetDist2DimLine(nDist2Dim, FALSE);
}
bRet=TRUE;
}
return bRet;
}
//设置标注固定线位置
BOOL TDbDimension::SetFixLinePos(XPoint pt)
{
assertWriteEnabled();
XCurveSegment seg=GetDimCurve();
double nOffDist=m_nDist2DimLine*GetPScale();
XCurveSegment cvFix=seg.Offset(nOffDist, LS_FINITE);
double nDist=cvFix.GetDist2Me(pt);
XCurveSegment cvNewFix=cvFix.Offset(nDist, LS_FINITE);
if(!cvNewFix)
return FALSE;
XPoint ptNew = cvNewFix.NearPoint(m_ptLocation);
m_nDist2DimLine = (nOffDist+nDist)/GetPScale();
m_ptLocation = ptNew;
return TRUE;
}
// 功能: 夹点操作, 还没有完全考虑圆弧类型
Acad::ErrorStatus TDbDimension::MoveGripPointsAt1(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
AcGePoint3dArray gripPoints;
AcDbIntArray ar;
subGetGripPoints(gripPoints, ar, ar);
AcGeVector3d vtLocal(offset[0], offset[1], 0.0);
for (int i = 0; i < indices.length(); i++) {
int idx = indices[i];
gripPoints[idx] += vtLocal;
}
int nVertNum=m_lstSegment.Length()+1;
XCurveSegment cv=GetDimCurve();
cv.SetPoints(XPoint(gripPoints[0]), XPoint(gripPoints[1]));
XPoint ptS, ptE;
XPoint ptS1=gripPoints[2], ptE1=gripPoints[2+nVertNum-1];
if(cv.ProjectToMe(ptS1, ptS)==RTNORM &&
cv.ProjectToMe(ptE1, ptE)==RTNORM)
cv.SetPoints(ptS, ptE);
if(cv.GetLength()<_DIST_SNAP)
return Acad::eInvalidInput;
XSortedVertexList lstVert(cv);
for(i=1; i<nVertNum-1; i++) {
XPoint ptFix=gripPoints[2+i];
XPoint ptOnDim;
if(cv.ProjectToMe(ptFix, ptOnDim)==RTNORM) {
lstVert.Insert(ptOnDim);
}
}
XPoly2D poly;
lstVert.AsPoly2D(poly);
m_lstSegment.Reset();
int nSeg=poly.TotalSegments();
for(i=0; i<nSeg; i++) {
XCurveSegment seg;
poly.Nth(i, seg);
double nVal=seg.GetLength();
if(IsValidSegment(nVal))
AppendSegment(nVal);
}
if(IsAngular() && (IsDimChord() || IsDimArcLen())) {
m_nObjRadius=cv.GetArc().GetCenterPt().Distance2d(gripPoints[2]);
// Location???
XLine ln(cv.StartPoint(), cv.IDirection(0)+PI/2);
XPoint ptNewLoc=m_ptLocation + XPoint(offset[0], offset[1]);
ptNewLoc.Project(&ln, m_ptLocation);
m_ptLocation.z=0;
} else SetLocation(gripPoints[2]);
SetRotation(cv.IDirection(0));
double nDist2DimLine=m_ptLocation.Distance2d(cv.StartPoint());
int nSide=cv.OnWhichSide(m_ptLocation);
SetDist2DimLine(nSide==OFFSET_RIGHT? nDist2DimLine : -nDist2DimLine, FALSE);
if(nSeg==nVertNum-1) { //区间数目没有变化
for(i=0; i<nSeg; i++) {
int nGripIndex=i+nVertNum+2;
if(indices.contains(nGripIndex) && m_lstTextPos.FindNode(&i, TDimTextPos::CompareByIndexForFind))
SetTextPos(i, gripPoints[nGripIndex]);
}
} else {
m_lstTextPos.Reset();
m_lstTextContent.Reset();
}
AutoSetFlag();
return Acad::eOk;
}
// 功能: 夹点操作
// Modify on 2002/8/8 解决调用getGripPoints效率很低
Acad::ErrorStatus TDbDimension::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
if(indices.length()>1)
return MoveGripPointsAt1(indices, offset);
assertWriteEnabled();
XPoint vtOffset=*(XPoint *)&offset;
vtOffset.z=0;
XPoly2D poly, polyNew;
GetPolySegOnDimLine(poly);
polyNew=poly;
XCurveSegment cv=GetDimCurve();
double nOffDist=m_nDist2DimLine*GetPScale();
XCurveSegment cvFix=cv.Offset(nOffDist, LS_FINITE);
XCurveSegment cvObj;
if(IsAngular())
{
double nDist2Obj=cv.GetArc().GetRadius()-m_nObjRadius;
cvObj=cv.Offset(-nDist2Obj, LS_FINITE);
}
for (int i = 0; i < indices.length(); i++)
{
int idx = indices[i];
if(idx<=1)
{ //改变尺寸线位置
XPoint ptVert=idx==0? *poly.Head() : *poly.Tail();
double nExtDir=idx==0? cv.IDirection(0) : cv.IDirection(1);
XLine lnExt(ptVert, nExtDir+PI/2);
XPoint ptOnExt=ptVert + vtOffset;
XPoint(ptOnExt).Project(&lnExt, ptOnExt);
int nSide=cv.OnWhichSide(ptOnExt);
double nDistMove=ptVert.Distance2d(ptOnExt);
double nOldDist2DimLine=m_nDist2DimLine,nOldDimRadius=m_nDimRadius;
int nSideLoc=cv.OnWhichSide(m_ptLocation);
if(fabs(m_nDist2DimLine)>_DIST_SNAP/GetPScale())
{
double nFactor=m_nDist2DimLine/fabs(m_nDist2DimLine);
if(nSide!=nSideLoc)
m_nDist2DimLine += nFactor*nDistMove/GetPScale();
else
m_nDist2DimLine -= nFactor*nDistMove/GetPScale();
}
else
{
if(nSideLoc==OFFSET_LEFT)
m_nDist2DimLine=-nDistMove/GetPScale();
}
if(IsAngular())
{
if(nSide==OFFSET_RIGHT)
m_nDimRadius += nDistMove;
else
m_nDimRadius -= nDistMove;
if(m_nDimRadius<_DIST_SNAP)
{
m_nDist2DimLine=nOldDist2DimLine;
m_nDimRadius=nOldDimRadius;
}
}
}
else if(idx<poly.Length()+2)
{ //改变定位点或区间
int ndx=idx-2;
XPoint ptGrip,ptGrip0;
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
cvObj.ProjectToMe(*poly[ndx], ptGrip);
else
cvFix.ProjectToMe(*poly[ndx], ptGrip);
int vtIdx=idx-2;
ptGrip0=ptGrip;
ptGrip += vtOffset;
if(!g_bStetchEntity&&GetCtrlToggle())
{
if(!AddSegment(ptGrip)&&GetSegmentNum()>1)
FindAndRemoveSegment(ptGrip0);
}
else
{
XPoint ptOnDim;
BOOL bGreatPrev=FALSE, bLessNext=FALSE;
if(cv.ProjectToMe(ptGrip, ptOnDim)==RTNORM)
{
if(vtIdx>0)
{
double nPathDist=cv.PathDistance(ptOnDim); //小于0时,为圆弧标注
if(IsAngular() && nPathDist<-_DIST_SNAP)
{
if(vtIdx==polyNew.Length()-1)
nPathDist=cv.GetArc().XCircle::GetLength()+nPathDist;
}
double nPathDistPrev=cv.PathDistance(*polyNew[vtIdx-1]);
bGreatPrev = (nPathDist-nPathDistPrev)>-_DIST_SNAP;
}
else
bGreatPrev=TRUE;
if(vtIdx<polyNew.Length()-1)
bLessNext = (cv.PathDistance(ptOnDim)-cv.PathDistance(*polyNew[vtIdx+1]))<_DIST_SNAP;
else bLessNext=TRUE;
if(bGreatPrev && bLessNext)
{
if(vtIdx==0)
{
XCurveSegment seg;
polyNew.Nth(0, seg);
seg.SetPoints(ptOnDim, seg.EndPoint());
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
{
XArc ar=seg.GetArc();
XCircle cir(ar.GetCenterPt(), ads_distance(ar.GetCenterPt(), m_ptLocation));
XPoint ptabc=m_ptLocation + vtOffset;
ptabc.Project(&cir, m_ptLocation);
m_nObjRadius=cir.GetCenterPt().Distance2d(ptGrip);
}
else
m_ptLocation += vtOffset;
if(IsValidSegment(seg.GetLength()))
{
m_nRotation=seg.IDirection(0);
SetSegment(0, seg.GetLength());
double nFactor = cv.OnWhichSide(m_ptLocation)==OFFSET_LEFT? -1.0 : 1.0;
if(!(IsAngular() && (IsDimChord() || IsDimArcLen())))
SetDist2DimLine(m_ptLocation.Distance2d(ptOnDim)*nFactor, FALSE);
}
else
{
if(m_lstSegment.Length()>1)
{
RemoveSegment(0);
polyNew.Nth(1, seg);
m_nRotation=seg.IDirection(0);
double nFactor = cv.OnWhichSide(m_ptLocation)==OFFSET_LEFT? -1.0 : 1.0;
if(!(IsAngular() && (IsDimChord() || IsDimArcLen())))
SetDist2DimLine(m_ptLocation.Distance2d(ptOnDim)*nFactor, FALSE);
}
}
}
else
{
BOOL bLast=(vtIdx==polyNew.Length()-1);
XCurveSegment seg, segPrev;
if(!bLast) polyNew.Nth(vtIdx, seg);
polyNew.Nth(vtIdx-1, segPrev);
if(!bLast)
ASSERT(IsValidSegment(seg.GetLength()));
ASSERT(IsValidSegment(segPrev.GetLength()));
if(!bLast) seg.SetPoints(ptOnDim, XPoint(seg.EndPoint()));
segPrev.SetPoints(XPoint(segPrev.StartPoint()), ptOnDim);
if(!bLast)
{
if(!IsValidSegment(seg.GetLength()))
RemoveSegment(vtIdx);
else
SetSegment(vtIdx, seg.GetLength());
}
else
{
double nFactor = cv.OnWhichSide(ptGrip)==OFFSET_LEFT? -1.0 : 1.0;
if(!(IsAngular() && (IsDimChord() || IsDimArcLen())))
SetDist2DimLine(ptGrip.Distance2d(ptOnDim)*nFactor, FALSE);
ads_polar(cv.StartPoint(), m_nRotation-PI/2, GetDist2DimLine(FALSE), m_ptLocation);
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
{
//改标注半径
XArc arDim=cv.GetArc();
arDim.SetRadius(m_nObjRadius);
XCurveSegment cvObj;
cvObj=arDim;
XPoint ptGrip=cvObj.EndPoint();
ptGrip += vtOffset;
m_nObjRadius = ptGrip.Distance2d(arDim.GetCenterPt());
}
}
if(!IsValidSegment(segPrev.GetLength()))
{
if(m_lstSegment.Length()>1)
RemoveSegment(vtIdx-1);
}
else
SetSegment(vtIdx-1, segPrev.GetLength());
}
}
}
}
}
else
{
int nSeg=idx - poly.Length() -2;
if(nSeg<poly.TotalSegments())
{
XPoint ptText = GetTextPos(nSeg);
ptText += vtOffset;
SetTextPos(nSeg, ptText);
}
else
{
ASSERT(IsAngular() && (IsDimChord() || IsDimArcLen()));
XLine ln(cv.StartPoint(), cv.IDirection(0)+PI/2);
XPoint ptNewLoc=m_ptLocation + vtOffset;
ptNewLoc.Project(&ln, m_ptLocation);
int nSide=cv.OnWhichSide(ptNewLoc);
double nFactor = cv.OnWhichSide(ptNewLoc)==OFFSET_LEFT? -1.0 : 1.0;
SetDist2DimLine(ptNewLoc.Distance2d(cv.StartPoint())*nFactor, FALSE);
}
}
}
//RemoveZeroSegment(); //把长度为0的区间移除
AutoSetFlag();
Acad::ErrorStatus es = Acad::eOk;
return es;
}
// 功能: 夹点操作
Acad::ErrorStatus TDbDimension::subMoveStretchPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
int nCount=indices.length();
XPushMemVar<BOOL> vTemp(g_bStetchEntity,TRUE);
return subMoveGripPointsAt(indices, offset);
}
// 取得夹点说明
Acad::ErrorStatus TDbDimension::GetGripText(int i, CString &cs) const
{
Acad::ErrorStatus es=Acad::eOk;
XPoly2D poly;
GetPolySegOnDimLine(poly);
if(i<=1)
cs = _T("移动尺寸线");
else if(i<poly.Length()+2)
{
if(!GetCtrlToggle())
{
if(i==2 || i==poly.Length()+1)
{
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
cs=_T("更改标注半径和开间(Ctrl-增补合并尺寸开间)");
else
cs=_T("移动定位点和更改开间(Ctrl-增补合并尺寸开间)");
}
else
cs = _T("更改合并尺寸开间(Ctrl-增补合并尺寸开间)");
}
else
{
if(i==2 || i==poly.Length()+1)
{
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
cs=_T("增补合并尺寸开间(Ctrl-更改标注半径和开间)");
else
cs=_T("增补合并尺寸开间(Ctrl-移动定位点和更改开间)");
}
else
cs = _T("增补合并尺寸开间(Ctrl-更改合并尺寸开间)");
}
}
else
{
int iVert=i-2-poly.Length();
if(iVert<poly.TotalSegments())
cs = _T("移动尺寸文本");
else if(IsAngular() && (IsDimChord() || IsDimArcLen()))
cs = _T("改尺寸界线");
}
return es;
}
int TDbDimension::ConvertText(TConvertTextPtr ptr, void *pData)
{
assertWriteEnabled();
int nLen=m_lstTextContent.Length();
int nCode=RTNONE;
for(int i=0; i<nLen; i++) {
TDimTextContent *pContent=m_lstTextContent[i];
XString sText;
int nRet=ptr(pContent->sText, sText, pData);
if(nRet==RTERROR)
nCode=nRet;
else if(nRet==RTNORM)
pContent->sText=sText;
}
return nCode;
}
// 返回发现的位置,同时posStart往前移动(以便继续找下一个使用),
TTextPosition
TDbDimension::FindSubText(const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange) const
{
assertReadEnabled();
TTextPosition pos;
if(!sSubText || !sSubText[0])
return pos;
AcDbObjectId idTextStyle;
double dimtxt=3.0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pStyle);
if(pStyle) {
idTextStyle=pStyle->dimtxsty();
dimtxt=pStyle->dimtxt();
}
OPENOBJ_END();
if(!idTextStyle)
return pos;
int nLen=GetSegmentNum(); //m_lstTextContent.Length();
int nCode=RTNONE;
TTextPosition posNext=posStart;
for(int i=posStart.m_nCookies; i<nLen; i++) {
//TDimTextContent content=m_lstTextContent[i];
XString sTextDim=GetText(i);
TDbText dimText;
dimText.setPropertiesFrom(this);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
dimText.SetHeight(dimtxt);
dimText.SetStyleId(idTextStyle);
dimText.SetText(sTextDim);
dimText.SetLocation(GetTextPos(i));
posNext.m_nCookies=i;
TTextPosition posRet=dimText.FindSubText(sSubText, posNext, pRange);
if(!posRet) {
posNext.m_nTextPos=0;
} else {
posStart=posNext;
if(!posStart && (int)posStart.m_nCookies<nLen-1) {
posStart.m_nCookies++;
posStart.m_nTextPos=0;
}
posRet.m_nCookies=i;
return posRet;
}
}
return pos;
}
// 返回下一次查找的开始位置
TTextPosition
TDbDimension::ReplaceSubText(const TTextPosition &posRep, const TCHAR *sRepText, TTextRange *pRange)
{
assertWriteEnabled();
TTextPosition pos;
pos.m_nBufLen=_tcslen(sRepText);
pos.m_nCookies=posRep.m_nCookies;
if(!posRep || (int)posRep.m_nCookies>=GetSegmentNum())
return pos;
AcDbObjectId idTextStyle;
double dimtxt=3.0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pStyle);
if(pStyle) {
idTextStyle=pStyle->dimtxsty();
dimtxt=pStyle->dimtxt();
}
OPENOBJ_END();
if(!idTextStyle)
return pos;
//TDimTextContent *pContent=m_lstTextContent[posRep.m_nCookies];
XString sTextDim=GetText(posRep.m_nCookies);
TDbText dimText;
dimText.setPropertiesFrom(this);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
dimText.SetHeight(dimtxt);
dimText.SetStyleId(idTextStyle);
dimText.SetText(sTextDim);
dimText.SetLocation(GetTextPos(posRep.m_nCookies));
TTextPosition posRet=dimText.ReplaceSubText(posRep, sRepText, pRange);
SetTextContent(posRep.m_nCookies, dimText.GetText());
if(!posRet) {
if((int)posRet.m_nCookies<GetSegmentNum()-1) {
posRet.m_nCookies=posRep.m_nCookies+1;
posRet.m_nTextPos=0;
}
}
return posRet;
}
Adesk::UInt32
TDbDimension::subSetAttributes(AcGiDrawableTraits * traits)
{
Adesk::UInt32 nRet=TDbEntity::subSetAttributes(traits);
//if(g_nAcadVer<15.0001)
// nRet |= kDrawableIsCompoundObject;
return nRet;
}
static BOOL g_bSelfDrawDim=FALSE;
TSubText* TDbDimension::GetSubText(long iText)const
{
XPushMemVar<BOOL> bExpl(g_bSelfDrawDim, TRUE);
TSubText*pSubText=TDbEntity::GetSubText(iText);
if(pSubText!=NULL)
pSubText->SetMenuType(6);
return pSubText;
}
TSubText* TDbDimension::HitTestText(XPoint pt)const
{
XPushMemVar<BOOL> bExpl(g_bSelfDrawDim, TRUE);
TSubText*pSubText=TDbEntity::HitTestText(pt);
if(pSubText!=NULL)
pSubText->SetMenuType(6);
return pSubText;
}
Acad::ErrorStatus TDbDimension::GetExtents2d(XPoint &ptLow, XPoint &ptUp) const
{
AcDbExtents ext;
Acad::ErrorStatus es=getGeomExtents(ext);
ptLow=ext.minPoint();
ptUp=ext.maxPoint();
return es;
}
Acad::ErrorStatus
TDbDimension::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
assertReadEnabled();
//if(_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0&&!dc.IsPlotGeneration())
//{
// AcGePoint3dArray gripPoints;
// double nOffDist=m_nDist2DimLine*GetPScale();
// XCurveSegment cv=GetDimCurve();
// XCurveSegment cvFix=cv.Offset(nOffDist, LS_FINITE);
// XCurveSegment cvObj;
// if(IsAngular()) {
// double nDist2Obj=cv.GetArc().radius-m_nObjRadius;
// cvObj=cv.Offset(-nDist2Obj, LS_FINITE);
// }
// XPoly2D poly;
// GetPolySegOnDimLine(poly);
// int nVertNum=poly.Length();
// for(int i=0; i<nVertNum; i++) {
// XPoint ptFix;
// if(IsAngular() && (IsDimChord() || IsDimArcLen()))
// cvObj.ProjectToMe(*poly[i], ptFix);
// else cvFix.ProjectToMe(*poly[i], ptFix);
// dc<<XLine(ptFix,ptFix);
// }
//}
//modified by whl on 060223
//BOOL bCheckDim=DocGetCheckDim();
BOOL bCheckDim=DocGetCheckDim()&&!g_bExplodeSubText;
double nPScale=GetPScale();
if(!IsValid())
return Acad::eInvalidInput;
int nColorOld=dc.GetColor();
double nOffDist=m_nDist2DimLine*GetPScale();
BOOL bDraw=(_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0||g_bSelfDrawDim);
BOOL bQuickMode=(bDraw && !ownerId() && m_lstSegment.Length()>=g_nDimNumGripTip);
if(g_bDisableQuickMode)
bQuickMode=FALSE;
XPoly2D poly;
GetPolySegOnDimLine(poly);
BOOL bAngular=IsAngular();
BOOL bSelfDraw=(g_bOsnapExpl || bDraw || //g_bExpOtherDb ||
(IsAngular() && (IsDimChord() || IsDimArcLen()))
);
if(bSelfDraw || bCheckDim) {
dc.SetAlignment(XExplodeDraw::kMiddleCenter);
XString sDimPrefix, sDimSuffix;
double dimgap=0, dimtxt=0, dimexe=0, dimexo=0;
double dimscale=1.0, dimasz=1.0,dimdle=0.0;
int dimclre=0, dimclrd=0, dimclrt=0;
int dimdec=0, dimadec=0;
double nArrowThick=6.0*nPScale;
double dimlfac=1.0; //标注显示的单位换算系数
AcDbObjectId dimblk;
AcDbObjectId idTextStyle;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
if(pDimStyle) {
dimdec=pDimStyle->dimdec();
dimadec=pDimStyle->dimadec();
dimgap=pDimStyle->dimgap();
dimtxt=pDimStyle->dimtxt();
dimblk=pDimStyle->dimblk();
dimlfac=pDimStyle->dimlfac();
dimscale=nPScale;
dimdle=pDimStyle->dimdle();
dimasz=pDimStyle->dimasz();
idTextStyle=pDimStyle->dimtxsty();
dimexe=pDimStyle->dimexe();
dimexo=pDimStyle->dimexo();
dimclre=pDimStyle->dimclre().colorIndex();
dimclrd=pDimStyle->dimclrd().colorIndex();
dimclrt=pDimStyle->dimclrt().colorIndex();
const TCHAR *dimpost=pDimStyle->dimpost();
const TCHAR *pStr=NULL;
if(dimpost)
pStr=_tcsstr(dimpost, _T("<>"));
if(pStr) {
StrCpy(sDimPrefix, dimpost, pStr);
StrCpy(sDimSuffix, pStr+2, NULL);
} else if(dimpost) {
_tcscpy(sDimSuffix, dimpost);
}
} else {
return Acad::eInvalidInput;
}
OPENOBJ_END();
XCurveSegment cv=GetDimCurve();
BOOL bDimArcLen=(IsAngular() && IsDimArcLen());
if(bDimArcLen) { //弧长标注
int numSeg=poly.TotalSegments();
for(int i=0; i<numSeg; i++) {
XCurveSegment segDim, segFix, segObj;
poly.Nth(i, segDim);
segFix = segDim.Offset(OFFSET_LEFT, -GetDist2DimLine(FALSE), LS_FINITE);
double nOffDist0=segDim.GetArc().GetRadius() - m_nObjRadius;
segObj = segDim.Offset(OFFSET_LEFT, nOffDist0, LS_FINITE);
XPoint ptAr1, ptAr2;
double nChorldDir=segObj.XLine::Direction();
XLine ln1(segObj.StartPoint(), nChorldDir+PI/2.0),
ln2(segObj.EndPoint(), nChorldDir+PI/2.0);
XPoint ptInt[2];
segDim.SetLineFlag(LS_INFINITE);
ln1.SetLineFlag(LS_INFINITE);
int nIntNum=segDim.Intersection(ln1, ptInt[0], ptInt[1]);
if(nIntNum==0)
continue;
else if(nIntNum==1)
ptAr1=ptInt[0];
else
ptAr1=XLine(ptInt[0], ptInt[1]).NearPoint(segDim.StartPoint());
nIntNum=segDim.Intersection(ln2, ptInt[0], ptInt[1]);
if(nIntNum==0)
continue;
else if(nIntNum==1)
ptAr2=ptInt[0];
else
ptAr2=XLine(ptInt[0], ptInt[1]).NearPoint(segDim.StartPoint());
segDim.SetPoints(ptAr1, ptAr2);
// 绘制尺寸线
if(dimclrd) dc.SetColor(dimclrd);
dc << segDim;
// 绘制尺寸界线
if(dimclre) dc.SetColor(dimclre);
if(bQuickMode) ;
else if(!g_bOsnapExpl) { //尺寸箭头
if(!dimblk) {
XPointDir2d pt1, pt2;
segDim.Polar(2.0*dimscale, pt1);
segDim.Polar(2.0*dimscale, pt2, FALSE);
AcDbPolyline plArrow1;
plArrow1.setPropertiesFrom(this);
plArrow1.addVertexAt(0, segDim.StartPoint());
plArrow1.setWidthsAt(0, 0.0, 0.66*dimscale);
plArrow1.addVertexAt(1, pt1);
plArrow1.setWidthsAt(1, 0.66*dimscale, 0.0);
dc.Polyline(plArrow1);
AcDbPolyline plArrow2;
plArrow2.setPropertiesFrom(this);
plArrow2.addVertexAt(0, pt2);
plArrow2.setWidthsAt(0, 0.66*dimscale, 0.0);
plArrow2.addVertexAt(1, segDim.EndPoint());
plArrow2.setWidthsAt(1, 0.0, 0.0);
dc.Polyline(plArrow2);
} else {
// 打印时,不能使用新方法
BOOL bNewMethod=(g_nAcadVer>15.0001 && g_bMakeBlock);
// sg add 091105,强制打印时,不使用新方法
if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 && dc.IsPlotGeneration())
bNewMethod = FALSE;
OPENOBJ_BEGIN(dimblk, AcDb::kForRead, AcDbBlockTableRecord, pBlock);
if(pBlock) {
dc.DrawBlock(*pBlock, segDim.EndPoint(), AcGeScale3d(dimscale*dimasz, dimscale*dimasz, dimscale*dimasz),
segDim.IDirection(1)+PI, bNewMethod);
dc.DrawBlock(*pBlock, segDim.StartPoint(), AcGeScale3d(dimscale*dimasz, dimscale*dimasz, dimscale*dimasz),
segDim.IDirection(0), bNewMethod);
}
OPENOBJ_END();
}
}
// 尺寸界限
XPoint pt1, pt2;
double nFactor=fabs(nOffDist)>_DIST_SNAP? nOffDist/fabs(nOffDist) : 1.0;
ads_polar(segDim.StartPoint(), nChorldDir-nFactor*PI/2, fabs(nOffDist)-dimexo*dimscale, pt1);
ads_polar(segDim.StartPoint(), nChorldDir+nFactor*PI/2, dimexe*dimscale, pt2);
dc << XLine(pt1, pt2);
ads_polar(segDim.EndPoint(), nChorldDir-nFactor*PI/2, fabs(nOffDist)-dimexo*dimscale, pt1);
ads_polar(segDim.EndPoint(), nChorldDir+nFactor*PI/2, dimexe*dimscale, pt2);
dc << XLine(pt1, pt2);
dc.SetColor(nColorOld);
// 尺寸文字
if(bQuickMode) ;
else if(!g_bOsnapExpl) {
TDbText dimText;
dimText.setPropertiesFrom(this);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
dimText.SetHeight(dimtxt);
dimText.SetStyleId(idTextStyle);
dimText.setColorIndex(dimclrt);
int numSeg=poly.TotalSegments();
BOOL bIsDefPos=TRUE;
XPoint ptText=GetTextPos(i, &bIsDefPos);
XPoint ptTemp;
XPointDir2d ptTempDir;
cv.ProjectToMe(ptText, ptTemp);
double nDist=cv.PathDistance(ptTemp);
cv.Polar(nDist, ptTempDir);
double nTextRot=NormalViewAngle(ptTempDir.nDirection);
BOOL bIsDefText=TRUE;
XString sText0=GetText(i, &bIsDefText);
XString sText;
if(bIsDefText)
sText << sDimPrefix << sText0 << sDimSuffix;
else
sText << sText0;
dimText.SetRotation(Wcs2Layout(nTextRot));
dimText.SetLocation(ptText);
if(bSelfDraw) {
TPushProperty vProp(&dimText, dc);
dimText.SetText(sText);
if(dc.IsFullExplode())
dimText.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(dimText);
XPoint ext=dimText.GetExtents();
XPoint ptMid, ptS, ptE;
ads_polar(ptText, nTextRot+PI/2, ext.y, ptMid);
ads_polar(ptText, nTextRot-PI, ext.x/2, ptS);
ads_polar(ptText, nTextRot, ext.x/2, ptE);
ads_polar(XPoint(ptS), nTextRot+PI/2, ext.y/2, ptS);
ads_polar(XPoint(ptE), nTextRot+PI/2, ext.y/2, ptE);
dc << XArc(ptS, ptMid, ptE);
}
if(bCheckDim && !bIsDefText) {
XString sCheckText(256);
sCheckText << _T("(") << sDimPrefix << GetDefaultText(i) << sDimSuffix << _T(")");
XPoint ptCheckText;
if(bIsDefPos) {
XPoint ptOnSeg;
if(segDim.ProjectToMe(ptText, ptOnSeg)==RTNORM) {
ptOnSeg.Mirror(ptText, ptCheckText);
}
} else {
int nSideText=segDim.OnWhichSide(ptText);
if(nSideText==OFFSET_RIGHT)
ads_polar(ptText, ptTempDir.nDirection-PI/2, nPScale*(dimgap+dimtxt), ptCheckText);
else
ads_polar(ptText, ptTempDir.nDirection+PI/2, nPScale*(dimgap+dimtxt), ptCheckText);
}
dimText.setColorIndex(1);
dimText.SetLocation(ptCheckText);
dimText.SetText(sCheckText);
{
TPushProperty vProp(&dimText, dc);
if(dc.IsFullExplode())
dimText.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(dimText);
}
dimText.setColorIndex(dimclrt);
} // bCheckDim
dc.SetColor(nColorOld);
} // g_bExplOsnap
} // End for
} else if(IsAngular() && IsDimChord()) { //弦长标注
XPushMemVar<BOOL> tVar1(g_bDisableQuickMode, TRUE);
int numSeg=poly.TotalSegments();
for(int i=0; i<numSeg; i++) {
XCurveSegment segDim, segFix, segObj;
poly.Nth(i, segDim);
segFix = segDim.Offset(OFFSET_LEFT, -GetDist2DimLine(FALSE), LS_FINITE);
double nOffDist0=segDim.GetArc().GetRadius() - m_nObjRadius;
segObj = segDim.Offset(OFFSET_LEFT, nOffDist0, LS_FINITE);
double nRot=segObj.XLine::Direction();
XPoint ptFix;
double nObj2Fix=segFix.GetArc().GetRadius()-segObj.GetArc().GetRadius();
ads_polar(segObj.StartPoint(), nRot-PI/2, nObj2Fix, ptFix);
TDbDimension objDim;
objDim.setPropertiesFrom(this);
objDim.SetLocation(ptFix);
objDim.SetRotation(nRot);
objDim.SetDist2DimLine(GetDist2DimLine());
objDim.AppendSegment(segObj.GetArc().ChordLength());
objDim.SetStyleId(GetStyleId());
TDimTextPos *pNode1=((TDbDimension *)this)->m_lstTextPos.FindNode(&i, TDimTextPos::CompareByIndexForFind);
if(pNode1) objDim.SetTextPos(0, pNode1->ptPos);
TDimTextContent *pNode=((TDbDimension *)this)->m_lstTextContent.FindNode(&i, TDimTextContent::CompareByIndexForFind);
if(pNode) objDim.SetTextContent(0, pNode->sText);
objDim.ExplodeOrDraw2d(dc);
}
} else
{ //直线标注或角度标注
if(bSelfDraw)
{
if(dimclrd) dc.SetColor(dimclrd);
if(IsAngular())
dc << poly;
else//使用的是样式比例
{
XPoint ptStart,ptEnd;
ads_polar(*poly[0],m_nRotation+PI,dimdle*dimscale,ptStart);
dc<<XLine(ptStart,*poly[0]);
ads_polar(*poly[poly.Length()-1],m_nRotation,dimdle*dimscale,ptEnd);
dc<<XLine(*poly[poly.Length()-1],ptEnd);
dc<<poly;
}
//dc << cv;
if(dimclre) dc.SetColor(dimclre);
int numVert=poly.Length();
for(int i=0; i<numVert; i++)
{
XPoint ptVert=*poly[i];
double nPathDist=cv.PathDistance(ptVert);
XPointDir2d ptVertDir;
cv.Polar(nPathDist, ptVertDir);
if(bQuickMode) ;
else if(!g_bOsnapExpl)
{
//尺寸箭头
if(!dimblk)
{
XPointDir2d pt1, pt2;
cv.Polar(nPathDist+2.0*dimscale, pt1);
cv.Polar(nPathDist-2.0*dimscale, pt2);
AcDbPolyline plArrow;
plArrow.setPropertiesFrom(this);
int iVert=0;
if(i>0)
{
plArrow.addVertexAt(iVert, pt2);
plArrow.setWidthsAt(iVert, 0.66*dimscale, 0.0);
iVert++;
}
plArrow.addVertexAt(iVert, ptVert);
plArrow.setWidthsAt(iVert, 0.0, 0.66*dimscale);
iVert++;
if(i<numVert-1)
{
plArrow.addVertexAt(iVert, pt1);
iVert++;
}
dc.Polyline(plArrow);
}
else
{
// 打印时,不能使用新方法
BOOL bNewMethod=(g_nAcadVer>15.0001 && g_bMakeBlock);
// sg add 091105,强制打印时,不使用新方法
if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 && dc.IsPlotGeneration())
bNewMethod = FALSE;
OPENOBJ_BEGIN(dimblk, AcDb::kForRead, AcDbBlockTableRecord, pBlock);
if(pBlock)
{
dc.DrawBlock(*pBlock, ptVert, AcGeScale3d(dimscale*dimasz, dimscale*dimasz, dimscale*dimasz),
NormalViewAngle(ptVertDir.nDirection), bNewMethod);
}
OPENOBJ_END();
}
}
// 尺寸界限
XPoint pt1, pt2;
double nFactor=fabs(nOffDist)>_DIST_SNAP? nOffDist/fabs(nOffDist) : 1.0;
ads_polar(ptVert, ptVertDir.nDirection-nFactor*PI/2, fabs(nOffDist)-dimexo*dimscale, pt1);
ads_polar(ptVert, ptVertDir.nDirection+nFactor*PI/2, dimexe*dimscale, pt2);
dc<<XLine(pt1,pt2);
}
}
dc.SetColor(nColorOld);
if(bQuickMode) ;
else if(!g_bOsnapExpl)
{
TDbText dimText;
dimText.setPropertiesFrom(this);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
dimText.SetHeight(dimtxt);
dimText.SetStyleId(idTextStyle);
dimText.setColorIndex(dimclrt);
int numSeg=poly.TotalSegments();
for(int i=0; i<numSeg; i++)
{
XCurveSegment seg;
poly.Nth(i, seg);
BOOL bIsDefPos=TRUE;
XPoint ptText=GetTextPos(i, &bIsDefPos);
XPoint ptTemp;
XPointDir2d ptTempDir;
cv.ProjectToMe(ptText, ptTemp);
double nDist=cv.PathDistance(ptTemp);
cv.Polar(nDist, ptTempDir);
double nTextRot=NormalViewAngle(ptTempDir.nDirection);
BOOL bIsDefText=TRUE;
XString sText0=GetText(i, &bIsDefText);
XString sText;
if(bIsDefText && !IsAngular())
sText << sDimPrefix << sText0 << sDimSuffix;
else
sText << sText0;
dimText.SetRotation(Wcs2Layout(nTextRot));
dimText.SetLocation(ptText);
if(bSelfDraw) {
TPushProperty vProp(&dimText, dc);
dimText.SetText(sText);
if(dc.IsFullExplode())
dimText.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(dimText);
}
if(bCheckDim && !bIsDefText) {
XString sCheckText(256);
sCheckText << _T("(");
if(!IsAngular())
sCheckText << sDimPrefix;
sCheckText << GetDefaultText(i);
if(!IsAngular())
sCheckText << sDimSuffix;
sCheckText << _T(")");
XPoint ptCheckText;
if(bIsDefPos) {
XPoint ptOnSeg;
if(seg.ProjectToMe(ptText, ptOnSeg)==RTNORM) {
ptOnSeg.Mirror(ptText, ptCheckText);
}
} else {
int nSideText=seg.OnWhichSide(ptText);
if(nSideText==OFFSET_RIGHT)
ads_polar(ptText, ptTempDir.nDirection-PI/2, nPScale*(dimgap+dimtxt), ptCheckText);
else
ads_polar(ptText, ptTempDir.nDirection+PI/2, nPScale*(dimgap+dimtxt), ptCheckText);
}
dimText.setColorIndex(1);
dimText.SetLocation(ptCheckText);
dimText.SetText(sCheckText);
{
TPushProperty vProp(&dimText, dc);
if(dc.IsFullExplode())
dimText.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(dimText);
}
dimText.setColorIndex(dimclrt);
} // bCheckDim
}
dc.SetColor(nColorOld);
} // g_bExplOsnap
}
}
if(!bSelfDraw) {
BOOL bDraw=(_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0);
BOOL bExplode=(_tcscmp(dc.Desc(), XExplodeStream::Descriptor())==0);
int nSeg=poly.TotalSegments();
for(int i=0; i<nSeg; i++) {
XCurveSegment seg;
poly.Nth(i, seg);
ASSERT(!!seg);
XCurveSegment segOnFix= seg.Offset(OFFSET_RIGHT, nOffDist, LS_FINITE);
AcDbDimension *pDim=NULL;
XPoint ptText=seg.MidPoint();
if(!bAngular) {
XPoint pt1=segOnFix.StartPoint(), pt2=segOnFix.EndPoint();
double nAng=NormalViewAngle(ads_angle(pt1, pt2));
if(!CT_IsExactSameDrt(nAng, ads_angle(pt1, pt2), _angSnap))
TchPrivate::Exchange(pt1, pt2);
pDim = new AcDbAlignedDimension(pt1, pt2, ptText);
} else {
XPoint ptCen=seg.GetArc().GetCenterPt();
pDim = new AcDb3PointAngularDimension(ptCen, segOnFix.StartPoint(), segOnFix.EndPoint(), ptText);
}
TDimTextPos *pNode=((TDbDimension *)this)->m_lstTextPos.FindNode(&i, TDimTextPos::CompareByIndexForFind);
if(pNode) {
pDim->setTextPosition(pNode->ptPos);
pDim->useSetTextPosition();
}
TDimTextContent *pNode1=((TDbDimension *)this)->m_lstTextContent.FindNode(&i, TDimTextContent::CompareByIndexForFind);
if(pNode1) pDim->setDimensionText(pNode1->sText);
AcDbObjectId idDimStyle=DimStyleTch2Acad(m_idDimStyle, GetPScale(), IsAngular(), database(), 0.0);
pDim->setDimensionStyle(idDimStyle);
pDim->setDimstyleData(idDimStyle);
pDim->setPropertiesFrom(this);
((XExplodeStream &)dc).Append(pDim, FALSE);
}
}
dc.SetColor(nColorOld);
return Acad::eOk;
}
const TCHAR *TDbDimension::GetDefaultLayer() const
{
return LAY_DIM;
}
TEntityBase::DrawType
TDbDimension::GetDrawType() const
{
return TEntityBase::k2DOnly;
}
/* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */
void TDbDimension::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("连续标注")));
const TCHAR *pSubType;
if(!IsAngular()) pSubType=_T("线性标注");
else if(IsDimChord()) pSubType=_T("弦长标注");
else if(IsDimArcLen()) pSubType=_T("弧长标注");
else pSubType=_T("角度标注");
lstInfo.Append(new TObjInfoUnit(_T("子类型"), pSubType));
lstInfo.Append(new TObjInfoUnit(_T("标注样式"), GetSymbolName(m_idDimStyle)));
XString sDist;
ftoa(fabs(m_nDist2DimLine), 1, sDist);
sDist << _T("P");
lstInfo.Append(new TObjInfoUnit(_T("尺寸线偏移"), sDist));
if(!IsAngular()) {
lstInfo.Append(new TObjInfoUnit(_T("旋转角度"), Angle2Str(m_nRotation*180/PI)));
} else if(IsDimChord() || IsDimArcLen()) {
lstInfo.Append(new TObjInfoUnit(_T("所注半径"), Dist2Str(m_nObjRadius)));
}
}
//尺寸文字位置的自动调整
// 返回最后一个的调整结果
// 0--缺省, 1--上调, 2--下调, 3--侧调
// nFromUp--开始调整的状态,bAllowExt--是否允许外调,bAutoReset--无需调整的是否自动复位
int TDbDimension::AdjustDim(BOOL bFromUp, BOOL bAllowExt, BOOL bAutoReset)
{
assertWriteEnabled();
if(!IsValid())
return 0;
double nPScale=GetPScale();
double dimgap=0, dimtxt=0, dimexe=0, dimexo=0;
double dimscale=1.0, dimasz=1.0;
int dimdec=0, dimadec=0;
double dimlfac=1.0;
double nArrowThick=6.0*nPScale;
AcDbObjectId dimblk;
AcDbObjectId dimtxsty;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
if(!pDimStyle)
return 0;
dimlfac=pDimStyle->dimlfac();
dimdec=pDimStyle->dimdec();
dimadec=pDimStyle->dimadec();
dimgap=pDimStyle->dimgap();
dimtxt=pDimStyle->dimtxt();
dimblk=pDimStyle->dimblk();
//dimscale=pDimStyle->dimscale();
dimscale=nPScale;
dimasz=pDimStyle->dimasz();
dimtxsty=pDimStyle->dimtxsty();
dimexe=pDimStyle->dimexe();
dimexo=pDimStyle->dimexo();
OPENOBJ_END();
if(!dimtxsty)
return 0;
int nRetCode=0;
if(bAutoReset)
m_lstTextPos.Reset();
XCurveSegment cv=GetDimCurve();
XPoly2D poly;
GetPolySegOnDimLine(poly);
if(IsAngular() && IsDimChord()) { //弦长标注
int numSeg=poly.TotalSegments();
int nCode=0;
for(int i=0; i<numSeg; i++) {
if(!bAutoReset && m_lstTextPos.FindNode(&i, TDimTextPos::CompareByIndexForFind))
continue;
XCurveSegment segDim, segFix, segObj;
poly.Nth(i, segDim);
segFix = segDim.Offset(OFFSET_LEFT, -GetDist2DimLine(FALSE), LS_FINITE);
double nOffDist=segDim.GetArc().GetRadius() - m_nObjRadius;
segObj = segDim.Offset(OFFSET_LEFT, nOffDist, LS_FINITE);
double nRot=segObj.XLine::Direction();
XPoint ptFix;
double nObj2Fix=segFix.GetArc().GetRadius()-segObj.GetArc().GetRadius();
ads_polar(segObj.StartPoint(), nRot-PI/2, nObj2Fix, ptFix);
TDbDimension objDim;
objDim.setPropertiesFrom(this);
objDim.SetLocation(ptFix);
objDim.SetRotation(nRot);
objDim.SetDist2DimLine(GetDist2DimLine());
objDim.AppendSegment(segObj.GetArc().ChordLength());
objDim.SetStyleId(GetStyleId());
TDimTextContent *pNode=((TDbDimension *)this)->m_lstTextContent.FindNode(&i, TDimTextContent::CompareByIndexForFind);
if(pNode) objDim.SetTextContent(0, pNode->sText);
BOOL bUpAdj=bFromUp;
if(!nCode)
nCode=objDim.AdjustDim(bUpAdj, (i==0 || i==numSeg));
BOOL bDef=TRUE;
XPoint ptTextPos=objDim.GetTextPos(0, &bDef);
if(!bDef)
SetTextPos(i, ptTextPos);
}
} else { //直线标注或角度标注
double nOffDist=m_nDist2DimLine*GetPScale();
int numVert=poly.Length();
DList<XLine> lstLineSet;
for(int i=0; i<numVert; i++) {
XPoint ptVert=*poly[i];
double nPathDist=cv.PathDistance(ptVert);
XPointDir2d ptVertDir;
cv.Polar(nPathDist, ptVertDir);
// 尺寸界限
XPoint pt1, pt2;
double nFactor=fabs(nOffDist)>_DIST_SNAP? nOffDist/fabs(nOffDist) : 1.0;
ads_polar(ptVert, ptVertDir.nDirection-nFactor*PI/2, dimexe*dimscale/*fabs(nOffDist)-dimexo*dimscale*/, pt1);
ads_polar(ptVert, ptVertDir.nDirection+nFactor*PI/2, dimexe*dimscale, pt2);
lstLineSet.Append(new XLine(pt1, pt2));
}
double nTextHeight=dimtxt*dimscale;
int numSeg=poly.TotalSegments();
// 0--缺省, 1--上调, 2--下调, 3--外调
TCHAR *pPosTable=new TCHAR [numSeg];
for(i=0; i<numSeg; i++) {
pPosTable[i]=0;
if(!bAutoReset && m_lstTextPos.FindNode(&i, TDimTextPos::CompareByIndexForFind))
continue;
XCurveSegment seg;
poly.Nth(i, seg);
XPoint ptText=GetDefaultTextPos(i);
XPoint ptTemp;
XPointDir2d ptTempDir;
cv.ProjectToMe(ptText, ptTemp);
double nDist=cv.PathDistance(ptTemp);
cv.Polar(nDist, ptTempDir);
double nTextRot=NormalViewAngle(ptTempDir.nDirection);
XString sText=GetText(i);
TDbText text;
text.setPropertiesFrom(this);
text.SetText(sText);
text.SetStyleId(dimtxsty);
text.SetHeight(nTextHeight, FALSE);
XPoint ptExt=text.GetExtents();
//ptExt.y *= nEn2Ch;
XLine lnUp, lnDown;
XPoint ptMidRight;
ads_polar(ptText, nTextRot, ptExt.x/2, ptMidRight);
XPoint ptVert;
ads_polar(ptMidRight, nTextRot+PI/2, ptExt.y/2, ptVert);
lnUp.StartPoint()=ptVert;
ads_polar(XPoint(ptVert), nTextRot+PI, ptExt.x, ptVert);
lnUp.EndPoint()=ptVert;
ads_polar(XPoint(ptVert), nTextRot-PI/2, ptExt.y, ptVert);
lnDown.StartPoint()=ptVert;
ads_polar(XPoint(ptVert), nTextRot, ptExt.x, ptVert);
lnDown.EndPoint()=ptVert;
XLine *ln1=lstLineSet[i];
ln1->SetLineFlag(LS_FINITE);
lnUp.SetLineFlag(LS_FINITE);
lnDown.SetLineFlag(LS_FINITE);
if(lnUp.Intersection(ln1, XPoint()) || lnDown.Intersection(ln1, XPoint())) {
// 需要自调
if(bAllowExt && (i==0 || i==numSeg-1)) { //侧调
XPointDir2d ptPosExt;
cv.Polar(-(ptExt.x/2+dimgap*nPScale), ptPosExt, i==0);
double nDirNext=NormalViewAngle(ptPosExt.nDirection)+PI/2;
XPoint ptTextPos;
ads_polar(ptPosExt, nDirNext, (dimgap+dimtxt*0.7)*nPScale, ptTextPos);
SetTextPos(i, ptTextPos);
pPosTable[i]=3;
} else {
BOOL bPrevAdj=FALSE;
if(i>0 && pPosTable[i-1]!=0)
bPrevAdj=TRUE;
if(bPrevAdj) {
pPosTable[i]=0;
} else {
BOOL bUpAdj=bFromUp;
XPoint ptTextPos;
//double nFactor=fabs(nOffDist)>_DIST_SNAP? nOffDist/fabs(nOffDist) : 1.0;
XPointDir2d ptVertDir;
seg.Polar(seg.GetLength()/2, ptVertDir);
double nUpDir=NormalViewAngle(ptVertDir.nDirection);
if(bUpAdj) { //尺寸线方向外
ads_polar(ptVertDir, nUpDir+PI/2,
(dimgap*2+dimtxt*1.5*0.7)*nPScale, ptTextPos);
pPosTable[i]=1;
} else {
ads_polar(ptVertDir, nUpDir-PI/2,
(dimgap+dimtxt*0.5)*nPScale, ptTextPos);
pPosTable[i]=2;
}
SetTextPos(i, ptTextPos);
}
}
} else {
pPosTable[i]=0;
}
}
nRetCode=pPosTable[numSeg-1];
}
return nRetCode;
}
//取得尺寸线
XCurveSegment
TDbDimension::GetDimCurve() const
{
assertReadEnabled();
ASSERT(IsValid());
XPoint ptStart, ptEnd;
double nDist=m_nDist2DimLine*GetPScale();
ads_polar(m_ptLocation, m_nRotation+PI/2, nDist, ptStart);
double nSweepAngle=0.0;
if(IsAngular()) {
XPoint ptCen;
ads_polar(ptStart, m_nRotation+PI/2, m_nDimRadius, ptCen);
nSweepAngle=GetTotalSegValue();
if(fabs(nSweepAngle-2.0*PI)<_angSnap)
nSweepAngle -= 2.0*_angSnap;
double nEndAng=ads_angle(ptCen, ptStart)+nSweepAngle;
ads_polar(ptCen, nEndAng, m_nDimRadius, ptEnd);
} else {
double nTotalDist=GetTotalSegValue();
ads_polar(ptStart, m_nRotation, nTotalDist, ptEnd);
}
return XCurveSegment(ptStart, ptEnd, nSweepAngle);
}
void TDbDimension::GetPolySegOnDimLine(XPoly2D &poly) const
{
assertReadEnabled();
XCurveSegment cv=GetDimCurve();
XSortedVertexList lstVert(cv);
int nSeg=m_lstSegment.Length();
double nDist=0.0;
for(int i=0; i<nSeg-1; i++) {
XPointDir2d ptVert;
double nVal=GetSegment(i);
nDist += nVal;
cv.Polar(nDist, ptVert);
lstVert.Insert(ptVert);
}
lstVert.AsPoly2D(poly);
}
int TDbDimension::HitTestOnDimSeg(XPoint pt) const
{
XCurveSegment cv=GetDimCurve();
XPoint ptOnDim;
if(cv.ProjectToMe(pt, ptOnDim)!=RTNORM)
return -1;
XPoly2D poly;
GetPolySegOnDimLine(poly);
int nSeg=poly.TotalSegments();
for(int i=0; i<nSeg; i++) {
XCurveSegment seg;
poly.Nth(i, seg);
if((ptOnDim&seg)==PR_INSIDE)
return i;
}
return -1;
}
int TDbDimension::HitTestOnText(XPoint pt) const
{
int nSeg=m_lstSegment.Length();
int nRet=-1;
double nDistMin=0.0;
for(int i=0; i<nSeg; i++) {
XPoint ptPos=GetTextPos(i);
if(nRet<0) {
nRet=i;
nDistMin=ptPos.Distance2d(pt);
} else {
double nDist=ptPos.Distance2d(pt);;
if(nDist<nDistMin) {
nDistMin=nDist;
nRet=i;
}
}
}
return nRet;
}
//add by whl on 041020
//返回节点索引,输入为近似节点,输出为准确节点,以系统拾取框大小为距离精度。
int TDbDimension::HitTestOnPoint(XPoint&pt)const
{
XCurveSegment cv=GetDimCurve();
XPoint ptOnDim;
if(cv.ProjectToMe(pt, ptOnDim)!=RTNORM)
return -1;
double nMaxDist=GetApertureWcs()/2;
XPoly2D poly;
GetPolySegOnDimLine(poly);
for(long i=0;i<poly.Length();i++)
if(ptOnDim.Distance2d(*poly[i])<=nMaxDist)
{
pt=*poly[i];
return i;
}
return -1;
}
// 角度-弦长-弧长
void TDbDimension::SwitchDimChord()
{
if(!IsAngular())
return;
BOOL bChord=IsDimChord();
BOOL bArcLen=IsDimArcLen();
if(!bChord && !bArcLen) { //角度
XCurveSegment cv=GetDimCurve();
XArc arDim=cv.GetArc();
double nObjRadius=GetObjRadius();
if(arDim.GetRadius() < nObjRadius) { //自动反向
double nDiff=nObjRadius-arDim.GetRadius();
arDim.SetRadius(arDim.GetRadius() + 2*nDiff);
SetDimRadius(arDim.GetRadius());
cv=arDim;
arDim.SetRadius(nObjRadius);
XCurveSegment segObj;
segObj=arDim;
XPoint ptNewLoc;
segObj.StartPoint().Mirror(GetLocation(), ptNewLoc);
double nDist=ptNewLoc.Distance2d(cv.StartPoint());
int nSide=cv.OnWhichSide(ptNewLoc);
if(nSide==OFFSET_LEFT)
nDist=-nDist;
SetDist2DimLine(nDist, FALSE);
SetLocation(ptNewLoc);
for(int i=0; i<m_lstTextPos.Length(); i++) {
TDimTextPos *pText=m_lstTextPos[i];
XPoint ptOnObj;
segObj.ProjectToMe(pText->ptPos, ptOnObj);
ptOnObj.Mirror(XPoint(pText->ptPos), pText->ptPos);
}
}
SetStyleId(InitDimStyle(DS_LINEAR));
SetDimChord(TRUE);
SetDimArcLen(FALSE);
} else if(bChord) {
SetStyleId(InitDimStyle(DS_ANGLE));
SetDimChord(FALSE);
SetDimArcLen(TRUE);
} else {
SetStyleId(InitDimStyle(DS_ANGLE));
SetDimChord(FALSE);
SetDimArcLen(FALSE);
}
}
void TDbDimension::RemoveZeroSegment()
{
assertWriteEnabled();
int nSeg=m_lstSegment.Length();
double nPrec=IsAngular()? _angSnap : _DIST_SNAP;
for(int i=0; i<nSeg; i++) {
if(*m_lstSegment[i]<nPrec) {
RemoveSegment(i);
i--;
nSeg--;
}
}
}
void TDbDimension::RemoveSegment(int iSeg)
{
assertWriteEnabled();
int nSeg=m_lstSegment.Length();
ASSERT(iSeg>=0 && iSeg<nSeg);
m_lstSegment.Remove(iSeg);
if(m_lstTextPos.FindNode(&iSeg, TDimTextPos::CompareByIndexForFind))
m_lstTextPos.Remove();
int nTextSeg=m_lstTextPos.Length();
for(int i=0; i<nTextSeg; i++) {
TDimTextPos *pNode=m_lstTextPos[i];
if(pNode->nIndex>iSeg)
pNode->nIndex--;
}
if(m_lstTextContent.FindNode(&iSeg, TDimTextContent::CompareByIndexForFind))
m_lstTextContent.Remove();
nTextSeg=m_lstTextContent.Length();
for(i=0; i<nTextSeg; i++) {
TDimTextContent *pNode=m_lstTextContent[i];
if(pNode->nIndex>iSeg)
pNode->nIndex--;
}
AutoSetFlag();
}
void
TDbDimension::InsertSegmentAt(int n, double nVal, BOOL bDist)
{
assertWriteEnabled();
ASSERT(IsValidSegment(nVal, bDist));
if(n>=0 && n<m_lstSegment.Length()) {
if(IsAngular() && bDist)
nVal=nVal/m_nDimRadius;
m_lstSegment[n];
m_lstSegment.Insert(new double(nVal));
int nTextSeg=m_lstTextPos.Length();
for(int i=0; i<nTextSeg; i++) {
TDimTextPos *pNode=m_lstTextPos[i];
if(pNode->nIndex>=n)
pNode->nIndex++;
}
nTextSeg=m_lstTextContent.Length();
for(i=0; i<nTextSeg; i++) {
TDimTextContent *pNode=m_lstTextContent[i];
if(pNode->nIndex>=n)
pNode->nIndex++;
}
} else if(n>=m_lstSegment.Length()) {
AppendSegment(nVal, bDist);
}
AutoSetFlag();
}
void
TDbDimension::SetSegment(int n, double nVal, BOOL bDist)
{
assertWriteEnabled();
ASSERT(IsValidSegment(nVal, bDist));
if(n>=0 && n<m_lstSegment.Length()) {
if(IsAngular() && bDist)
nVal=nVal/m_nDimRadius;
*m_lstSegment[n]=nVal;
}
}
// 在指定的位置加入一区间
BOOL TDbDimension::AddSegment(XPoint ptAdd)
{
assertWriteEnabled();
XCurveSegment cv=GetDimCurve();
XPoint ptOnDim;
if(cv.ProjectToMe(ptAdd, ptOnDim)!=RTNORM)
return FALSE;
int nPrFlag=(ptOnDim&cv);
if(nPrFlag==PR_ONPT1 && nPrFlag==PR_ONPT2)
return FALSE;
BOOL bRet=FALSE;
if(nPrFlag==PR_INSIDE)
{
XPoly2D poly;
GetPolySegOnDimLine(poly);
int nSeg=poly.TotalSegments();
for(int n=0; n<nSeg; n++)
{
XCurveSegment seg;
poly.Nth(n, seg);
if((ptOnDim&seg)==PR_INSIDE)
{
double nVal=fabs(seg.PathDistance(ptOnDim));
double nVal1=fabs(seg.PathDistance(ptOnDim, FALSE)); //距离终点的距离
if(IsValidSegment(nVal) && IsValidSegment(nVal1))
{
TDimTextPos *pNode=m_lstTextPos.FindNode(&n, TDimTextPos::CompareByIndexForFind);
if(pNode) m_lstTextPos.Remove();
SetSegment(n, nVal1);
InsertSegmentAt(n, nVal);
bRet=TRUE;
}
break;
}
}
}
else if(ptOnDim.Distance2d(cv.EndPoint()) < ptOnDim.Distance2d(cv.StartPoint()))
{
double nVal=fabs(cv.PathDistance(ptOnDim, FALSE));
if(IsValidSegment(nVal))
{
AppendSegment(nVal);
bRet=TRUE;
}
}
else
{
double nVal=fabs(cv.PathDistance(ptOnDim, TRUE));
if(IsValidSegment(nVal))
{
cv.SetPoints(ptOnDim, XPoint(cv.EndPoint()));
InsertSegmentAt(0, nVal);
m_nRotation = cv.IDirection(0);
ads_polar(cv.StartPoint(), m_nRotation-PI/2, m_nDist2DimLine*GetPScale(), m_ptLocation);
bRet=TRUE;
}
}
if(bRet)
AutoSetFlag();
return bRet;
}
//add by whl on 040810
BOOL TDbDimension::FindAndRemoveSegment(XPoint pt)
{
XCurveSegment seg=GetDimCurve();
XPoint ptOnSeg;
seg.ProjectToMe(pt, ptOnSeg);
double value=seg.PathDistance(ptOnSeg);
long i=-1;
if(value>_DIST_SNAP)
{
double curValue=0;
for(i=0;i<GetSegmentNum();i++)
{
curValue+=GetSegment(i);
if(fabs(curValue-value)<_DIST_SNAP)
break;
}
}
if(i>=GetSegmentNum())
return FALSE;//useful
if(i>=0)
{
double temp=GetSegment(i);
if(i<GetSegmentNum()-1)//是中间段
SetSegment(i+1,temp+GetSegment(i+1));//后一段合并之
RemoveSegment(i);
}
else//第一个标注段的起点特殊处理,弧段不对!
{
double temp=GetSegment(0);
RemoveSegment(0);
XVector3D vt=seg.EndPoint()-seg.StartPoint();
vt.Scale(temp/vt.Length());
SetLocation(GetLocation()+vt);
}
return TRUE;
}
BOOL TDbDimension::MergeDim(const TDbDimension *pDim)
{
assertWriteEnabled();
if(!IsUseDefaultText())
return FALSE;
XCurveSegment cv=GetDimCurve();
XSortedVertexList lstVert(cv);
int nSeg=m_lstSegment.Length();
double nDist=0.0;
for(int i=0; i<nSeg-1; i++) {
XPointDir2d ptVert;
double nVal=GetSegment(i);
nDist += nVal;
cv.Polar(nDist, ptVert);
lstVert.Insert(ptVert);
}
XPoly2D poly;
pDim->GetPolySegOnDimLine(poly);
for(i=0; i<poly.Length(); i++) {
XPoint ptVert;
if(cv.ProjectToMe(*poly[i], ptVert)==RTNORM)
lstVert.Insert(ptVert, TRUE);
}
m_lstTextPos.Reset();
m_lstSegment.Reset();
XPoly2D polyNew;
lstVert.AsPoly2D(polyNew);
nSeg=polyNew.TotalSegments();
for(i=0; i<nSeg; i++) {
XCurveSegment seg;
polyNew.Nth(i, seg);
double nVal=seg.GetLength();
ASSERT(nVal>_DIST_SNAP);
if(IsValidSegment(nVal))
AppendSegment(nVal);
if(i==0) {
m_nRotation=seg.IDirection(0);
ads_polar(seg.StartPoint(), m_nRotation-PI/2, m_nDist2DimLine*GetPScale(), m_ptLocation);
}
}
AutoSetFlag();
return TRUE;
}
BOOL TDbDimension::ConvertFrom(const AcDbDimension *pDim)
{
assertWriteEnabled();
double nScale=100.0;
AcDbObjectId idStyle=DimStyleAcad2Tch(pDim->dimensionStyle(), nScale);
SetPScale(nScale);
//double val;
//VERIFY(pDim->measurement(val)==Acad::eOk);
XString sText;
sText=pDim->dimensionText();
double dotVec=pDim->normal().dotProduct(AcGeVector3d(0,0,1));
if(fabs(dotVec-1.0)>1.0E-6 || !idStyle)
return FALSE;
setPropertiesFrom(pDim);
m_idDimStyle = idStyle;
m_lstTextPos.Reset();
if(!pDim->isUsingDefaultTextPosition()) {
m_lstTextPos.Append(new TDimTextPos(0, XPoint(pDim->textPosition())));
}
m_lstTextContent.Reset();
if(!!sText)
m_lstTextContent.Append(new TDimTextContent(0, sText));
BOOL bRet=FALSE;
if(pDim->isKindOf(AcDb2LineAngularDimension::desc())||
pDim->isKindOf(AcDb3PointAngularDimension::desc())) {
AcDb3PointAngularDimension *pDim1=AcDb3PointAngularDimension::cast(pDim);
AcDb2LineAngularDimension *pDim2=AcDb2LineAngularDimension::cast(pDim);
XPoint pt1, pt2, ptDim, ptCen;
if(pDim1) {
pt1=pDim1->xLine1Point();
pt2=pDim1->xLine2Point();
ptDim=pDim1->arcPoint();
ptCen=pDim1->centerPoint();
} else {
pt1=pDim2->xLine1Start();
pt2=pDim2->xLine2Start();
ptDim=pDim2->arcPoint();
XPoint qt1=pDim2->xLine1End(),
qt2=pDim2->xLine2End();
XLine ll(pt2, qt2);
XLine(pt1, qt1).Intersection(&ll, ptCen);
}
m_nDimRadius=ptCen.Distance2d(ptDim);
SetAngular(TRUE);
SetDimChord(FALSE);
m_ptLocation=pt1;
m_ptLocation.z=0;
m_nRotation=ads_angle(ptCen, pt1)+PI/2;
XArc arDim(ptCen, m_nDimRadius, ads_angle(ptCen, pt1), ads_angle(ptCen, pt2));
XCurveSegment segDim;
segDim=arDim;
//XPoint ptOnDim1;
//pt1.Project(arDim, ptOnDim1);
double nDist2DimLine=fabs(m_nDimRadius-ptCen.Distance2d(pt1));
int nSide=segDim.OnWhichSide(m_ptLocation);
if(nSide==OFFSET_LEFT)
nDist2DimLine=-nDist2DimLine;
m_nObjRadius=m_nDimRadius+nDist2DimLine;
SetDist2DimLine(nDist2DimLine, FALSE);
m_lstSegment.Reset();
if(IsValidSegment(arDim.Bulge(), FALSE)) {
AppendSegment(arDim.Bulge(), FALSE);
bRet=TRUE;
}
} else if(pDim->isKindOf(AcDbAlignedDimension::desc()) ||
pDim->isKindOf(AcDbRotatedDimension::desc())) {
AcDbAlignedDimension *pDim1=AcDbAlignedDimension::cast(pDim);
AcDbRotatedDimension *pDim2=AcDbRotatedDimension::cast(pDim);
ASSERT(pDim1 || pDim2);
XPoint pt1, pt2, ptDim;
if(pDim1) {
pt1=pDim1->xLine1Point();
pt2=pDim1->xLine2Point();
ptDim=pDim1->dimLinePoint();
} else {
pt1=pDim2->xLine1Point();
pt2=pDim2->xLine2Point();
ptDim=pDim2->dimLinePoint();
if(!CT_IsSameDrt(ads_angle(pt1, pt2), pDim2->rotation(), _angSnap))
return FALSE;
}
m_nDimRadius=m_nObjRadius=0;
SetAngular(FALSE);
SetDimChord(FALSE);
m_ptLocation=pt1;
m_ptLocation.z=0;
m_nRotation=ads_angle(pt1, pt2);
XPoint ptOnDim1, ptOnDim2;
XLine ll(ptDim, m_nRotation);
pt1.Project(&ll, ptOnDim1);
pt2.Project(&ll, ptOnDim2);
int nSide=XLine(ptDim, m_nRotation).OnWhichSide(m_ptLocation);
m_nDist2DimLine=pt1.Distance2d(ptOnDim1)/GetPScale();
if(nSide==OFFSET_LEFT)
m_nDist2DimLine=-m_nDist2DimLine;
m_lstSegment.Reset();
double nVal=ptOnDim1.Distance2d(ptOnDim2);
if(IsValidSegment(nVal)) {
AppendSegment(nVal);
bRet=TRUE;
}
}
if(bRet)
AutoSetFlag();
return bRet;
}
// Properties
double TDbDimension::GetSegment(int n, BOOL bDist) const
{
ASSERT(n>=0 && n<m_lstSegment.Length());
double nVal=m_lstSegment[n];
if(IsAngular() && bDist) {
ASSERT(m_nDimRadius>_DIST_SNAP);
nVal *= m_nDimRadius;
}
return nVal;
}
double
TDbDimension::GetTotalSegValue() const
{
double nVal=0.0;
int nCount=m_lstSegment.Length();
for(int i=0; i<nCount; i++)
nVal += m_lstSegment[i];
return nVal;
}
BOOL
TDbDimension::IsAngular() const
{
return ((m_nDimFlag&DF_ANGULAR)!=0);
//return (m_nDimRadius>_angSnap);
}
int TDbDimension::GetSegmentNum() const
{
return m_lstSegment.Length();
}
double
TDbDimension::GetObjRadius() const
{
return m_nObjRadius;
}
BOOL
TDbDimension::IsDimChord() const
{
return ((m_nDimFlag&DF_CHORD));
}
BOOL
TDbDimension::IsDimArcLen() const
{
return ((m_nDimFlag&DF_ARCLEN));
}
XPoint
TDbDimension::GetLocation() const
{
return m_ptLocation;
}
double
TDbDimension::GetRotation() const
{
return m_nRotation;
}
double
TDbDimension::GetDist2DimLine(BOOL bAsPaperUnit) const
{
double val=m_nDist2DimLine;
if(!bAsPaperUnit)
val *= GetPScale();
return val;
}
double
TDbDimension::GetDimRadius() const
{
return m_nDimRadius;
}
AcDbObjectId
TDbDimension::GetStyleId() const
{
return m_idDimStyle;
}
static void DelSuffixZero(TCHAR *sText)
{
if(!sText)
return;
size_t nLen=_tcslen(sText);
TCHAR *pDot=_tcschr(sText, _T('.'));
if(pDot) {
for(size_t i=nLen-1; i>=0; i--) {
if(sText[i]!=_T('0')) {
if(sText[i]==_T('.'))
sText[i]=0;
break;
} else {
sText[i]=0;
}
}
}
}
// Modify on 2002/02/05, 考虑dimlfac进行单位换算
XString
TDbDimension::GetDefaultText(int nIndex) const
{
ASSERT(nIndex<m_lstSegment.Length() && nIndex>=0);
XPoly2D poly;
GetPolySegOnDimLine(poly);
XCurveSegment seg;
poly.Nth(nIndex, seg);
int dimdec, dimadec;
double dimlfac=1.0;
int dimaunit=0;
int dimzin=0;
int dimazin=0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
ASSERT(pDimStyle);
dimdec=pDimStyle->dimdec();
dimadec=pDimStyle->dimadec();
dimlfac=pDimStyle->dimlfac();
dimaunit=pDimStyle->dimaunit();
dimzin=pDimStyle->dimzin();
dimazin=pDimStyle->dimazin();
if(dimaunit>1)
dimaunit=1;
OPENOBJ_END();
XString sText;
if(IsAngular()) {
if(IsDimChord()) {
ASSERT(0); //永远也不会执行这儿
ftoa(seg.XLine::GetLength()*dimlfac, dimdec, sText);
} else if(IsDimArcLen()) {
XArc ar=seg.GetArc();
ar.SetRadius(m_nObjRadius);
ftoa(ar.GetLength()*dimlfac, dimdec, sText);
} else {
XString sTemp;
ads_angtos(fabs(seg.GetBulge()), dimaunit, dimadec, sTemp);
const TCHAR *pd=_tcschr(sTemp, _T('d'));
if(pd) {
StrCpy(sText, sTemp, pd);
sText << _T("%%d");
sText << (pd+1);
} else if(dimaunit==0) {
if(dimazin&0x02)
DelSuffixZero(sTemp);
sText << sTemp << _T("%%d");
}else {
sText << sTemp;
}
}
} else {
ftoa(seg.GetLength()*dimlfac, dimdec, sText);
if((dimzin&0x08)!=0) {
DelSuffixZero(sText);
}
}
return sText;
}
XString
TDbDimension::GetText(int nIndex, BOOL *bIsDefault) const
{
XString sText;
TDimTextContent *pNode=((TDbDimension *)this)->m_lstTextContent.FindNode(&nIndex, TDimTextContent::CompareByIndexForFind);
if(pNode) {
sText=pNode->sText;
if(bIsDefault) *bIsDefault=FALSE;
} else {
if(bIsDefault) *bIsDefault=TRUE;
sText=GetDefaultText(nIndex);
}
return sText;
}
XPoint
TDbDimension::GetTextPos(int nIndex, BOOL *bIsDefault) const
{
ASSERT(nIndex<m_lstSegment.Length() && nIndex>=0);
TDimTextPos *pNode=((TDbDimension *)this)->m_lstTextPos.FindNode(&nIndex, TDimTextPos::CompareByIndexForFind);
if(pNode) {
if(bIsDefault) *bIsDefault=FALSE;
return pNode->ptPos;
}
if(bIsDefault)
*bIsDefault=TRUE;
XPoint ptText=GetDefaultTextPos(nIndex);
return ptText;
}
XPoint
TDbDimension::GetDefaultTextPos(int nIndex) const
{
ASSERT(nIndex<m_lstSegment.Length() && nIndex>=0);
XPoly2D poly;
GetPolySegOnDimLine(poly);
double nOffDist=m_nDist2DimLine*GetPScale();
BOOL bAngular=IsAngular();
int nSeg=poly.TotalSegments();
XCurveSegment seg;
poly.Nth(nIndex, seg);
ASSERT(!!seg);
XPointDir2d ptTextPos;
seg.Polar(seg.GetLength()/2.0, ptTextPos);
XPoint ptText=ptTextPos;
double nDist2Dim=0.0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
if(pDimStyle)
nDist2Dim = (pDimStyle->dimgap() + pDimStyle->dimtxt()/2)*GetPScale(); //pDimStyle->dimscale();
else
nDist2Dim = 3.0*GetPScale();
OPENOBJ_END();
XPoint ptBase;
if(IsAngular() && IsDimChord()) {
Midpoint(seg.StartPoint(), seg.EndPoint(), ptBase);
} else {
ptBase=ptTextPos;
}
ads_polar(ptBase, NormalViewAngle(ptTextPos.nDirection)+PI/2.0, nDist2Dim, ptText);
return ptText;
}
AcDbObjectId
TDbDimension::GetBindId() const
{
return m_idBind;
}
void
TDbDimension::SetLocation(XPoint pt)
{
assertWriteEnabled();
m_ptLocation=pt;
m_ptLocation.z=0;
}
void
TDbDimension::SetRotation(double nAng)
{
assertWriteEnabled();
m_nRotation=nAng;
}
void
TDbDimension::SetDist2DimLine(double nVal, BOOL bAsPaperUnit)
{
assertWriteEnabled();
m_nDist2DimLine=nVal;
if(!bAsPaperUnit)
m_nDist2DimLine /= GetPScale();
}
void
TDbDimension::SetAngular(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue) m_nDimFlag |= DF_ANGULAR;
else m_nDimFlag &= ~DF_ANGULAR;
}
void
TDbDimension::SetDimChord(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue) m_nDimFlag |= DF_CHORD;
else m_nDimFlag &= ~DF_CHORD;
}
void
TDbDimension::SetDimArcLen(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue) m_nDimFlag |= DF_ARCLEN;
else m_nDimFlag &= ~DF_ARCLEN;
}
void
TDbDimension::SetObjRadius(double nVal)
{
assertWriteEnabled();
m_nObjRadius = nVal;
}
void
TDbDimension::SetDimRadius(double nAng)
{
assertWriteEnabled();
m_nDimRadius=nAng;
}
void
TDbDimension::SetStyleId(AcDbObjectId idStyle)
{
assertWriteEnabled();
m_idDimStyle=idStyle;
}
void TDbDimension::SetTextPos(int nIndex, XPoint ptPos)
{
assertWriteEnabled();
ASSERT(nIndex<m_lstSegment.Length() && nIndex>=0);
TDimTextPos *pNode=m_lstTextPos.FindNode(&nIndex, TDimTextPos::CompareByIndexForFind);
if(!pNode) {
XPoint ptOld=GetTextPos(nIndex);
if(ptOld.Distance2d(ptPos)>_DIST_SNAP)
m_lstTextPos.Append(new TDimTextPos(nIndex, ptPos));
} else {
int nPos=m_lstTextPos.CurPosition();
XPoint ptDefault=GetDefaultTextPos(nIndex);
if(ptDefault.Distance2d(ptPos)<_DIST_SNAP)
m_lstTextPos.Remove(nPos);
else
m_lstTextPos[nPos]->ptPos=ptPos;
}
AutoSetFlag();
}
void TDbDimension::SetTextContent(int n, const TCHAR *pszChar)
{
assertWriteEnabled();
ASSERT(n<m_lstSegment.Length() && n>=0);
TDimTextContent *pNode=m_lstTextContent.FindNode(&n, TDimTextContent::CompareByIndexForFind);
if(!pNode) {
if(pszChar && pszChar[0])
m_lstTextContent.Append(new TDimTextContent(n, pszChar));
} else {
if(!pszChar || !pszChar[0])
m_lstTextContent.Remove();
else
pNode->sText=pszChar;
}
AutoSetFlag();
}
void TDbDimension::SetBindId(AcDbObjectId id)
{
assertWriteEnabled();
m_idBind=id;
AutoSetFlag();
}
void
TDbDimension::AppendSegment(double nVal, BOOL bDist)
{
assertWriteEnabled();
ASSERT(IsValidSegment(nVal, bDist));
if(IsAngular() && bDist)
nVal = nVal/m_nDimRadius;
m_lstSegment.Append(new double(nVal));
}
void
TDbDimension::ResetTextPos()
{
assertWriteEnabled();
m_lstTextPos.Reset();
AutoSetFlag();
}
void
TDbDimension::ResetTextContent()
{
assertWriteEnabled();
m_lstTextContent.Reset();
AutoSetFlag();
}
BOOL
TDbDimension::IsTextMoved() const
{
return ((m_nDimFlag&DF_POSITION)!=0 && m_lstTextPos.Length());
}
BOOL
TDbDimension::IsUseDefaultText() const
{
return ((m_nDimFlag&DF_TEXT)==0 || m_lstTextContent.Length()==0);
}
BOOL
TDbDimension::IsBind() const
{
return ((m_nDimFlag&DF_BIND)!=0 && !!m_idBind);
}
BOOL
TDbDimension::IsUseDimStyleScale() const
{
return ((m_nDimFlag&DF_DSSCALE)!=0);
}
void
TDbDimension::UseDimStyleScale(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nDimFlag |= DF_DSSCALE;
else
m_nDimFlag &= ~DF_DSSCALE;
}
void TDbDimension::AutoSetFlag()
{
assertWriteEnabled();
if(!!m_idBind)
m_nDimFlag |= DF_BIND;
else
m_nDimFlag &= ~DF_BIND;
if(m_lstTextPos.Length())
m_nDimFlag |= DF_POSITION;
else
m_nDimFlag &= ~DF_POSITION;
if(m_lstTextContent.Length())
m_nDimFlag |= DF_TEXT;
else
m_nDimFlag &= ~DF_TEXT;
}
/////////////////////////////////////////////////////////////
// 新尺寸对象类
/////////////////////////////////////////////////////////////
//TArch7-1,
const Adesk::UInt8 TDbDimension2::g_nVersion = 1;
ACRX_DXF_DEFINE_MEMBERS(ATSDimension2, ATSCurveEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_DIMENSION2, "ATS_DIMENSION2图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbDimension2);
//BOOL TDbDimension2::g_bExplAcadDim=TRUE;
TDbDimension2::TDbDimension2()
{
m_nRotation=0; //旋转角度
m_nDist2DimLine=0; //定位点到尺寸线的距离, 可以为负值
m_nDimRadius=0; //夹角,可以为负
m_nObjRadius=0;
m_nDimFlag=g_bDynDim?DF_ASSOCIATE:0;
}
TDbDimension2::~TDbDimension2()
{
}
BOOL TDbDimension2::IsValid() const
{
BOOL bRet=TDbCurveEntity::IsValid();
if(!bRet)
return bRet;
bRet=m_lstSegment.Length()>=1;
return bRet;
}
BOOL TDbDimension2::IsValidSegment(double nVal, BOOL bDist) const
{
double nPrec=IsAngular()? _angSnap : _DIST_SNAP;
if(IsAngular() && bDist) {
ASSERT(m_nDimRadius>_DIST_SNAP);
nVal = nVal/m_nDimRadius;
}
return (nVal>nPrec);
}
void TDbDimension2::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
double nOldScale=GetPScale();
double nDimDist=GetDist2DimLine(FALSE);
TDbCurveEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbDimension2 *pSrc=TDbDimension2::cast(pSrcEntity);
if(pSrc) {
if(database()==NULL||
pSrcEntity->database()==NULL||
database()==pSrcEntity->database())//add by whl on 060317
{
m_idDimStyle=pSrc->m_idDimStyle; //尺寸标注类型
}
UseDimStyleScale(pSrc->IsUseDimStyleScale());
}
double nNewScale=GetPScale();
if(fabs(nNewScale-nOldScale)>1.0E-3 && IsAngular()) {
SetDist2DimLine(nDimDist, FALSE);
}
}
Acad::ErrorStatus
TDbDimension2::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
// 从DWG读入数据:
Acad::ErrorStatus TDbDimension2::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbCurveEntity::dwgInFields(pFiler);
if(es != Acad::eOk) return es;
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
if(nVer>g_nVersion) {// Version is too new
return Acad::eMakeMeProxy;
}
pFiler->readItem((AcGePoint3d *)&m_ptLocation); //定位点--即不动点
m_ptLocation.z=0; //必须是二维
pFiler->readItem(&m_nRotation); //旋转角度
pFiler->readItem(&m_nDist2DimLine); //定位点到尺寸线的距离, 可以为负值
pFiler->readItem(&m_idDimStyle); //尺寸标注类型
m_lstSegment.Reset();
Adesk::UInt16 nSeg=0;
pFiler->readItem(&nSeg);
for(Adesk::UInt16 i=0; i<nSeg; i++) {
double nVal=0;
pFiler->readItem(&nVal);
m_lstSegment.Append(new double(nVal));
}
pFiler->readItem(&m_nDimFlag);
m_lstTextPos.Reset();
if(m_nDimFlag&DF_POSITION) {
m_lstTextPos.Reset();
Adesk::UInt16 nTextSeg=0;
pFiler->readItem(&nTextSeg);
for(i=0; i<nTextSeg; i++) {
AcGePoint2d ptPos;
Adesk::UInt16 nIndex;
pFiler->readItem(&nIndex);
pFiler->readItem(&ptPos);
m_lstTextPos.Append(new TDimTextPos(nIndex, XPoint(ptPos[0], ptPos[1])));
}
}
m_lstTextContent.Reset();
if(m_nDimFlag&DF_TEXT) {
Adesk::UInt16 nTextSeg=0;
pFiler->readItem(&nTextSeg);
for(i=0; i<nTextSeg; i++) {
XString sText;
Adesk::UInt16 nIndex;
pFiler->readItem(&nIndex);
ReadString(pFiler, sText);
m_lstTextContent.Append(new TDimTextContent(nIndex, sText));
}
}
if(m_nDimFlag&DF_BIND)
pFiler->readItem(&m_idBind);
if(IsAngular()) {
pFiler->readItem(&m_nDimRadius);
pFiler->readItem(&m_nObjRadius);
}
m_lstOffset.Reset();
if(m_nDimFlag&DF_ASSOCIATE)
{
Adesk::UInt16 nSeg=0;
pFiler->readItem(&nSeg);
for(Adesk::UInt16 i=0; i<nSeg; i++)
{
double nVal=0;
pFiler->readItem(&nVal);
m_lstOffset.Append(new double(nVal));
}
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbDimension2::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbCurveEntity::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem((const AcGePoint3d &)m_ptLocation); //定位点--即不动点
pFiler->writeItem(m_nRotation); //旋转角度
pFiler->writeItem(m_nDist2DimLine); //定位点到尺寸线的距离, 可以为负值
pFiler->writeItem(m_idDimStyle); //尺寸标注类型
Adesk::UInt16 nSeg=m_lstSegment.Length();
pFiler->writeItem(nSeg);
for(Adesk::UInt16 i=0; i<nSeg; i++) {
double nVal=m_lstSegment[i];
pFiler->writeItem(nVal);
}
pFiler->writeItem(m_nDimFlag);
if(m_nDimFlag&DF_POSITION) {
Adesk::UInt16 nTextSeg=m_lstTextPos.Length();
pFiler->writeItem(nTextSeg);
for(i=0; i<nTextSeg; i++) {
const TDimTextPos &pTextPos=m_lstTextPos[i];
pFiler->writeItem(pTextPos.nIndex);
pFiler->writeItem((const AcGePoint2d &)pTextPos.ptPos);
}
}
if(m_nDimFlag&DF_TEXT) {
Adesk::UInt16 nTextSeg=m_lstTextContent.Length();
pFiler->writeItem(nTextSeg);
for(i=0; i<nTextSeg; i++) {
const TDimTextContent &text=m_lstTextContent[i];
pFiler->writeItem(text.nIndex);
pFiler->writeString(text.sText);
}
}
if(IsBind()) {
pFiler->writeItem(m_idBind);
}
if(IsAngular()) {
pFiler->writeItem(m_nDimRadius); //夹角,可以为负
pFiler->writeItem(m_nObjRadius);
}
if(IsAssociate())
{
Adesk::UInt16 nSeg=m_lstOffset.Length();
pFiler->writeItem(nSeg);
for(Adesk::UInt16 i=0; i<nSeg; i++)
{
double nVal=m_lstOffset[i];
pFiler->writeItem(nVal);
}
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbDimension2::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbCurveEntity::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbDimension2"))) {
return Acad::eBadDxfSequence;
}
return pFiler->filerStatus();
// 不读入任何数据
}
Acad::ErrorStatus TDbDimension2::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es=TDbCurveEntity::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbDimension2"));
assert(es == Acad::eOk);
return es;
}
// -----------------------------------------------------------------------
Acad::ErrorStatus
TDbDimension2::subGetOsnapPoints(AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
Acad::ErrorStatus es = Acad::eOk;
switch (osnapMode) {
case AcDb::kOsModeNode:
case AcDb::kOsModeIns: {
double nOffDist=m_nDist2DimLine*GetPScale();
XCurveSegment cv=GetDimCurve();
XCurveSegment cvFix=cv.Offset(nOffDist, LS_FINITE);
XPoly2D poly;
GetPolySegOnDimLine(poly);
if(osnapMode==AcDb::kOsModeNode) {
int nVertNum=poly.Length();
for(int i=0; i<nVertNum; i++) {
XPoint ptFix;
cvFix.ProjectToMe(*poly[i], ptFix);
snapPoints.append(*poly[i]);
snapPoints.append(ptFix);
}
} else {
int nSeg=poly.TotalSegments();
for(int i=0; i<nSeg; i++) {
XPoint ptText = GetTextPos(i);
snapPoints.append(ptText);
}
}
}
break;
default: {
//XPushMemVar<BOOL> vTemp(g_bExplAcadDim, FALSE);
TDbCurveEntity::subGetOsnapPoints(osnapMode, gsSelectionMark, pickPoint,
lastPoint, viewXform, snapPoints,
geomIds);
}
return Acad::eOk;
}
return es;
}
// Overriden functions for edit
// to do:
// 允许通过夹点改变边界
Acad::ErrorStatus TDbDimension2::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
double nOffDist=m_nDist2DimLine*GetPScale();
XCurveSegment cv=GetDimCurve();
XCurveSegment cvFix=cv.Offset(nOffDist, LS_FINITE);
XCurveSegment cvObj;
if(IsAngular()) {
double nDist2Obj=cv.GetArc().GetRadius()-m_nObjRadius;
cvObj=cv.Offset(-nDist2Obj, LS_FINITE);
}
XPoly2D poly;
GetPolySegOnDimLine(poly);
int nVertNum=poly.Length();
gripPoints.append(*poly.Head()); //0
gripPoints.append(*poly.Tail()); //1
for(int i=0; i<nVertNum; i++)
{
XPoint ptFix;
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
cvObj.ProjectToMe(*poly[i], ptFix);
else cvFix.ProjectToMe(*poly[i], ptFix);
gripPoints.append(ptFix);
}
int nSeg=poly.TotalSegments();
BOOL bIsDef = false;
for(i=0; i<nSeg; i++)
{
XPoint ptText = GetTextPos(i);
gripPoints.append(ptText);
}
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
gripPoints.append(m_ptLocation);
else if(!IsAngular()&&IsAssociate())
{
XCurveSegment curve=GetDimCurve();
if(m_nDist2DimLine>0)
curve=curve.Offset((m_nDist2DimLine+GetMaxScope())*GetPScale(),0);
else
curve=curve.Offset((m_nDist2DimLine-GetMaxScope())*GetPScale(),0);
gripPoints.append(curve.StartPoint());
gripPoints.append(curve.MidPoint());
gripPoints.append(curve.EndPoint());
}
return Acad::eOk;
}
// stretch points is diffrent from grep points, with no midpoint included
Acad::ErrorStatus TDbDimension2::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
assertReadEnabled();
AcDbIntArray osnapModes;
AcDbIntArray geomIds;
return subGetGripPoints(stretchPoints, osnapModes, geomIds);
}
void TDbDimension2::UnionScale(double nScale)
{
assertWriteEnabled();
AcGeMatrix3d mat;
mat.setToScaling(nScale);
m_ptLocation.TransformBy(mat);
for(int i=0; i<m_lstTextPos.Length(); i++)
m_lstTextPos[i]->ptPos.TransformBy(mat);
for(i=0;i<m_lstSegment.Length();i++)
(*m_lstSegment[i])*=nScale;
m_nDimRadius*=nScale;
m_nObjRadius*=nScale;
for(i=0;i<m_lstOffset.Length();i++)
(*m_lstOffset[i])*=nScale;
}
// Active when being rotated, scaled, moved, etc.
// Scale is disabled here
Acad::ErrorStatus TDbDimension2::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
TDbCurveEntity::subTransformBy(xform);
ads_matrix mat;
AsAdsMatrix(xform, mat);
for(int i=0; i<m_lstTextPos.Length(); i++) {
m_lstTextPos[i]->ptPos.TransformBy(mat);
}
if(IsAngular()) {
XCurveSegment cv=GetDimCurve();
cv.TransformBy(mat);
m_nRotation=cv.IDirection(0);
ads_polar(cv.StartPoint(), m_nRotation-PI/2, GetDist2DimLine(FALSE), m_ptLocation);
if(IsMirrorMatrix(mat)) {
m_lstTextPos.Reverse();
m_lstTextContent.Reverse();
m_lstSegment.Reverse();
}
} else {
m_ptLocation.TransformBy(mat);
m_ptLocation.z=0;
XVector3D vt(cos(m_nRotation), sin(m_nRotation));
((AcGeVector3d &)vt).transformBy(xform);
m_nRotation = ads_angle(XPoint(), vt);
if(IsMirrorMatrix(mat)) {
m_nDist2DimLine=-m_nDist2DimLine;
}
}
return Acad::eOk;
}
//设置尺寸线位置
BOOL TDbDimension2::SetDimLinePos(XPoint pt)
{
assertWriteEnabled();
BOOL bRet=FALSE;
XCurveSegment seg=GetDimCurve();
XPoint ptOnSeg;
if(seg.ProjectToMe(pt, ptOnSeg)==RTNORM) {
double nDistMove=pt.Distance2d(ptOnSeg);
int nSideLoc=seg.OnWhichSide(GetLocation());
int nSide=seg.OnWhichSide(pt);
double nDist2Dim=GetDist2DimLine(FALSE);
if(fabs(nDist2Dim)>1.0E-6) {
double nFactor=nDist2Dim/fabs(nDist2Dim);
if(nSide!=nSideLoc)
nDistMove *= nFactor;
else
nDistMove *= -nFactor;
} else {
if(nSideLoc=OFFSET_LEFT) nDistMove=-nDistMove;
}
if(IsAngular()) {
nDist2Dim += nDistMove;
double nDistRad= GetDimRadius();
nDistRad -= nDistMove;
if(nDistRad>_DIST_SNAP) {
SetDimRadius(nDistRad);
SetDist2DimLine(nDist2Dim, FALSE);
}
} else {
nDist2Dim += nDistMove;
SetDist2DimLine(nDist2Dim, FALSE);
}
bRet=TRUE;
}
return bRet;
}
//设置标注固定线位置
BOOL TDbDimension2::SetFixLinePos(XPoint pt)
{
assertWriteEnabled();
XCurveSegment seg=GetDimCurve();
double nOffDist=m_nDist2DimLine*GetPScale();
XCurveSegment cvFix=seg.Offset(nOffDist, LS_FINITE);
double nDist=cvFix.GetDist2Me(pt);
XCurveSegment cvNewFix=cvFix.Offset(nDist, LS_FINITE);
if(!cvNewFix)
return FALSE;
XPoint ptNew = cvNewFix.NearPoint(m_ptLocation);
m_nDist2DimLine = (nOffDist+nDist)/GetPScale();
m_ptLocation = ptNew;
return TRUE;
}
// 功能: 夹点操作, 还没有完全考虑圆弧类型
Acad::ErrorStatus TDbDimension2::MoveGripPointsAt1(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
AcGePoint3dArray gripPoints;
AcDbIntArray ar;
subGetGripPoints(gripPoints, ar, ar);
AcGeVector3d vtLocal(offset[0], offset[1], 0.0);
for (int i = 0; i < indices.length(); i++) {
int idx = indices[i];
gripPoints[idx] += vtLocal;
}
int nVertNum=m_lstSegment.Length()+1;
XCurveSegment cv=GetDimCurve();
cv.SetPoints(XPoint(gripPoints[0]), XPoint(gripPoints[1]));
XPoint ptS, ptE;
XPoint ptS1=gripPoints[2], ptE1=gripPoints[2+nVertNum-1];
if(cv.ProjectToMe(ptS1, ptS)==RTNORM &&
cv.ProjectToMe(ptE1, ptE)==RTNORM)
cv.SetPoints(ptS, ptE);
if(cv.GetLength()<_DIST_SNAP)
return Acad::eInvalidInput;
XSortedVertexList lstVert(cv);
for(i=1; i<nVertNum-1; i++) {
XPoint ptFix=gripPoints[2+i];
XPoint ptOnDim;
if(cv.ProjectToMe(ptFix, ptOnDim)==RTNORM) {
lstVert.Insert(ptOnDim);
}
}
XPoly2D poly;
lstVert.AsPoly2D(poly);
m_lstSegment.Reset();
int nSeg=poly.TotalSegments();
for(i=0; i<nSeg; i++) {
XCurveSegment seg;
poly.Nth(i, seg);
double nVal=seg.GetLength();
if(IsValidSegment(nVal))
AppendSegment(nVal);
}
if(IsAngular() && (IsDimChord() || IsDimArcLen())) {
m_nObjRadius=cv.GetArc().GetCenterPt().Distance2d(gripPoints[2]);
// Location???
XLine ln(cv.StartPoint(), cv.IDirection(0)+PI/2);
XPoint ptNewLoc=m_ptLocation + XPoint(offset[0], offset[1]);
ptNewLoc.Project(&ln, m_ptLocation);
m_ptLocation.z=0;
} else SetLocation(gripPoints[2]);
SetRotation(cv.IDirection(0));
double nDist2DimLine=m_ptLocation.Distance2d(cv.StartPoint());
int nSide=cv.OnWhichSide(m_ptLocation);
SetDist2DimLine(nSide==OFFSET_RIGHT? nDist2DimLine : -nDist2DimLine, FALSE);
if(nSeg==nVertNum-1) { //区间数目没有变化
for(i=0; i<nSeg; i++) {
int nGripIndex=i+nVertNum+2;
if(indices.contains(nGripIndex) && m_lstTextPos.FindNode(&i, TDimTextPos::CompareByIndexForFind))
SetTextPos(i, gripPoints[nGripIndex]);
}
} else {
m_lstTextPos.Reset();
m_lstTextContent.Reset();
}
AutoSetFlag();
return Acad::eOk;
}
// 功能: 夹点操作
// Modify on 2002/8/8 解决调用getGripPoints效率很低
Acad::ErrorStatus TDbDimension2::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
if(indices.length()>1)
return MoveGripPointsAt1(indices, offset);
assertWriteEnabled();
XPoint vtOffset=*(XPoint *)&offset;
vtOffset.z=0;
XPoly2D poly, polyNew;
GetPolySegOnDimLine(poly);
polyNew=poly;
XCurveSegment cv=GetDimCurve();
double nOffDist=m_nDist2DimLine*GetPScale();
XCurveSegment cvFix=cv.Offset(nOffDist, LS_FINITE);
XCurveSegment cvObj;
if(IsAngular())
{
double nDist2Obj=cv.GetArc().GetRadius()-m_nObjRadius;
cvObj=cv.Offset(-nDist2Obj, LS_FINITE);
}
for (int i = 0; i < indices.length(); i++)
{
int idx = indices[i];
if(idx<=1)
{ //改变尺寸线位置
XPoint ptVert=idx==0? *poly.Head() : *poly.Tail();
double nExtDir=idx==0? cv.IDirection(0) : cv.IDirection(1);
XLine lnExt(ptVert, nExtDir+PI/2);
XPoint ptOnExt=ptVert + vtOffset;
XPoint(ptOnExt).Project(&lnExt, ptOnExt);
int nSide=cv.OnWhichSide(ptOnExt);
double nDistMove=ptVert.Distance2d(ptOnExt);
double nOldDist2DimLine=m_nDist2DimLine,nOldDimRadius=m_nDimRadius;
int nSideLoc=cv.OnWhichSide(m_ptLocation);
if(fabs(m_nDist2DimLine)>_DIST_SNAP/GetPScale())
{
double nFactor=m_nDist2DimLine/fabs(m_nDist2DimLine);
if(nSide!=nSideLoc)
m_nDist2DimLine += nFactor*nDistMove/GetPScale();
else
m_nDist2DimLine -= nFactor*nDistMove/GetPScale();
}
else
{
if(nSideLoc==OFFSET_LEFT)
m_nDist2DimLine=-nDistMove/GetPScale();
}
if(IsAngular())
{
if(nSide==OFFSET_RIGHT)
m_nDimRadius += nDistMove;
else
m_nDimRadius -= nDistMove;
if(m_nDimRadius<_DIST_SNAP)
{
m_nDist2DimLine=nOldDist2DimLine;
m_nDimRadius=nOldDimRadius;
}
}
}
else if(idx<poly.Length()+2)
{ //改变定位点或区间
int ndx=idx-2;
XPoint ptGrip,ptGrip0;
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
cvObj.ProjectToMe(*poly[ndx], ptGrip);
else
cvFix.ProjectToMe(*poly[ndx], ptGrip);
int vtIdx=idx-2;
ptGrip0=ptGrip;
ptGrip += vtOffset;
if(!g_bStetchEntity&&GetCtrlToggle())
{
if(!AddSegment(ptGrip)&&GetSegmentNum()>1)
FindAndRemoveSegment(ptGrip0);
}
else
{
XPoint ptOnDim;
BOOL bGreatPrev=FALSE, bLessNext=FALSE;
if(cv.ProjectToMe(ptGrip, ptOnDim)==RTNORM)
{
if(vtIdx>0)
{
double nPathDist=cv.PathDistance(ptOnDim); //小于0时,为圆弧标注
if(IsAngular() && nPathDist<-_DIST_SNAP)
{
if(vtIdx==polyNew.Length()-1)
nPathDist=cv.GetArc().XCircle::GetLength()+nPathDist;
}
double nPathDistPrev=cv.PathDistance(*polyNew[vtIdx-1]);
bGreatPrev = (nPathDist-nPathDistPrev)>-_DIST_SNAP;
}
else
bGreatPrev=TRUE;
if(vtIdx<polyNew.Length()-1)
bLessNext = (cv.PathDistance(ptOnDim)-cv.PathDistance(*polyNew[vtIdx+1]))<_DIST_SNAP;
else bLessNext=TRUE;
if(bGreatPrev && bLessNext)
{
if(vtIdx==0)
{
XCurveSegment seg;
polyNew.Nth(0, seg);
seg.SetPoints(ptOnDim, seg.EndPoint());
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
{
XArc ar=seg.GetArc();
XCircle cir(ar.GetCenterPt(), ads_distance(ar.GetCenterPt(), m_ptLocation));
XPoint ptabc=m_ptLocation + vtOffset;
ptabc.Project(&cir, m_ptLocation);
m_nObjRadius=cir.GetCenterPt().Distance2d(ptGrip);
}
else
m_ptLocation += vtOffset;
if(IsValidSegment(seg.GetLength()))
{
m_nRotation=seg.IDirection(0);
SetSegment(0, seg.GetLength());
double nFactor = cv.OnWhichSide(m_ptLocation)==OFFSET_LEFT? -1.0 : 1.0;
if(!(IsAngular() && (IsDimChord() || IsDimArcLen())))
SetDist2DimLine(m_ptLocation.Distance2d(ptOnDim)*nFactor, FALSE);
}
else
{
if(m_lstSegment.Length()>1)
{
RemoveSegment(0);
polyNew.Nth(1, seg);
m_nRotation=seg.IDirection(0);
double nFactor = cv.OnWhichSide(m_ptLocation)==OFFSET_LEFT? -1.0 : 1.0;
if(!(IsAngular() && (IsDimChord() || IsDimArcLen())))
SetDist2DimLine(m_ptLocation.Distance2d(ptOnDim)*nFactor, FALSE);
}
}
}
else
{
BOOL bLast=(vtIdx==polyNew.Length()-1);
XCurveSegment seg, segPrev;
if(!bLast) polyNew.Nth(vtIdx, seg);
polyNew.Nth(vtIdx-1, segPrev);
if(!bLast)
ASSERT(IsValidSegment(seg.GetLength()));
ASSERT(IsValidSegment(segPrev.GetLength()));
if(!bLast) seg.SetPoints(ptOnDim, XPoint(seg.EndPoint()));
segPrev.SetPoints(XPoint(segPrev.StartPoint()), ptOnDim);
if(!bLast)
{
if(!IsValidSegment(seg.GetLength()))
RemoveSegment(vtIdx);
else
SetSegment(vtIdx, seg.GetLength());
}
else
{
double nFactor = cv.OnWhichSide(ptGrip)==OFFSET_LEFT? -1.0 : 1.0;
if(!(IsAngular() && (IsDimChord() || IsDimArcLen())))
SetDist2DimLine(ptGrip.Distance2d(ptOnDim)*nFactor, FALSE);
ads_polar(cv.StartPoint(), m_nRotation-PI/2, GetDist2DimLine(FALSE), m_ptLocation);
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
{
//改标注半径
XArc arDim=cv.GetArc();
arDim.SetRadius(m_nObjRadius);
XCurveSegment cvObj;
cvObj=arDim;
XPoint ptGrip=cvObj.EndPoint();
ptGrip += vtOffset;
m_nObjRadius = ptGrip.Distance2d(arDim.GetCenterPt());
}
}
if(!IsValidSegment(segPrev.GetLength()))
{
if(m_lstSegment.Length()>1)
RemoveSegment(vtIdx-1);
}
else
SetSegment(vtIdx-1, segPrev.GetLength());
}
}
}
}
}
else
{
int nSeg=idx - poly.Length() -2;
if(nSeg<poly.TotalSegments())
{
XPoint ptText = GetTextPos(nSeg);
ptText += vtOffset;
SetTextPos(nSeg, ptText);
}
else
{
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
{
XLine ln(cv.StartPoint(), cv.IDirection(0)+PI/2);
XPoint ptNewLoc=m_ptLocation + vtOffset;
ptNewLoc.Project(&ln, m_ptLocation);
int nSide=cv.OnWhichSide(ptNewLoc);
double nFactor = cv.OnWhichSide(ptNewLoc)==OFFSET_LEFT? -1.0 : 1.0;
SetDist2DimLine(ptNewLoc.Distance2d(cv.StartPoint())*nFactor, FALSE);
}
else if(!IsAngular()&&IsAssociate())
{
XPoint ptEnd;
ads_polar(m_ptLocation,m_nRotation,1,ptEnd);
XCurveSegment curve(m_ptLocation,ptEnd,0);
XPoint ptVert,pt;
AcGePoint3dArray grips;
AcDbIntArray osnapModes,geomIds;
subGetGripPoints(grips,osnapModes,geomIds);
pt=grips[indices[0]];
pt+=vtOffset;
if(curve.ProjectToMe(pt,ptVert)==RTNORM)
{
double dist=ptVert.Distance2d(pt);
double nValue=dist/GetPScale();
if(nValue<0.1)
return Acad::eInvalidInput;
if(m_lstOffset.Length()<1)
m_lstOffset.Append(new double(nValue));
else
*m_lstOffset[0]=nValue;
}
}
}
}
}
//RemoveZeroSegment(); //把长度为0的区间移除
AutoSetFlag();
Acad::ErrorStatus es = Acad::eOk;
return es;
}
// 功能: 夹点操作
Acad::ErrorStatus TDbDimension2::subMoveStretchPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
int nCount=indices.length();
XPushMemVar<BOOL> vTemp(g_bStetchEntity,TRUE);
return subMoveGripPointsAt(indices, offset);
}
// 取得夹点说明
Acad::ErrorStatus TDbDimension2::GetGripText(int i, CString &cs) const
{
Acad::ErrorStatus es=Acad::eOk;
XPoly2D poly;
GetPolySegOnDimLine(poly);
if(i<=1)
cs = _T("移动尺寸线");
else if(i<poly.Length()+2)
{
if(!GetCtrlToggle())
{
if(i==2 || i==poly.Length()+1)
{
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
cs=_T("更改标注半径和开间(Ctrl-增补合并尺寸开间)");
else
cs=_T("移动定位点和更改开间(Ctrl-增补合并尺寸开间)");
}
else
cs = _T("更改合并尺寸开间(Ctrl-增补合并尺寸开间)");
}
else
{
if(i==2 || i==poly.Length()+1)
{
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
cs=_T("增补合并尺寸开间(Ctrl-更改标注半径和开间)");
else
cs=_T("增补合并尺寸开间(Ctrl-移动定位点和更改开间)");
}
else
cs = _T("增补合并尺寸开间(Ctrl-更改合并尺寸开间)");
}
}
else
{
int iVert=i-2-poly.Length();
if(iVert<poly.TotalSegments())
cs = _T("移动尺寸文本");
else
{
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
cs = _T("改尺寸界线");
else if(!IsAngular()&&IsAssociate())
{
cs = _T("改尺寸关联范围");
}
}
}
return es;
}
int TDbDimension2::ConvertText(TConvertTextPtr ptr, void *pData)
{
assertWriteEnabled();
int nLen=m_lstTextContent.Length();
int nCode=RTNONE;
for(int i=0; i<nLen; i++) {
TDimTextContent *pContent=m_lstTextContent[i];
XString sText;
int nRet=ptr(pContent->sText, sText, pData);
if(nRet==RTERROR)
nCode=nRet;
else if(nRet==RTNORM)
pContent->sText=sText;
}
return nCode;
}
// 返回发现的位置,同时posStart往前移动(以便继续找下一个使用),
TTextPosition
TDbDimension2::FindSubText(const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange) const
{
assertReadEnabled();
TTextPosition pos;
if(!sSubText || !sSubText[0])
return pos;
AcDbObjectId idTextStyle;
double dimtxt=3.0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pStyle);
if(pStyle) {
idTextStyle=pStyle->dimtxsty();
dimtxt=pStyle->dimtxt();
}
OPENOBJ_END();
if(!idTextStyle)
return pos;
int nLen=GetSegmentNum(); //m_lstTextContent.Length();
int nCode=RTNONE;
TTextPosition posNext=posStart;
for(int i=posStart.m_nCookies; i<nLen; i++) {
//TDimTextContent content=m_lstTextContent[i];
XString sTextDim=GetText(i);
TDbText dimText;
dimText.setPropertiesFrom(this);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
dimText.SetHeight(dimtxt);
dimText.SetStyleId(idTextStyle);
dimText.SetText(sTextDim);
dimText.SetLocation(GetTextPos(i));
posNext.m_nCookies=i;
TTextPosition posRet=dimText.FindSubText(sSubText, posNext, pRange);
if(!posRet) {
posNext.m_nTextPos=0;
} else {
posStart=posNext;
if(!posStart && (int)posStart.m_nCookies<nLen-1) {
posStart.m_nCookies++;
posStart.m_nTextPos=0;
}
posRet.m_nCookies=i;
return posRet;
}
}
return pos;
}
// 返回下一次查找的开始位置
TTextPosition
TDbDimension2::ReplaceSubText(const TTextPosition &posRep, const TCHAR *sRepText, TTextRange *pRange)
{
assertWriteEnabled();
TTextPosition pos;
pos.m_nBufLen=_tcslen(sRepText);
pos.m_nCookies=posRep.m_nCookies;
if(!posRep || (int)posRep.m_nCookies>=GetSegmentNum())
return pos;
AcDbObjectId idTextStyle;
double dimtxt=3.0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pStyle);
if(pStyle) {
idTextStyle=pStyle->dimtxsty();
dimtxt=pStyle->dimtxt();
}
OPENOBJ_END();
if(!idTextStyle)
return pos;
//TDimTextContent *pContent=m_lstTextContent[posRep.m_nCookies];
XString sTextDim=GetText(posRep.m_nCookies);
TDbText dimText;
dimText.setPropertiesFrom(this);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
dimText.SetHeight(dimtxt);
dimText.SetStyleId(idTextStyle);
dimText.SetText(sTextDim);
dimText.SetLocation(GetTextPos(posRep.m_nCookies));
TTextPosition posRet=dimText.ReplaceSubText(posRep, sRepText, pRange);
SetTextContent(posRep.m_nCookies, dimText.GetText());
if(!posRet) {
if((int)posRet.m_nCookies<GetSegmentNum()-1) {
posRet.m_nCookies=posRep.m_nCookies+1;
posRet.m_nTextPos=0;
}
}
return posRet;
}
Adesk::UInt32
TDbDimension2::subSetAttributes(AcGiDrawableTraits * traits)
{
Adesk::UInt32 nRet=TDbCurveEntity::subSetAttributes(traits);
//if(g_nAcadVer<15.0001)
// nRet |= kDrawableIsCompoundObject;
return nRet;
}
TSubText* TDbDimension2::GetSubText(long iText)const
{
XPushMemVar<BOOL> bExpl(g_bSelfDrawDim, TRUE);
TSubText*pSubText=TDbCurveEntity::GetSubText(iText);
if(pSubText!=NULL)
pSubText->SetMenuType(6);
return pSubText;
}
TSubText* TDbDimension2::HitTestText(XPoint pt)const
{
XPushMemVar<BOOL> bExpl(g_bSelfDrawDim, TRUE);
TSubText*pSubText=TDbCurveEntity::HitTestText(pt);
if(pSubText!=NULL)
pSubText->SetMenuType(6);
return pSubText;
}
Acad::ErrorStatus TDbDimension2::GetExtents2d(XPoint &ptLow, XPoint &ptUp) const
{
AcDbExtents ext;
Acad::ErrorStatus es=getGeomExtents(ext);
ptLow=ext.minPoint();
ptUp=ext.maxPoint();
return es;
}
Acad::ErrorStatus
TDbDimension2::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
assertReadEnabled();
BOOL bIsDefText;
// modify by xlc on 101209 效率低,减少执行次数,解决多视口图纸切换运行慢的问题
XPoly2D poly;
GetPolySegOnDimLine(poly);
// 绘制标注点,不打印
if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0&&!dc.IsPlotGeneration())
{
AcGePoint3dArray gripPoints;
double nOffDist=m_nDist2DimLine*GetPScale();
XCurveSegment cv=GetDimCurve();
XCurveSegment cvFix=cv.Offset(nOffDist, LS_FINITE);
XCurveSegment cvObj;
if(IsAngular())
{
double nDist2Obj=cv.GetArc().GetRadius()-m_nObjRadius;
cvObj=cv.Offset(-nDist2Obj, LS_FINITE);
}
// modify by xlc on 101209 移到外边了
//XPoly2D poly;
//GetPolySegOnDimLine(poly);
int nVertNum=poly.Length();
for (int i=0; i<nVertNum; i++)
{
XPoint ptFix;
if(IsAngular() && (IsDimChord() || IsDimArcLen()))
cvObj.ProjectToMe(*poly[i], ptFix);
else cvFix.ProjectToMe(*poly[i], ptFix);
dc<<XLine(ptFix,ptFix);
}
}
// modified by whl on 060223
// BOOL bCheckDim=DocGetCheckDim();
BOOL bCheckDim=DocGetCheckDim()&&!g_bExplodeSubText;
double nPScale=GetPScale();
if (!IsValid())
return Acad::eInvalidInput;
int nColorOld = dc.GetColor();
double nOffDist=m_nDist2DimLine*GetPScale();
BOOL bDraw=(_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0||g_bSelfDrawDim);
BOOL bQuickMode=(bDraw && !ownerId() && m_lstSegment.Length()>=g_nDimNumGripTip);
if (g_bDisableQuickMode)
bQuickMode=FALSE;
// modify by xlc on 101209 提前了
// XPoly2D poly;
// GetPolySegOnDimLine(poly);
BOOL bAngular=IsAngular();
BOOL bSelfDraw=(g_bOsnapExpl || bDraw || //g_bExpOtherDb ||
(IsAngular() && (IsDimChord() || IsDimArcLen()))
);
if (bSelfDraw || bCheckDim)
{
dc.SetAlignment(XExplodeDraw::kMiddleCenter);
XString sDimPrefix, sDimSuffix;
double dimgap=0, dimtxt=0, dimexe=0, dimexo=0;
double dimscale=1.0, dimasz=1.0,dimdle=0.0;
int dimclre=0, dimclrd=0, dimclrt=0;
int dimdec=0, dimadec=0;
double nArrowThick = 6.0*nPScale;
double dimlfac=1.0; // 标注显示的单位换算系数
AcDbObjectId dimblk;
AcDbObjectId idTextStyle;
// sg add 20120413,增加对“标注文字从默认位置(由标注样式定义的位置)移动时标注文字的位置”设置的支持
int nDimTextMovePos = 2;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
if (pDimStyle != NULL)
{
dimdec=pDimStyle->dimdec();
dimadec=pDimStyle->dimadec();
dimgap=pDimStyle->dimgap();
dimtxt=pDimStyle->dimtxt();
dimblk=pDimStyle->dimblk();
dimlfac=pDimStyle->dimlfac();
dimscale=nPScale; //pDimStyle->dimscale();
dimdle=pDimStyle->dimdle();
dimasz=pDimStyle->dimasz();
idTextStyle=pDimStyle->dimtxsty();
dimexe=pDimStyle->dimexe();
dimexo=pDimStyle->dimexo();
dimclre=pDimStyle->dimclre().colorIndex();
dimclrd=pDimStyle->dimclrd().colorIndex();
dimclrt=pDimStyle->dimclrt().colorIndex();
// sg add 20120413,增加对“标注文字从默认位置(由标注样式定义的位置)移动时标注文字的位置”设置的支持
nDimTextMovePos = pDimStyle->dimtmove();
const TCHAR *dimpost = pDimStyle->dimpost();
const TCHAR *pStr = NULL;
if (dimpost)
pStr = _tcsstr(dimpost, _T("<>"));
if (pStr)
{
StrCpy(sDimPrefix, dimpost, pStr);
StrCpy(sDimSuffix, pStr+2, NULL);
}
else if (dimpost)
{
_tcscpy(sDimSuffix, dimpost);
}
}
else
{
return Acad::eInvalidInput;
}
OPENOBJ_END();
XCurveSegment cv = GetDimCurve();
BOOL bDimArcLen = (IsAngular() && IsDimArcLen());
if (bDimArcLen) // 弧长标注
{
int numSeg = poly.TotalSegments();
for (int i=0; i<numSeg; i++)
{
XCurveSegment segDim, segFix, segObj;
poly.Nth(i, segDim);
segFix = segDim.Offset(OFFSET_LEFT, -GetDist2DimLine(FALSE), LS_FINITE);
double nOffDist0 = segDim.GetArc().GetRadius() - m_nObjRadius;
segObj = segDim.Offset(OFFSET_LEFT, nOffDist0, LS_FINITE);
XPoint ptAr1, ptAr2; // 弧长两端的标注点
double nChorldDir = segObj.XLine::Direction();
XLine ln1(segObj.GetStartPoint(), nChorldDir+PI/2.0),
ln2(segObj.GetEndPoint(), nChorldDir+PI/2.0);
XPoint ptInt[2];
segDim.SetLineFlag(LS_INFINITE);
ln1.SetLineFlag(LS_INFINITE);
int nIntNum = segDim.Intersection(ln1, ptInt[0], ptInt[1]);
if (nIntNum == 0)
continue;
else if (nIntNum == 1)
ptAr1 = ptInt[0];
else
ptAr1 = XLine(ptInt[0], ptInt[1]).NearPoint(segDim.StartPoint());
nIntNum = segDim.Intersection(ln2, ptInt[0], ptInt[1]);
if (nIntNum == 0)
continue;
else if (nIntNum == 1)
ptAr2 = ptInt[0];
else
ptAr2 = XLine(ptInt[0], ptInt[1]).NearPoint(segDim.StartPoint());
// sg add 120412,根据9.0需求,增加设置弧长标注样式的设置
int nDimType = DocGetArcLenDimType();
if (nDimType == 1) // 旧样式才修改标注样式点
{
segDim.SetPoints(ptAr1, ptAr2);
}
// 绘制尺寸线
if (dimclrd)
dc.SetColor(dimclrd);
dc << segDim;
// 绘制尺寸界线
if (dimclre)
dc.SetColor(dimclre);
if (bQuickMode)
;
else if (!g_bOsnapExpl)
{
if (!dimblk) // 尺寸箭头
{
// sg modify 120412,解决“实心闭合”样式,不支持设置“箭头大小”的问题
double dXSize = 1.0*dimscale*dimasz,
dYSize = 0.33*dimscale*dimasz;
int nDealOldDimArrowSize = DocGetDealOldDimArrowSize();
if (nDealOldDimArrowSize==0 && fabs(dimasz-1.0)<1.0E-3) // 旧版本的“实心闭合”样式
{
dXSize *= 2;
dYSize *= 2;
}
XPointDir2d pt1, pt2;
//segDim.Polar(2.0*dimscale, pt1);
//segDim.Polar(2.0*dimscale, pt2, FALSE);
segDim.Polar(dXSize, pt1);
segDim.Polar(dXSize, pt2, FALSE);
AcDbPolyline plArrow1;
plArrow1.setPropertiesFrom(this);
plArrow1.addVertexAt(0, segDim.StartPoint());
//plArrow1.setWidthsAt(0, 0.0, 0.66*dimscale);
plArrow1.setWidthsAt(0, 0.0, dYSize);
plArrow1.addVertexAt(1, pt1);
//plArrow1.setWidthsAt(1, 0.66*dimscale, 0.0);
plArrow1.setWidthsAt(1, dYSize, 0.0);
dc.Polyline(plArrow1);
AcDbPolyline plArrow2;
plArrow2.setPropertiesFrom(this);
plArrow2.addVertexAt(0, pt2);
//plArrow2.setWidthsAt(0, dYSize, 0.0);
plArrow2.setWidthsAt(0, dYSize, 0.0);
plArrow2.addVertexAt(1, segDim.EndPoint());
plArrow2.setWidthsAt(1, 0.0, 0.0);
dc.Polyline(plArrow2);
}
else
{
// 打印时,不能使用新方法
BOOL bNewMethod=(g_nAcadVer>15.0001 && g_bMakeBlock);
// sg add 091105,强制打印时,不使用新方法
if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 && dc.IsPlotGeneration())
bNewMethod = FALSE;
OPENOBJ_BEGIN(dimblk, AcDb::kForRead, AcDbBlockTableRecord, pBlock);
if (pBlock)
{
dc.DrawBlock(*pBlock, segDim.EndPoint(), AcGeScale3d(dimscale*dimasz, dimscale*dimasz, dimscale*dimasz),
segDim.IDirection(1)+PI, bNewMethod);
dc.DrawBlock(*pBlock, segDim.StartPoint(), AcGeScale3d(dimscale*dimasz, dimscale*dimasz, dimscale*dimasz),
segDim.IDirection(0), bNewMethod);
}
OPENOBJ_END();
}
}
// 尺寸界限
XPoint pt1, pt2;
double nFactor = fabs(nOffDist)>_DIST_SNAP? nOffDist/fabs(nOffDist) : 1.0;
// sg add 120412,根据9.0需求,增加设置弧长标注样式的设置
if (nDimType == 0) // 新样式
{
double dStartDir = ads_angle(segDim.StartPoint(), segObj.StartPoint());
ads_polar(segDim.StartPoint(), dStartDir, fabs(nOffDist)-dimexo*dimscale, pt1);
ads_polar(segDim.StartPoint(), dStartDir, -dimexe*dimscale, pt2);
}
else // 旧样式
{
ads_polar(segDim.StartPoint(), nChorldDir-nFactor*PI/2, fabs(nOffDist)-dimexo*dimscale, pt1);
ads_polar(segDim.StartPoint(), nChorldDir+nFactor*PI/2, dimexe*dimscale, pt2);
}
dc << XLine(pt1, pt2);
// sg add 120412,根据9.0需求,增加设置弧长标注样式的设置
if (nDimType == 0) // 新样式
{
double dEndDir = ads_angle(segDim.EndPoint(), segObj.EndPoint());
ads_polar(segDim.EndPoint(), dEndDir, fabs(nOffDist)-dimexo*dimscale, pt1);
ads_polar(segDim.EndPoint(), dEndDir, -dimexe*dimscale, pt2);
}
else // 旧样式
{
ads_polar(segDim.EndPoint(), nChorldDir-nFactor*PI/2, fabs(nOffDist)-dimexo*dimscale, pt1);
ads_polar(segDim.EndPoint(), nChorldDir+nFactor*PI/2, dimexe*dimscale, pt2);
}
dc << XLine(pt1, pt2);
dc.SetColor(nColorOld);
// 尺寸文字
if (bQuickMode)
;
else if (!g_bOsnapExpl)
{
TDbText dimText;
dimText.setPropertiesFrom(this);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
dimText.SetHeight(dimtxt);
dimText.SetStyleId(idTextStyle);
dimText.setColorIndex(dimclrt);
int numSeg = poly.TotalSegments();
BOOL bIsDefPos = TRUE;
// modify by xlc on 101209 解决速度慢问题
//XPoint ptText=GetTextPos(i, &bIsDefPos);
XPoint ptText = GetTextPos(i, poly, &bIsDefPos);
XPoint ptTemp;
XPointDir2d ptTempDir;
cv.ProjectToMe(ptText, ptTemp);
double nDist = cv.PathDistance(ptTemp);
cv.Polar(nDist, ptTempDir);
// sg modify 120410,使用新增加的接口,代替基类中的NormalViewAngle函数,主要解决精确度是1度的问题
// double nTextRot=NormalViewAngle(ptTempDir.nDirection);
double nTextRot=ChangeToNormalViewAngle(ptTempDir.nDirection);
bIsDefText=TRUE;
// modify by xlc on 101209 解决速度慢问题
//XString sText0=GetText(i, &bIsDefText);
XString sText0 = GetText(i, poly, &bIsDefText);
XString sText;
if (bIsDefText)
sText << sDimPrefix << sText0 << sDimSuffix;
else
sText << sText0;
dimText.SetRotation(Wcs2Layout(nTextRot));
dimText.SetLocation(ptText);
if (bSelfDraw)
{
TPushProperty vProp(&dimText, dc);
dimText.SetText(sText);
if (dc.IsFullExplode())
dimText.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(dimText);
XPoint ext = dimText.GetExtents();
XPoint ptMid, ptS, ptE;
ads_polar(ptText, nTextRot+PI/2, ext.y, ptMid);
ads_polar(ptText, nTextRot-PI, ext.x/2, ptS);
ads_polar(ptText, nTextRot, ext.x/2, ptE);
ads_polar(XPoint(ptS), nTextRot+PI/2, ext.y/2, ptS);
ads_polar(XPoint(ptE), nTextRot+PI/2, ext.y/2, ptE);
dc << XArc(ptS, ptMid, ptE);
}
// sg add 120413,增加文字不在默认位置时候的引线
if (nDimTextMovePos!=2 && !bIsDefPos) // 在线旁和有引线,暂时都用通一种表示方法
{
cv.ProjectToMe(ptText, ptTemp);
double dDistance = ptText.Distance2d(ptTemp),
dMixLeaderDis = nPScale*(dimgap + dimtxt*0.5 + dimexe);
if (dDistance > dMixLeaderDis + _DIST_SNAP)
{
if (dimclrd) // 使用尺寸线的颜色
dc.SetColor(dimclrd);
XPoint ptLeader1 = segDim.MidPoint(), // 引线起点
ptLeaderS, ptLeaderE; // 引线文字基线两个端点
// sg modify 120706,解决有布局转角的尺寸标注的文字引线角度不正确的问题
//double dLineDir = Wcs2Layout(nTextRot); // 引线文字基线方向
double dLineDir = nTextRot; // 引线文字基线方向
ads_polar(ptText, dLineDir-PI/2, nPScale*(dimgap+dimtxt*0.5), ptLeaderS);
ads_polar(ptText, dLineDir-PI/2, nPScale*(dimgap+dimtxt*0.5), ptLeaderE);
XPoint ptExt = dimText.GetExtents();
double dTextXLen = ptExt.x;
dTextXLen *= 0.6; // 1.2*0.5,引线长默认是文字的1.2倍吧
ads_polar(ptLeaderS, dLineDir, -dTextXLen, ptLeaderS);
ads_polar(ptLeaderE, dLineDir, dTextXLen, ptLeaderE);
XPoint ptLeader2 = XLine(ptLeaderS, ptLeaderE).NearPoint(ptLeader1);
dc << XLine(ptLeader1, ptLeader2);
dc << XLine(ptLeaderS, ptLeaderE);
}
}
if (bCheckDim && !bIsDefText)
{
XString sCheckText(256);
// modify by xlc on 101209 解决速度慢问题
// sCheckText << _T("(") << sDimPrefix << GetDefaultText(i) << sDimSuffix << _T(")");
sCheckText << _T("(") << sDimPrefix << GetDefaultText(i, poly) << sDimSuffix << _T(")");
XPoint ptCheckText;
if (bIsDefPos)
{
XPoint ptOnSeg;
if (segDim.ProjectToMe(ptText, ptOnSeg) == RTNORM)
{
ptOnSeg.Mirror(ptText, ptCheckText);
}
}
else
{
int nSideText = segDim.OnWhichSide(ptText);
if (nSideText == OFFSET_RIGHT)
ads_polar(ptText, ptTempDir.nDirection-PI/2, nPScale*(dimgap+dimtxt), ptCheckText);
else
ads_polar(ptText, ptTempDir.nDirection+PI/2, nPScale*(dimgap+dimtxt), ptCheckText);
}
dimText.setColorIndex(1);
dimText.SetLocation(ptCheckText);
dimText.SetText(sCheckText);
{
TPushProperty vProp(&dimText, dc);
if(dc.IsFullExplode())
dimText.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(dimText);
}
dimText.setColorIndex(dimclrt);
} // bCheckDim
dc.SetColor(nColorOld);
} // g_bExplOsnap
} // End for
}
else if (IsAngular() && IsDimChord()) // 弦长标注
{
XPushMemVar<BOOL> tVar1(g_bDisableQuickMode, TRUE);
int numSeg = poly.TotalSegments();
for (int i=0; i<numSeg; i++)
{
XCurveSegment segDim, segFix, segObj;
poly.Nth(i, segDim);
segFix = segDim.Offset(OFFSET_LEFT, -GetDist2DimLine(FALSE), LS_FINITE);
double nOffDist0=segDim.GetArc().GetRadius() - m_nObjRadius;
segObj = segDim.Offset(OFFSET_LEFT, nOffDist0, LS_FINITE);
double nRot=segObj.XLine::Direction();
XPoint ptFix;
double nObj2Fix=segFix.GetArc().GetRadius()-segObj.GetArc().GetRadius();
ads_polar(segObj.StartPoint(), nRot-PI/2, nObj2Fix, ptFix);
TDbDimension2 objDim;
objDim.setPropertiesFrom(this);
objDim.SetLocation(ptFix);
objDim.SetRotation(nRot);
objDim.SetDist2DimLine(GetDist2DimLine());
objDim.AppendSegment(segObj.GetArc().ChordLength());
objDim.SetStyleId(GetStyleId());
TDimTextPos *pNode1=((TDbDimension2 *)this)->m_lstTextPos.FindNode(&i, TDimTextPos::CompareByIndexForFind);
if(pNode1)
objDim.SetTextPos(0, pNode1->ptPos);
TDimTextContent *pNode=((TDbDimension2 *)this)->m_lstTextContent.FindNode(&i, TDimTextContent::CompareByIndexForFind);
if(pNode)
objDim.SetTextContent(0, pNode->sText);
objDim.ExplodeOrDraw2d(dc);
}
}
else // 直线标注或角度标注
{
if (bSelfDraw)
{
if (dimclrd) // 尺寸线颜色
dc.SetColor(dimclrd);
if (IsAngular())
dc << poly;
else
{
XPoint ptStart,ptEnd;
ads_polar(*poly[0],m_nRotation+PI,dimdle*dimscale,ptStart);
dc << XLine(ptStart,*poly[0]);
ads_polar(*poly[poly.Length()-1],m_nRotation,dimdle*dimscale,ptEnd);
dc << XLine(*poly[poly.Length()-1],ptEnd);
dc<<poly;
}
// dc << cv;
if (dimclre) // 尺寸界线颜色
dc.SetColor(dimclre);
int numVert = poly.Length();
for (int i=0; i<numVert; i++)
{
XPoint ptVert = *poly[i];
double nPathDist = cv.PathDistance(ptVert);
XPointDir2d ptVertDir;
cv.Polar(nPathDist, ptVertDir);
if (bQuickMode)
;
else if(!g_bOsnapExpl)
{
if (!dimblk) // 尺寸箭头,对AutoDesk强烈抗议,为什么只有“实心闭合”不是块呢
{
// sg modify 120412,解决“实心闭合”样式,不支持设置“箭头大小”的问题
double dXSize = 1.0*dimscale*dimasz,
dYSize = 0.33*dimscale*dimasz;
int nDealOldDimArrowSize = DocGetDealOldDimArrowSize();
if (nDealOldDimArrowSize==0 && fabs(dimasz-1.0)<1.0E-3) // 旧版本的“实心闭合”样式
{
dXSize *= 2;
dYSize *= 2;
}
XPointDir2d pt1, pt2;
//cv.Polar(nPathDist+2.0*dimscale, pt1);
//cv.Polar(nPathDist-2.0*dimscale, pt2);
cv.Polar(nPathDist+dXSize, pt1);
cv.Polar(nPathDist-dXSize, pt2);
AcDbPolyline plArrow;
plArrow.setPropertiesFrom(this);
int iVert=0;
if (i > 0)
{
plArrow.addVertexAt(iVert, pt2);
//plArrow.setWidthsAt(iVert, 0.66*dimscale, 0.0);
plArrow.setWidthsAt(iVert, dYSize, 0.0);
iVert++;
}
plArrow.addVertexAt(iVert, ptVert);
//plArrow.setWidthsAt(iVert, 0.0, 0.66*dimscale);
plArrow.setWidthsAt(iVert, 0.0, dYSize);
iVert++;
if (i<numVert-1)
{
plArrow.addVertexAt(iVert, pt1);
iVert++;
}
dc.Polyline(plArrow);
}
else
{
// 打印时,不能使用新方法
BOOL bNewMethod = (g_nAcadVer>15.0001 && g_bMakeBlock);
// sg add 091105,强制打印时,不使用新方法
if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 && dc.IsPlotGeneration())
bNewMethod = FALSE;
OPENOBJ_BEGIN(dimblk, AcDb::kForRead, AcDbBlockTableRecord, pBlock);
if (pBlock)
{
// sg modify 120410,使用新增加的接口,代替基类中的NormalViewAngle函数,主要解决精确度是1度的问题
//dc.DrawBlock(*pBlock, ptVert, AcGeScale3d(dimscale*dimasz, dimscale*dimasz, dimscale*dimasz),
// NormalViewAngle(ptVertDir.nDirection), bNewMethod);
dc.DrawBlock(*pBlock, ptVert, AcGeScale3d(dimscale*dimasz, dimscale*dimasz, dimscale*dimasz),
ChangeToNormalViewAngle(ptVertDir.nDirection), bNewMethod);
}
OPENOBJ_END();
}
}
// 尺寸界限
XPoint pt1, pt2;
double nFactor = fabs(nOffDist)>_DIST_SNAP? nOffDist/fabs(nOffDist) : 1.0;
ads_polar(ptVert, ptVertDir.nDirection-nFactor*PI/2, fabs(nOffDist)-dimexo*dimscale, pt1);
ads_polar(ptVert, ptVertDir.nDirection+nFactor*PI/2, dimexe*dimscale, pt2);
dc<<XLine(pt1,pt2);
}
}
dc.SetColor(nColorOld);
if (bQuickMode)
;
else if (!g_bOsnapExpl)
{
TDbText dimText;
dimText.setPropertiesFrom(this);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
dimText.SetHeight(dimtxt);
dimText.SetStyleId(idTextStyle);
dimText.setColorIndex(dimclrt); // 文字颜色
int numSeg = poly.TotalSegments();
for (int i=0; i<numSeg; i++)
{
TGGeCurveSegment seg;
poly.Nth(i, seg);
BOOL bIsDefPos = TRUE;
// modify by xlc on 101209 解决速度慢问题
// XPoint ptText=GetTextPos(i, &bIsDefPos);
XPoint ptText = GetTextPos(i, poly, &bIsDefPos);
XPoint ptTemp;
XPointDir2d ptTempDir;
cv.ProjectToMe(ptText, ptTemp);
double nDist = cv.PathDistance(ptTemp);
cv.Polar(nDist, ptTempDir);
// sg modify 120410,使用新增加的接口,代替基类中的NormalViewAngle函数,主要解决精确度是1度的问题
// double nTextRot=NormalViewAngle(ptTempDir.nDirection);
double nTextRot = ChangeToNormalViewAngle(ptTempDir.nDirection);
BOOL bIsDefText = TRUE;
// modify by xlc on 101209 解决速度慢问题
//XString sText0=GetText(i, &bIsDefText);
XString sText0 = GetText(i, poly, &bIsDefText);
XString sText;
if (bIsDefText && !IsAngular())
sText << sDimPrefix << sText0 << sDimSuffix;
else
sText << sText0;
dimText.SetText(sText);
dimText.SetRotation(Wcs2Layout(nTextRot));
XPoint ptLeader1 = seg.MidPoint(),ptLeader2; // 引线起点
XPoint ptDimPos = ptText, ptLeaderS, ptLeaderE;
// sg add 120413,增加文字不在默认位置时候的引线
if (nDimTextMovePos!=2 && !bIsDefPos) // 在线旁和有引线,暂时都用通一种表示方法
{
XPoint ptExt = dimText.GetExtents();
double ddimgap = nPScale*(dimgap + dimtxt*0.5);
cv.ProjectToMe(ptDimPos, ptTemp);
double dDistance = ptDimPos.Distance2d(ptTemp);
double dMixLeaderDis = ddimgap + nPScale * dimexe;
if (dDistance + _DIST_SNAP > dMixLeaderDis)
{
ads_polar(ptDimPos, nTextRot+PI/2,ddimgap, ptDimPos);
XPoint ptDim1, ptDim2;
ads_polar(ptDimPos, nTextRot, -ptExt.x*0.5, ptDim1);
ads_polar(ptDimPos, nTextRot, ptExt.x*0.5, ptDim2);
double dAngle = acutAngle(seg.StartPoint(), seg.EndPoint());
AcGeVector3d vtSeg = seg.StartPoint() - seg.EndPoint();
if (dAngle > PI/2 && dAngle <= PI)
{
vtSeg *= -1;
}
if (dAngle > PI && dAngle <= 1.5 * PI)
{
vtSeg *= -1;
}
XPoint ptOnline;
seg.ProjectToMe(ptText, ptOnline);
AcGeVector3d vtTxt = ptOnline - ptLeader1;
if (vtTxt.isCodirectionalTo(vtSeg))
{
ads_polar(ptDimPos, nTextRot, -ptExt.x * 0.5, ptDimPos);
}
else
{
ads_polar(ptDimPos, nTextRot, ptExt.x * 0.5, ptDimPos);
}
//ptDimPos = XLine(ptDim1, ptDim2).NearPoint(ptText);
//ads_polar(ptDimPos, nTextRot, ptExt.x * 0.5, ptText);
//ptText = ptDimPos;
// sg modify 120706,解决有布局转角的尺寸标注的文字引线角度不正确的问题
//double dLineDir = Wcs2Layout(nTextRot); // 引线文字基线方向
double dLineDir = nTextRot; // 引线文字基线方向
ads_polar(ptDimPos, dLineDir-PI/2, ddimgap, ptLeaderS);
ptLeaderE = ptLeaderS;
double dTextXLen = ptExt.x;
dTextXLen *= 0.6; // 1.2*0.5,引线长默认是文字的1.2倍吧
ads_polar(ptLeaderS, dLineDir, -dTextXLen, ptLeaderS);
ads_polar(ptLeaderE, dLineDir, dTextXLen, ptLeaderE);
ptLeader2 = XLine(ptLeaderS, ptLeaderE).NearPoint(ptLeader1);
// wlw add 12.9.7角度引线的修改
if (IsAngular())
{
dimText.SetRotation(0.0);
AcGeCircArc3d cir(seg.StartPoint(),seg.MidPoint(),seg.EndPoint());
vtSeg = acdbCurDwg()->ucsxdir();
if (cir.center().distanceTo(ptText.AsAcGePoint3d()) > cir.radius())
{
vtSeg *= -1;
}
ptLeaderE = ptText + vtSeg * (ptExt.x * 0.5 + dimgap * nPScale);
ptLeaderS = ptLeaderE + vtSeg * nPScale;
ptDimPos = ptText;
ptLeader2 = ptLeaderS;
}
dc << XLine(ptLeader1, ptLeader2);
dc << XLine(ptLeaderS, ptLeaderE);
}
}
dimText.SetLocation(ptDimPos);
if (bSelfDraw)
{
TPushProperty vProp(&dimText, dc);
if (dc.IsFullExplode())
dimText.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(dimText);
}
if (bCheckDim && !bIsDefText) // 尺寸检查
{
XString sCheckText(256);
sCheckText << _T("(");
if (!IsAngular())
sCheckText << sDimPrefix;
// modify by xlc on 101209 解决速度慢问题
// sCheckText << GetDefaultText(i);
sCheckText << GetDefaultText(i, poly);
if (!IsAngular())
sCheckText << sDimSuffix;
sCheckText << _T(")");
XPoint ptCheckText;
if (bIsDefPos)
{
XPoint ptOnSeg;
if (seg.ProjectToMe(ptText, ptOnSeg)==RTNORM)
{
ptOnSeg.Mirror(ptText, ptCheckText);
}
}
else
{
int nSideText = seg.OnWhichSide(ptText);
if (nSideText == OFFSET_RIGHT)
ads_polar(ptText, ptTempDir.nDirection-PI/2, nPScale*(dimgap+dimtxt), ptCheckText);
else
ads_polar(ptText, ptTempDir.nDirection+PI/2, nPScale*(dimgap+dimtxt), ptCheckText);
}
dimText.setColorIndex(1);
dimText.SetLocation(ptCheckText);
dimText.SetText(sCheckText);
{
TPushProperty vProp(&dimText, dc);
if (dc.IsFullExplode())
dimText.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(dimText);
}
dimText.setColorIndex(dimclrt);
} // bCheckDim && !bIsDefText
} // for
dc.SetColor(nColorOld);
} // !g_bOsnapExpl
} // 直线标注或角度标注
} // bSelfDraw || bCheckDim
if (!bSelfDraw)
{
BOOL bDraw = (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0);
BOOL bExplode = (_tcscmp(dc.Desc(), XExplodeStream::Descriptor())==0);
double dTxtHeight = 0.0,dtxtw = 0.0;
double dPScale = GetPScale();
AcDbObjectId idDimStyle = DimStyleTch2Acad(m_idDimStyle, dPScale, IsAngular(), database(), dTxtHeight);
int nSeg = poly.TotalSegments();
for (int i=0; i<nSeg; i++)
{
XCurveSegment seg;
poly.Nth(i, seg);
ASSERT(!!seg);
XCurveSegment segOnFix = seg.Offset(OFFSET_RIGHT, nOffDist, LS_FINITE);
AcDbDimension *pDim = NULL;
XPoint ptText = seg.MidPoint();
if (!bAngular)
{
XPoint pt1 = segOnFix.StartPoint(),
pt2 = segOnFix.EndPoint();
// sg modify 120410,使用新增加的接口,代替基类中的NormalViewAngle函数,主要解决精确度是1度的问题
// double nAng = NormalViewAngle(ads_angle(pt1, pt2));
double nAng = ChangeToNormalViewAngle(ads_angle(pt1, pt2));
if (!CT_IsExactSameDrt(nAng, ads_angle(pt1, pt2), _angSnap))
TchPrivate::Exchange(pt1, pt2);
pDim = new AcDbAlignedDimension(pt1, pt2, ptText);
}
else
{
XPoint ptCen = seg.GetArc().GetCenterPt();
pDim = new AcDb3PointAngularDimension(ptCen, segOnFix.StartPoint(), segOnFix.EndPoint(), ptText);
}
bool bModifyGap = false; // 标记是否需要单独修改“文字偏移”
TDimTextPos *pNode = ((TDbDimension2 *)this)->m_lstTextPos.FindNode(&i, TDimTextPos::CompareByIndexForFind);
if (pNode)
{
// sg add 120718,用来标记是否是角度标注,并且带引线的样式,文字不在默认位置,此情况下,导出的时候需要特殊处理布局转角
int nDimTextMovePos(2);
double dimgap(0),
dimtxt(0),
dimexe(0);
AcDbObjectId idTextStyle;
XString sDimPrefix, sDimSuffix;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
if (pDimStyle != NULL)
{
nDimTextMovePos = pDimStyle->dimtmove();
dimgap = pDimStyle->dimgap();
dimtxt = pDimStyle->dimtxt();
dimexe = pDimStyle->dimexe();
idTextStyle = pDimStyle->dimtxsty();
const TCHAR *dimpost = pDimStyle->dimpost();
const TCHAR *pStr = NULL;
if (dimpost)
pStr = _tcsstr(dimpost, _T("<>"));
if (pStr)
{
StrCpy(sDimPrefix, dimpost, pStr);
StrCpy(sDimSuffix, pStr+2, NULL);
}
else if (dimpost)
{
_tcscpy(sDimSuffix, dimpost);
}
}
OPENOBJ_END();
/*wlw 12.9.7
XPoint ptDimPos = pNode->ptPos,
ptTempPos;
XCurveSegment cvDim = GetDimCurve();
cvDim.ProjectToMe(pNode->ptPos, ptTempPos);
XPointDir2d ptTempDir;
double dDistNonDefPt = cvDim.PathDistance(ptTempPos);
cvDim.Polar(dDistNonDefPt, ptTempDir);
double dTextRot = ChangeToNormalViewAngle(ptTempDir.nDirection);
if (!bAngular && nDimTextMovePos!=2)
{
double dDistance = ptDimPos.Distance2d(ptTempPos),
dMixLeaderDis = nPScale*(dimgap + dimtxt*0.5 + dimexe);
ads_polar(ptDimPos, dTextRot-PI/2, nPScale*(dimgap + dimtxt*0.5), ptDimPos);
if (dDistance > dMixLeaderDis + _DIST_SNAP) // 有引线
{
TDbText dimText;
dimText.setPropertiesFrom(this);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
dimText.SetHeight(dimtxt);
dimText.SetStyleId(idTextStyle);
dimText.SetRotation(Wcs2Layout(dTextRot));
dimText.SetLocation(pNode->ptPos);
BOOL bIsDefText = TRUE;
XString sText0 = GetText(i, poly, &bIsDefText),
sText;
if (bIsDefText && !IsAngular())
sText << sDimPrefix << sText0 << sDimSuffix;
else
sText << sText0;
dimText.SetText(sText);
XPoint ptExt = dimText.GetExtents();
XPoint ptDim1, ptDim2;
ads_polar(ptDimPos, dTextRot, -ptExt.x*0.5, ptDim1);
ads_polar(ptDimPos, dTextRot, ptExt.x*0.5, ptDim2);
ptDimPos = XLine(ptDim1, ptDim2).NearPoint(ptText);
}
}
if (bAngular && nDimTextMovePos!=2)
{
//pDim->setTextRotation(dTextRot);
}
*/
XPoint ptDimPos = pNode->ptPos, ptTempPos;
XPointDir2d ptTempDir;
XCurveSegment cvDim = GetDimCurve();
cvDim.ProjectToMe(pNode->ptPos, ptTempPos);
double dDistNonDefPt = cvDim.PathDistance(ptTempPos);
cvDim.Polar(dDistNonDefPt, ptTempDir);
double dTextRot = ChangeToNormalViewAngle(ptTempDir.nDirection);
pDim->setTextPosition(pNode->ptPos);
if (nDimTextMovePos == 1)
{
//wlw add 12.09.17带引线的标注,如果小于cad引线范围内,人为修改文字位置,否则导t3文字移位
double ddimgapX = nPScale*(dimgap + dimtxt*0.5);
if (ptDimPos.Distance2d(ptTempPos) + _DIST_SNAP < ddimgapX + nPScale * dimexe)
{
ads_polar(ptDimPos, dTextRot-PI/2, ddimgapX, ptDimPos);
pDim->setTextPosition(ptDimPos);
}
}
pDim->useSetTextPosition();
}
// sg modify 120315,解决如果单独设置过上华的布局转角,图形导出T3或者炸开后,文字位置错误的问题
// 主要是CAD的对象没有布局转角的概念,需要额外处理一下
else if (fabs(m_nLayoutRotation) > _angSnap)
{
XPoint ptDefText = GetDefaultTextPos(i, poly);
pDim->setTextPosition(ptDefText); // 固定文字位置
pDim->useSetTextPosition();
double dTextAngle = ads_angle(ptText, ptDefText); // 重新计算标注的角度,0位置表示的是与Y轴正向间的夹角
dTextAngle -= PI/2;
pDim->setTextRotation(dTextAngle);
// 需要单独修改扩展数据来设置对象内的“文字偏移”
bModifyGap = true;
}
// TDimTextContent *pNode1 = ((TDbDimension2 *)this)->m_lstTextContent.FindNode(&i, TDimTextContent::CompareByIndexForFind);
XString sTextdim = GetText(i, poly, &bIsDefText);
//wlw mod 130929导出T3保持文字不变
if (bIsDefText)
{
pDim->setDimensionText(_T(""));
}
else
{
pDim->setDimensionText(sTextdim);
}
pDim->setDimensionStyle(idDimStyle);
pDim->setDimstyleData(idDimStyle);
pDim->setPropertiesFrom(this);
#if (ADS != 17)
if (bModifyGap) // 标记为真的适合,表示需要单独修改“文字偏移”量,上华的尺寸标注对象,不支持遮挡效果,所以直接设置为0即可
{
pDim->setDimgap(0);
}
#endif
((XExplodeStream &)dc).Append(pDim, FALSE);
}
}
dc.SetColor(nColorOld);
return Acad::eOk;
}
const TCHAR *TDbDimension2::GetDefaultLayer() const
{
return LAY_DIM;
}
TEntityBase::DrawType
TDbDimension2::GetDrawType() const
{
return TEntityBase::k2DOnly;
}
/* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */
void TDbDimension2::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("连续标注")));
const TCHAR *pSubType;
if(!IsAngular()) pSubType=_T("线性标注");
else if(IsDimChord()) pSubType=_T("弦长标注");
else if(IsDimArcLen()) pSubType=_T("弧长标注");
else pSubType=_T("角度标注");
lstInfo.Append(new TObjInfoUnit(_T("子类型"), pSubType));
lstInfo.Append(new TObjInfoUnit(_T("标注样式"), GetSymbolName(m_idDimStyle)));
XString sDist;
ftoa(fabs(m_nDist2DimLine), 1, sDist);
sDist << _T("P");
lstInfo.Append(new TObjInfoUnit(_T("尺寸线偏移"), sDist));
if(!IsAngular()) {
lstInfo.Append(new TObjInfoUnit(_T("旋转角度"), Angle2Str(m_nRotation*180/PI)));
} else if(IsDimChord() || IsDimArcLen()) {
lstInfo.Append(new TObjInfoUnit(_T("所注半径"), Dist2Str(m_nObjRadius)));
}
}
class XDimAutoAdjust
{
public:
XDimAutoAdjust() {}
protected:
typedef struct dimTextInfo
{
// 文字测量值
double dDimText;
// Y方向文字位置,0外偏;1、2、3...原位、上调;-1、-2、-3...下调
int nYLoc;
// X方向文字包围盒位置,全部投影到尺寸标注中的GetDimCurve上
double dSLoc;
double dELoc;
// 文字包围框的X值大小
double dX;
}SDimInfo;
typedef struct rowInfo
{
// 当前排号,1、2、3...原位、上调;-1、-2、-3...下调
int nY;
// 当前排号下,最后一个编号
int nIndex;
}SRow;
public:
// 设置标注的基本通用信息
void SetDimParam(XCurveSegment seg, AcDbObjectId idStyle, double dHeight, double dLayoutRotation);
// 向数组中添加标注信息段
void AppendDim(const TCHAR* pszDimText, const TCHAR* pszText, XPoint pt);
// 进行自动调整
void AutoAdjust(BOOL bUp, BOOL bAllowExt);
// 获得某一段最后Y方向的偏移位置
int GetYLoc(int nIndex) const;
// 获得文字包围盒的X方向大小
double GetXDist(int nIndex) const;
//默认是一个文字宽度1.0
void SetDispSnap(double dScale = 1.0);
protected:
// 单独处理第1段和最后一段的外偏情况
void DealFirstAndLastDim(BOOL bAllowExt);
int RecursionUpDownAdjust(int nIndex, BOOL bUp, BOOL bAllowExt);
void GetDimPathDist(XPoint pt, XPointDir2d &ptDir) const;
double ChangeToNormalViewAngle(double dAngWcs) const;
int GetRowMaxIndex(int nY) const;
void AppendRow(int nY, int nIndexNum);
protected:
// 将每一个尺寸标注对象拆分保存成一个一个SDimInfo
CArray<SDimInfo, SDimInfo&> m_arDimInfo;
// 将每排的情况列到一个数组中
CArray<SRow, SRow&> m_arRows;
private:
XCurveSegment m_segDim;
AcDbObjectId m_idTextStyle;
double m_dTextHeight;
double m_dLayoutRotation;
double m_d_DIST_SNAP;//判断文字重合间隙
};
void XDimAutoAdjust::SetDimParam(XCurveSegment seg, AcDbObjectId idStyle, double dHeight, double dLayoutRotation)
{
m_segDim = seg;
m_idTextStyle = idStyle;
m_dTextHeight = dHeight;
m_dLayoutRotation = dLayoutRotation;
}
void XDimAutoAdjust::SetDispSnap(double dSnap)
{
TDbText text;
text.SetText(_T("5"));
text.SetStyleId(m_idTextStyle);
text.SetHeight(m_dTextHeight, FALSE);
text.SetAlignment(XExplodeDraw::kBottomLeft);
XPoint ptTextExt = text.GetExtents(); // 文字轮廓
m_d_DIST_SNAP = ptTextExt.x * dSnap;
}
int XDimAutoAdjust::GetYLoc(int nIndex) const
{
return m_arDimInfo[nIndex].nYLoc;
}
double XDimAutoAdjust::GetXDist(int nIndex) const
{
return m_arDimInfo[nIndex].dX;
}
void XDimAutoAdjust::AppendDim(const TCHAR* pszDimText, const TCHAR* pszText, XPoint pt)
{
SDimInfo dim;
dim.nYLoc = 1;
dim.dDimText = _tstof(pszDimText);
XPointDir2d ptDir;
GetDimPathDist(pt, ptDir);
TDbText text;
text.SetText(pszText);
text.SetStyleId(m_idTextStyle);
text.SetHeight(m_dTextHeight, FALSE);
text.SetAlignment(XExplodeDraw::kBottomLeft);
XPoint ptTextExt = text.GetExtents(), // 文字轮廓
pt1, pt2;
double dTextRot = ChangeToNormalViewAngle(ptDir.nDirection); // 文字角度
ads_polar(pt, dTextRot, ptTextExt.x/2, pt1);
ads_polar(pt1, dTextRot+PI, ptTextExt.x, pt2);
double dDist1 = m_segDim.PathDistance(pt1, 1), // 都是相对m_segDim的起点的
dDist2 = m_segDim.PathDistance(pt2, 1);
dim.dSLoc = (dDist1 > dDist2 + _DIST_SNAP) ? dDist2 : dDist1; // 较小的作为起点
dim.dELoc = (dDist1 > dDist2 + _DIST_SNAP) ? dDist1 : dDist2; // 较大的作为终点
dim.dX = ptTextExt.x;
m_arDimInfo.Add(dim);
}
int XDimAutoAdjust::GetRowMaxIndex(int nY) const
{
int nRows = (int)m_arRows.GetSize();
for (int i=0; i<nRows; i++)
{
if (m_arRows[i].nY == nY)
return m_arRows[i].nIndex;
}
return -1;
}
void XDimAutoAdjust::AppendRow(int nY, int nIndexNum)
{
int nRows = (int)m_arRows.GetSize();
for (int i=0; i<nRows; i++)
{
if (m_arRows[i].nY == nY)
{
m_arRows[i].nIndex = nIndexNum;
return;
}
}
SRow row;
row.nIndex = nIndexNum;
row.nY = nY;
m_arRows.Add(row);
}
int XDimAutoAdjust::RecursionUpDownAdjust(int nIndex, BOOL bUp, BOOL bAllowExt)
{
int nCurY = m_arDimInfo[nIndex].nYLoc,
nMax(0), nPrev(0), nNextY(0);
while (1) // 将nIndex从1排开始,一排一排比较后,上移或者下移,尝试确定位置
{
nMax = GetRowMaxIndex(nCurY); // 得到“当前排”最大的一个索引号
nPrev = (nMax==-1) ? (nIndex-1) : nMax;
if (nPrev<0 || nPrev==nIndex || m_arDimInfo[nPrev].nYLoc!=nCurY)
{
AppendRow(nCurY, nIndex);
return -1; // 没有引起其他段变化
}
if (nPrev > nIndex)
break;
if (m_arDimInfo[nIndex].dSLoc < m_arDimInfo[nPrev].dELoc + m_d_DIST_SNAP) // 有重合,要调整文字
{
nNextY = bUp ? (nCurY+1) : (nCurY-1);
nNextY = (nNextY==0) ? -1 : nNextY;
if (m_arDimInfo[nIndex].dDimText > m_arDimInfo[nPrev].dDimText + m_d_DIST_SNAP) // 当前数字大于前一个数字
{
if (nIndex==0 && bAllowExt) // 允许外偏
break;
m_arDimInfo[nPrev].nYLoc = nNextY;
AppendRow(nCurY, nIndex);
break;
}
else // 当前数字小于、等于前一个数字
{
if (nPrev==0 && bAllowExt) // 允许外偏
{
AppendRow(nCurY, nIndex);
break;
}
m_arDimInfo[nIndex].nYLoc = nNextY;
nCurY = nNextY;
continue;
}
}
else
{
AppendRow(nCurY, nIndex);
return -1;
}
}
return nPrev;
}
void XDimAutoAdjust::AutoAdjust(BOOL bUp, BOOL bAllowExt)
{
int nSize = (int)m_arDimInfo.GetSize(),
nCur(0), nMax(0), nPrev(0), nInd(0), nCurY(0), nNextY(0),i(0);
int nUpY = 2, nDownY = -1;
nNextY = bUp ? nUpY : nDownY;
int nBackNextY = bUp ? nDownY : nUpY;
for (nCur = 2; nCur < nSize - 1; nCur++)
{
double dtttt = m_arDimInfo[nCur].dDimText;
double ddist = m_arDimInfo[nCur].dX;
nCurY = m_arDimInfo[nCur].nYLoc;
for (i = nCur - 1; i > 0; i--)
{
if (m_arDimInfo[nCur].nYLoc == m_arDimInfo[i].nYLoc)
{
nPrev = i;
break;
}
}
double ds = m_arDimInfo[nCur].dSLoc;
double de = m_arDimInfo[nPrev].dELoc;
if (m_arDimInfo[nCur].dSLoc < m_arDimInfo[nPrev].dELoc + m_d_DIST_SNAP) // 有重合,要调整文字
{
if(m_arDimInfo[nCur+1].dSLoc < m_arDimInfo[nCur].dELoc + m_d_DIST_SNAP)
{//当前与前一个和后一个都重叠
if (nCur == nPrev + 1)
{
m_arDimInfo[nCur].nYLoc = nNextY;
}
else
{
m_arDimInfo[nCur].nYLoc = nBackNextY;
}
continue;
}
if (m_arDimInfo[nCur].dDimText > m_arDimInfo[nPrev].dDimText + m_d_DIST_SNAP) // 当前数字大于前一个数字
{
if (nCur == nPrev + 1)
{//相邻的两个文字作比较
m_arDimInfo[nPrev].nYLoc = nNextY;
if (m_arDimInfo[nPrev - 1].nYLoc == nNextY)
{//前一个文字上移时,先检查前一个的前一个是否也上移了。
if (m_arDimInfo[nPrev].dSLoc < m_arDimInfo[nPrev-1].dELoc + m_d_DIST_SNAP)
{
//文字有交叉,直接放到对面位置上
m_arDimInfo[nPrev].nYLoc = nBackNextY;
}
}
}
else
{//非相邻做比较,说明相邻的已经move过位置了
m_arDimInfo[nPrev].nYLoc = nBackNextY;
}
}
else // 当前数字小于、等于前一个数字
{
if (nCur == nPrev + 1)
{
m_arDimInfo[nCur].nYLoc = nNextY;
if (m_arDimInfo[nPrev].nYLoc == nNextY)
{
if (m_arDimInfo[nCur].dSLoc < m_arDimInfo[nPrev].dELoc + m_d_DIST_SNAP)
{
//文字有交叉,直接放到对面位置上
m_arDimInfo[nCur].nYLoc = nBackNextY;
}
}
}
else
{
m_arDimInfo[nCur].nYLoc = nBackNextY;
}
}
}
}
DealFirstAndLastDim(bAllowExt);
}
// 单独处理第1段和最后一段的外偏情况
void XDimAutoAdjust::DealFirstAndLastDim(BOOL bAllowExt)
{
if (!bAllowExt) // 如果允许外偏,还要额外判断一下,是否查过了尺寸界线
{
return;
}
double ddd = m_arDimInfo[0].dSLoc;
double dsss = m_arDimInfo[0].dDimText;
if (m_arDimInfo[0].dSLoc < 1)
{
m_arDimInfo[0].nYLoc = 0;
}
int nSize = (int)m_arDimInfo.GetSize();
if (nSize > 1) // 有1段以上
{
if (m_arDimInfo[1].dSLoc < m_arDimInfo[0].dELoc)
{//如果第二个与第一个重合,则优先考虑侧移第一个
if (m_arDimInfo[1].nYLoc == m_arDimInfo[0].nYLoc)
{
m_arDimInfo[0].nYLoc = 0;
}
}
double ddde = m_arDimInfo[nSize-1].dELoc;
double ddds = m_arDimInfo[nSize-1].dSLoc;
double dsss = m_arDimInfo[nSize-1].dDimText;
double dssss = m_segDim.GetLength();
if (m_arDimInfo[nSize-1].dELoc > m_segDim.GetLength())
{
m_arDimInfo[nSize-1].nYLoc = 0;
}
if (m_arDimInfo[nSize-1].dSLoc < m_arDimInfo[nSize-2].dELoc)
{//如果最后一个与倒数第二个重合,则优先考虑侧移最后一个
if (m_arDimInfo[nSize-1].nYLoc == m_arDimInfo[nSize-2].nYLoc)
{
m_arDimInfo[nSize-1].nYLoc = 0;
}
}
}
}
double XDimAutoAdjust::ChangeToNormalViewAngle(double dAngWcs) const
{
double dAng = TchExport::AngleRangeTo2PI(dAngWcs - m_dLayoutRotation),
dSnap = 1.0E-1,
dAng1 = TchExport::AngleRangeTo2PI(dAng);//double dSnap = 1.0E-9, 9.0beta1
if (GreatThan(dAng1, PI/2.0, dSnap) && LessThan(dAng1, PI, dSnap))
{
dAng1 += PI;
}
else if (GreatEqual(dAng1, PI, dSnap) && LessEqual(dAng1, PI*1.5, dSnap))
{
dAng1 -= PI;
}
dAng = dAng1;
dAng = TchExport::AngleRangeTo2PI(m_dLayoutRotation + dAng);
return dAng;
}
void XDimAutoAdjust::GetDimPathDist(XPoint pt, XPointDir2d &ptDir) const
{
double dPathDist = m_segDim.PathDistance(pt);
m_segDim.Polar(dPathDist, ptDir);
}
//尺寸文字位置的自动调整
// 返回最后一个的调整结果
// 0--缺省, 1--上调, 2--下调, 3--侧调
// nFromUp--开始调整的状态,bAllowExt--是否允许外调,bAutoReset--无需调整的是否自动复位
int TDbDimension2::AdjustDim(BOOL bFromUp, BOOL bAllowExt, BOOL bAutoReset)
{
assertWriteEnabled();
if (!IsValid())
return 0;
double nPScale = GetPScale();
double dimgap = 0,
dimtxt = 0,
dimexe = 0,
dimexo = 0;
double dimscale = 1.0,
dimasz = 1.0;
int dimdec = 0, dimadec = 0 ,nDimTextMovePos;
double dimlfac = 1.0;
double nArrowThick = 6.0*nPScale;
AcDbObjectId dimblk;
AcDbObjectId dimtxsty;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
if (!pDimStyle)
return 0;
dimlfac = pDimStyle->dimlfac(); // 比例因子
dimdec = pDimStyle->dimdec(); // 线型标注显示的小数位数(精度)
dimadec = pDimStyle->dimadec(); // 角度标注显示的小数位数(精度)
dimgap = pDimStyle->dimgap(); // 从尺寸线偏移
dimtxt = pDimStyle->dimtxt(); // 指定标注文字的高
dimblk = pDimStyle->dimblk(); // 箭头块名称
//dimscale = pDimStyle->dimscale();
dimscale = nPScale; // 全局比例因子
dimasz = pDimStyle->dimasz(); // 箭头大小
dimtxsty = pDimStyle->dimtxsty(); // 文字样式
dimexe = pDimStyle->dimexe(); // 尺寸界线上超尺寸线的距离
dimexo = pDimStyle->dimexo(); // 尺寸界线偏离原点的距离
// wlw add 20120913,增加对“标注文字从默认位置(由标注样式定义的位置)移动时标注文字的位置”设置的支持,引线
nDimTextMovePos = pDimStyle->dimtmove();
OPENOBJ_END();
if (!dimtxsty)
return 0;
int nRetCode = 0;
if (bAutoReset)
m_lstTextPos.Reset();
XCurveSegment cv = GetDimCurve();
XPoly2D poly;
GetPolySegOnDimLine(poly);
if (IsAngular() && IsDimChord()) //弦长标注
{
int numSeg=poly.TotalSegments();
int nCode=0;
for(int i=0; i<numSeg; i++)
{
if(!bAutoReset && m_lstTextPos.FindNode(&i, TDimTextPos::CompareByIndexForFind))
continue;
XCurveSegment segDim, segFix, segObj;
poly.Nth(i, segDim);
segFix = segDim.Offset(OFFSET_LEFT, -GetDist2DimLine(FALSE), LS_FINITE);
double nOffDist=segDim.GetArc().GetRadius() - m_nObjRadius;
segObj = segDim.Offset(OFFSET_LEFT, nOffDist, LS_FINITE);
double nRot=segObj.XLine::Direction();
XPoint ptFix;
double nObj2Fix=segFix.GetArc().GetRadius()-segObj.GetArc().GetRadius();
ads_polar(segObj.StartPoint(), nRot-PI/2, nObj2Fix, ptFix);
TDbDimension2 objDim;
objDim.setPropertiesFrom(this);
objDim.SetLocation(ptFix);
objDim.SetRotation(nRot);
objDim.SetDist2DimLine(GetDist2DimLine());
objDim.AppendSegment(segObj.GetArc().ChordLength());
objDim.SetStyleId(GetStyleId());
TDimTextContent *pNode=((TDbDimension2 *)this)->m_lstTextContent.FindNode(&i, TDimTextContent::CompareByIndexForFind);
if(pNode) objDim.SetTextContent(0, pNode->sText);
BOOL bUpAdj=bFromUp;
if(!nCode)
nCode=objDim.AdjustDim(bUpAdj, (i==0 || i==numSeg));
BOOL bDef=TRUE;
XPoint ptTextPos=objDim.GetTextPos(0, &bDef);
if(!bDef)
SetTextPos(i, ptTextPos);
}
}
//else // 直线标注或角度标注
//{
// double nOffDist = m_nDist2DimLine*GetPScale();
// DList<XLine> lstLineSet;
// int numVert = poly.Length();
// for (int i=0; i<numVert; i++)
// {
// XPoint ptVert = *poly[i];
// double nPathDist = cv.PathDistance(ptVert);
// XPointDir2d ptVertDir;
// cv.Polar(nPathDist, ptVertDir);
// // 尺寸界限
// XPoint pt1, pt2;
// double nFactor = fabs(nOffDist)>_DIST_SNAP? nOffDist/fabs(nOffDist) : 1.0;
// ads_polar(ptVert, ptVertDir.nDirection-nFactor*PI/2, dimexe*dimscale/*fabs(nOffDist)-dimexo*dimscale*/, pt1);
// ads_polar(ptVert, ptVertDir.nDirection+nFactor*PI/2, dimexe*dimscale, pt2);
// lstLineSet.Append(new XLine(pt1, pt2));
// }
// double nTextHeight = dimtxt*dimscale;
// int numSeg = poly.TotalSegments();
// // 0--缺省, 1--上调, 2--下调, 3--外调
// TCHAR *pPosTable = new TCHAR [numSeg];
// for (i=0; i<numSeg; i++)
// {
// pPosTable[i] = 0;
// if (!bAutoReset && m_lstTextPos.FindNode(&i, TDimTextPos::CompareByIndexForFind))
// continue;
// XCurveSegment seg;
// poly.Nth(i, seg);
// XPoint ptText = GetDefaultTextPos(i);
// XPoint ptTemp;
// XPointDir2d ptTempDir;
// cv.ProjectToMe(ptText, ptTemp);
// double nDist = cv.PathDistance(ptTemp);
// cv.Polar(nDist, ptTempDir);
// // sg modify 120410,使用新增加的接口,代替基类中的NormalViewAngle函数,主要解决精确度是1度的问题
// // double nTextRot=NormalViewAngle(ptTempDir.nDirection);
// double nTextRot = ChangeToNormalViewAngle(ptTempDir.nDirection);
// XString sText = GetText(i);
// TDbText text;
// text.setPropertiesFrom(this);
// text.SetText(sText);
// text.SetStyleId(dimtxsty);
// text.SetHeight(nTextHeight, FALSE);
// XPoint ptExt = text.GetExtents();
// //ptExt.y *= nEn2Ch;
// XLine lnUp, lnDown;
// XPoint ptMidRight;
// ads_polar(ptText, nTextRot, ptExt.x/2, ptMidRight);
// XPoint ptVert;
// ads_polar(ptMidRight, nTextRot+PI/2, ptExt.y/2, ptVert);
// lnUp.StartPoint() = ptVert;
// ads_polar(XPoint(ptVert), nTextRot+PI, ptExt.x, ptVert);
// lnUp.EndPoint() = ptVert;
// ads_polar(XPoint(ptVert), nTextRot-PI/2, ptExt.y, ptVert);
// lnDown.StartPoint() = ptVert;
// ads_polar(XPoint(ptVert), nTextRot, ptExt.x, ptVert);
// lnDown.EndPoint() = ptVert;
// XLine *ln1 = lstLineSet[i];
// ln1->SetLineFlag(LS_FINITE);
// lnUp.SetLineFlag(LS_FINITE);
// lnDown.SetLineFlag(LS_FINITE);
// if (lnUp.Intersection(ln1, XPoint()) || lnDown.Intersection(ln1, XPoint()))
// {
// // 需要自调
// if (bAllowExt && (i==0 || i==numSeg-1)) // 侧调
// {
// XPointDir2d ptPosExt;
// cv.Polar(-(ptExt.x/2+dimgap*nPScale), ptPosExt, i==0);
// // sg modify 120410,使用新增加的接口,代替基类中的NormalViewAngle函数,主要解决精确度是1度的问题
// // double nDirNext=NormalViewAngle(ptPosExt.nDirection)+PI/2;
// double nDirNext = ChangeToNormalViewAngle(ptPosExt.nDirection)+PI/2;
// XPoint ptTextPos;
// ads_polar(ptPosExt, nDirNext, (dimgap+dimtxt*0.7)*nPScale, ptTextPos);
// SetTextPos(i, ptTextPos);
// pPosTable[i] = 3;
// }
// else
// {
// BOOL bPrevAdj = FALSE;
// if (i>0 && pPosTable[i-1]!=0)
// bPrevAdj = TRUE;
// if (bPrevAdj)
// {
// pPosTable[i] = 0;
// }
// else
// {
// BOOL bUpAdj = bFromUp;
// XPoint ptTextPos;
// //double nFactor = fabs(nOffDist)>_DIST_SNAP? nOffDist/fabs(nOffDist) : 1.0;
// XPointDir2d ptVertDir;
// seg.Polar(seg.GetLength()/2, ptVertDir);
// // sg modify 120410,使用新增加的接口,代替基类中的NormalViewAngle函数,主要解决精确度是1度的问题
// // double nUpDir = NormalViewAngle(ptVertDir.nDirection);
// double nUpDir = ChangeToNormalViewAngle(ptVertDir.nDirection);
// if(bUpAdj) // 尺寸线方向外
// {
// ads_polar(ptVertDir, nUpDir+PI/2, (dimgap*2+dimtxt*1.5*0.7)*nPScale, ptTextPos);
// pPosTable[i]=1;
// }
// else
// {
// ads_polar(ptVertDir, nUpDir-PI/2, (dimgap+dimtxt*0.5)*nPScale, ptTextPos);
// pPosTable[i]=2;
// }
// SetTextPos(i, ptTextPos);
// }
// }
// }
// else
// {
// pPosTable[i] = 0;
// }
// }
// nRetCode = pPosTable[numSeg-1];
//}
else // 直线标注或角度标注
{
double dTextHeight = dimtxt * dimscale, // 文字字高
dTextRot(0.0);
XDimAutoAdjust dimAdjust;
dimAdjust.SetDimParam(cv, dimtxsty, dTextHeight, m_nLayoutRotation);
//wlw add 120912设置文字间隙
dimAdjust.SetDispSnap(0.6);
int nSegNums = poly.TotalSegments(),
nCur(0);
for (nCur=0; nCur<nSegNums; nCur++)
{
XPoint ptText = GetDefaultTextPos(nCur); // 文字默认位置点
XString sDefaultText = GetDefaultText(nCur), // 文字默认内容
sText = GetText(nCur); // 文字实际注写的内容
dimAdjust.AppendDim(sDefaultText, sText, ptText);
}
dimAdjust.AutoAdjust(bFromUp, bAllowExt); // 处理自动调整的情况
XPoint ptTextPos;
XPointDir2d ptVertDir;
for (nCur=0; nCur<nSegNums; nCur++)
{
if (!bAutoReset && m_lstTextPos.FindNode(&nCur, TDimTextPos::CompareByIndexForFind)) // 不允许尺寸自调
continue;
int nLoc = dimAdjust.GetYLoc(nCur);
if (nLoc == 1)
continue;
if (nLoc == 0) // 外偏
{
cv.Polar(-(dimAdjust.GetXDist(nCur)/2+dimgap*nPScale), ptVertDir, nCur==0);
dTextRot = ChangeToNormalViewAngle(ptVertDir.nDirection)+PI/2;
ads_polar(ptVertDir, dTextRot, (dimgap+dimtxt*0.5)*nPScale, ptTextPos);
SetTextPos(nCur, ptTextPos);
continue;
}
XCurveSegment seg;
poly.Nth(nCur, seg);
seg.Polar(seg.GetLength()/2, ptVertDir);
dTextRot = ChangeToNormalViewAngle(ptVertDir.nDirection);
double dDimLen = dimgap + dimtxt/2 + (dimtxt + dimgap/2) * (abs(nLoc) - 1);
if (nDimTextMovePos == 1)
{//带引线//wlw mod 12.09.15
dDimLen = dimgap + dimexe + dimtxt/2;
}
if (nLoc > 1) // 尺寸线方向上调 wlw add 120918向下调一点,避开上面的尺寸线(dDimLen - 0.5)
{
ads_polar(ptVertDir, dTextRot+PI/2, (dDimLen - 0.5)*nPScale, ptTextPos);
}
else
{// 尺寸线方向下调
ads_polar(ptVertDir, dTextRot-PI/2, dDimLen*nPScale, ptTextPos);
}
SetTextPos(nCur, ptTextPos);
}
}
return nRetCode;
}
//取得尺寸线
XCurveSegment
TDbDimension2::GetDimCurve() const
{
assertReadEnabled();
//ASSERT(IsValid());
XPoint ptStart, ptEnd;
double nDist=m_nDist2DimLine*GetPScale();
ads_polar(m_ptLocation, m_nRotation+PI/2, nDist, ptStart);
double nSweepAngle=0.0;
if(IsAngular()) {
XPoint ptCen;
ads_polar(ptStart, m_nRotation+PI/2, m_nDimRadius, ptCen);
nSweepAngle=GetTotalSegValue();
if(fabs(nSweepAngle-2.0*PI)<_angSnap)
nSweepAngle -= 2.0*_angSnap;
//add by whl on 060110
if(fabs(nSweepAngle)<1E-6)
nSweepAngle=PI;
double nEndAng=ads_angle(ptCen, ptStart)+nSweepAngle;
ads_polar(ptCen, nEndAng, m_nDimRadius, ptEnd);
} else {
double nTotalDist=GetTotalSegValue();
//add by whl on 060110
if(fabs(nTotalDist)<1E-6)
nTotalDist=1;
ads_polar(ptStart, m_nRotation, nTotalDist, ptEnd);
}
return XCurveSegment(ptStart, ptEnd, nSweepAngle);
}
void TDbDimension2::GetPolySegOnDimLine(XPoly2D &poly) const
{
assertReadEnabled();
XCurveSegment cv=GetDimCurve();
XSortedVertexList lstVert(cv);
int nSeg=m_lstSegment.Length();
double nDist=0.0;
for(int i=0; i<nSeg-1; i++) {
XPointDir2d ptVert;
double nVal=GetSegment(i);
nDist += nVal;
cv.Polar(nDist, ptVert);
lstVert.Insert(ptVert);
}
lstVert.AsPoly2D(poly);
}
AcDbCurve* TDbDimension2::GetBaseCurve()const
{
assertReadEnabled();
XPoly2D poly;
GetPolySegOnDimLine(poly);
return poly.AsAcDbCurve();
}
Acad::ErrorStatus TDbDimension2::SetBaseCurve(AcDbCurve*pCurve)
{
assertWriteEnabled();
XPoly2D poly;
if(poly.SetAcDbCurve(pCurve)&&poly.Length()>1)
{
XPoint ptFirst=*poly.Head(),ptLast=*poly.Tail();
XCurveSegment cvOld=GetDimCurve();
XPoly2D polyOld;
GetPolySegOnDimLine(polyOld);
bool bChangeFirst=ptFirst!=cvOld.StartPoint();
bool bChangeLast=ptLast!=cvOld.EndPoint();
if(bChangeFirst&&bChangeLast)//首尾都变
{
m_lstSegment.Reset();
for(long i=1;i<poly.Length();i++)
m_lstSegment.Append(new double(poly[i]->Distance2d(*poly[i-1])));
XCurveSegment cv;
poly.Nth(0,cv);
cv=cv.Offset(m_nDist2DimLine*GetPScale(),1);
m_ptLocation=cv.StartPoint();
m_lstTextPos.Reset();
m_lstTextContent.Reset();
}
else if(bChangeFirst)//首变
{
FindAndRemoveSegment(cvOld.StartPoint());
double dist=cvOld.PathDistance(ptFirst,FALSE);
for(long i=1;i<polyOld.Length();i++)
{
if((cvOld.PathDistance(*polyOld[i],FALSE)-dist)>_DIST_SNAP)//在新起点之前
FindAndRemoveSegment(*polyOld[i]);
else
break;
}
AddSegment(ptFirst);
}
else if(bChangeLast)//尾变
{
FindAndRemoveSegment(cvOld.EndPoint());
double dist=cvOld.PathDistance(ptLast,TRUE);
for(long i=polyOld.Length()-2;i>=0;i--)
{
if((cvOld.PathDistance(*polyOld[i],TRUE)-dist)>_DIST_SNAP)//在新终点之后
FindAndRemoveSegment(*polyOld[i]);
else
break;
}
AddSegment(ptLast);
}
return Acad::eOk;
}
else
return Acad::eInvalidInput;
}
int TDbDimension2::HitTestOnDimSeg(XPoint pt) const
{
XCurveSegment cv=GetDimCurve();
XPoint ptOnDim;
if(cv.ProjectToMe(pt, ptOnDim)!=RTNORM)
return -1;
XPoly2D poly;
GetPolySegOnDimLine(poly);
int nSeg=poly.TotalSegments();
for(int i=0; i<nSeg; i++) {
XCurveSegment seg;
poly.Nth(i, seg);
if((ptOnDim&seg)==PR_INSIDE)
return i;
}
return -1;
}
int TDbDimension2::HitTestOnText(XPoint pt) const
{
int nSeg=m_lstSegment.Length();
int nRet=-1;
double nDistMin=0.0;
for(int i=0; i<nSeg; i++) {
XPoint ptPos=GetTextPos(i);
if(nRet<0) {
nRet=i;
nDistMin=ptPos.Distance2d(pt);
} else {
double nDist=ptPos.Distance2d(pt);;
if(nDist<nDistMin) {
nDistMin=nDist;
nRet=i;
}
}
}
return nRet;
}
//add by whl on 041020
//返回节点索引,输入为近似节点,输出为准确节点,以系统拾取框大小为距离精度。
int TDbDimension2::HitTestOnPoint(XPoint&pt)const
{
XCurveSegment cv=GetDimCurve();
XPoint ptOnDim;
if(cv.ProjectToMe(pt, ptOnDim)!=RTNORM)
return -1;
double nMaxDist=GetApertureWcs()/2;
XPoly2D poly;
GetPolySegOnDimLine(poly);
for(long i=0;i<poly.Length();i++)
if(ptOnDim.Distance2d(*poly[i])<=nMaxDist)
{
pt=*poly[i];
return i;
}
return -1;
}
// 角度-弦长-弧长
void TDbDimension2::SwitchDimChord()
{
if(!IsAngular())
return;
BOOL bChord=IsDimChord();
BOOL bArcLen=IsDimArcLen();
if(!bChord && !bArcLen) { //角度
XCurveSegment cv=GetDimCurve();
XArc arDim=cv.GetArc();
double nObjRadius=GetObjRadius();
if(arDim.GetRadius() < nObjRadius) { //自动反向
double nDiff=nObjRadius-arDim.GetRadius();
arDim.SetRadius(arDim.GetRadius() + 2*nDiff);
SetDimRadius(arDim.GetRadius());
cv=arDim;
arDim.SetRadius(nObjRadius);
XCurveSegment segObj;
segObj=arDim;
XPoint ptNewLoc;
segObj.StartPoint().Mirror(GetLocation(), ptNewLoc);
double nDist=ptNewLoc.Distance2d(cv.StartPoint());
int nSide=cv.OnWhichSide(ptNewLoc);
if(nSide==OFFSET_LEFT)
nDist=-nDist;
SetDist2DimLine(nDist, FALSE);
SetLocation(ptNewLoc);
for(int i=0; i<m_lstTextPos.Length(); i++) {
TDimTextPos *pText=m_lstTextPos[i];
XPoint ptOnObj;
segObj.ProjectToMe(pText->ptPos, ptOnObj);
ptOnObj.Mirror(XPoint(pText->ptPos), pText->ptPos);
}
}
SetStyleId(InitDimStyle(DS_LINEAR));
SetDimChord(TRUE);
SetDimArcLen(FALSE);
} else if(bChord) {
SetStyleId(InitDimStyle(DS_ANGLE));
SetDimChord(FALSE);
SetDimArcLen(TRUE);
} else {
SetStyleId(InitDimStyle(DS_ANGLE));
SetDimChord(FALSE);
SetDimArcLen(FALSE);
}
}
void TDbDimension2::RemoveZeroSegment()
{
assertWriteEnabled();
int nSeg=m_lstSegment.Length();
double nPrec=IsAngular()? _angSnap : _DIST_SNAP;
for(int i=0; i<nSeg; i++) {
if(*m_lstSegment[i]<nPrec) {
RemoveSegment(i);
i--;
nSeg--;
}
}
}
void TDbDimension2::RemoveSegment(int iSeg)
{
assertWriteEnabled();
int nSeg=m_lstSegment.Length();
ASSERT(iSeg>=0 && iSeg<nSeg);
m_lstSegment.Remove(iSeg);
if(m_lstTextPos.FindNode(&iSeg, TDimTextPos::CompareByIndexForFind))
m_lstTextPos.Remove();
int nTextSeg=m_lstTextPos.Length();
for(int i=0; i<nTextSeg; i++) {
TDimTextPos *pNode=m_lstTextPos[i];
if(pNode->nIndex>iSeg)
pNode->nIndex--;
}
if(m_lstTextContent.FindNode(&iSeg, TDimTextContent::CompareByIndexForFind))
m_lstTextContent.Remove();
nTextSeg=m_lstTextContent.Length();
for(i=0; i<nTextSeg; i++) {
TDimTextContent *pNode=m_lstTextContent[i];
if(pNode->nIndex>iSeg)
pNode->nIndex--;
}
AutoSetFlag();
}
void
TDbDimension2::InsertSegmentAt(int n, double nVal, BOOL bDist)
{
assertWriteEnabled();
ASSERT(IsValidSegment(nVal, bDist));
if(n>=0 && n<m_lstSegment.Length()) {
if(IsAngular() && bDist)
nVal=nVal/m_nDimRadius;
m_lstSegment[n];
m_lstSegment.Insert(new double(nVal));
int nTextSeg=m_lstTextPos.Length();
for(int i=0; i<nTextSeg; i++) {
TDimTextPos *pNode=m_lstTextPos[i];
if(pNode->nIndex>=n)
pNode->nIndex++;
}
nTextSeg=m_lstTextContent.Length();
for(i=0; i<nTextSeg; i++) {
TDimTextContent *pNode=m_lstTextContent[i];
if(pNode->nIndex>=n)
pNode->nIndex++;
}
} else if(n>=m_lstSegment.Length()) {
AppendSegment(nVal, bDist);
}
AutoSetFlag();
}
void
TDbDimension2::SetSegment(int n, double nVal, BOOL bDist)
{
assertWriteEnabled();
ASSERT(IsValidSegment(nVal, bDist));
if(n>=0 && n<m_lstSegment.Length()) {
if(IsAngular() && bDist)
nVal=nVal/m_nDimRadius;
*m_lstSegment[n]=nVal;
}
}
// 在指定的位置加入一区间
BOOL TDbDimension2::AddSegment(XPoint ptAdd)
{
assertWriteEnabled();
XCurveSegment cv=GetDimCurve();
XPoint ptOnDim;
if(cv.ProjectToMe(ptAdd, ptOnDim)!=RTNORM)
return FALSE;
int nPrFlag=(ptOnDim&cv);
if(nPrFlag==PR_ONPT1 && nPrFlag==PR_ONPT2)
return FALSE;
BOOL bRet=FALSE;
if(nPrFlag==PR_INSIDE) {
if(GetSegmentNum()>0)
{
XPoly2D poly;
GetPolySegOnDimLine(poly);
int nSeg=poly.TotalSegments();
for(int n=0; n<nSeg; n++) {
XCurveSegment seg;
poly.Nth(n, seg);
if((ptOnDim&seg)==PR_INSIDE) {
double nVal=fabs(seg.PathDistance(ptOnDim));
double nVal1=fabs(seg.PathDistance(ptOnDim, FALSE)); //距离终点的距离
if(IsValidSegment(nVal) && IsValidSegment(nVal1)) {
TDimTextPos *pNode=m_lstTextPos.FindNode(&n, TDimTextPos::CompareByIndexForFind);
if(pNode) m_lstTextPos.Remove();
SetSegment(n, nVal1);
InsertSegmentAt(n, nVal);
bRet=TRUE;
}
break;
}
}
}
else
{
double nVal=fabs(cv.PathDistance(ptOnDim, TRUE));
if(IsValidSegment(nVal)) {
AppendSegment(nVal);
bRet=TRUE;
}
}
} else if(ptOnDim.Distance2d(cv.EndPoint()) < ptOnDim.Distance2d(cv.StartPoint())) {
if(GetSegmentNum()>0)
{
double nVal=fabs(cv.PathDistance(ptOnDim, FALSE));
if(IsValidSegment(nVal)) {
AppendSegment(nVal);
bRet=TRUE;
}
}
else
{
double nVal=fabs(cv.PathDistance(ptOnDim, TRUE));
if(IsValidSegment(nVal)) {
AppendSegment(nVal);
bRet=TRUE;
}
}
} else {
double nVal=fabs(cv.PathDistance(ptOnDim, TRUE));
if(IsValidSegment(nVal)) {
cv.SetPoints(ptOnDim, XPoint(cv.EndPoint()));
InsertSegmentAt(0, nVal);
m_nRotation = cv.IDirection(0);
ads_polar(cv.StartPoint(), m_nRotation-PI/2, m_nDist2DimLine*GetPScale(), m_ptLocation);
bRet=TRUE;
}
}
if(bRet)
AutoSetFlag();
return bRet;
}
//add by whl on 040810
BOOL TDbDimension2::FindAndRemoveSegment(XPoint pt)
{
if(GetSegmentNum()<1)
return FALSE;
XCurveSegment seg=GetDimCurve();
XPoint ptOnSeg;
seg.ProjectToMe(pt, ptOnSeg);
double value=seg.PathDistance(ptOnSeg);
long i=-1;
if(value>_DIST_SNAP)
{
double curValue=0;
for(i=0;i<GetSegmentNum();i++)
{
curValue+=GetSegment(i);
if(fabs(curValue-value)<_DIST_SNAP)
break;
}
}
if(i>=GetSegmentNum())
return FALSE;//useful
if(i>=0)
{
double temp=GetSegment(i);
if(i<GetSegmentNum()-1)//是中间段
SetSegment(i+1,temp+GetSegment(i+1));//后一段合并之
RemoveSegment(i);
}
else//第一个标注段的起点特殊处理,弧段不对!
{
double temp=GetSegment(0);
RemoveSegment(0);
XVector3D vt=seg.EndPoint()-seg.StartPoint();
vt.Scale(temp/vt.Length());
SetLocation(GetLocation()+vt);
}
return TRUE;
}
BOOL TDbDimension2::FindPoint(XPoint pt)const
{
XCurveSegment cv=GetDimCurve();
XPoint ptOnDim;
if(cv.ProjectToMe(pt, ptOnDim)!=RTNORM)
return FALSE;
double nMaxDist=1E-3;
XPoly2D poly;
GetPolySegOnDimLine(poly);
for(long i=0;i<poly.Length();i++)
{
double nDist=ptOnDim.Distance2d(*poly[i]);
if(nDist<=nMaxDist)
return TRUE;
}
return FALSE;
}
double TDbDimension2::GetMaxScope()const
{
if(m_lstOffset.Length()>0)
return m_lstOffset[0];
else
return 20;
}
BOOL TDbDimension2::UpdateFrom(XPoint ptNew0,XPoint ptNew1,XPoint ptOld0,XPoint ptOld1,bool bErased)
{
ptNew0.z=0;
ptNew1.z=0;
ptOld0.z=0;
ptOld1.z=0;
AcGeVector2d vtDim(cos(m_nRotation),sin(m_nRotation));
AcGeVector2d vtNew(ptNew1.x-ptNew0.x,ptNew1.y-ptNew0.y);
AcGeVector2d vtOld(ptOld1.x-ptOld0.x,ptOld1.y-ptOld0.y);
vtNew.normalize();
vtOld.normalize();
if(vtNew.isZeroLength()||vtOld.isZeroLength())
return FALSE;
if(!vtOld.isParallelTo(vtDim)||!vtNew.isParallelTo(vtDim))
return FALSE;
if(!FindPoint(ptOld0)||!FindPoint(ptOld1))
return FALSE;
XCurveSegment curve1=GetDimCurve();
XCurveSegment curve2;
if(m_nDist2DimLine>0)
curve2=curve1.Offset((m_nDist2DimLine+GetMaxScope())*GetPScale(),0);
else
curve2=curve1.Offset((m_nDist2DimLine-GetMaxScope())*GetPScale(),0);
XPoly2D poly(1);
poly.AppendNode(curve1.StartPoint());
poly.AppendNode(curve1.EndPoint());
poly.AppendNode(curve2.EndPoint());
poly.AppendNode(curve2.StartPoint());
if((ptOld0&poly)==PR_OUTSIDE||
(ptOld1&poly)==PR_OUTSIDE)
return FALSE;
if(upgradeOpen()!=Acad::eOk)
return FALSE;
if(bErased)
{
FindAndRemoveSegment(ptOld0);
FindAndRemoveSegment(ptOld1);
}
else
{
long oldSegNum=GetSegmentNum();
if(ptOld0!=ptNew0&&ptOld0!=ptNew1)
FindAndRemoveSegment(ptOld0);
if(ptOld1!=ptNew0&&ptOld1!=ptNew1)
FindAndRemoveSegment(ptOld1);
if(GetSegmentNum()<oldSegNum)
{
if(GetSegmentNum()>0)
{
AddSegment(ptNew0);
AddSegment(ptNew1);
}
else
{
XPoint ptLocation0=m_ptLocation;
AddSegment(ptNew0);
AddSegment(ptNew1);
if(GetSegmentNum()>oldSegNum)
FindAndRemoveSegment(ptLocation0);
}
}
}
return TRUE;
}
BOOL TDbDimension2::MergeDim(const TDbDimension2 *pDim)
{
assertWriteEnabled();
if(!IsUseDefaultText())
return FALSE;
XCurveSegment cv=GetDimCurve();
XSortedVertexList lstVert(cv);
int nSeg=m_lstSegment.Length();
double nDist=0.0;
for(int i=0; i<nSeg-1; i++) {
XPointDir2d ptVert;
double nVal=GetSegment(i);
nDist += nVal;
cv.Polar(nDist, ptVert);
lstVert.Insert(ptVert);
}
XPoly2D poly;
pDim->GetPolySegOnDimLine(poly);
for(i=0; i<poly.Length(); i++) {
XPoint ptVert;
if(cv.ProjectToMe(*poly[i], ptVert)==RTNORM)
lstVert.Insert(ptVert, TRUE);
}
m_lstTextPos.Reset();
m_lstSegment.Reset();
XPoly2D polyNew;
lstVert.AsPoly2D(polyNew);
nSeg=polyNew.TotalSegments();
for(i=0; i<nSeg; i++) {
XCurveSegment seg;
polyNew.Nth(i, seg);
double nVal=seg.GetLength();
ASSERT(nVal>_DIST_SNAP);
if(IsValidSegment(nVal))
AppendSegment(nVal);
if(i==0) {
m_nRotation=seg.IDirection(0);
ads_polar(seg.StartPoint(), m_nRotation-PI/2, m_nDist2DimLine*GetPScale(), m_ptLocation);
}
}
AutoSetFlag();
return TRUE;
}
BOOL TDbDimension2::ConvertFrom(const AcDbDimension *pDim)
{
assertWriteEnabled();
double nScale=100.0;
AcDbObjectId idStyle=DimStyleAcad2Tch(pDim->dimensionStyle(), nScale);
SetPScale(nScale);
//double val;
//VERIFY(pDim->measurement(val)==Acad::eOk);
XString sText;
sText=pDim->dimensionText();
double dotVec=pDim->normal().dotProduct(AcGeVector3d(0,0,1));
if(fabs(dotVec-1.0)>1.0E-6 || !idStyle)
return FALSE;
setPropertiesFrom(pDim);
m_idDimStyle = idStyle;
m_lstTextPos.Reset();
if(!pDim->isUsingDefaultTextPosition()) {
m_lstTextPos.Append(new TDimTextPos(0, XPoint(pDim->textPosition())));
}
m_lstTextContent.Reset();
if(!!sText)
m_lstTextContent.Append(new TDimTextContent(0, sText));
BOOL bRet=FALSE;
if(pDim->isKindOf(AcDb2LineAngularDimension::desc())||
pDim->isKindOf(AcDb3PointAngularDimension::desc())) {
AcDb3PointAngularDimension *pDim1=AcDb3PointAngularDimension::cast(pDim);
AcDb2LineAngularDimension *pDim2=AcDb2LineAngularDimension::cast(pDim);
XPoint pt1, pt2, ptDim, ptCen;
if(pDim1) {
pt1=pDim1->xLine1Point();
pt2=pDim1->xLine2Point();
ptDim=pDim1->arcPoint();
ptCen=pDim1->centerPoint();
} else {
pt1=pDim2->xLine1Start();
pt2=pDim2->xLine2Start();
ptDim=pDim2->arcPoint();
XPoint qt1=pDim2->xLine1End(),
qt2=pDim2->xLine2End();
XLine ll(pt2, qt2);
XLine(pt1, qt1).Intersection(&ll, ptCen);
}
m_nDimRadius=ptCen.Distance2d(ptDim);
SetAngular(TRUE);
SetDimChord(FALSE);
m_ptLocation=pt1;
m_ptLocation.z=0;
m_nRotation=ads_angle(ptCen, pt1)+PI/2;
XArc arDim(ptCen, m_nDimRadius, ads_angle(ptCen, pt1), ads_angle(ptCen, pt2));
XCurveSegment segDim;
segDim=arDim;
//XPoint ptOnDim1;
//pt1.Project(arDim, ptOnDim1);
double nDist2DimLine=fabs(m_nDimRadius-ptCen.Distance2d(pt1));
int nSide=segDim.OnWhichSide(m_ptLocation);
if(nSide==OFFSET_LEFT)
nDist2DimLine=-nDist2DimLine;
m_nObjRadius=m_nDimRadius+nDist2DimLine;
SetDist2DimLine(nDist2DimLine, FALSE);
m_lstSegment.Reset();
if(IsValidSegment(arDim.Bulge(), FALSE)) {
AppendSegment(arDim.Bulge(), FALSE);
bRet=TRUE;
}
} else if(pDim->isKindOf(AcDbAlignedDimension::desc()) ||
pDim->isKindOf(AcDbRotatedDimension::desc())) {
AcDbAlignedDimension *pDim1=AcDbAlignedDimension::cast(pDim);
AcDbRotatedDimension *pDim2=AcDbRotatedDimension::cast(pDim);
ASSERT(pDim1 || pDim2);
XPoint pt1, pt2, ptDim;
if(pDim1) {
pt1=pDim1->xLine1Point();
pt2=pDim1->xLine2Point();
ptDim=pDim1->dimLinePoint();
} else {
pt1=pDim2->xLine1Point();
pt2=pDim2->xLine2Point();
ptDim=pDim2->dimLinePoint();
if(!CT_IsSameDrt(ads_angle(pt1, pt2), pDim2->rotation(), _angSnap))
return FALSE;
}
m_nDimRadius=m_nObjRadius=0;
SetAngular(FALSE);
SetDimChord(FALSE);
m_ptLocation=pt1;
m_ptLocation.z=0;
m_nRotation=ads_angle(pt1, pt2);
XPoint ptOnDim1, ptOnDim2;
XLine ll(ptDim, m_nRotation);
pt1.Project(&ll, ptOnDim1);
pt2.Project(&ll, ptOnDim2);
int nSide=XLine(ptDim, m_nRotation).OnWhichSide(m_ptLocation);
m_nDist2DimLine=pt1.Distance2d(ptOnDim1)/GetPScale();
if(nSide==OFFSET_LEFT)
m_nDist2DimLine=-m_nDist2DimLine;
m_lstSegment.Reset();
double nVal=ptOnDim1.Distance2d(ptOnDim2);
if(IsValidSegment(nVal)) {
AppendSegment(nVal);
bRet=TRUE;
}
}
if(bRet)
AutoSetFlag();
return bRet;
}
BOOL TDbDimension2::ConvertFrom(const TDbDimension *pDim)
{
assertWriteEnabled();
TDbDimension2::CopyPropertiesFrom((AcDbEntity*)pDim,0xFFFFFFFF);
m_ptLocation=pDim->m_ptLocation;
m_nRotation=pDim->m_nRotation;
m_nDist2DimLine=pDim->m_nDist2DimLine;
m_nDimRadius=pDim->m_nDimRadius;
m_nObjRadius=pDim->m_nObjRadius;
m_idDimStyle=pDim->m_idDimStyle;
m_lstSegment.Reset();
for(long i=0;i<pDim->m_lstSegment.Length();i++)
m_lstSegment.Append(new double(pDim->m_lstSegment[i]));
m_lstTextPos.Reset();
for(i=0;i<pDim->m_lstTextPos.Length();i++)
{
TDimTextPos *pNew=new TDimTextPos;
pNew->nIndex=pDim->m_lstTextPos[i].nIndex;
pNew->ptPos=pDim->m_lstTextPos[i].ptPos;
m_lstTextPos.Append(pNew);
}
m_nDimFlag=pDim->m_nDimFlag;
m_lstTextContent.Reset();
for(i=0;i<pDim->m_lstTextContent.Length();i++)
{
TDimTextContent *pNew=new TDimTextContent;
pNew->nIndex=pDim->m_lstTextContent[i].nIndex;
pNew->sText=pDim->m_lstTextContent[i].sText;
m_lstTextContent.Append(pNew);
}
return TRUE;
}
Acad::ErrorStatus TDbDimension2::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet, BOOL *bErase)
{
Acad::ErrorStatus es=Acad::eOk;
if(g_nSaveTArchVer>=GetFirstVersion())
{
if(bErase)
*bErase=FALSE;
}
else if(IsValid())
{
TDbDimension* pDim=new TDbDimension;
pDim->CopyPropertiesFrom(this,0xFFFFFFFF);
pDim->m_ptLocation=m_ptLocation;
pDim->m_nRotation=m_nRotation;
pDim->m_nDist2DimLine=m_nDist2DimLine;
pDim->m_nDimRadius=m_nDimRadius;
pDim->m_nObjRadius=m_nObjRadius;
pDim->m_idDimStyle=m_idDimStyle;
pDim->m_lstSegment.Reset();
for(long i=0;i<m_lstSegment.Length();i++)
pDim->m_lstSegment.Append(new double(*m_lstSegment[i]));
pDim->m_lstTextPos.Reset();
for(i=0;i<m_lstTextPos.Length();i++)
{
TDimTextPos *pNew=new TDimTextPos;
pNew->nIndex=m_lstTextPos[i]->nIndex;
pNew->ptPos=m_lstTextPos[i]->ptPos;
pDim->m_lstTextPos.Append(pNew);
}
pDim->m_nDimFlag=m_nDimFlag;
pDim->m_lstTextContent.Reset();
for(i=0;i<m_lstTextContent.Length();i++)
{
TDimTextContent *pNew=new TDimTextContent;
pNew->nIndex=m_lstTextContent[i]->nIndex;
pNew->sText=m_lstTextContent[i]->sText;
pDim->m_lstTextContent.Append(pNew);
}
entSet.append(pDim);
if(bErase)
*bErase=TRUE;
}
return es;
}
// Properties
double TDbDimension2::GetSegment(int n, BOOL bDist) const
{
ASSERT(n>=0 && n<m_lstSegment.Length());
double nVal=m_lstSegment[n];
if(IsAngular() && bDist) {
ASSERT(m_nDimRadius>_DIST_SNAP);
nVal *= m_nDimRadius;
}
return nVal;
}
double
TDbDimension2::GetTotalSegValue() const
{
double nVal=0.0;
int nCount=m_lstSegment.Length();
for(int i=0; i<nCount; i++)
nVal += m_lstSegment[i];
return nVal;
}
BOOL
TDbDimension2::IsAngular() const
{
return ((m_nDimFlag&DF_ANGULAR)!=0);
//return (m_nDimRadius>_angSnap);
}
BOOL
TDbDimension2::IsAssociate() const
{
return ((m_nDimFlag&DF_ASSOCIATE)!=0);
}
void
TDbDimension2::SetAssociate(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nDimFlag |= DF_ASSOCIATE;
else
m_nDimFlag &= ~DF_ASSOCIATE;
}
int TDbDimension2::GetSegmentNum() const
{
return m_lstSegment.Length();
}
double
TDbDimension2::GetObjRadius() const
{
return m_nObjRadius;
}
BOOL
TDbDimension2::IsDimChord() const
{
return ((m_nDimFlag&DF_CHORD));
}
BOOL
TDbDimension2::IsDimArcLen() const
{
return ((m_nDimFlag&DF_ARCLEN));
}
XPoint
TDbDimension2::GetLocation() const
{
return m_ptLocation;
}
double
TDbDimension2::GetRotation() const
{
return m_nRotation;
}
double
TDbDimension2::GetDist2DimLine(BOOL bAsPaperUnit) const
{
double val=m_nDist2DimLine;
if(!bAsPaperUnit)
val *= GetPScale();
return val;
}
double
TDbDimension2::GetDimRadius() const
{
return m_nDimRadius;
}
AcDbObjectId
TDbDimension2::GetStyleId() const
{
return m_idDimStyle;
}
// Modify on 2002/02/05, 考虑dimlfac进行单位换算
XString
TDbDimension2::GetDefaultText(int nIndex) const
{
ASSERT(nIndex<m_lstSegment.Length() && nIndex>=0);
XPoly2D poly;
GetPolySegOnDimLine(poly);
XCurveSegment seg;
poly.Nth(nIndex, seg);
int dimdec, dimadec;
double dimlfac=1.0;
int dimaunit=0;
int dimzin=0;
int dimazin=0;
double dimrnd =0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
ASSERT(pDimStyle);
dimdec=pDimStyle->dimdec();
dimadec=pDimStyle->dimadec();
dimlfac=pDimStyle->dimlfac();
dimaunit=pDimStyle->dimaunit();
dimzin=pDimStyle->dimzin();
dimazin=pDimStyle->dimazin();
dimrnd = pDimStyle->dimrnd();
if(dimaunit>1)
dimaunit=1;
OPENOBJ_END();
XString sText;
if(IsAngular())
{
if(IsDimChord())
{
ASSERT(0); //永远也不会执行这儿
ftoa(seg.XLine::GetLength()*dimlfac, dimdec, sText);
}
else if(IsDimArcLen())
{
XArc ar=seg.GetArc();
ar.SetRadius(m_nObjRadius);
ftoa(ar.GetLength()*dimlfac, dimdec, sText);
}
else
{
XString sTemp;
ads_angtos(fabs(seg.GetBulge()), dimaunit, dimadec, sTemp);
const TCHAR *pd=_tcschr(sTemp, _T('d'));
if(pd) {
StrCpy(sText, sTemp, pd);
sText << _T("%%d");
sText << (pd+1);
} else if(dimaunit==0) {
if(dimazin&0x02)
DelSuffixZero(sTemp);
sText << sTemp << _T("%%d");
}else {
sText << sTemp;
}
}
}
else
{
XString sDimrnd;
ftoa(seg.GetLength()*dimlfac, dimdec, sText);
//////// 处理 标注样式中舍入的问题zzg 090515
double dTemLen(0),dTemrnd(0);
ftoa(dimrnd,dimdec,sDimrnd);
dTemLen = _tstof(sText);
dTemrnd = _tstof(sDimrnd);
if (!Equal(dTemrnd,0,0.00000001))
{
double dT = dTemLen/dTemrnd;
XString sT;
ftoa(dT,0,sT);
dT = _tstof(sT);
int nt = (int)dT;
double dDimNum = dTemrnd*nt;
ftoa(dDimNum, dimdec, sText);
}
//////zzg090515//////////////
if((dimzin&0x08)!=0) {
DelSuffixZero(sText);
}
}
return sText;
}
XString
TDbDimension2::GetText(int nIndex, BOOL *bIsDefault) const
{
XString sText;
TDimTextContent *pNode=((TDbDimension2 *)this)->m_lstTextContent.FindNode(&nIndex, TDimTextContent::CompareByIndexForFind);
if(pNode) {
sText=pNode->sText;
if(bIsDefault) *bIsDefault=FALSE;
} else {
if(bIsDefault) *bIsDefault=TRUE;
sText=GetDefaultText(nIndex);
}
return sText;
}
XPoint
TDbDimension2::GetTextPos(int nIndex, BOOL *bIsDefault) const
{
ASSERT(nIndex<m_lstSegment.Length() && nIndex>=0);
TDimTextPos *pNode=((TDbDimension2 *)this)->m_lstTextPos.FindNode(&nIndex, TDimTextPos::CompareByIndexForFind);
if(pNode) {
if(bIsDefault) *bIsDefault=FALSE;
return pNode->ptPos;
}
if(bIsDefault)
*bIsDefault=TRUE;
XPoint ptText=GetDefaultTextPos(nIndex);
return ptText;
}
XPoint
TDbDimension2::GetDefaultTextPos(int nIndex) const
{
ASSERT(nIndex<m_lstSegment.Length() && nIndex>=0);
XPoly2D poly;
GetPolySegOnDimLine(poly);
double nOffDist=m_nDist2DimLine*GetPScale();
BOOL bAngular=IsAngular();
int nSeg=poly.TotalSegments();
XCurveSegment seg;
poly.Nth(nIndex, seg);
ASSERT(!!seg);
XPointDir2d ptTextPos;
seg.Polar(seg.GetLength()/2.0, ptTextPos);
XPoint ptText=ptTextPos;
double nDist2Dim=0.0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
if(pDimStyle)
nDist2Dim = (pDimStyle->dimgap() + pDimStyle->dimtxt()/2)*GetPScale(); //pDimStyle->dimscale();
else
nDist2Dim = 3.0*GetPScale();
OPENOBJ_END();
XPoint ptBase;
if(IsAngular() && IsDimChord()) {
Midpoint(seg.StartPoint(), seg.EndPoint(), ptBase);
} else {
ptBase=ptTextPos;
}
// sg modify 120410,使用新增加的接口,代替基类中的NormalViewAngle函数,主要解决精确度是1度的问题
// ads_polar(ptBase, NormalViewAngle(ptTextPos.nDirection)+PI/2.0, nDist2Dim, ptText);
ads_polar(ptBase, ChangeToNormalViewAngle(ptTextPos.nDirection)+PI/2.0, nDist2Dim, ptText);
return ptText;
}
//add by xlc on 101209 解决多视口图纸切换速度慢的问题
XString
TDbDimension2::GetDefaultText(int nIndex, XPoly2D poly) const
{
ASSERT(nIndex<m_lstSegment.Length() && nIndex>=0);
// XPoly2D poly;
// GetPolySegOnDimLine(poly);
XCurveSegment seg;
poly.Nth(nIndex, seg);
int dimdec, dimadec;
double dimlfac=1.0;
int dimaunit=0;
int dimzin=0;
int dimazin=0;
double dimrnd =0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
ASSERT(pDimStyle);
dimdec=pDimStyle->dimdec();
dimadec=pDimStyle->dimadec();
dimlfac=pDimStyle->dimlfac();
dimaunit=pDimStyle->dimaunit();
dimzin=pDimStyle->dimzin();
dimazin=pDimStyle->dimazin();
dimrnd = pDimStyle->dimrnd();
if(dimaunit>1)
dimaunit=1;
OPENOBJ_END();
XString sText;
if(IsAngular())
{
if(IsDimChord())
{
ASSERT(0); //永远也不会执行这儿
ftoa(seg.XLine::GetLength()*dimlfac, dimdec, sText);
}
else if(IsDimArcLen())
{
XArc ar=seg.GetArc();
ar.SetRadius(m_nObjRadius);
ftoa(ar.GetLength()*dimlfac, dimdec, sText);
}
else
{
XString sTemp;
ads_angtos(fabs(seg.GetBulge()), dimaunit, dimadec, sTemp);
const TCHAR *pd=_tcschr(sTemp, _T('d'));
if(pd) {
StrCpy(sText, sTemp, pd);
sText << _T("%%d");
sText << (pd+1);
} else if(dimaunit==0) {
if(dimazin&0x02)
DelSuffixZero(sTemp);
sText << sTemp << _T("%%d");
}else {
sText << sTemp;
}
}
}
else
{
XString sDimrnd;
ftoa(seg.GetLength()*dimlfac, dimdec, sText);
//////// 处理 标注样式中舍入的问题zzg 090515
double dTemLen(0),dTemrnd(0);
ftoa(dimrnd,dimdec,sDimrnd);
dTemLen = _tstof(sText);
dTemrnd = _tstof(sDimrnd);
if (!Equal(dTemrnd,0,0.00000001))
{
double dT = dTemLen/dTemrnd;
XString sT;
ftoa(dT,0,sT);
dT = _tstof(sT);
int nt = (int)dT;
double dDimNum = dTemrnd*nt;
ftoa(dDimNum, dimdec, sText);
}
//////zzg090515//////////////
if((dimzin&0x08)!=0) {
DelSuffixZero(sText);
}
}
return sText;
}
XString
TDbDimension2::GetText(int nIndex, XPoly2D poly, BOOL *bIsDefault) const
{
XString sText;
TDimTextContent *pNode=((TDbDimension2 *)this)->m_lstTextContent.FindNode(&nIndex, TDimTextContent::CompareByIndexForFind);
if(pNode) {
sText=pNode->sText;
if(bIsDefault) *bIsDefault=FALSE;
} else {
if(bIsDefault) *bIsDefault=TRUE;
sText=GetDefaultText(nIndex, poly);
}
return sText;
}
XPoint
TDbDimension2::GetTextPos(int nIndex, XPoly2D poly, BOOL *bIsDefault) const
{
ASSERT(nIndex<m_lstSegment.Length() && nIndex>=0);
TDimTextPos *pNode=((TDbDimension2 *)this)->m_lstTextPos.FindNode(&nIndex, TDimTextPos::CompareByIndexForFind);
if(pNode) {
if(bIsDefault) *bIsDefault=FALSE;
return pNode->ptPos;
}
if(bIsDefault)
*bIsDefault=TRUE;
XPoint ptText=GetDefaultTextPos(nIndex, poly);
return ptText;
}
XPoint
TDbDimension2::GetDefaultTextPos(int nIndex, XPoly2D poly) const
{
ASSERT(nIndex<m_lstSegment.Length() && nIndex>=0);
// XPoly2D poly;
// GetPolySegOnDimLine(poly);
double nOffDist=m_nDist2DimLine*GetPScale();
BOOL bAngular=IsAngular();
int nSeg=poly.TotalSegments();
XCurveSegment seg;
poly.Nth(nIndex, seg);
ASSERT(!!seg);
XPointDir2d ptTextPos;
seg.Polar(seg.GetLength()/2.0, ptTextPos);
XPoint ptText=ptTextPos;
double nDist2Dim=0.0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
if(pDimStyle)
nDist2Dim = (pDimStyle->dimgap() + pDimStyle->dimtxt()/2)*GetPScale(); //pDimStyle->dimscale();
else
nDist2Dim = 3.0*GetPScale();
OPENOBJ_END();
XPoint ptBase;
if(IsAngular() && IsDimChord()) {
Midpoint(seg.StartPoint(), seg.EndPoint(), ptBase);
} else {
ptBase=ptTextPos;
}
// sg modify 120410,使用新增加的接口,代替基类中的NormalViewAngle函数,主要解决精确度是1度的问题
//ads_polar(ptBase, NormalViewAngle(ptTextPos.nDirection)+PI/2.0, nDist2Dim, ptText);
ads_polar(ptBase, ChangeToNormalViewAngle(ptTextPos.nDirection)+PI/2.0, nDist2Dim, ptText);
return ptText;
}
// sg add 120410,增加一个新的接口,代替基类中的NormalViewAngle函数,主要解决TchPrivate::ChangeAngleTo1_4精确度是1度的问题
// 在布局时正常观察的WCS角度
double TDbDimension2::ChangeToNormalViewAngle(double nAngWcs) const
{
double dAng = Wcs2Layout(nAngWcs);
// 下面这段代码,用于替换TchPrivate::ChangeAngleTo1_4里的精确度,其实功能是一样的
{
double dSnap = 1.0E-3,
dAng1 = TchExport::AngleRangeTo2PI(dAng); //double dSnap = 1.0E-9, 9.0beta1
if (GreatThan(dAng1, PI/2.0, dSnap) && LessThan(dAng1, PI, dSnap))
{
dAng1 += PI;
}
else if (GreatEqual(dAng1, PI, dSnap) && LessEqual(dAng1, PI*1.5, dSnap))
{
dAng1 -= PI;
}
dAng = dAng1;
}
dAng = AngleRangeTo2PI(m_nLayoutRotation + dAng);
return dAng;
}
AcDbObjectId
TDbDimension2::GetBindId() const
{
return m_idBind;
}
void
TDbDimension2::SetLocation(XPoint pt)
{
assertWriteEnabled();
m_ptLocation=pt;
m_ptLocation.z=0;
}
void
TDbDimension2::SetRotation(double nAng)
{
assertWriteEnabled();
m_nRotation=nAng;
}
void
TDbDimension2::SetDist2DimLine(double nVal, BOOL bAsPaperUnit)
{
assertWriteEnabled();
m_nDist2DimLine=nVal;
if(!bAsPaperUnit)
m_nDist2DimLine /= GetPScale();
}
void
TDbDimension2::SetAngular(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue) m_nDimFlag |= DF_ANGULAR;
else m_nDimFlag &= ~DF_ANGULAR;
}
void
TDbDimension2::SetDimChord(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue) m_nDimFlag |= DF_CHORD;
else m_nDimFlag &= ~DF_CHORD;
}
void
TDbDimension2::SetDimArcLen(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue) m_nDimFlag |= DF_ARCLEN;
else m_nDimFlag &= ~DF_ARCLEN;
}
void
TDbDimension2::SetObjRadius(double nVal)
{
assertWriteEnabled();
m_nObjRadius = nVal;
}
void
TDbDimension2::SetDimRadius(double nAng)
{
assertWriteEnabled();
m_nDimRadius=nAng;
}
void
TDbDimension2::SetStyleId(AcDbObjectId idStyle)
{
assertWriteEnabled();
m_idDimStyle = idStyle;
}
void TDbDimension2::SetTextPos(int nIndex, XPoint ptPos)
{
assertWriteEnabled();
ASSERT(nIndex<m_lstSegment.Length() && nIndex>=0);
TDimTextPos *pNode=m_lstTextPos.FindNode(&nIndex, TDimTextPos::CompareByIndexForFind);
if(!pNode) {
XPoint ptOld=GetTextPos(nIndex);
if(ptOld.Distance2d(ptPos)>_DIST_SNAP)
m_lstTextPos.Append(new TDimTextPos(nIndex, ptPos));
} else {
int nPos=m_lstTextPos.CurPosition();
XPoint ptDefault=GetDefaultTextPos(nIndex);
if(ptDefault.Distance2d(ptPos)<_DIST_SNAP)
m_lstTextPos.Remove(nPos);
else
m_lstTextPos[nPos]->ptPos=ptPos;
}
AutoSetFlag();
}
void TDbDimension2::SetTextContent(int n, const TCHAR *pszChar)
{
assertWriteEnabled();
ASSERT(n<m_lstSegment.Length() && n>=0);
//wlw add 13.06.22 增加对等式的智能判断
XString scharok = pszChar;
double dDis = GetSegment(n);
double dPrec = 1E-4;
CString sExpression(pszChar);
CString sLeft1,sLeft2,sRight;
int nstar = sExpression.Find(_T("X"));
int nstar1 = sExpression.Find(_T("="));
if (nstar < 0)
{
nstar = sExpression.Find(_T("x"));
}
if (nstar > 0 && nstar1 > 0)
{
sLeft1 = sExpression.Left(nstar);
sLeft2 = sExpression.Mid(nstar+1,nstar1 - nstar - 1);
sRight = sExpression.Right(sExpression.GetLength() - nstar1 - 1);
double dRight = _tstof(sRight);
//看看哪些数字改变过
CString sOld = GetText(n).cs();
CString soldLeft1,soldLeft2,soldRight;
nstar = sOld.Find(_T("X"));
nstar1 = sOld.Find(_T("="));
if (nstar < 0)
{
nstar = sOld.Find(_T("x"));
}
if (nstar > 0 && nstar1 > 0)
{
soldLeft1 = sOld.Left(nstar);
soldLeft2 = sOld.Mid(nstar+1,nstar1 - nstar - 1);
soldRight = sOld.Right(sOld.GetLength() - nstar1 - 1);
double d1,d2;
double doldRight = _tstof(soldRight);
d1 = _tstof(sLeft2);
d2 = _tstof(soldLeft2);
if (RealEqual(dRight, doldRight, dPrec))
{//总长度没变,改前面任意一个
if (d1 < 1E-10)
{
return;
}
if (RealEqual(d1, d2, dPrec))
{//第二个数没变,按照第一数进行计算
d1 = _tstof(sLeft1);
if (d1 < 1E-10)
return;
d2 = doldRight / d1;
}
else
{//第二个数变,按照第二数进行计算
d2 = _tstof(sLeft2);
if (d2 < 1E-10)
return;
d1 = doldRight / d2;
}
}
else
{//总长度变化了,按照乘数不变的原则改第一个数
d2 = _tstof(sLeft2);
if (d2 < 1E-10)
{
return;
}
d1 = dRight / d2;
}
int nd1 = d1;
int nd2 = d2;
if (d2 != nd2)
{
if (d1 != nd1)
{
sExpression.Format(_T("%.1fX%.1f=%.0f"),d1,d2,dRight);
}
else
{
sExpression.Format(_T("%.0fX%.1f=%.0f"),d1,d2,dRight);
}
}
else
{
if (d1 != nd1)
{
sExpression.Format(_T("%.1fX%.0f=%.0f"),d1,d2,dRight);
}
else
{
sExpression.Format(_T("%.0fX%.0f=%.0f"),d1,d2,dRight);
}
}
}
}
scharok = sExpression;
TDimTextContent *pNode=m_lstTextContent.FindNode(&n, TDimTextContent::CompareByIndexForFind);
if(!pNode) {
if(pszChar && pszChar[0])
m_lstTextContent.Append(new TDimTextContent(n, scharok));
} else {
if(!pszChar || !pszChar[0])
m_lstTextContent.Remove();
else
pNode->sText=scharok;
}
AutoSetFlag();
}
void TDbDimension2::SetBindId(AcDbObjectId id)
{
assertWriteEnabled();
m_idBind=id;
AutoSetFlag();
}
void
TDbDimension2::AppendSegment(double nVal, BOOL bDist)
{
assertWriteEnabled();
ASSERT(IsValidSegment(nVal, bDist));
if(IsAngular() && bDist)
nVal = nVal/m_nDimRadius;
m_lstSegment.Append(new double(nVal));
}
void
TDbDimension2::ResetTextPos()
{
assertWriteEnabled();
m_lstTextPos.Reset();
AutoSetFlag();
}
void
TDbDimension2::ResetTextContent()
{
assertWriteEnabled();
m_lstTextContent.Reset();
AutoSetFlag();
}
BOOL
TDbDimension2::IsTextMoved() const
{
return ((m_nDimFlag&DF_POSITION)!=0 && m_lstTextPos.Length());
}
BOOL
TDbDimension2::IsUseDefaultText() const
{
return ((m_nDimFlag&DF_TEXT)==0 || m_lstTextContent.Length()==0);
}
BOOL
TDbDimension2::IsBind() const
{
return ((m_nDimFlag&DF_BIND)!=0 && !!m_idBind);
}
BOOL
TDbDimension2::IsUseDimStyleScale() const
{
return ((m_nDimFlag&DF_DSSCALE)!=0);
}
void
TDbDimension2::UseDimStyleScale(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nDimFlag |= DF_DSSCALE;
else
m_nDimFlag &= ~DF_DSSCALE;
}
void TDbDimension2::AutoSetFlag()
{
assertWriteEnabled();
if(!!m_idBind)
m_nDimFlag |= DF_BIND;
else
m_nDimFlag &= ~DF_BIND;
if(m_lstTextPos.Length())
m_nDimFlag |= DF_POSITION;
else
m_nDimFlag &= ~DF_POSITION;
if(m_lstTextContent.Length())
m_nDimFlag |= DF_TEXT;
else
m_nDimFlag &= ~DF_TEXT;
}
// sg add 101116,支持统一标高
bool TDbDimension2::UnifyElevation(double dElevation)
{
assertWriteEnabled();
m_ptLocation.z = dElevation;
for (int i=0; i<m_lstTextPos.Length(); i++)
{
m_lstTextPos[i]->ptPos.z = dElevation;
}
return true;
}
Acad::ErrorStatus TDbDimension2::getSplitCurves (const AcGeDoubleArray& params,
AcDbVoidPtrArray& curveSegments) const
{
assertReadEnabled();
if (IsAngular() || IsDimArcLen())
{
AcGePoint3dArray points;
for (int i = 0 ; i < params.length(); i++)
{
AcGePoint3d pt;
getPointAtParam(params[i], pt);
points.append(pt);
}
return getSplitCurves(points, curveSegments);
}
else
{
return TDbCurveEntity::getSplitCurves(params,curveSegments);
}
}
Acad::ErrorStatus TDbDimension2::getSplitCurves (const AcGePoint3dArray& points,
AcDbVoidPtrArray& curveSegments) const
{
assertReadEnabled();
if (IsAngular() || IsDimArcLen())
{
int nlen = points.length();
XPoint ptOnDim;
XPoint ptPick, ptPick2;
TDbDimension2 *pDimClone = (TDbDimension2 *)clone();
getClosestPointTo(points[0], ptPick);
pDimClone->AddSegment(ptPick);
if (nlen > 1)
{
getClosestPointTo(points[1], ptPick2);
pDimClone->AddSegment(ptPick2);
}
XPoly2D poly;
pDimClone->GetPolySegOnDimLine(poly);
int nSeg= -1;
int nSeg2= -1;
for(int i=0; i<poly.TotalSegments(); i++)
{
XCurveSegment seg;
poly.Nth(i, seg);
if((ptPick&seg)==PR_ONPT1 || (ptPick&seg)==PR_ONPT2)
{
nSeg = i;
break;
}
}
if (nlen > 1)
{
for(i=0; i<poly.TotalSegments(); i++)
{
XCurveSegment seg;
poly.Nth(i, seg);
if((ptPick2&seg)==PR_ONPT1 || (ptPick2&seg)==PR_ONPT2)
{
nSeg2 = i;
break;
}
}
int nTmp;
if (nSeg > nSeg2)
{
nTmp = nSeg;
nSeg = nSeg2;
nSeg2 = nTmp;
}
}
XDirectionCurve seg;
XPoint ptLoc;
TDbDimension2 *pDimNew2=(TDbDimension2 *)pDimClone->clone();
int nTotalSeg=poly.TotalSegments();
int nSeg1 = nSeg+1;
for(i=nSeg1; i<nTotalSeg; i++)
pDimNew2->RemoveSegment(nSeg1);
curveSegments.append(pDimNew2);
if (nlen > 1)
{
TDbDimension2 *pDimNew3=(TDbDimension2 *)pDimClone->clone();
curveSegments.append(pDimNew3);
poly.Nth(nSeg2+1, seg);
}
else
{
poly.Nth(nSeg1, seg);
}
double nRot = seg.IDirection(0);
ads_polar(seg.StartPoint(), nRot-PI/2.0, pDimClone->GetDist2DimLine(FALSE), ptLoc);
TDbDimension2 *pDimNew=(TDbDimension2 *)pDimClone->clone();
if (nlen > 1)
{
for(i=0; i<nSeg2+1; i++)
pDimNew->RemoveSegment(0);
}
else
{
for(i=0; i<nSeg1; i++)
pDimNew->RemoveSegment(0);
}
pDimNew->SetLocation(ptLoc);
pDimNew->SetRotation(nRot);
curveSegments.append(pDimNew);
delete pDimClone;
return Acad::eOk;
}
else
{
return TDbCurveEntity::getSplitCurves(points,curveSegments);
}
}
///////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////
// 尺寸对象类
/////////////////////////////////////////////////////////////
const Adesk::UInt8 TDbRadiusDim::g_nVersion = 1;
ACRX_DXF_DEFINE_MEMBERS(ATSRadiusDim, ATSEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_RADIUSDIM, "ATS_RADIUSDIM图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbRadiusDim);
TDbRadiusDim::TDbRadiusDim()
{
m_nDimFlag=0;
m_nDimLen=26.0;
}
TDbRadiusDim::~TDbRadiusDim()
{
}
BOOL TDbRadiusDim::IsValid() const
{
BOOL bRet=TDbEntity::IsValid();
return bRet;
}
Acad::ErrorStatus
TDbRadiusDim::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
void TDbRadiusDim::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbRadiusDim *pSrc=TDbRadiusDim::cast(pSrcEntity);
if(pSrc) {
if(database()==NULL||
pSrcEntity->database()==NULL||
database()==pSrcEntity->database())//add by whl on 060317
{
m_idDimStyle=pSrc->m_idDimStyle; //尺寸标注类型
}
}
}
// 从DWG读入数据:
Acad::ErrorStatus TDbRadiusDim::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbEntity::dwgInFields(pFiler);
if(es != Acad::eOk) return es;
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
if(nVer>g_nVersion) {// Version is too new
return Acad::eMakeMeProxy;
}
pFiler->readItem(&m_nDimFlag);
pFiler->readItem(&m_idDimStyle);
pFiler->readItem(&m_nDimLen);
pFiler->readItem((AcGePoint3d *)&m_ptCenter);
pFiler->readItem((AcGePoint2d *)&m_ptOnArc);
m_sText=_T("");
if(m_nDimFlag&DF_TEXT)
ReadString(pFiler, m_sText);
if(m_nDimFlag&DF_POSITION)
pFiler->readItem((AcGePoint2d *)&m_ptText);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbRadiusDim::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem(m_nDimFlag);
pFiler->writeItem(m_idDimStyle);
pFiler->writeItem(m_nDimLen);
pFiler->writeItem((const AcGePoint3d &)m_ptCenter);
pFiler->writeItem((const AcGePoint2d &)m_ptOnArc);
if(m_nDimFlag&DF_TEXT)
pFiler->writeString(m_sText);
if(m_nDimFlag&DF_POSITION)
pFiler->writeItem((const AcGePoint2d &)m_ptText);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbRadiusDim::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbEntity::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbRadiusDim"))) {
return Acad::eBadDxfSequence;
}
XString sText, sName;
double nDist;
int nFlag;
XPoint pt1, pt2, pt3;
Adesk::UInt32 fieldsFlags = 0;
resbuf rb;
while ((es == Acad::eOk)
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
switch (rb.restype) {
case AcDb::kDxfInt16:
nFlag=rb.resval.rint;
fieldsFlags |= 0x01;
break;
case AcDb::kDxfXCoord:
pt1=rb.resval.rpoint;
fieldsFlags |= 0x02;
break;
case AcDb::kDxfXCoord+1:
pt2=rb.resval.rpoint;
fieldsFlags |= 0x04;
break;
case AcDb::kDxfXCoord+5:
pt3=rb.resval.rpoint;
fieldsFlags |= 0x08;
break;
case AcDb::kDxfText:
fieldsFlags |= 0x10;
sText = rb.resval.rstring;
break;
case AcDb::kDxfDimStyleName:
sName=rb.resval.rstring;
fieldsFlags |= 0x20;
break;
case AcDb::kDxfReal:
fieldsFlags |= 0x40;
nDist = rb.resval.rreal;
break;
//fall through intentional
default:
// An unrecognized group. Push it back so that
// the subclass can read it again.
pFiler->pushBackItem();
es = Acad::eEndOfFile;
break;
}
}
// At this point the es variable must contain eEndOfFile
// - either from readResBuf() or from pushback. If not,
// it indicates that an error happened and we should
// return immediately.
//
if (es != Acad::eEndOfFile)
return Acad::eInvalidResBuf;
if (!(fieldsFlags & 0x02)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 10"));
return Acad::eMissingDxfField;
}
if (!(fieldsFlags & 0x04)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 11"));
return Acad::eMissingDxfField;
}
if (!(fieldsFlags & 0x08)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 15"));
return Acad::eMissingDxfField;
}
if(fieldsFlags&0x01)
m_nDimFlag=nFlag;
m_ptCenter=pt1;
m_ptText=pt2;
m_ptOnArc=pt3;
if(fieldsFlags&0x10)
m_sText=sText;
AcDbObjectId id;
if(fieldsFlags&0x20) {
id=TchExport::GetDimStyleId(sName);
}
if(!id) {
XString style;
xg_getvar(_T("DIMSTYLE"), style);
m_idDimStyle = TchExport::GetTextStyleId(style);
} else
m_idDimStyle=id;
if(fieldsFlags&0x40)
m_nDimLen=nDist;
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbRadiusDim::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es=TDbEntity::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbRadiusDim"));
assert(es == Acad::eOk);
pFiler->writeInt16(AcDb::kDxfInt16, m_nDimFlag);
pFiler->writePoint2d(AcDb::kDxfXCoord, m_ptCenter.AsAcGePoint2d());
pFiler->writePoint2d(AcDb::kDxfXCoord+1, m_ptText.AsAcGePoint2d());
pFiler->writePoint2d(AcDb::kDxfXCoord+5, m_ptOnArc.AsAcGePoint2d());
pFiler->writeString(AcDb::kDxfText, (const TCHAR *)m_sText);
XString sName=GetSymbolName(m_idDimStyle);
pFiler->writeString(AcDb::kDxfDimStyleName, (const TCHAR *)sName); //3
pFiler->writeDouble(AcDb::kDxfReal, m_nDimLen);
return pFiler->filerStatus();
}
// -----------------------------------------------------------------------
Acad::ErrorStatus
TDbRadiusDim::subGetOsnapPoints(AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& pickPoint,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
Acad::ErrorStatus es = Acad::eOk;
switch (osnapMode) {
case AcDb::kOsModeNode:
snapPoints.append(m_ptOnArc);
break;
case AcDb::kOsModeIns: {
XPoint ptText = GetTextPos();
snapPoints.append(ptText);
}
break;
default:
es=TDbEntity::subGetOsnapPoints(osnapMode, gsSelectionMark, pickPoint,
lastPoint, viewXform, snapPoints,
geomIds);
}
return es;
}
// Overriden functions for edit
// to do:
// 允许通过夹点改变边界
Acad::ErrorStatus TDbRadiusDim::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
gripPoints.append(m_ptCenter); //0
XPoint ptFix=GetDimStartPoint();
gripPoints.append(ptFix); //1
gripPoints.append(m_ptOnArc); //2
XPoint ptText=GetTextPos(); //3
gripPoints.append(ptText);
return Acad::eOk;
}
// stretch points is diffrent from grep points, with no midpoint included
Acad::ErrorStatus TDbRadiusDim::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
assertReadEnabled();
AcDbIntArray osnapModes;
AcDbIntArray geomIds;
return subGetGripPoints(stretchPoints, osnapModes, geomIds);
}
// Active when being rotated, scaled, moved, etc.
// Scale is disabled here
Acad::ErrorStatus TDbRadiusDim::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
TDbEntity::subTransformBy(xform);
ads_matrix mat;
AsAdsMatrix(xform, mat);
m_ptCenter.TransformBy(mat);
m_ptOnArc.TransformBy(mat);
BOOL bIsDefault=TRUE;
XPoint ptText=GetTextPos(&bIsDefault);
if(!bIsDefault) {
ptText.TransformBy(mat);
SetTextPos(ptText);
}
return Acad::eOk;
}
// 功能: 夹点操作
Acad::ErrorStatus TDbRadiusDim::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
if(offset.length()<_DIST_SNAP)
return Acad::eOk;
XPoint vtOffset(offset[0], offset[1]);
AcGePoint3dArray ptArray;
XPoint ptFix=GetDimStartPoint();
for (int i = 0; i < indices.length(); i++) {
int idx = indices[i];
switch(idx) {
case 0:
m_ptCenter += vtOffset;
break;
case 1:
ptFix += vtOffset;
break;
case 2:
m_ptOnArc += vtOffset;
break;
case 3: {
XPoint ptText=GetTextPos();
ptText += vtOffset;
SetTextPos(ptText);
}
break;
default:
break;
}
}
if(indices.contains(1)) {
XLine ln(m_ptCenter, m_ptOnArc);
XPoint ptOnLine;
ptFix.Project(&ln, ptOnLine);
double nDist=ptOnLine.Distance2d(m_ptOnArc);
if((ptOnLine&ln)==PR_EXTEND &&
ptOnLine.Distance2d(ln.EndPoint())<ptOnLine.Distance2d(ln.StartPoint())) {
nDist = -nDist;
}
SetDimLen(nDist, FALSE);
}
return Acad::eOk;
}
// 功能: 夹点操作
Acad::ErrorStatus TDbRadiusDim::subMoveStretchPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
return subMoveGripPointsAt(indices, offset);
}
// 取得夹点说明
Acad::ErrorStatus TDbRadiusDim::GetGripText(int i, CString &cs) const
{
Acad::ErrorStatus es=Acad::eOk;
switch(i) {
case 0:
cs=_T("移动圆心");
break;
case 1:
cs=_T("移动引线位置");
break;
case 2:
cs=_T("移动标注点");
break;
case 3:
cs=_T("移动文字");
break;
default:
es=Acad::eInvalidInput;
}
return es;
}
Acad::ErrorStatus
TDbRadiusDim::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
assertReadEnabled();
//modified by whl on 060223
//BOOL bCheckDim=DocGetCheckDim();
BOOL bCheckDim=DocGetCheckDim()&&!g_bExplodeSubText;
double nPScale=GetPScale();
double nArrowLen=2.0;
double nArrowWidth=0.66;
double dimgap=0, dimtxt=0;
double dimscale=1.0, dimasz=1.0;
int dimclrd=0, dimclrt=0;
int dimdec=0;
double dimlfac=1.0; //单位换算系数;
XString sDimPrefix, sDimSuffix;
AcDbObjectId dimblk;
AcDbObjectId dimtxsty;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
if(pDimStyle) {
dimdec=pDimStyle->dimdec();
dimgap=pDimStyle->dimgap();
dimtxt=pDimStyle->dimtxt();
dimscale=GetPScale(); //pDimStyle->dimscale();
dimasz=pDimStyle->dimasz();
dimtxsty=pDimStyle->dimtxsty();
dimblk=pDimStyle->dimblk();
dimlfac=pDimStyle->dimlfac();
//sTextStyle=GetSymbolName(dimtxsty);
dimclrd=pDimStyle->dimclrd().colorIndex();
dimclrt=pDimStyle->dimclrt().colorIndex();
const TCHAR *dimpost=pDimStyle->dimpost();
const TCHAR *pStr=NULL;
if(dimpost)
pStr=_tcsstr(dimpost, _T("<>"));
if(pStr) {
StrCpy(sDimPrefix, dimpost, pStr);
StrCpy(sDimSuffix, pStr+2, NULL);
} else if(dimpost) {
_tcscpy(sDimSuffix, dimpost);
}
} else {
return Acad::eInvalidInput;
}
OPENOBJ_END();
int nOldColor=dc.GetColor();
AcDbPolyline pline;
XPoint ptStart=GetDimStartPoint();
XPoint ptEnd=GetDimEndPoint();
if(!IsDiameter())
{
XPoint ptArrow;
ads_polar(ptEnd, ads_angle(ptEnd, ptStart), nArrowLen*nPScale, ptArrow);
pline.addVertexAt(0, ptStart);
pline.addVertexAt(1, ptArrow);
pline.addVertexAt(2, ptEnd);
/*pline.setWidthsAt(1, nArrowWidth*nPScale, 0.0);*/
//TGGeCurveSegment(const TADSGePoint3d &spt, const TADSGePoint3d &ept, ads_real dAng, int flg = LS_FINITE);
XCurveSegment segDim(ptStart, ptEnd, 0, LS_FINITE);
//支持箭头的更改
if (!dimblk) // 尺寸箭头
{
// sg modify 120412,解决“实心闭合”样式,不支持设置“箭头大小”的问题
double dXSize = 1.0*dimscale*dimasz,
dYSize = 0.33*dimscale*dimasz;
int nDealOldDimArrowSize = DocGetDealOldDimArrowSize();
if (nDealOldDimArrowSize==0 && fabs(dimasz-1.0)<1.0E-3) // 旧版本的“实心闭合”样式
{
dXSize *= 2;
dYSize *= 2;
}
XPointDir2d pt1, pt2;
segDim.Polar(dXSize, pt1);
segDim.Polar(dXSize, pt2, FALSE);
AcDbPolyline plArrow2;
plArrow2.setPropertiesFrom(this);
plArrow2.addVertexAt(0, pt2);
plArrow2.setWidthsAt(0, dYSize, 0.0);
plArrow2.addVertexAt(1, segDim.EndPoint());
plArrow2.setWidthsAt(1, 0.0, 0.0);
dc.Polyline(plArrow2);
}
else
{
// 打印时,不能使用新方法
BOOL bNewMethod=(g_nAcadVer>15.0001 && g_bMakeBlock);
// sg add 091105,强制打印时,不使用新方法
if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 && dc.IsPlotGeneration())
bNewMethod = FALSE;
OPENOBJ_BEGIN(dimblk, AcDb::kForRead, AcDbBlockTableRecord, pBlock);
if (pBlock)
{
dc.DrawBlock(*pBlock, ptEnd, AcGeScale3d(dimscale*dimasz, dimscale*dimasz, dimscale*dimasz),
segDim.IDirection(0), bNewMethod);
OPENOBJ_END();
}
}
}
else
{
//直径标注
double nAng=ads_angle(m_ptOnArc, m_ptCenter);
XPoint ptOnArc0, ptArrow0, ptArrow;
ads_polar(m_ptCenter, nAng, GetRadius(), ptOnArc0);
ads_polar(ptOnArc0, nAng+PI, nArrowLen*nPScale, ptArrow0);
ads_polar(m_ptOnArc, nAng, nArrowLen*nPScale, ptArrow);
pline.addVertexAt(0, ptOnArc0);
//pline.addVertexAt(1, ptArrow0);
//pline.addVertexAt(2, ptArrow);
pline.addVertexAt(1, m_ptOnArc);
//pline.setWidthsAt(0, 0.0, nArrowWidth*nPScale);
//pline.setWidthsAt(2, nArrowWidth*nPScale, 0.0);
if(m_nDimLen<0) { //外标注
XPoint ptStart=GetDimStartPoint();
pline.addVertexAt(2, ptStart);
}
XCurveSegment segDim(ptOnArc0, m_ptOnArc, 0, LS_FINITE);
//支持箭头的更改
if (!dimblk) // 尺寸箭头
{
// sg modify 120412,解决“实心闭合”样式,不支持设置“箭头大小”的问题
double dXSize = 1.0*dimscale*dimasz,
dYSize = 0.33*dimscale*dimasz;
int nDealOldDimArrowSize = DocGetDealOldDimArrowSize();
if (nDealOldDimArrowSize==0 && fabs(dimasz-1.0)<1.0E-3) // 旧版本的“实心闭合”样式
{
dXSize *= 2;
dYSize *= 2;
}
XPointDir2d pt1, pt2;
segDim.Polar(dXSize, pt1);
segDim.Polar(dXSize, pt2, FALSE);
AcDbPolyline plArrow1;
plArrow1.setPropertiesFrom(this);
plArrow1.addVertexAt(0, pt1);
plArrow1.setWidthsAt(0, dYSize, 0.0);
plArrow1.addVertexAt(1, segDim.StartPoint());
plArrow1.setWidthsAt(1, 0.0, 0.0);
dc.Polyline(plArrow1);
AcDbPolyline plArrow2;
plArrow2.setPropertiesFrom(this);
plArrow2.addVertexAt(0, pt2);
plArrow2.setWidthsAt(0, dYSize, 0.0);
plArrow2.addVertexAt(1, segDim.EndPoint());
plArrow2.setWidthsAt(1, 0.0, 0.0);
dc.Polyline(plArrow2);
}
else
{
// 打印时,不能使用新方法
BOOL bNewMethod=(g_nAcadVer>15.0001 && g_bMakeBlock);
// sg add 091105,强制打印时,不使用新方法
if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 && dc.IsPlotGeneration())
bNewMethod = FALSE;
OPENOBJ_BEGIN(dimblk, AcDb::kForRead, AcDbBlockTableRecord, pBlock);
if (pBlock)
{
dc.DrawBlock(*pBlock, segDim.EndPoint(), AcGeScale3d(dimscale*dimasz, dimscale*dimasz, dimscale*dimasz),
segDim.IDirection(1)+PI, bNewMethod);
dc.DrawBlock(*pBlock, segDim.StartPoint(), AcGeScale3d(dimscale*dimasz, dimscale*dimasz, dimscale*dimasz),
segDim.IDirection(0), bNewMethod);
}
OPENOBJ_END();
}
}
pline.setPropertiesFrom(this);
if(dimclrd && dimclrd!=256)
pline.setColorIndex(dimclrd);
if(_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) {
XAcGiViewDraw &dcView=(XAcGiViewDraw &)dc;
if(dcView.m_pWd)
pline.worldDraw(dcView.m_pWd);
else
pline.viewportDraw(dcView.m_pVd);
} else if(_tcscmp(dc.Desc(), XExplodeStream::Descriptor())==0) {
((XExplodeStream &)dc).Append((AcDbPolyline *)pline.clone());
} else {
if(dimclrd) dc.SetColor(dimclrd);
XPoly2D poly;
PolyConvert(pline, poly);
dc << poly;
}
// 文字
TDbText dimText;
dimText.setPropertiesFrom(this);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
dimText.SetHeight(dimtxt);
dimText.SetStyleId(dimtxsty);
if(dimclrt) dimText.setColorIndex(dimclrt);
BOOL bIsDefPos=TRUE;
XPoint ptText=GetTextPos(&bIsDefPos);
double nTextRot=NormalViewAngle(ads_angle(ptStart, ptEnd));
BOOL bIsDefText=TRUE;
XString sText0=GetText(&bIsDefText);
XString sText;
if(bIsDefText) {
if(sDimPrefix[0]) {
sText << sDimPrefix << &sText0[1] << sDimSuffix;
} else {
sText << sDimPrefix << sText0 << sDimSuffix;
}
} else {
sText << sText0;
}
dimText.SetRotation(Wcs2Layout(nTextRot));
dimText.SetLocation(ptText);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
dimText.SetText(sText);
{
TPushProperty vProp(&dimText, dc);
if(dc.IsFullExplode())
dimText.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(dimText);
}
XCurveSegment seg(ptStart, ptEnd, 0.0, LS_INFINITE);
if(bCheckDim && !bIsDefText) {
XString sCheckText(256);
XString sDefText=GetDefaultText();
sCheckText << _T("(");
if(sDimPrefix[0]) {
sCheckText << sDimPrefix << &sDefText[1];
} else {
sCheckText << sDefText;
}
sCheckText << sDimSuffix << _T(")");
XPoint ptCheckText;
if(bIsDefPos) {
XPoint ptOnSeg;
if(seg.ProjectToMe(ptText, ptOnSeg)==RTNORM) {
ptOnSeg.Mirror(ptText, ptCheckText);
}
} else {
int nSideText=seg.OnWhichSide(ptText);
if(nSideText==OFFSET_RIGHT)
ads_polar(ptText, seg.XLine::Direction()-PI/2, nPScale*(dimgap+dimtxt), ptCheckText);
else
ads_polar(ptText, seg.XLine::Direction()+PI/2, nPScale*(dimgap+dimtxt), ptCheckText);
}
dimText.setColorIndex(1);
dimText.SetLocation(ptCheckText);
dimText.SetText(sCheckText);
TPushProperty vProp(&dimText, dc);
if(dc.IsFullExplode())
dimText.ExplodeOrDraw2d(dc);
else
dc.DrawEntity(dimText);
}
dc.SetColor(nOldColor);
return Acad::eOk;
}
int TDbRadiusDim::ConvertText(TConvertTextPtr ptr, void *pData)
{
XString sText;
int nRet=ptr(m_sText, sText, pData);
if(nRet==RTNORM) {
assertWriteEnabled();
m_sText=sText;
}
return nRet;
}
void TDbRadiusDim::GetDimText(TDbText &dimText) const
{
BOOL bIsDefText=TRUE;
XString sText=GetText(&bIsDefText);
TTextPosition pos;
AcDbObjectId dimtxsty;
double dimtxt=3.0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
if(pDimStyle) {
dimtxsty=pDimStyle->dimtxsty();
dimtxt=pDimStyle->dimtxt();
}
OPENOBJ_END();
dimText.setPropertiesFrom(this);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
dimText.SetHeight(dimtxt);
dimText.SetStyleId(dimtxsty);
XPoint ptText=GetTextPos();
double nTextRot=NormalViewAngle(ads_angle(GetDimStartPoint(), GetDimEndPoint()));
dimText.SetRotation(Wcs2Layout(nTextRot));
dimText.SetLocation(ptText);
dimText.SetAlignment(XExplodeDraw::kMiddleCenter);
if(bIsDefText)
dimText.SetText(_T(""));
else
dimText.SetText(sText);
}
// 返回发现的位置,同时posStart往前移动(以便继续找下一个使用),
TTextPosition
TDbRadiusDim::FindSubText(const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange) const
{
assertReadEnabled();
TDbText dimText;
GetDimText(dimText);
TTextPosition pos=dimText.FindSubText(sSubText, posStart, pRange);
return pos;
}
// 返回下一次查找的开始位置
TTextPosition
TDbRadiusDim::ReplaceSubText(const TTextPosition &posRep, const TCHAR *sRepText, TTextRange *pRange)
{
assertWriteEnabled();
TDbText dimText;
GetDimText(dimText);
TTextPosition pos=dimText.ReplaceSubText(posRep, sRepText, pRange);
SetText(dimText.GetText());
return pos;
}
const TCHAR *TDbRadiusDim::GetDefaultLayer() const
{
return LAY_DIM;
}
TEntityBase::DrawType
TDbRadiusDim::GetDrawType() const
{
return TEntityBase::k2DOnly;
}
/* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */
void TDbRadiusDim::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), IsDiameter()? _T("直径标注") : _T("半径标注")));
lstInfo.Append(new TObjInfoUnit(_T("标注样式"), GetSymbolName(m_idDimStyle)));
XString sDist;
ftoa(fabs(m_nDimLen), 1, sDist);
sDist << _T("P");
lstInfo.Append(new TObjInfoUnit(_T("尺寸线长度"), sDist));
lstInfo.Append(new TObjInfoUnit(_T("测量值"), GetDefaultText()));
lstInfo.Append(new TObjInfoUnit(_T("替代文字"), m_sText));
}
// Helper Method
BOOL TDbRadiusDim::ConvertFrom(const AcDbRadialDimension *pDim)
{
assertWriteEnabled();
AcDbObjectId idStyle=pDim->dimensionStyle();
XString sText;
sText=pDim->dimensionText();
if(pDim->normal() != AcGeVector3d(0,0,1) || !idStyle)
return FALSE;
setPropertiesFrom(pDim);
m_idDimStyle = idStyle;
if(!pDim->isUsingDefaultTextPosition()) {
m_ptText=pDim->textPosition();
m_nDimFlag |= DF_POSITION;
} else m_nDimFlag &= ~DF_POSITION;
if(!!sText) {
m_sText = sText;
m_nDimFlag |= DF_TEXT;
} else {
m_nDimFlag &=~DF_TEXT;
}
m_ptCenter=pDim->center();
m_ptOnArc=pDim->chordPoint();
m_nDimLen=m_ptCenter.Distance2d(m_ptOnArc)/GetPScale();
return TRUE;
}
// Properties
// Modified by ZJQ on 2003/01/23
// 支持直径标注
XPoint
TDbRadiusDim::GetDimStartPoint() const
{
XPoint ptStart;
//if(IsDiameter())
// ads_polar(m_ptOnArc, ads_angle(m_ptOnArc, m_ptCenter), GetRadius()*2, ptStart);
//else
ads_polar(m_ptOnArc, ads_angle(m_ptOnArc, m_ptCenter), m_nDimLen*GetPScale(), ptStart);
return ptStart;
}
XPoint
TDbRadiusDim::GetDimEndPoint() const
{
return m_ptOnArc;
}
XPoint
TDbRadiusDim::GetDimCenter() const
{
return m_ptCenter;
}
double
TDbRadiusDim::GetDimLen(BOOL bAsPaperUnit) const
{
double nVal=m_nDimLen;
if(!bAsPaperUnit) nVal *= GetPScale();
return nVal;
}
AcDbObjectId
TDbRadiusDim::GetStyleId() const
{
return m_idDimStyle;
}
XPoint
TDbRadiusDim::GetTextPos(BOOL *bIsDefault) const
{
XPoint ptText;
if(m_nDimFlag&DF_POSITION) {
ptText=m_ptText;
if(bIsDefault) *bIsDefault=FALSE;
} else {
ptText=GetDefaultTextPos();
if(bIsDefault) *bIsDefault=TRUE;
}
return ptText;
}
// Modify on 2003/01/23
// 支持直径标注
XPoint
TDbRadiusDim::GetDefaultTextPos() const
{
AcDbObjectId dimtxsty;
double dimtxt=3.0;
double dimgap=0.0;
double dimlfac=1.0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
ASSERT(pDimStyle);
dimtxt=pDimStyle->dimtxt();
dimgap=pDimStyle->dimgap();
dimtxsty=pDimStyle->dimtxsty();
dimlfac=pDimStyle->dimlfac();
OPENOBJ_END();
double nScale=GetPScale();
double nTextHeight=dimtxt*nScale;
TDbText text;
text.setPropertiesFrom(this);
text.SetText(GetText());
text.SetStyleId(dimtxsty);
text.SetHeight(nTextHeight, FALSE);
XPoint ptExt=text.GetExtents();
XPoint ptText, ptTemp;
if(!IsDiameter() || m_nDimLen<0) {
XPoint ptStart=GetDimStartPoint();
double nRot=ads_angle(ptStart, m_ptOnArc);
ads_polar(ptStart, nRot, ptExt.x/2 + dimgap*nScale, ptTemp);
ads_polar(ptTemp, NormalViewAngle(nRot)+PI/2, (dimgap+dimtxt/2)*nScale, ptText);
} else {
double nRot=ads_angle(m_ptCenter, m_ptOnArc);
//ads_polar(m_ptCenter, nRot+PI, ptExt.x/2, ptTemp);
ads_polar(m_ptCenter, NormalViewAngle(nRot)+PI/2, (dimgap+dimtxt/2)*nScale, ptText);
}
return ptText;
}
XString
TDbRadiusDim::GetText(BOOL *bIsDefault) const
{
XString sText;
if(m_nDimFlag&DF_TEXT) {
sText=m_sText;
if(bIsDefault) *bIsDefault=FALSE;
} else {
sText=GetDefaultText();
if(bIsDefault) *bIsDefault=TRUE;
}
return sText;
}
// Modify on 2002/02/05 by ZJQ
// 支持单位换算dimlfac
// Modify on 2003/01/23 by ZJQ
// 支持直径标注
XString
TDbRadiusDim::GetDefaultText() const
{
int dimdec=0;
double dimlfac=1.0;
double dimrnd =0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
ASSERT(pDimStyle);
dimdec=pDimStyle->dimdec();
dimlfac=pDimStyle->dimlfac();
dimrnd = pDimStyle->dimrnd();
OPENOBJ_END();
XString sText, sTemp,sTemrnd;
double dTemLen(0),dTemrnd(0);
XString sDimrnd;
if(IsDiameter())
{
ftoa(m_ptCenter.Distance2d(m_ptOnArc)*dimlfac*2, dimdec, sTemp);
ftoa(dimrnd,dimdec,sDimrnd);
dTemLen = _tstof(sTemp);
dTemrnd = _tstof(sDimrnd);
if (!Equal(dTemrnd,0,0.00000001))
{
double dT = dTemLen/dTemrnd;
XString sT;
ftoa(dT,0,sT);
dT = _tstof(sT);
int nt = (int)dT;
double dDimNum = dTemrnd*nt;
ftoa(dDimNum, dimdec, sTemp);
}
//////zzg090515//////////////
sText << _T("%%c") << sTemp;
}
else
{
ftoa(m_ptCenter.Distance2d(m_ptOnArc)*dimlfac, dimdec, sTemp);
ftoa(dimrnd,dimdec,sDimrnd);
dTemLen = _tstof(sTemp);
dTemrnd = _tstof(sDimrnd);
if (!Equal(dTemrnd,0,0.00000001))
{
double dT = dTemLen/dTemrnd;
XString sT;
ftoa(dT,0,sT);
dT = _tstof(sT);
int nt = (int)dT;
double dDimNum = dTemrnd*nt;
ftoa(dDimNum, dimdec, sTemp);
}
//////zzg090515//////////////
sText << _T("R") << sTemp;
}
//////// 处理 标注样式中舍入的问题zzg 090515
return sText;
}
void
TDbRadiusDim::SetDimEndPoint(XPoint ptEnd)
{
assertWriteEnabled();
m_ptOnArc=ptEnd;
}
void
TDbRadiusDim::SetDimCenter(XPoint ptCen)
{
assertWriteEnabled();
m_ptCenter=ptCen;
}
void TDbRadiusDim::SetDimLen(double nLen, BOOL bAsPaperUnit)
{
assertWriteEnabled();
if(bAsPaperUnit) m_nDimLen=nLen;
else m_nDimLen=nLen/GetPScale();
}
void TDbRadiusDim::SetStyleId(AcDbObjectId id)
{
assertWriteEnabled();
m_idDimStyle=id;
}
void TDbRadiusDim::SetTextPos(XPoint ptPos)
{
assertWriteEnabled();
XPoint ptDefault=GetDefaultTextPos();
if(ptPos.Distance2d(ptDefault)<_DIST_SNAP) {
m_nDimFlag &= ~DF_POSITION;
} else {
m_ptText=ptPos;
m_nDimFlag |= DF_POSITION;
}
}
void TDbRadiusDim::SetText(const TCHAR *pszText)
{
assertWriteEnabled();
if(!pszText) m_sText=_T("");
else m_sText=pszText;
if(!m_sText) {
m_nDimFlag &= ~DF_TEXT;
} else {
m_nDimFlag |= DF_TEXT;
}
}
void TDbRadiusDim::SetDiameter(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nDimFlag |= DF_DIAMETER;
else
m_nDimFlag &= ~DF_DIAMETER;
}
BOOL TDbRadiusDim::IsDiameter() const
{
return ((m_nDimFlag&DF_DIAMETER)!=0);
}
// sg add 101116,支持统一标高
bool TDbRadiusDim::UnifyElevation(double dElevation)
{
assertWriteEnabled();
m_ptCenter.z = dElevation;
m_ptOnArc.z = dElevation;
XPoint ptText = GetTextPos();
ptText.z = dElevation;
SetTextPos(ptText);
return true;
}
// jsx add 160922,支持导低版本
Acad::ErrorStatus TDbRadiusDim::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet, BOOL *bErase)
{
Acad::ErrorStatus es=Acad::eOk;
if (g_nSaveTArchVer > 3 && g_nSaveTArchVer < 11)
{
AcDbObjectId dimblk;
double dimasz = 2.0;
OPENOBJ_BEGIN(m_idDimStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
if(pDimStyle)
{
dimasz=pDimStyle->dimasz();
dimblk=pDimStyle->dimblk();
}
OPENOBJ_END();
//只要检测到半径\直径标注的箭头形式、箭头大小、后缀或文字翻转方向中任一个参数与程序的默认值不同,则在导出成T5-T20格式时,程序直接将其分解为CAD对象
if (fabs(dimasz - 2.0) > 1E-6 || dimblk || GetLayoutRotation() != 0)
{
XExplodeStream dc(entSet);
if (!OnExplodeOrDraw(dc))
return es;
dc.SetPropertiesFrom(this);
if (nDrawMode == DRAW_2D)
es = ExplodeOrDraw2d(dc);
else
es = ExplodeOrDraw3d(dc);
if (bErase)
*bErase = TRUE;
}
}
return es;
}
void InitDbDimension(BOOL bTrue)
{
if(bTrue) {
TDbDimension::rxInit();
TDbDimension2::rxInit();
TDbRadiusDim::rxInit();
acrxBuildClassHierarchy();
TDbDimension::InitMatchProtocol(TRUE);
TDbDimension2::InitMatchProtocol(TRUE);
TDbRadiusDim::InitMatchProtocol(TRUE);
} else {
TDbDimension::InitMatchProtocol(FALSE);
TDbDimension2::InitMatchProtocol(FALSE);
TDbRadiusDim::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbRadiusDim::desc());
deleteAcRxClass(TDbDimension2::desc());
deleteAcRxClass(TDbDimension::desc());
}
}
BOOL ConvertDim0(const Entity &dimAcDb, Entity &dimT)
{
BOOL bRet=FALSE;
OPENOBJ_BEGIN(dimAcDb.name, AcDb::kForWrite, AcDbDimension, pDimOld);
if(!pDimOld)
return FALSE;
AcDbObjectId idMaster;
if(pDimOld->isKindOf(AcDbRadialDimension::desc())) {
TDbRadiusDim *pMaster=new TDbRadiusDim;
if(!pMaster->ConvertFrom((AcDbRadialDimension *)pDimOld) || !pMaster->IsValid())
delete pMaster;
else {
pDimOld->erase();
idMaster=AddToModelSpace(pMaster, Adesk::kTrue);
bRet=TRUE;
}
} else {
TDbDimension *pMaster=new TDbDimension;
if(!pMaster->ConvertFrom(pDimOld) || !pMaster->IsValid()) {
delete pMaster;
} else {
pDimOld->erase();
idMaster=AddToModelSpace(pMaster, Adesk::kTrue);
bRet=TRUE;
}
}
if(bRet==TRUE)
VERIFY(acdbGetAdsName(dimT.name, idMaster)==Acad::eOk);
OPENOBJ_END();
return bRet;
}
BOOL ConvertDim(const Entity &dimAcDb, Entity &dimT)
{
BOOL bRet=FALSE;
OPENOBJ_BEGIN(dimAcDb.name, AcDb::kForWrite, AcDbEntity, pDimOld);
if(!pDimOld)
return FALSE;
AcDbObjectId idMaster;
if(pDimOld->isKindOf(AcDbDimension::desc()))
{
if(pDimOld->isKindOf(AcDbRadialDimension::desc())) {
TDbRadiusDim *pMaster=new TDbRadiusDim;
if(!pMaster->ConvertFrom((AcDbRadialDimension *)pDimOld) || !pMaster->IsValid())
delete pMaster;
else {
pDimOld->erase();
idMaster=AddToModelSpace(pMaster, Adesk::kTrue);
bRet=TRUE;
}
} else {
TDbDimension2 *pMaster=new TDbDimension2;
if(!pMaster->ConvertFrom((AcDbDimension*)pDimOld) || !pMaster->IsValid()) {
delete pMaster;
} else {
pDimOld->erase();
idMaster=AddToModelSpace(pMaster, Adesk::kTrue);
bRet=TRUE;
}
}
}
else if(pDimOld->isKindOf(TDbDimension::desc()))
{
TDbDimension2 *pMaster=new TDbDimension2;
if(!pMaster->ConvertFrom((TDbDimension*)pDimOld) || !pMaster->IsValid()) {
delete pMaster;
} else {
pDimOld->erase();
idMaster=AddToModelSpace(pMaster, Adesk::kTrue);
bRet=TRUE;
}
}
if(bRet==TRUE)
VERIFY(acdbGetAdsName(dimT.name, idMaster)==Acad::eOk);
OPENOBJ_END();
return bRet;
}
void ConvertDim6()
{
PickSet ss(SS_FREE);
ss.Get(_T("X"),NULL,NULL,RBList(RTDXF0,_T("ATS_DIMENSION"),NULL));
long count=ss.Length();
for(long i=0;i<count;i++)
{
AcDbObjectId nId;
Entity ent=ss[i];
if(acdbGetObjectId(nId, (TLong_ptr *)ent)==Acad::eOk)
{
TDbDimension *pDim=NULL;
acdbOpenObject(pDim, nId, AcDb::kForWrite);
if(pDim!=NULL)
{
TDbDimension2 *pNewDim=new TDbDimension2;
pNewDim->ConvertFrom(pDim);
if(pDim->handOverTo(pNewDim)==Acad::eObjectToBeDeleted)
{
delete pDim;
pNewDim->close();
}
else
{
delete pNewDim;
pDim->close();
}
}
}
}
}