4578 lines
112 KiB
C++
4578 lines
112 KiB
C++
#include "stdafx.h"
|
|
#include "windef.h"
|
|
#include "dbmatch.h"
|
|
#include <vector>
|
|
#include "acgiutil.h"
|
|
#include "dbcfilrs.h"
|
|
#include "actrans.h"
|
|
#include "RBGroups.h"
|
|
#include "FindParser.h"
|
|
#include "AcEdInputPointMonitorEx.h"
|
|
#include "xtext.h"
|
|
#include "AecDbText.h"
|
|
#include "SubText.h"
|
|
#include "DListStack.h"
|
|
#include "adsgepoint3d.h"
|
|
#include "AcDbObjectPtr.h"
|
|
#include "ADSGePointDir2d.h"
|
|
#include "AecDbDimension.h"
|
|
#include "AecDbDimension_old.h"
|
|
#include "AecDbRadiusDim.h"
|
|
#include "PickEntSet.h"
|
|
#include "GeCurveInline.h"
|
|
#include "AecDbSymbArrow.h"
|
|
#include "AecDbSymbElevation.h"
|
|
#include "AecDbSymbSection.h"
|
|
#include "AecDbSymbNorthThumb.h"
|
|
#include "AecDbSymbDrawingIndex.h"
|
|
#include "AecDbDrawingName.h"
|
|
|
|
|
|
//extern GEOAPI int XGetCorner(const XPoint &ptCorn1, const TCHAR *pszMsg, XPoint &ptCorn2);
|
|
|
|
// add by xly On 110107 引入设置实体的图层并将实体添加到图纸中
|
|
//
|
|
//wlw add 130529 作为两点标注时门窗的高亮使用
|
|
static EntitySet entShow;
|
|
static CString entFilter = _T("");
|
|
|
|
extern AcDbObjectId InitDimStyle(TDimStyle ds);
|
|
|
|
namespace
|
|
{
|
|
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())) {
|
|
AecXDbRadiusDim *pMaster = new AecXDbRadiusDim;
|
|
if (!pMaster->ConvertFrom((AcDbRadialDimension *)pDimOld))
|
|
delete pMaster;
|
|
else {
|
|
pDimOld->erase();
|
|
idMaster = GlobalFunc::AddToModelSpace(pMaster, Adesk::kTrue);
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
else {
|
|
AecDbDimension *pMaster = new AecDbDimension;
|
|
if (!pMaster->ConvertFrom((AcDbDimension *)pDimOld) || !pMaster->IsValid()) {
|
|
delete pMaster;
|
|
}
|
|
else {
|
|
pDimOld->erase();
|
|
idMaster = GlobalFunc::AddToModelSpace(pMaster, Adesk::kTrue);
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
}
|
|
else if (pDimOld->isKindOf(AecXDbDimension_Old::desc()))
|
|
{
|
|
AecDbDimension *pMaster = new AecDbDimension;
|
|
if (!pMaster->ConvertFrom((AecXDbDimension_Old *)pDimOld) || !pMaster->IsValid()) {
|
|
delete pMaster;
|
|
}
|
|
else {
|
|
pDimOld->erase();
|
|
idMaster = GlobalFunc::AddToModelSpace(pMaster, Adesk::kTrue);
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
if (bRet==TRUE)
|
|
VERIFY(acdbGetAdsName(dimT.name, idMaster)==Acad::eOk);
|
|
OPENOBJ_END();
|
|
return bRet;
|
|
}
|
|
|
|
BOOL GetEntFromPt(const AcGePoint3d& pt, LPCTSTR sDxfName, EntitySet& ent)
|
|
{
|
|
RBList tgMask(RTDXF0, sDxfName, NULL);
|
|
PickEntSet ssEnts(SS_FREE);
|
|
ADSGePoint3d pt1, pt2;
|
|
pt1[X] = pt.x;
|
|
pt1[Y] = pt.y;
|
|
pt1[Z] = pt.z;
|
|
pt1 = GlobalFunc::Wcs2Ucs(pt1);
|
|
pt2 = pt1;
|
|
//得到拾取框大小
|
|
double dAperture = 50.0;//GetPickBoxWcs();
|
|
pt1[X] -= dAperture;
|
|
pt1[Y] += dAperture;
|
|
pt2[X] += dAperture;
|
|
pt2[Y] -= dAperture;
|
|
AcDbObjectId id = AcDbObjectId::kNull;
|
|
if (ssEnts.Get(_T("C"), pt1, pt2, tgMask) == RTNORM)
|
|
{
|
|
ent = ssEnts[0L];
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
}
|
|
//TUTIL_IMPEXP void SetHandCursorSelectType(LPCTSTR pszType);
|
|
//TUTIL_IMPEXP void SetHandCursorGlobalFunc::SelectEntity(EntitySet & ent);
|
|
//TUTIL_IMPEXP BOOL MouseMoveMonitorByHandCursor(MSG* msg) ;
|
|
//TUTIL_IMPEXP void StartChangeCursor();
|
|
//TUTIL_IMPEXP void EndChangeCursor();
|
|
|
|
int GetFullOsMode(int nFlagsAdd)
|
|
{
|
|
int nOsMode=0;
|
|
xg_getvar(_T("OSMODE"), &nOsMode);
|
|
nOsMode &= ~0x4000;
|
|
nOsMode |= nFlagsAdd;
|
|
return nOsMode;
|
|
}
|
|
|
|
//数据结构,辅助计算角度标注起点和终点
|
|
typedef struct CptData
|
|
{
|
|
AcGePoint2d ptCenter;
|
|
|
|
AcGePoint2d ptTem;
|
|
}PTDATA,*pPTDATA;
|
|
|
|
|
|
//双层JIG通用
|
|
class TMulDimEntity : public AcDbEntity
|
|
{
|
|
public:
|
|
TMulDimEntity() {}
|
|
virtual ~TMulDimEntity() {}
|
|
|
|
AecDbDimension *m_pDrawEnt; //临时实体,
|
|
AecDbDimension *m_pDrawEntAll; //临时实体,
|
|
int m_iFlag;
|
|
virtual Adesk::Boolean subWorldDraw(AcGiWorldDraw* mode)
|
|
{
|
|
assertReadEnabled();
|
|
AcGiViewDraw dc(mode, NULL);
|
|
|
|
m_pDrawEnt->Draw2d(dc);
|
|
if (m_iFlag == 2 && m_pDrawEntAll != NULL)
|
|
{
|
|
m_pDrawEntAll->Draw2d(dc);
|
|
}
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
};
|
|
|
|
//双层JIG通用
|
|
class TMulDimEntity1 : public AcDbEntity
|
|
{
|
|
public:
|
|
TMulDimEntity1() {}
|
|
virtual ~TMulDimEntity1() {}
|
|
|
|
AecDbDimension *m_pDrawEnt; //临时实体,
|
|
AecDbDimension *m_pDrawEnt2; //临时实体,
|
|
virtual Adesk::Boolean subWorldDraw(AcGiWorldDraw* mode)
|
|
{
|
|
assertReadEnabled();
|
|
AcGiViewDraw dc(mode, NULL);
|
|
|
|
m_pDrawEnt->Draw2d(dc);
|
|
m_pDrawEnt2->Draw2d(dc);
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
};
|
|
|
|
//双层标注动态效果类 add by wlw on 2012/12/12
|
|
class TDimDoubleJig:public AcEdJig
|
|
{
|
|
public:
|
|
TDimDoubleJig(AecDbDimension * pdim, AecDbDimension * pdim2)
|
|
{
|
|
m_pDim.m_pDrawEnt = pdim;
|
|
m_pDim.m_pDrawEnt2 = pdim2;
|
|
}
|
|
~TDimDoubleJig() {}
|
|
AcEdJig::DragStatus doIt();
|
|
virtual AcEdJig::DragStatus sampler();
|
|
virtual Adesk::Boolean update();
|
|
virtual AcDbEntity* entity() const;
|
|
|
|
public:
|
|
AcGePoint3d m_ptDim;
|
|
TMulDimEntity1 m_pDim;//标注
|
|
};
|
|
|
|
AcEdJig::DragStatus TDimDoubleJig::doIt()
|
|
{
|
|
return drag();
|
|
}
|
|
AcEdJig::DragStatus TDimDoubleJig::sampler()
|
|
{
|
|
setUserInputControls((UserInputControls)(AcEdJig::kAccept3dCoordinates|
|
|
AcEdJig::kNullResponseAccepted));
|
|
|
|
ADSGePoint3d ptCursor;
|
|
DragStatus stat = acquirePoint(ptCursor);
|
|
if(stat == AcEdJig::kNormal)
|
|
{
|
|
if (ptCursor.Distance2d(m_ptDim) > g_Option::instance()._DIST_SNAP)
|
|
m_ptDim = ptCursor;
|
|
else
|
|
stat = AcEdJig::kNoChange;
|
|
}
|
|
return stat;
|
|
}
|
|
|
|
Adesk::Boolean TDimDoubleJig::update()
|
|
{
|
|
XPoint ptOnSeg;
|
|
GeCurveSegment seg;
|
|
seg = m_pDim.m_pDrawEnt->GetDimCurve();
|
|
if(seg.ProjectToMe(m_ptDim, ptOnSeg) == RTNORM)
|
|
{
|
|
double nDistMove = ptOnSeg.Distance2d(m_ptDim);
|
|
int nSideLoc = seg.OnWhichSide(m_pDim.m_pDrawEnt->GetLocation());
|
|
int nSide = seg.OnWhichSide(m_ptDim);
|
|
double nDist2Dim = m_pDim.m_pDrawEnt->GetDist2DimLine(FALSE);
|
|
double nFactor = nDist2Dim/fabs(nDist2Dim);
|
|
if(fabs(nDist2Dim) > 1.0E-6)
|
|
{
|
|
if(nSide != nSideLoc)
|
|
{
|
|
nDistMove *= nFactor;
|
|
}
|
|
else
|
|
{
|
|
nDistMove *= -nFactor;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(nSideLoc == OFFSET_LEFT)
|
|
nDistMove *= -1;
|
|
}
|
|
nDist2Dim += nDistMove;
|
|
m_pDim.m_pDrawEnt->SetDist2DimLine(nDist2Dim, FALSE);
|
|
if(nDist2Dim >= 0)
|
|
nDist2Dim -= 1000;
|
|
else
|
|
nDist2Dim += 1000;
|
|
m_pDim.m_pDrawEnt2->SetDist2DimLine(nDist2Dim, FALSE);
|
|
|
|
}
|
|
return Adesk::kTrue;
|
|
}
|
|
AcDbEntity* TDimDoubleJig::entity() const
|
|
{
|
|
return (AcDbEntity*)&m_pDim;
|
|
}
|
|
|
|
//角度标注动态效果类 add by lxb on 2011/11/24
|
|
class TDimAngleJig:public AcEdJig
|
|
{
|
|
public:
|
|
TDimAngleJig(AecDbDimension *pDim,
|
|
AcGeLine2d &line1, AcGeLine2d &line2, XPoint &pt,
|
|
TCHAR *pszPrompt, TCHAR *pszKeyword=NULL);
|
|
|
|
~TDimAngleJig();
|
|
AcEdJig::DragStatus doIt();
|
|
|
|
protected:
|
|
virtual AcEdJig::DragStatus sampler();
|
|
virtual Adesk::Boolean update();
|
|
virtual AcDbEntity* entity() const;
|
|
|
|
static int QsortFun(const void *p1,const void *p2);//交点排序函数
|
|
|
|
private:
|
|
AecDbDimension *m_pDim;//标注
|
|
|
|
TCHAR *m_pszPrompt; //提示语
|
|
TCHAR *m_pszKeyword; //关键字
|
|
AcGePoint3d m_ptLast; //记录鼠标上次位置
|
|
AcGePoint3d m_ptCur; //记录鼠标当前位置
|
|
AcGeLine2d m_line1; //成角直线1
|
|
AcGeLine2d m_line2; //成角直线2
|
|
XPoint m_ptCen; //成角顶点
|
|
|
|
};
|
|
|
|
TDimAngleJig::TDimAngleJig(AecDbDimension *pDim,
|
|
AcGeLine2d &line1, AcGeLine2d &line2, XPoint &pt ,
|
|
TCHAR *pszPrompt, TCHAR *pszKeyword):
|
|
m_pDim(pDim),
|
|
m_line1(line1),m_line2(line2),m_ptCen(pt),
|
|
m_pszPrompt(pszPrompt),m_pszKeyword(pszKeyword)
|
|
{
|
|
}
|
|
|
|
TDimAngleJig::~TDimAngleJig()
|
|
{
|
|
}
|
|
|
|
AcEdJig::DragStatus TDimAngleJig::doIt()
|
|
{
|
|
setDispPrompt(m_pszPrompt);
|
|
AcEdJig::DragStatus status =AcEdJig::kNull;
|
|
try
|
|
{
|
|
status = drag();
|
|
}
|
|
catch(...)
|
|
{
|
|
status = AcEdJig::kCancel;
|
|
}
|
|
return status;
|
|
}
|
|
|
|
AcEdJig::DragStatus TDimAngleJig::sampler()
|
|
{
|
|
setUserInputControls((UserInputControls)(AcEdJig::kAccept3dCoordinates|
|
|
AcEdJig::kNullResponseAccepted));
|
|
|
|
AcEdJig::DragStatus status =AcEdJig::kCancel;
|
|
|
|
status = acquirePoint(m_ptCur);
|
|
|
|
if (status == AcEdJig::kNormal)
|
|
{
|
|
if (m_ptCur.isEqualTo(m_ptLast))
|
|
{
|
|
return AcEdJig::kNoChange;
|
|
}
|
|
}
|
|
m_ptLast = m_ptCur;
|
|
|
|
return status;
|
|
}
|
|
|
|
int TDimAngleJig::QsortFun(const void *p1,const void *p2)
|
|
{
|
|
double dangle1 = ads_angle(asDblArray(((pPTDATA)p1)->ptCenter),asDblArray(((pPTDATA)p1)->ptTem));
|
|
double dangle2 = ads_angle(asDblArray(((pPTDATA)p2)->ptCenter),asDblArray(((pPTDATA)p2)->ptTem)) ;
|
|
return( dangle1 > dangle2);
|
|
}
|
|
|
|
Adesk::Boolean TDimAngleJig::update()
|
|
{
|
|
double dRadiu = m_ptCen.Distance(m_ptCur);
|
|
if (dRadiu < 5.0)
|
|
{
|
|
return Adesk::kFalse;
|
|
}
|
|
|
|
//构造圆
|
|
AcGeCircArc2d circle(m_ptCen,dRadiu);
|
|
|
|
//求圆与直线交点
|
|
int iCount = 0;
|
|
AcGePoint2d pt[4];
|
|
circle.intersectWith(m_line1,iCount,pt[0],pt[1]);
|
|
circle.intersectWith(m_line2,iCount,pt[2],pt[3]);
|
|
|
|
//点队列
|
|
CArray<PTDATA,PTDATA> arr;
|
|
for (int i=0;i<4;i++)
|
|
{
|
|
PTDATA temp;
|
|
temp.ptCenter = m_ptCen;
|
|
temp.ptTem = pt[i];
|
|
arr.Add(temp);
|
|
}
|
|
|
|
PTDATA temp;
|
|
temp.ptCenter = m_ptCen;
|
|
temp.ptTem = AcGePoint2d(m_ptCur.x,m_ptCur.y);
|
|
arr.Add(temp);
|
|
|
|
//队列排序(升序)
|
|
qsort(&arr[0],arr.GetSize(),sizeof(PTDATA&),QsortFun);
|
|
|
|
//取标注起点和终点
|
|
XPoint qt1(arr[0].ptTem),qt2(arr[1].ptTem);
|
|
|
|
int iPos = 1;
|
|
for (int j=0;j<arr.GetSize();j++)
|
|
{
|
|
if (arr[j].ptTem.isEqualTo(AcGePoint2d(m_ptCur.x,m_ptCur.y)))
|
|
{
|
|
iPos = j;
|
|
break;
|
|
}
|
|
}
|
|
if (iPos == arr.GetSize()-1)
|
|
{
|
|
qt1 = arr[iPos-1].ptTem;
|
|
qt2 = arr[0].ptTem;
|
|
}
|
|
else if (iPos == 0)
|
|
{
|
|
qt1 = arr[arr.GetSize()-1].ptTem;
|
|
qt2 = arr[1].ptTem;
|
|
}
|
|
else
|
|
{
|
|
qt1 = arr[iPos-1].ptTem;
|
|
qt2 = arr[iPos+1].ptTem;
|
|
}
|
|
|
|
//初始化
|
|
m_pDim->RemoveSegment(m_pDim->GetSegmentNum()-1);
|
|
|
|
//更新标注属性
|
|
XPoint ptLoc;
|
|
ads_polar(qt1, ads_angle(m_ptCen, qt1),
|
|
2.0*GlobalFunc::DocGetPScale(),
|
|
ptLoc);
|
|
m_pDim->SetLocation(ptLoc);
|
|
m_pDim->SetDimRadius(m_ptCen.Distance2d(qt1));
|
|
m_pDim->SetRotation(CT_std_angle(ads_angle(m_ptCen, qt1)+PI/2));
|
|
m_pDim->SetObjRadius(m_ptCen.Distance2d(qt1)+2.0*GlobalFunc::DocGetPScale());
|
|
|
|
XArc ar(m_ptCen, m_ptCen.Distance2d(qt1),
|
|
ads_angle(m_ptCen, qt1),
|
|
ads_angle(m_ptCen, qt2));
|
|
|
|
if(m_pDim->IsValidSegment(ar.GetLength()))
|
|
{
|
|
m_pDim->AppendSegment(ar.GetLength());
|
|
}
|
|
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
AcDbEntity * TDimAngleJig::entity() const
|
|
{
|
|
return(m_pDim);
|
|
}
|
|
|
|
// 拖曳显示点
|
|
class TDimensionEdJig : public AcEdJig
|
|
{
|
|
public:
|
|
TDimensionEdJig(AecDbDimension *pDim, const TCHAR *pszPrompt, const TCHAR *pszKeyword=NULL);
|
|
~TDimensionEdJig();
|
|
int doIt();
|
|
virtual DragStatus sampler();
|
|
virtual Adesk::Boolean update();
|
|
virtual AcDbEntity* entity() const;
|
|
void Swap();
|
|
|
|
int GetRetCode(int *kwordId=NULL) const;
|
|
int m_nRetCode; //返回码
|
|
const TCHAR *m_pszPrompt; //提示信息
|
|
const TCHAR *m_pszKeyword; //关键字
|
|
AecDbDimension *m_pDrawEnt; //临时实体,
|
|
AecDbDimension *m_pTemp; //临时实体, 用于m_nFlag==3
|
|
|
|
GeArc m_ObjarDim;// 被标注对象
|
|
BOOL m_bKeyword;//是否按下关键字,玄长标注用
|
|
|
|
XPoint m_ptDim;
|
|
int m_nFlag; //0--尺寸方向, 1--尺寸线位置, 2--第二个标注点, 3--其它标注点
|
|
|
|
//add by whl on 03/08/08
|
|
DListStack<XPoint> ptStack;//标注点栈
|
|
void Step();//当前点入栈
|
|
void Undo();//撤消
|
|
XPoint GetLastPoint();
|
|
bool CanUndo();//是否可撤消
|
|
//add by lgy 20120315 设置弧长标注标记
|
|
void SetIsArcDim();
|
|
|
|
BOOL m_bInView; //add by lgy 20120503 保存标注是否是在视口中绘制
|
|
int m_nPortNum; //视口编号
|
|
PickEntSet m_entSet;//add by lgy 20120507 保存所有视口对象
|
|
AcDbObjectId m_idDimNew;//新标注样式ID
|
|
AcDbObjectId m_idDimOld;//老标注样式ID
|
|
BOOL m_bSaveStyle; //保存是不是设置新样式
|
|
protected:
|
|
void FindAndRemoveSeg(XPoint pt);//由一标注点找出对应段并且正确去除之
|
|
|
|
private:
|
|
//add by lxb on 2011/11/22
|
|
AcEdInputPointMonitorEx m_cMonitor;//监视器
|
|
bool m_bIsArcDim; //add by lgy 20120315 弧长标注标记
|
|
};
|
|
|
|
|
|
//add by lgy 20120509 判断点在不在实体上
|
|
//pt:模型空间中的点
|
|
//返回值:如果pt在当前图纸中的莫个实体上,返回TRUE,否则返回FALSE
|
|
BOOL GetIsOnEntity(XPoint pt)
|
|
{
|
|
BOOL bOn = FALSE; //用来保存点是否在实体上
|
|
Acad::ErrorStatus es = Acad::eOk;
|
|
AcDbBlockTable *pTable = NULL;
|
|
es = acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pTable, AcDb::kForRead);
|
|
if (es != Acad::eOk)
|
|
{
|
|
return bOn;
|
|
}
|
|
|
|
AcDbBlockTableRecord *pBlockTableRecord = NULL;
|
|
es = pTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForRead);
|
|
if (es != Acad::eOk)
|
|
{
|
|
pTable->close();
|
|
return bOn;
|
|
}
|
|
|
|
AcDbBlockTableRecordIterator *pBlockIterator = NULL;
|
|
if (Acad::eOk == pBlockTableRecord->newIterator(pBlockIterator))
|
|
{
|
|
AcDbEntity *pEnt = NULL;
|
|
for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step())
|
|
{
|
|
if (Acad::eOk == pBlockIterator->getEntity(pEnt, AcDb::kForRead))
|
|
{
|
|
PickEntSet entSet(SS_FREE);
|
|
entSet += pEnt->id();
|
|
if (entSet.Length() == 0)
|
|
{
|
|
continue;
|
|
}
|
|
Entity ent = entSet[0L];
|
|
XPoly2D poly(ent);
|
|
|
|
for (int i = 0; i < poly.TotalSegments(); i++)
|
|
{
|
|
GeCurveSegment cvSeg;
|
|
poly.Nth(i, cvSeg);
|
|
double dDistance = cvSeg.GetDist2Me(pt);
|
|
if (cvSeg.GetLength() > 0)
|
|
{
|
|
//转换点时由于从图纸空间转换到模型空间中时转换误差较大
|
|
//设置为50的另外一个原因是对象捕捉的距离
|
|
if (fabs(dDistance) < 50)
|
|
{
|
|
bOn = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*if (pEnt->isKindOf(TDbCurveEntity::desc())|| pEnt->isKindOf(AcDbEntity::desc()))*/
|
|
/*if (pEnt->isKindOf(TDbOpening::desc()))
|
|
{
|
|
AcDbVoidPtrArray dbArray;
|
|
pEnt->explode(dbArray);
|
|
int n = dbArray.length();
|
|
for (int i = 0; i < dbArray.length(); i++)
|
|
{
|
|
AcDbLine *pLine = AcDbLine::cast((AcDbEntity *)dbArray[i]);
|
|
if (pLine != NULL)
|
|
{
|
|
GeCurveSegment seg(pLine->startPoint(), pLine->endPoint(), 0);
|
|
double dDist = fabs(seg.GetDist2Me(pt));
|
|
if (fabs(seg.GetDist2Me(pt))< 100) //上华对象炸开后可能引起的误差值会更大些
|
|
{
|
|
bOn = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
AcDbBlockTableRecord *pBlock = AcDbBlockTableRecord::cast((AcDbObject*)dbArray[i]);
|
|
if (pBlock != NULL)
|
|
{
|
|
acutPrintf(_T("aa"));
|
|
}
|
|
AcDbArc *pArc = AcDbArc::cast((AcDbEntity*)dbArray[i]);
|
|
if (pArc != NULL)
|
|
{
|
|
XPoint ptCenter = pArc->center();
|
|
XArc arc(ptCenter, pArc->radius(), pArc->startAngle(), pArc->endAngle());
|
|
GeCurveSegment segArc;
|
|
segArc = arc;
|
|
double dDist = fabs(segArc.GetDist2Me(pt));
|
|
if (fabs(segArc.GetDist2Me(pt))< 100)
|
|
{
|
|
bOn = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}*/
|
|
|
|
pEnt->close();
|
|
if (bOn) //点在实体上
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
delete pBlockIterator;
|
|
pBlockIterator = NULL;
|
|
}
|
|
pTable->close();
|
|
pBlockTableRecord->close();
|
|
return bOn;
|
|
}
|
|
|
|
//add by lgy 20120509 以下函数目的是为了获得点在的视口编号和视口比例
|
|
//pt:图纸空间中点取的点
|
|
//dScale:对应视口的比例
|
|
//entSet:当前图纸所有视口对象
|
|
//返回值:视口编号 如果为0表示没有点中视口
|
|
int GetPtOnWhichPort(XPoint pt, double &dScale,BOOL &bOnEnt, PickEntSet entSet)
|
|
{
|
|
for(long i = 0; i < entSet.Length(); i++)
|
|
{
|
|
Entity ent = entSet[i];
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbViewport, pViewPort);
|
|
if (pViewPort == NULL)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
double dWidth = pViewPort->width();
|
|
double dHeight = pViewPort->height();
|
|
XPoint ptCenter = pViewPort->centerPoint();
|
|
|
|
XPoly2D poly;
|
|
XRectAngle rect(ptCenter, dWidth, dHeight);
|
|
rect.AsPoly2D(poly);
|
|
poly.SetClosed();
|
|
poly.SetElevation(0.0);
|
|
if ((pt&poly) == PR_INSIDE) //在视口内
|
|
{
|
|
dScale = pViewPort->customScale();
|
|
|
|
XPoint ptPortCenter = pViewPort->viewCenter();
|
|
XPoint ptCenter = pViewPort->centerPoint();
|
|
double dAngle = ads_angle(ptCenter, pt); //点取的点跟视口中心点的角度
|
|
double dDistance = ptCenter.Distance2d(pt);
|
|
XPoint ptView2Mod;
|
|
ads_polar(ptPortCenter, dAngle, dDistance/dScale, ptView2Mod);
|
|
bOnEnt = GetIsOnEntity(ptView2Mod); //判断点是否在实体上
|
|
|
|
return pViewPort->number();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//add by lgy 20120315 设置弧长标记
|
|
void TDimensionEdJig::SetIsArcDim()
|
|
{
|
|
m_bIsArcDim = true;
|
|
}
|
|
|
|
//add by whl on 03/08/08
|
|
void TDimensionEdJig::FindAndRemoveSeg(XPoint pt)
|
|
{
|
|
GeCurveSegment seg=m_pDrawEnt->GetDimCurve();
|
|
XPoint ptOnSeg;
|
|
seg.ProjectToMe(pt, ptOnSeg);
|
|
double value=seg.StartPoint().Distance2d(ptOnSeg);
|
|
long i=-1;
|
|
if(value>g_Option::instance()._DIST_SNAP)
|
|
{
|
|
double curValue=0;
|
|
for(i=0;i<m_pDrawEnt->GetSegmentNum();i++)
|
|
{
|
|
curValue+=m_pDrawEnt->GetSegment(i);
|
|
if(fabs(curValue-value)<g_Option::instance()._DIST_SNAP)
|
|
break;
|
|
}
|
|
}
|
|
if(i>=m_pDrawEnt->GetSegmentNum())
|
|
return;//useful
|
|
|
|
if(i>=0)
|
|
{
|
|
double temp=m_pDrawEnt->GetSegment(i);
|
|
if(i<(m_pDrawEnt->GetSegmentNum()-1))//是中间段
|
|
m_pDrawEnt->SetSegment(i+1,temp+m_pDrawEnt->GetSegment(i+1));//后一段合并之
|
|
m_pDrawEnt->RemoveSegment(i);
|
|
}
|
|
else//第一个标注段的起点(不一定是DimContinue中提示的第一点)特殊处理
|
|
{
|
|
double temp=m_pDrawEnt->GetSegment(0);
|
|
m_pDrawEnt->RemoveSegment(0);
|
|
XVector3D vt=seg.EndPoint()-seg.StartPoint();
|
|
vt.Scale(temp/vt.Length());
|
|
m_pDrawEnt->SetLocation(m_pDrawEnt->GetLocation()+vt);
|
|
}
|
|
}
|
|
void TDimensionEdJig::Step()
|
|
{
|
|
ptStack.Push(m_ptDim);
|
|
}
|
|
bool TDimensionEdJig::CanUndo()
|
|
{
|
|
return ptStack.GetDepth()>1;
|
|
}
|
|
void TDimensionEdJig::Undo()
|
|
{
|
|
XPoint pt;
|
|
ptStack.GetTopData(pt);
|
|
ptStack.GoBack();
|
|
if(CanUndo())
|
|
m_pDrawEnt->FindAndRemoveSegment(pt);
|
|
}
|
|
XPoint TDimensionEdJig::GetLastPoint()
|
|
{
|
|
XPoint pt;
|
|
ptStack.GetTopData(pt);
|
|
return pt;
|
|
}
|
|
//end
|
|
|
|
void TDimensionEdJig::Swap()
|
|
{
|
|
if(m_pTemp) {
|
|
AcDbDeepCloneFiler filer;
|
|
if(m_pTemp->dwgOut(&filer)==Acad::eOk) {
|
|
filer.seek(0L,0);
|
|
VERIFY(m_pDrawEnt->dwgIn(&filer)==Acad::eOk);
|
|
}
|
|
ASSERT(m_pTemp && m_pTemp->IsValid());
|
|
} else {
|
|
m_pTemp = (AecDbDimension *)m_pDrawEnt->clone();
|
|
ASSERT(m_pTemp && m_pTemp->IsValid());
|
|
}
|
|
}
|
|
|
|
// 转换成ARX代码
|
|
int TDimensionEdJig::GetRetCode(int *kwordId) const
|
|
{
|
|
int ret = m_nRetCode;
|
|
if (ret == AcEdJig::kCancel)
|
|
ret = RTCAN;
|
|
else if(ret == AcEdJig::kNull)
|
|
ret = RTNONE;
|
|
else if (ret <= 0)
|
|
ret = RTNORM;
|
|
else {
|
|
if(kwordId) *kwordId = ret;
|
|
ret = RTKWORD;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
TDimensionEdJig::TDimensionEdJig(AecDbDimension *pDim, const TCHAR *pszPrompt, const TCHAR *pszKeyword)
|
|
:m_pDrawEnt(pDim), m_pszPrompt(pszPrompt), m_pszKeyword(pszKeyword), m_nRetCode(0),m_cMonitor(curDoc())
|
|
{
|
|
m_pTemp=NULL;
|
|
m_nFlag=0;
|
|
m_ptDim=pDim->GetLocation();
|
|
//add by lgy 20120315 弧长标注标记
|
|
m_bIsArcDim = false; //false为不是弧长标注
|
|
|
|
m_bInView = FALSE; //add by lgy 20120503 保存标注是否是在视口中绘制
|
|
m_nPortNum = 0; //add by lgy 20120509 默认视口为0
|
|
m_bSaveStyle = FALSE;//add by lgy 20120519 默认不保存标注样式
|
|
m_bKeyword = FALSE;
|
|
}
|
|
|
|
|
|
TDimensionEdJig::~TDimensionEdJig()
|
|
{
|
|
if(m_pTemp)
|
|
delete m_pTemp;
|
|
}
|
|
|
|
// 开始执行拖动
|
|
int TDimensionEdJig::doIt()
|
|
{
|
|
setDispPrompt(m_pszPrompt);
|
|
try
|
|
{
|
|
if (m_nFlag == 1)
|
|
{
|
|
if (m_pDrawEnt->IsDimChord() && m_pDrawEnt->IsAngular())
|
|
{//玄长jig
|
|
|
|
GeCurveSegment seg=m_pDrawEnt->GetDimCurve();
|
|
ADSGePoint3d pt1,pt2,ptc;
|
|
ptc = seg.MidPoint();
|
|
pt1 = seg.GetStartPoint();
|
|
pt2 = seg.GetEndPoint();
|
|
|
|
while(m_pDrawEnt->GetSegmentNum() > 0)
|
|
m_pDrawEnt->RemoveSegment(0);
|
|
|
|
m_pDrawEnt->SetObjRadius(0);
|
|
m_pDrawEnt->SetDimRadius(0);
|
|
|
|
m_pDrawEnt->SetAngular(FALSE);
|
|
m_pDrawEnt->SetDimChord(FALSE);
|
|
|
|
m_pDrawEnt->AppendSegment(pt1.Distance2d(pt2));
|
|
m_pDrawEnt->AddSegment(pt1);
|
|
|
|
m_pDrawEnt->SetLocation(pt1);
|
|
m_pDrawEnt->SetFixLinePos(pt1);
|
|
GeCurveSegment seg1(pt1,pt2,0);
|
|
double nDirection=seg1.Direction(ptc);
|
|
m_pDrawEnt->SetRotation(nDirection);
|
|
}
|
|
}
|
|
m_nRetCode = drag();
|
|
}
|
|
catch(...)
|
|
{
|
|
m_nRetCode=AcEdJig::kCancel;
|
|
}
|
|
return GetRetCode();
|
|
}
|
|
|
|
// 反馈
|
|
AcEdJig::DragStatus TDimensionEdJig::sampler()
|
|
{
|
|
DragStatus stat;
|
|
|
|
setUserInputControls((UserInputControls)
|
|
(AcEdJig::kAccept3dCoordinates|AcEdJig::kNullResponseAccepted));
|
|
|
|
if (m_pszKeyword) setKeywordList(m_pszKeyword);
|
|
XPoint ptTemp;
|
|
if(m_nFlag==0)
|
|
{
|
|
stat=acquirePoint(ptTemp, m_pDrawEnt->GetLocation().AsAcGePoint3d());
|
|
}
|
|
else if((m_nFlag == 1) || (m_nFlag == 2) || (m_nFlag == 5))
|
|
{
|
|
ADSGePoint3d ptCur;
|
|
GlobalFunc::GetWcsCursor(ptCur);
|
|
ptCur.z = 0;
|
|
//辅助计算直线wlw mod 20150518 辅助线需要清零z,否则引线会飞
|
|
XPoint pt1(ptStack[0]),pt2(ptStack[1]);
|
|
pt1.z = 0.0;
|
|
pt2.z = 0.0;
|
|
XLine line1(pt1,pt2);
|
|
ads_real rAng = line1.Direction();
|
|
XPoint pt;
|
|
ads_polar(ptCur, rAng + 0.5 * PI, 100.0, pt);
|
|
XLine line2(ptCur, pt);
|
|
|
|
//获取基点
|
|
ads_point ptIntersection;
|
|
line1.Intersection(&line2,ptIntersection);
|
|
AcGePoint3d ptBase = asPnt3d(ptIntersection);
|
|
|
|
if (!m_bIsArcDim)
|
|
{
|
|
stat = acquirePoint(ptTemp,ptBase);
|
|
}
|
|
else
|
|
{
|
|
stat = acquirePoint(ptTemp);
|
|
}
|
|
}
|
|
else if(m_nFlag==3)
|
|
{
|
|
//modidfied by whl on 03/08/08
|
|
XPoint ptLast=GetLastPoint();
|
|
stat=acquirePoint(ptTemp, ptLast);
|
|
}
|
|
else if(m_nFlag==4)
|
|
{
|
|
XPoint ptLast;
|
|
xg_getvar(_T("LASTPOINT"), ptLast);
|
|
ptLast = GlobalFunc::Ucs2Wcs(ptLast);
|
|
stat=acquirePoint(ptTemp, ptLast);
|
|
}
|
|
|
|
if(stat == AcEdJig::kNormal)
|
|
{
|
|
if (ptTemp.Distance2d(m_ptDim)>g_Option::instance()._DIST_SNAP)
|
|
{
|
|
double nDist=m_ptDim.Distance2d(ptTemp);
|
|
m_ptDim=ptTemp;
|
|
}
|
|
else
|
|
{
|
|
return AcEdJig::kNoChange;
|
|
}
|
|
}
|
|
|
|
return stat;
|
|
}
|
|
|
|
// 更新实体数据
|
|
Adesk::Boolean TDimensionEdJig::update()
|
|
{
|
|
if(m_nFlag==0)
|
|
{
|
|
m_pDrawEnt->SetRotation(ads_angle(m_ptDim, m_pDrawEnt->GetLocation())+PI);
|
|
double nVal=m_ptDim.Distance2d(m_pDrawEnt->GetLocation());
|
|
//modify by lgy 20120503 如果标注在图纸空间中的视口中
|
|
//if(m_pDrawEnt->IsValidSegment(nVal))
|
|
// m_pDrawEnt->SetSegment(0, nVal);
|
|
if(m_pDrawEnt->IsValidSegment(nVal))
|
|
{
|
|
m_pDrawEnt->SetSegment(0, nVal);
|
|
|
|
if (m_bInView)
|
|
{
|
|
double dScale = 1.0;
|
|
BOOL bFit = FALSE;
|
|
int nNum = GetPtOnWhichPort(m_ptDim, dScale, bFit, m_entSet);
|
|
if (nNum == m_nPortNum || !bFit)
|
|
{
|
|
m_pDrawEnt->SetStyleId(m_idDimNew);
|
|
m_bSaveStyle = TRUE;
|
|
}
|
|
else
|
|
{
|
|
m_pDrawEnt->SetStyleId(m_idDimOld);
|
|
m_bSaveStyle = FALSE;
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
else if(m_nFlag==1)
|
|
{
|
|
GeCurveSegment seg=m_pDrawEnt->GetDimCurve();
|
|
XPoint ptOnSeg;
|
|
if(seg.ProjectToMe(m_ptDim, ptOnSeg)==RTNORM)
|
|
{
|
|
double nDistMove=m_ptDim.Distance2d(ptOnSeg);
|
|
int nSideLoc=seg.OnWhichSide(m_pDrawEnt->GetLocation());
|
|
int nSide=seg.OnWhichSide(m_ptDim);
|
|
double nDist2Dim = m_pDrawEnt->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(m_pDrawEnt->IsAngular())
|
|
{ //弧墙有错,不知道原因
|
|
nDist2Dim += nDistMove;
|
|
double nDistRad= m_pDrawEnt->GetDimRadius();
|
|
//seg.GetArc().center.Distance(m_ptDim);
|
|
nDistRad -= nDistMove;
|
|
if(nDistRad>g_Option::instance()._DIST_SNAP)
|
|
{
|
|
m_pDrawEnt->SetDimRadius(nDistRad);
|
|
m_pDrawEnt->SetDist2DimLine(nDist2Dim, FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nDist2Dim += nDistMove;
|
|
m_pDrawEnt->SetDist2DimLine(nDist2Dim, FALSE);
|
|
}
|
|
|
|
}
|
|
}
|
|
else if(m_nFlag==2)
|
|
{ //修改标注位置
|
|
AcDbIntArray indices;
|
|
indices.append(3);
|
|
AcGePoint3dArray ptArray;
|
|
m_pDrawEnt->getStretchPoints(ptArray);
|
|
ASSERT(ptArray.length()>3);
|
|
AcGeVector3d vtOffset=m_ptDim.AsAcGePoint3d()-ptArray[3];
|
|
m_pDrawEnt->moveGripPointsAt(indices, vtOffset);
|
|
}
|
|
else if(m_nFlag==3)
|
|
{//modified by whl on 03/08/08
|
|
ASSERT(m_pTemp);
|
|
GlobalFunc::CopyObject(*m_pDrawEnt, *m_pTemp);
|
|
if(CanUndo())
|
|
{
|
|
if(!m_pTemp->AddSegment(m_ptDim))
|
|
return Adesk::kFalse;
|
|
}
|
|
else
|
|
{
|
|
m_pTemp->SetRotation(ads_angle(m_ptDim, m_pTemp->GetLocation())+PI);
|
|
double nVal=m_ptDim.Distance2d(m_pTemp->GetLocation());
|
|
if(m_pTemp->IsValidSegment(nVal))
|
|
m_pTemp->SetSegment(0, nVal);
|
|
}
|
|
ASSERT(m_pTemp && m_pTemp->IsValid());
|
|
}
|
|
else if(m_nFlag==4)
|
|
{
|
|
ASSERT(m_pTemp);
|
|
GlobalFunc::CopyObject(*m_pDrawEnt, *m_pTemp);
|
|
m_pTemp->AddSegment(m_ptDim);
|
|
}
|
|
else if(m_nFlag==5)
|
|
{
|
|
double dr = m_pDrawEnt->GetObjRadius();
|
|
ADSGePoint3d pt1,pt2;
|
|
m_ObjarDim.GetStartPoint(pt1);
|
|
m_ObjarDim.GetEndPoint(pt2);
|
|
double dDist2d = m_ptDim.Distance2d(m_ObjarDim.GetCenterPt());
|
|
GeCurveSegment ln1(m_ObjarDim.GetCenterPt(), m_ptDim,0), ln2(pt1,pt2,0);
|
|
ln2.SetLineFlag(LS_FINITE);
|
|
ln1.SetLineFlag(LS_FINITE);
|
|
int nptins = ln1.Intersection(ln2,pt1,pt2);
|
|
m_pDrawEnt->SetStyleId(InitDimStyle(DS_ANGLE));
|
|
if (dDist2d < dr)
|
|
{//圆内
|
|
if (nptins > 0)
|
|
{//玄长
|
|
m_pDrawEnt->SetStyleId(InitDimStyle(DS_LINEAR));
|
|
m_pDrawEnt->SetAngular(TRUE);
|
|
m_pDrawEnt->SetDimArcLen(FALSE);
|
|
m_pDrawEnt->SetDimChord(TRUE);
|
|
m_pDrawEnt->SetDist2DimLine(0.0);
|
|
m_pDrawEnt->SetDimRadius(m_ObjarDim.GetRadius()/*-6*GlobalFunc::DocGetPScale()*/);
|
|
}
|
|
else
|
|
{//角度
|
|
m_pDrawEnt->SetAngular(TRUE);
|
|
m_pDrawEnt->SetDimArcLen(FALSE);
|
|
m_pDrawEnt->SetDimChord(FALSE);
|
|
m_pDrawEnt->SetDist2DimLine(10);
|
|
m_pDrawEnt->SetDimRadius(m_ObjarDim.GetRadius()-10*GlobalFunc::DocGetPScale());
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
if (nptins > 0)
|
|
{//弧长
|
|
m_pDrawEnt->SetAngular(TRUE);
|
|
m_pDrawEnt->SetDimArcLen(TRUE);
|
|
m_pDrawEnt->SetDimChord(FALSE);
|
|
m_pDrawEnt->SetDist2DimLine(-6);
|
|
m_pDrawEnt->SetDimRadius(m_ObjarDim.GetRadius()+6.0*GlobalFunc::DocGetPScale());
|
|
}
|
|
else
|
|
{//角度
|
|
m_pDrawEnt->SetAngular(TRUE);
|
|
m_pDrawEnt->SetDimArcLen(FALSE);
|
|
m_pDrawEnt->SetDimChord(FALSE);
|
|
m_pDrawEnt->SetDist2DimLine(10);
|
|
m_pDrawEnt->SetDimRadius(m_ObjarDim.GetRadius()-10*GlobalFunc::DocGetPScale());
|
|
|
|
}
|
|
}
|
|
}
|
|
ASSERT(m_pDrawEnt && m_pDrawEnt->IsValid());
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
AcDbEntity* TDimensionEdJig::entity() const
|
|
{
|
|
if((m_nFlag==3 || m_nFlag==4) && m_pTemp)
|
|
return m_pTemp;
|
|
else
|
|
return m_pDrawEnt;
|
|
}
|
|
|
|
double XYDistance(XPoint pt1,XPoint pt2)
|
|
{
|
|
double XDis=pt1.x-pt2.x;
|
|
double YDis=pt1.y-pt2.y;
|
|
return sqrt(XDis*XDis+YDis*YDis);
|
|
}
|
|
|
|
struct EntAng
|
|
{
|
|
Entity ent;
|
|
double angle;
|
|
};
|
|
|
|
void ArrangeEnt(BOOL bIncrease)
|
|
{
|
|
|
|
}
|
|
|
|
// 把pDim2合并到pDim1去
|
|
int MergeDim(AecDbDimension *pDim1, AecDbDimension *pDim2)
|
|
{
|
|
if(!IsSameDrt(pDim1->GetRotation(), pDim2->GetRotation(), g_DimOption::instance()._angSnap)) {
|
|
g_Option::instance().adsout << _T("\n方向不平齐!");
|
|
return RTERROR;
|
|
} else if(pDim1->IsAngular()!=pDim2->IsAngular()) {
|
|
g_Option::instance().adsout << _T("\n类型不匹配!");
|
|
return RTERROR;
|
|
} else if(!!pDim1->GetBindId() || !!pDim2->GetBindId()) {
|
|
g_Option::instance().adsout << _T("\n尺寸对象已经绑定在其他对象上!");
|
|
return RTERROR;
|
|
}
|
|
|
|
if(pDim1->MergeDim(pDim2))
|
|
return RTNORM;
|
|
g_Option::instance().adsout << _T("\n不能合并!");
|
|
return RTERROR;
|
|
}
|
|
// Add by lcf on 2005/05/26
|
|
BOOL MergeDimFromTo(AecDbDimension *pTo, const AecDbDimension *pFrom)
|
|
{
|
|
XPoly2D poly;
|
|
pFrom->GetPolySegOnDimLine(poly);
|
|
GeCurveSegment cv = pTo->GetDimCurve();
|
|
if(!pTo->IsUseDefaultText() || !pFrom->IsUseDefaultText())
|
|
{
|
|
for(int i=0; i<poly.Length(); i++)
|
|
{
|
|
XPoint ptVert;
|
|
if(cv.ProjectToMe(*poly[i], ptVert) != RTNORM)
|
|
continue;
|
|
if((ptVert & cv) != 4)
|
|
{
|
|
g_Option::instance().adsout << _T("\n尺寸文字被更改过, 并且尺寸线重叠, 不能连接尺寸!");
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
int nSeg = pTo->GetSegmentNum();
|
|
for(int i=0; i<poly.Length(); i++)
|
|
{
|
|
XPoint ptVert;
|
|
if(cv.ProjectToMe(*poly[i], ptVert) != RTNORM)
|
|
continue;
|
|
pTo->AddSegment(ptVert);
|
|
}
|
|
cv = pTo->GetDimCurve();
|
|
|
|
int nTo = pTo->GetSegmentNum();
|
|
int nFrom = pFrom->GetSegmentNum();
|
|
|
|
XPoint ptSta, ptEnd;
|
|
cv.ProjectToMe(*poly.Head(), ptSta);
|
|
cv.ProjectToMe(*poly.Tail(), ptEnd);
|
|
|
|
int nFlag = 0;
|
|
if(ptSta.Distance2d(cv.StartPoint()) < 1E-6)
|
|
{
|
|
nFlag = 0;
|
|
}
|
|
else if(ptSta.Distance2d(cv.EndPoint()) < 1E-6)
|
|
{
|
|
nFlag = 1;
|
|
}
|
|
else if(ptEnd.Distance2d(cv.StartPoint()) < 1E-6)
|
|
{
|
|
nFlag = 2;
|
|
}
|
|
else if(ptEnd.Distance2d(cv.EndPoint()) < 1E-6)
|
|
{
|
|
nFlag = 3;
|
|
}
|
|
else
|
|
{
|
|
// sg modify 120615,解决在中间部分的尺寸标注如果文字不在默认位置,连接尺寸后,文字不在默认位置的问题
|
|
// return TRUE;
|
|
for (i=0; i<nFrom; i++)
|
|
{
|
|
XPoint ptVert;
|
|
if (cv.ProjectToMe(*poly[i], ptVert) != RTNORM)
|
|
continue;
|
|
|
|
BOOL bIsDefText = TRUE;
|
|
XString szText = pFrom->GetText(i, &bIsDefText);
|
|
BOOL bIsDefPos = TRUE;
|
|
XPoint ptPos = pFrom->GetTextPos(i, &bIsDefPos);
|
|
if (bIsDefText && bIsDefPos)
|
|
continue;
|
|
|
|
XPoint ptNew = ptPos;
|
|
ptNew += ptVert - *poly[i];
|
|
|
|
int nPos = pTo->HitTestOnDimSeg(ptNew);
|
|
if (nPos==-1 || nPos>nTo)
|
|
continue;
|
|
|
|
double dCur = pFrom->GetSegment(i),
|
|
dProject = pTo->GetSegment(nPos);
|
|
if (fabs(dCur-dProject) > g_Option::instance()._DIST_SNAP) // 中间部分的外偏情况,不处理
|
|
continue;
|
|
|
|
if (!bIsDefText)
|
|
pTo->SetTextContent(nPos, szText);
|
|
|
|
if (!bIsDefPos)
|
|
{
|
|
if (_tcscmp(szText, pTo->GetText(nPos)) == 0)
|
|
pTo->SetTextPos(nPos, ptNew);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
for(i=0; i<nFrom; i++)
|
|
{
|
|
XPoint ptVert;
|
|
if(cv.ProjectToMe(*poly[i], ptVert) != RTNORM)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
BOOL bIsDefText = TRUE;
|
|
XString szText = pFrom->GetText(i, &bIsDefText);
|
|
BOOL bIsDefPos = TRUE;
|
|
XPoint ptPos = pFrom->GetTextPos(i, &bIsDefPos);
|
|
if(bIsDefText && bIsDefPos)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
int nPos;
|
|
if(nFlag == 0)
|
|
{
|
|
nPos = i;
|
|
}
|
|
else if(nFlag == 1)
|
|
{
|
|
nPos = nTo - i - 1;
|
|
}
|
|
else if(nFlag == 2)
|
|
{
|
|
nPos = nFrom - i - 1;
|
|
}
|
|
else if(nFlag == 3)
|
|
{
|
|
nPos = nTo - nFrom + i;
|
|
}
|
|
|
|
if(!bIsDefText)
|
|
pTo->SetTextContent(nPos, szText);
|
|
|
|
if(!bIsDefPos)
|
|
{
|
|
if(_tcscmp(szText, pTo->GetText(nPos)) == 0)
|
|
{
|
|
ptPos += ptVert - *poly[i];
|
|
pTo->SetTextPos(nPos, ptPos);
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
// Command: 连接尺寸标注
|
|
// 不支持自调
|
|
void MergeDim()
|
|
{
|
|
//Add by lxb on 2011/11/17
|
|
//允许用户通过框选的方式,同时选中多道尺寸线与主尺寸连接
|
|
//修改系统变量PICKADD
|
|
XPushVar<int> pickmode(_T("PICKADD"), 1);
|
|
|
|
//与主尺寸连接标注选择集
|
|
PickEntSet ss(SS_FREE);
|
|
RBList mask(RTDXF0, _T("DIMENSION,AEC_CHICUNBIAOZHU"), NULL);
|
|
EntitySet entMaster;
|
|
if (entMaster.FilterSelect(_T("\n选择主尺寸标注<退出>: "),mask) != RTNORM)
|
|
{
|
|
return;
|
|
}
|
|
entMaster.Redraw(3);
|
|
|
|
|
|
GlobalFunc::DocGetPickFirst().Free();
|
|
|
|
if(RTNORM != GlobalFunc::SelectEntities(_T("\n选择需要连接尺寸标注<退出>: "),ss, mask))
|
|
{
|
|
entMaster.Redraw(4);
|
|
return;
|
|
}
|
|
ss -= entMaster;
|
|
|
|
Entity entDim;
|
|
if(entMaster.Is(_T("DIMENSION")))
|
|
{
|
|
if(!ConvertDim(entMaster, entDim))
|
|
{
|
|
g_Option::instance().adsout << _T("\n不能转化ACAD尺寸标注对象!");
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else if(!entDim.Is(_T("AEC_CHICUNBIAOZHU")))
|
|
{
|
|
g_Option::instance().adsout << _T("\n不是线性标注!");
|
|
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
entDim = entMaster;
|
|
}
|
|
|
|
|
|
OPENOBJ_BEGIN(entDim, AcDb::kForRead, AecDbDimension, pMaster);
|
|
if (!pMaster)
|
|
{
|
|
return;
|
|
}
|
|
//连接操作
|
|
long nLen = ss.Length();
|
|
for (long i = 0;i < nLen; i++)
|
|
{
|
|
Entity entDim;
|
|
if(entMaster.Is(_T("DIMENSION")))
|
|
{
|
|
if(!ConvertDim(ss[i], entDim))
|
|
{
|
|
g_Option::instance().adsout << _T("\n不能转化ACAD尺寸标注对象!");
|
|
{
|
|
continue;;
|
|
}
|
|
}
|
|
else if(!entDim.Is(_T("AEC_CHICUNBIAOZHU")))
|
|
{
|
|
g_Option::instance().adsout << _T("\n不是线性标注!");
|
|
|
|
continue;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
entDim = ss[i];
|
|
}
|
|
|
|
OPENOBJ_BEGIN(entDim, AcDb::kForWrite, AecDbDimension, pSlaver);
|
|
if(pSlaver)
|
|
{
|
|
if(pMaster->upgradeOpen()!=Acad::eOk)
|
|
{
|
|
g_Option::instance().adsout << _T("\n不能修改主尺寸!");
|
|
continue;
|
|
}
|
|
if(pMaster->IsAngular()!=pSlaver->IsAngular())
|
|
{
|
|
g_Option::instance().adsout << _T("\n直线类型的尺寸不能和角度类型的尺寸进行连接!");
|
|
}
|
|
else
|
|
{
|
|
BOOL bCanMerge=TRUE;
|
|
if(!pMaster->IsAngular())
|
|
{
|
|
if(!IsSameDrt(pMaster->GetRotation(), pSlaver->GetRotation(), g_Option::instance()._DIST_SNAP))
|
|
{
|
|
g_Option::instance().adsout << _T("\n尺寸线的方向不平行, 无法连接!");
|
|
bCanMerge=FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
XArc ar1=pMaster->GetDimCurve().GetArc();
|
|
XArc ar2=pSlaver->GetDimCurve().GetArc();
|
|
if(ar1.GetCenterPt().Distance2d(ar2.GetCenterPt())>g_Option::instance()._DIST_SNAP)
|
|
{
|
|
g_Option::instance().adsout << _T("\n角度类型的尺寸圆心不一样, 无法连接!");
|
|
bCanMerge=FALSE;
|
|
}
|
|
}
|
|
if(bCanMerge)
|
|
{
|
|
if(MergeDimFromTo(pMaster, pSlaver))
|
|
{
|
|
pSlaver->erase();
|
|
}
|
|
}
|
|
}
|
|
pMaster->downgradeOpen();
|
|
}
|
|
else
|
|
{
|
|
g_Option::instance().adsout << _T("\n不能修改尺寸标注!");
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
// Command: 转化尺寸标注 (AcDbDimension -> AecDbDimension)
|
|
void ConvertDim()
|
|
{
|
|
RBList mask(RTDXF0, _T("DIMENSION,AEC_CHICUNBIAOZHU"), NULL);
|
|
PickEntSet ss(SS_FREE);
|
|
if(GlobalFunc::SelectEntities(_T("\n请选择ACAD尺寸标注: "), ss, mask)==RTNORM) {
|
|
PickEntSet ss1(SS_FREE|SS_CREATE);
|
|
long lCount=ss.Length();
|
|
for(long i=0; i<lCount; i++) {
|
|
Entity ent=ss[i], _tmp;
|
|
|
|
if(!ConvertDim(ent, _tmp))
|
|
ss1 += ent;
|
|
}
|
|
long num=ss1.Length();
|
|
if(num) {
|
|
g_Option::instance().adsout << _T("\n有") << int(num) << _T("个对象不能被转化!");
|
|
ss1.Redraw(3);
|
|
} else {
|
|
g_Option::instance().adsout << _T("\n全部选中的") << int(lCount) << _T("个对象成功的转化为上华尺寸标注!");
|
|
}
|
|
}
|
|
}
|
|
// Command: 切换角标
|
|
void TogDimAngular()
|
|
{
|
|
RBList mask(RTDXF0, _T("AEC_CHICUNBIAOZHU"), NULL);
|
|
PickEntSet ss(SS_FREE);
|
|
if(GlobalFunc::SelectEntities(_T("\n请选择上华角度标注: "), ss, mask)==RTNORM) {
|
|
long lCount=ss.Length();
|
|
for(long i=0; i<lCount; i++) {
|
|
Entity ent=ss[i];
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecDbDimension, pDim);
|
|
if(pDim && pDim->IsAngular()) {
|
|
pDim->SwitchDimChord();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
}
|
|
// Command: 尺寸复位
|
|
void ResetDimP()
|
|
{
|
|
// modify by xly on 100913 支持符号标注中:标高符号、箭头引注、剖面剖切和断面剖切四种文字复位,(20111222新加)指北针
|
|
// RBList mask(RTDXF0, _T("AEC_CHICUNBIAOZHU,AEC_BANJINGBIAOZHU"), NULL);
|
|
// RBList mask(RTDXF0, _T("AEC_CHICUNBIAOZHU,AEC_BANJINGBIAOZHU,ATS_ARROW,ATS_ELEVATION,AEC_POQIE,ATS_NORTHTHUMB"), NULL);
|
|
// sg modify 120117,根据9.0的需求,增加了对索引图名对象的支持,主要是将圆圈外的文字还原
|
|
RBList mask(RTDXF0, _T("AEC_CHICUNBIAOZHU,AEC_BANJINGBIAOZHU,ATS_ARROW,ATS_ELEVATION,AEC_POQIE,ATS_NORTHTHUMB,AEC_SUOYINTUMING"), NULL);
|
|
PickEntSet ss(SS_FREE);
|
|
|
|
// if(GlobalFunc::SelectEntities(_T("\n请选择上华尺寸标注: "), ss, mask)==RTNORM) {
|
|
if(GlobalFunc::SelectEntities(_T("\n请选择需复位文字的对象: "), ss, mask)==RTNORM)
|
|
{
|
|
long lCount=ss.Length();
|
|
for(long i=0; i<lCount; i++)
|
|
{
|
|
Entity ent=ss[i];
|
|
|
|
// modify by xly 0n 100913 添加部分符号标注的文字复位
|
|
/*OPENOBJ_BEGIN(ent, AcDb::kForWrite, AcDbEntity, pDim);
|
|
AecDbDimension *pDim1=AecDbDimension::cast(pDim);
|
|
AecXDbRadiusDim *pDim2=AecXDbRadiusDim::cast(pDim);
|
|
if(pDim1)
|
|
pDim1->ResetTextPos();
|
|
else if(pDim2)
|
|
{
|
|
pDim2->SetTextPos(pDim2->GetDefaultTextPos());
|
|
}
|
|
OPENOBJ_END();*/
|
|
|
|
if (ent.Is(_T("AEC_CHICUNBIAOZHU"))) // 标注对象
|
|
{
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecDbDimension, pDim);
|
|
if (pDim != NULL)
|
|
{
|
|
pDim->ResetTextPos();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
else if (ent.Is(_T("AEC_BANJINGBIAOZHU"))) // 半径标注对象
|
|
{
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecXDbRadiusDim, pDim);
|
|
if (pDim != NULL)
|
|
{
|
|
pDim->SetTextPos(pDim->GetDefaultTextPos());
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
else if (ent.Is(_T("AEC_JIANTOUYINZHU"))) // 箭头引注对象
|
|
{
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecXDbSymbArrow, pArrow);
|
|
if (pArrow != NULL)
|
|
{
|
|
pArrow->SetTextLocation(pArrow->GetDefaultTextLocation());
|
|
|
|
// 支持下标文字复位
|
|
pArrow->SetText2Location(pArrow->GetDefaultText2Location());
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
else if (ent.Is(_T("AEC_BIAOGAOBIAOZHU"))) // 标高标注对象
|
|
{
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecXDbSymbElevation, pEle);
|
|
if (pEle != NULL)
|
|
{
|
|
pEle->SetTextPoint(pEle->GetDefaultTextLocation());
|
|
|
|
// 支持相对标高,上下排列的文字复位
|
|
pEle->SetLowTextPt(pEle->GetDefaultTextLocation2());
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
else if (ent.Is(_T("AEC_POQIE")))// 剖面剖切,断面剖切对象
|
|
{
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecXDbSymbSection, pSection);
|
|
if (pSection != NULL)
|
|
{
|
|
pSection->SetTextLocation(0,pSection->GetDefaultTextLocation(0));
|
|
pSection->SetTextLocation(1,pSection->GetDefaultTextLocation(1));
|
|
//add by lgy 20120528 为剖切图号设置文字位置
|
|
pSection->SetIndexLocation(0, pSection->GetDefaultIndexLocation(0));
|
|
pSection->SetIndexLocation(1, pSection->GetDefaultIndexLocation(1));
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
else if (ent.Is(_T("AEC_ZHIBEIZHEN")))//指北针 add by lxb on 2011/12/22
|
|
{
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecXDbSymbNorthThumb, pNorthThumb);
|
|
if (pNorthThumb != NULL)
|
|
{
|
|
pNorthThumb->SetTextPoint(pNorthThumb->GetDefaultTextLocation());
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
else if (ent.Is(_T("AEC_SUOYINTUMING"))) // 索引图名,sg add 120117
|
|
{
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecXDbSymbDrawingIndex, pDrawingIndex);
|
|
if (pDrawingIndex != NULL)
|
|
{
|
|
pDrawingIndex->SetScaleTextPt(pDrawingIndex->GetDefaultScaleTextLocation());
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Command: 尺寸复原
|
|
void ResetDimT()
|
|
{
|
|
RBList mask(RTDXF0, _T("AEC_CHICUNBIAOZHU,AEC_BANJINGBIAOZHU"), NULL);
|
|
PickEntSet ss(SS_FREE);
|
|
if(GlobalFunc::SelectEntities(_T("\n请选择上华尺寸标注: "), ss, mask)==RTNORM) {
|
|
long lCount=ss.Length();
|
|
for(long i=0; i<lCount; i++) {
|
|
Entity ent=ss[i];
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AcDbEntity, pDim);
|
|
AecDbDimension *pDim1=AecDbDimension::cast(pDim);
|
|
AecXDbRadiusDim *pDim2=AecXDbRadiusDim::cast(pDim);
|
|
if(pDim1) pDim1->ResetTextContent();
|
|
else if(pDim2) pDim2->SetText(NULL);
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
}
|
|
// Command: 更改文字
|
|
void DimChText()
|
|
{
|
|
RBList mask(RTDXF0, _T("DIMENSION,AEC_CHICUNBIAOZHU,AEC_BANJINGBIAOZHU"), NULL);
|
|
Entity entMaster;
|
|
XPoint ptPick;
|
|
while(entMaster.FilterSelect(_T("\n请选择尺寸区间<退出>: "), mask, ptPick)==RTNORM) {
|
|
Entity entDim;
|
|
if(entMaster.Is(_T("DIMENSION"))) {
|
|
if(!ConvertDim(entMaster, entDim)) {
|
|
g_Option::instance().adsout << _T("\n不能转化ACAD尺寸标注对象!");
|
|
return;
|
|
}
|
|
} else {
|
|
entDim=entMaster;
|
|
}
|
|
|
|
if(entDim.Is(_T("AEC_BANJINGBIAOZHU"))) {
|
|
OPENOBJ_BEGIN(entDim, AcDb::kForRead, AecXDbRadiusDim, pDim);
|
|
ASSERT(pDim);
|
|
XString sText;
|
|
XString sTemp=pDim->GetText();
|
|
g_Option::instance().adsout << _T("\n输入标注文字<") << sTemp << _T(">: ");
|
|
if(ads_getstring(1, _T(""), sText)==RTNORM) {
|
|
if(pDim->upgradeOpen()==Acad::eOk) {
|
|
pDim->SetText(sText);
|
|
pDim->downgradeOpen();
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
} else if(entDim.Is(_T("AEC_CHICUNBIAOZHU"))) {
|
|
OPENOBJ_BEGIN(entDim, AcDb::kForRead, AecDbDimension, pDim);
|
|
ASSERT(pDim);
|
|
int nSeg=pDim->HitTestOnText(GlobalFunc::Ucs2Wcs(ptPick));
|
|
if(nSeg<0) {
|
|
g_Option::instance().adsout << _T("\n请正确点取在尺寸线上!");
|
|
} else {
|
|
XString sText;
|
|
g_Option::instance().adsout << _T("\n输入标注文字<") << pDim->GetText(nSeg) << _T(">: ");
|
|
if(ads_getstring(1, _T(""), sText)==RTNORM) {
|
|
if(pDim->upgradeOpen()==Acad::eOk) {
|
|
pDim->SetTextContent(nSeg, sText);
|
|
pDim->downgradeOpen();
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
//标注一根墙宽
|
|
//传入:ptLeft 左标注点
|
|
// ptMid 中标注点
|
|
// ptRight 右标注点
|
|
// nDimAxis 轴线标志
|
|
// = 1 标
|
|
// = 0, 2 不标
|
|
//返回:成功, RTNORM; 出错, RTERROR
|
|
int DimOne(XPoint ptLeft, XPoint ptMid, XPoint ptRight, BOOL nDimAxis)
|
|
{
|
|
if(ptMid.Distance2d(ptLeft)<g_Option::instance()._DIST_SNAP || ptMid.Distance2d(ptRight)<g_Option::instance()._DIST_SNAP)
|
|
{
|
|
nDimAxis=FALSE;
|
|
}
|
|
AecDbDimension *pDim=new AecDbDimension;
|
|
pDim->SetLayoutRotation(GlobalFunc::Ucs2Wcs(0));//add by whl on 060306
|
|
pDim->SetLocation(ptLeft);
|
|
pDim->SetRotation(ads_angle(ptLeft, ptRight));
|
|
pDim->SetDist2DimLine(6.0, TRUE);
|
|
pDim->AppendSegment(ptLeft.Distance2d(ptRight));
|
|
AcDbObjectId idStyle=InitDimStyle(DS_LINEAR);
|
|
pDim->SetStyleId(idStyle);
|
|
|
|
|
|
AcGiTextStyle txtStyle;
|
|
OPENOBJ_BEGIN(idStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pStyle);
|
|
ASSERT(pStyle);
|
|
VERIFY(fromAcDbTextStyle(txtStyle, pStyle->dimtxsty())==Acad::eOk);
|
|
int nRetFlag=txtStyle.loadStyleRec();
|
|
txtStyle.setTextSize(pStyle->dimtxt()*pDim->GetPScale()*0.8);
|
|
OPENOBJ_END();
|
|
|
|
if(nDimAxis)
|
|
{
|
|
pDim->AddSegment(ptMid);
|
|
|
|
//add by lxb on 2011/11/18
|
|
//针对基线在墙外时调整标注的显示位置
|
|
XLine line(ptLeft, ptRight, LS_FINITE);
|
|
ADSGePoint3d ptLRMid = line.MidPoint();
|
|
|
|
ads_real rHLeft = ads_distance(ptLeft, ptMid)/2, // ZJQ modify 2 to 4, so it is more close to wall
|
|
rHRight = ads_distance(ptMid, ptRight)/2,
|
|
// rALeft = ads_angle(ptMid, ptLeft), //左标移动方向
|
|
// rARight = ads_angle(ptMid, ptRight); //右标移动方向
|
|
rALeft = ads_angle(ptLRMid, ptLeft), //左标移动方向
|
|
rARight = ads_angle(ptLRMid, ptRight); //右标移动方向
|
|
AcGePoint2d ptExt=txtStyle.extents(pDim->GetText(0), Adesk::kFalse, -1, Adesk::kTrue);
|
|
rHLeft += ptExt[0]/2 + 1.0*pDim->GetPScale();
|
|
ptExt = txtStyle.extents(pDim->GetText(1), Adesk::kFalse, -1, Adesk::kTrue);
|
|
rHRight += ptExt[0]/2 + 1.0*pDim->GetPScale();
|
|
XVector3D vtLeft(rHLeft*cos(rALeft), rHLeft*sin(rALeft));
|
|
XVector3D vtRight(rHRight*cos(rARight), rHRight*sin(rARight));
|
|
XPoint ptLText=pDim->GetTextPos(0);
|
|
ptLText += vtLeft;
|
|
XPoint ptRText=pDim->GetTextPos(1);
|
|
ptRText += vtRight;
|
|
pDim->SetTextPos(0, ptLText);
|
|
pDim->SetTextPos(1, ptRText);
|
|
}
|
|
else
|
|
{
|
|
ads_real rHWidth = ads_distance(ptLeft, ptRight)/2, // ZJQ modify 2 to 4, so it is more close to wall
|
|
rAngle = ads_angle(ptLeft, ptRight); //移动方向
|
|
AcGePoint2d ptExt=txtStyle.extents(pDim->GetText(0), Adesk::kTrue, -1, Adesk::kTrue);
|
|
rHWidth += ptExt[0]/2 + 1.0*pDim->GetPScale();
|
|
XVector3D vtMove(rHWidth*cos(rAngle), rHWidth*sin(rAngle));
|
|
XPoint ptText=pDim->GetTextPos(0);
|
|
ptText += vtMove;
|
|
pDim->SetTextPos(0, ptText);
|
|
}
|
|
|
|
// sg add 120410,增加布局转角的设置,解决UCS下,文字方向错误的问题
|
|
pDim->SetLayoutRotation(GlobalFunc::Ucs2Wcs(0.0));
|
|
|
|
// modify by xly on 110107 支持图层切换
|
|
//pDim->AddToMSpace(Adesk::kTrue);
|
|
GlobalFunc::AddToSpace(Adesk::kTrue, pDim);
|
|
return RTNORM;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Command: 打断尺寸
|
|
void DimBreak()
|
|
{
|
|
RBList mask(RTDXF0, _T("AEC_CHICUNBIAOZHU"), NULL);
|
|
Entity ent;
|
|
XPoint ptPick;
|
|
if(GlobalFunc::SelectEntity(_T("\n请在要打断的一侧点取尺寸线<退出>: "), ent, ptPick, mask)==RTNORM)
|
|
{
|
|
ptPick=GlobalFunc::Ucs2Wcs(ptPick);
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecDbDimension, pDim);
|
|
if(pDim)
|
|
{
|
|
if(pDim->IsBind())
|
|
{
|
|
g_Option::instance().adsout << _T("\n此尺寸标注绑定在其他对象上, 因此不能编辑!");
|
|
return;
|
|
}
|
|
int nSeg = pDim->HitTestOnDimSeg(ptPick);
|
|
if(nSeg < 0||nSeg>=pDim->GetSegmentNum())
|
|
return;
|
|
|
|
XPoly2D poly;
|
|
pDim->GetPolySegOnDimLine(poly);
|
|
|
|
XDirectionCurve seg;
|
|
poly.Nth(nSeg, seg);
|
|
XPoint ptLoc;
|
|
double nDist1 = ads_distance(seg.StartPoint(), ptPick);
|
|
double nDist2 = ads_distance(seg.EndPoint(), ptPick);
|
|
if(nDist1>nDist2)
|
|
nSeg++;
|
|
|
|
if(nSeg<0||nSeg>=pDim->GetSegmentNum())
|
|
return;
|
|
poly.Nth(nSeg, seg);
|
|
|
|
double nRot = seg.IDirection(0);
|
|
ads_polar(seg.StartPoint(), nRot-PI/2.0, pDim->GetDist2DimLine(FALSE), ptLoc);
|
|
|
|
AecDbDimension *pDimNew=(AecDbDimension *)pDim->clone();
|
|
for(int i=0; i<nSeg; i++)
|
|
pDimNew->RemoveSegment(0);
|
|
pDimNew->SetLocation(ptLoc);
|
|
pDimNew->SetRotation(nRot);
|
|
GlobalFunc::AddToCurrentSpace(pDimNew, Adesk::kTrue);
|
|
int nTotalSeg=poly.TotalSegments();
|
|
for(i=nSeg; i<nTotalSeg; i++)
|
|
pDim->RemoveSegment(nSeg);
|
|
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
// Command: 取消尺寸区间
|
|
void RemoveDimSeg()
|
|
{
|
|
// 解决选中标注后,运行“取消标注”命令,当删除最后一个标注崩溃的问题
|
|
ads_name name = {0, 0};
|
|
acedSSSetFirst(name, NULL);
|
|
// end
|
|
|
|
PickEntSet sets(SS_FREE);
|
|
RBList mask(RTDXF0, _T("AEC_CHICUNBIAOZHU"), NULL);
|
|
Entity ent;
|
|
XPoint ptPick;
|
|
|
|
while(1)
|
|
{
|
|
int iRet;
|
|
CHookMsg hookmsg;
|
|
INITGET_BEG(0,_T("A"))
|
|
iRet = GlobalFunc::SelectEntity(_T("\n选择待删除尺寸的区间线或尺寸文字[整体删除(A)]<退出>: "), ent, ptPick, mask);
|
|
INITGET_END()
|
|
if (iRet == RTERROR)
|
|
{
|
|
if (hookmsg.GetValue() == 0)
|
|
continue;
|
|
else
|
|
return;
|
|
}
|
|
if (iRet == RTCAN)
|
|
return;
|
|
if (iRet == RTKWORD)
|
|
{
|
|
TCHAR buf[256];
|
|
acedGetInput(buf);
|
|
if(buf[0] == _T('A') || buf[0] == _T('a'))
|
|
{
|
|
RBList rb(RTDXF0, _T("AEC_CHICUNBIAOZHU"));
|
|
if (GlobalFunc::SelectEntities(_T("\n选择待删除的所有尺寸对象<退出>:"), sets, rb) != RTNORM)
|
|
return;
|
|
sets.Erase();
|
|
return;
|
|
}
|
|
}
|
|
ptPick = GlobalFunc::Ucs2Wcs(ptPick);
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecDbDimension, pDim);
|
|
if (pDim)
|
|
{
|
|
if (pDim->IsBind())
|
|
{
|
|
g_Option::instance().adsout << _T("\n此尺寸标注绑定在其他对象上, 因此不能编辑!");
|
|
return;
|
|
}
|
|
int nSeg = -1;
|
|
SubText* psubtext = pDim->HitTestText(ptPick);
|
|
if (psubtext == NULL)
|
|
{
|
|
nSeg = pDim->HitTestOnDimSeg(ptPick);
|
|
}
|
|
else
|
|
{
|
|
nSeg = psubtext->GetIndex();
|
|
delete psubtext;
|
|
psubtext = NULL;
|
|
}
|
|
|
|
if (nSeg >= 0)
|
|
{
|
|
XPoly2D poly;
|
|
pDim->GetPolySegOnDimLine(poly);
|
|
int n = poly.TotalSegments();
|
|
ASSERT(nSeg < poly.TotalSegments());
|
|
if (nSeg == poly.TotalSegments() - 1)
|
|
{
|
|
pDim->RemoveSegment(nSeg);
|
|
if (!pDim->IsValid())
|
|
pDim->erase();
|
|
}
|
|
else if (nSeg == 0)
|
|
{
|
|
XDirectionCurve seg;
|
|
poly.Nth(1, seg);
|
|
double nDist2DimLine = pDim->GetDist2DimLine(FALSE);
|
|
double nRot = seg.IDirection(0);
|
|
XPoint ptLoc;
|
|
ads_polar(seg.StartPoint(), nRot - PI / 2.0, nDist2DimLine, ptLoc);
|
|
pDim->RemoveSegment(nSeg);
|
|
pDim->SetLocation(ptLoc);
|
|
pDim->SetRotation(nRot);
|
|
}
|
|
else
|
|
{
|
|
AecDbDimension *pDimNew = (AecDbDimension *)pDim->clone();
|
|
XDirectionCurve seg;
|
|
poly.Nth(nSeg + 1, seg);
|
|
double nRot = seg.IDirection(0);
|
|
XPoint ptLoc;
|
|
ads_polar(seg.StartPoint(), nRot - PI / 2.0, pDimNew->GetDist2DimLine(FALSE), ptLoc);
|
|
for (int i = 0; i <= nSeg; i++)
|
|
pDimNew->RemoveSegment(0);
|
|
pDimNew->SetLocation(ptLoc);
|
|
pDimNew->SetRotation(nRot);
|
|
GlobalFunc::AddToCurrentSpace(pDimNew, Adesk::kTrue);
|
|
int nTotalSeg = poly.TotalSegments();
|
|
for (i = nSeg; i < nTotalSeg; i++)
|
|
pDim->RemoveSegment(nSeg);
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
void DimTextMirror()
|
|
{
|
|
RBList mask(RTDXF0, _T("AEC_CHICUNBIAOZHU"), NULL);
|
|
Entity ent;
|
|
XPoint ptPick;
|
|
if(GlobalFunc::SelectEntity(_T("\n请选择上华尺寸标注<退出>: "), ent, ptPick, mask)==RTNORM) {
|
|
ptPick=GlobalFunc::Ucs2Wcs(ptPick);
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecDbDimension, pDim);
|
|
if(pDim) {
|
|
int nSeg=pDim->HitTestOnText(ptPick);
|
|
if(nSeg>=0) {
|
|
XPoly2D poly;
|
|
pDim->GetPolySegOnDimLine(poly);
|
|
ASSERT(nSeg<poly.TotalSegments());
|
|
XPoint ptText=pDim->GetTextPos(nSeg);
|
|
GeCurveSegment seg;
|
|
poly.Nth(nSeg, seg);
|
|
XPoint ptOnSeg;
|
|
if(pDim->IsAngular() && pDim->IsDimChord())
|
|
seg=XLine(seg.StartPoint(), seg.EndPoint());
|
|
if(seg.ProjectToMe(ptText, ptOnSeg)==RTNORM) {
|
|
XPoint ptTextNew;
|
|
ptOnSeg.Mirror(ptText, ptTextNew);
|
|
pDim->SetTextPos(nSeg, ptTextNew);
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
|
|
// Command: 裁剪延伸
|
|
// 支持尺寸自调
|
|
void DimTrimOrExt()
|
|
{
|
|
//wlw mod 2013.5.29 先选尺寸线后裁剪
|
|
Entity entDim;
|
|
RBList mask(RTDXF0, _T("AEC_CHICUNBIAOZHU,DIMENSION"), NULL);
|
|
XPoint ptPick;
|
|
if(entDim.FilterSelect(_T("\n要裁剪或延伸的尺寸线<退出>: "), mask, ptPick) != RTNORM)
|
|
{
|
|
return;
|
|
}
|
|
if(entDim.Is(_T("DIMENSION")))
|
|
{
|
|
Entity entNew;
|
|
if(!ConvertDim(entDim, entNew))
|
|
{
|
|
g_Option::instance().adsout << _T("\n不能转化ACAD尺寸标注对象!");
|
|
return;
|
|
}
|
|
else if(!entDim.Is(_T("AEC_CHICUNBIAOZHU")))
|
|
{
|
|
g_Option::instance().adsout << _T("\n不是线性标注!");
|
|
return;
|
|
}
|
|
entDim=entNew;
|
|
}
|
|
ptPick=GlobalFunc::Ucs2Wcs(ptPick);
|
|
|
|
OPENOBJ_BEGIN(entDim, AcDb::kForRead, AecDbDimension, pDim1);
|
|
if(pDim1 !=NULL && pDim1->IsBind())
|
|
{
|
|
g_Option::instance().adsout << _T("\n尺寸对象已经绑定在其他对象上,不能进行编辑!");
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
pDim1->getClosestPointTo(ptPick,ptPick);
|
|
}
|
|
OPENOBJ_END()
|
|
|
|
entDim.Redraw(3);
|
|
|
|
XPoint ptBase;
|
|
ptPick=GlobalFunc::Wcs2Ucs(ptPick);
|
|
|
|
if(acedGetPoint(ptPick, _T("\n请给出裁剪延伸的基准点"), ptBase) != RTNORM)
|
|
{
|
|
entDim.Redraw(4);
|
|
return;
|
|
}
|
|
entDim.Redraw(4);
|
|
OPENOBJ_BEGIN(entDim, AcDb::kForWrite, AecDbDimension, pDim);
|
|
if(pDim->IsBind())
|
|
{
|
|
g_Option::instance().adsout << _T("\n尺寸对象已经绑定在其他对象上,不能进行编辑!");
|
|
return;
|
|
}
|
|
ptBase=GlobalFunc::Ucs2Wcs(ptBase);
|
|
GeCurveSegment seg=pDim->GetDimCurve();
|
|
XPoint ptBaseOnSeg;
|
|
VERIFY(seg.ProjectToMe(ptBase, ptBaseOnSeg)==RTNORM);
|
|
if((ptBaseOnSeg&seg)!=PR_INSIDE)
|
|
{
|
|
if(pDim->AddSegment(ptBaseOnSeg))
|
|
{
|
|
AcGePoint3dArray ptArray;
|
|
pDim->getStretchPoints(ptArray);
|
|
AcDbIntArray indices;
|
|
if(ptBaseOnSeg.Distance2d(seg.StartPoint())<ptBaseOnSeg.Distance2d(seg.EndPoint()))
|
|
{
|
|
AcGeVector3d vtOffset=ptArray[2]-ptArray[2+1];
|
|
indices.append(3);
|
|
pDim->moveGripPointsAt(indices, vtOffset);
|
|
}
|
|
else
|
|
{
|
|
int numSeg=pDim->GetSegmentNum();
|
|
AcGeVector3d vtOffset=ptArray[2+numSeg]-ptArray[2+numSeg-1];
|
|
indices.append(2+numSeg-1);
|
|
pDim->moveGripPointsAt(indices, vtOffset);
|
|
}
|
|
if(g_Option::instance().g_nDimAdjust)
|
|
pDim->AdjustDim(g_Option::instance().g_nDimAdjust!=2, TRUE, FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pDim->getClosestPointTo(ptBase, ptBase);
|
|
AcGePoint3dArray points;
|
|
AcDbVoidPtrArray curveSegments;
|
|
points.append(ptBase);
|
|
if (pDim->getSplitCurves(points, curveSegments) != Acad::eOk)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (curveSegments.length() == 2)
|
|
{
|
|
pDim->erase();
|
|
|
|
AecDbDimension *pDim1 = (AecDbDimension*)curveSegments[0];
|
|
AecDbDimension *pDim2 = (AecDbDimension*)curveSegments[1];
|
|
|
|
if (pDim1->GetTotalSegValue() > pDim2->GetTotalSegValue() )
|
|
{
|
|
GlobalFunc::AddToModelSpace((AcDbEntity*)curveSegments[0]);
|
|
delete pDim2;
|
|
}
|
|
else
|
|
{
|
|
GlobalFunc::AddToModelSpace((AcDbEntity*)curveSegments[1]);
|
|
delete pDim1;
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
OPENOBJ_END()
|
|
}
|
|
|
|
int CmpPoint(const XPoint *pt1, const XPoint *pt2)
|
|
{
|
|
if(pt1->z < pt2->z)
|
|
return -1;
|
|
else
|
|
return 1;
|
|
}
|
|
// add by lcf 2004/08/11
|
|
class TDimTwoPointArg
|
|
{
|
|
public:
|
|
DListStack<XPoint> m_ptStack;
|
|
void AddDim(AcDbObjectId idDim, XPoint ptNew);
|
|
void RemoveDim(AcDbObjectId idDim, XPoint ptOld);
|
|
void Step(XPoint ptNew);
|
|
BOOL CanUndo();
|
|
void Undo(AcDbObjectId idDim);
|
|
XPoint GetLastPoint();
|
|
};
|
|
|
|
void TDimTwoPointArg::AddDim(AcDbObjectId idDim, XPoint ptNew)
|
|
{
|
|
ptNew = GlobalFunc::Ucs2Wcs(ptNew);
|
|
OPENOBJ_BEGIN(idDim, AcDb::kForWrite, AecDbDimension, pDimNew);
|
|
ASSERT(pDimNew);
|
|
pDimNew->AddSegment(ptNew);
|
|
if(g_Option::instance().g_nDimAdjust)
|
|
pDimNew->AdjustDim(g_Option::instance().g_nDimAdjust!=2);
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
void TDimTwoPointArg::RemoveDim(AcDbObjectId idDim, XPoint ptOld)
|
|
{
|
|
ptOld = GlobalFunc::Ucs2Wcs(ptOld);
|
|
OPENOBJ_BEGIN(idDim, AcDb::kForWrite, AecDbDimension, pDimNew);
|
|
ASSERT(pDimNew);
|
|
pDimNew->FindAndRemoveSegment(ptOld);
|
|
if(g_Option::instance().g_nDimAdjust) pDimNew->AdjustDim(g_Option::instance().g_nDimAdjust!=2);
|
|
OPENOBJ_END();
|
|
}
|
|
void TDimTwoPointArg::Step(XPoint ptNew)
|
|
{
|
|
m_ptStack.Push(ptNew);
|
|
}
|
|
|
|
BOOL TDimTwoPointArg::CanUndo()
|
|
{
|
|
return m_ptStack.GetDepth() > 0;
|
|
}
|
|
|
|
void TDimTwoPointArg::Undo(AcDbObjectId idDim)
|
|
{
|
|
XPoint pt;
|
|
m_ptStack.GetTopData(pt);
|
|
if(CanUndo())
|
|
RemoveDim(idDim, pt);
|
|
m_ptStack.GoBack();
|
|
}
|
|
|
|
XPoint TDimTwoPointArg::GetLastPoint()
|
|
{
|
|
XPoint pt;
|
|
m_ptStack.GetTopData(pt);
|
|
return pt;
|
|
}
|
|
|
|
//wlw 121017 显示两点标注后的jig效果,实现距离墙远近不同标注内容
|
|
class T2PtDimensionJig : public AcEdJig
|
|
{
|
|
public:
|
|
T2PtDimensionJig(AecDbDimension *pDim, const GeCurveSegment& wall,const ADSGePointList& lstPts,
|
|
const ADSGePointList& lstPts1,const ADSGePointList& lstPts2);
|
|
AcEdJig::DragStatus doIt();
|
|
virtual DragStatus sampler();
|
|
virtual Adesk::Boolean update();
|
|
virtual AcDbEntity* entity() const;
|
|
AecDbDimension *m_pDrawEnt;
|
|
AcGePoint3d m_ptDim;
|
|
int m_bFlag; //判断近端还是远端
|
|
BOOL m_bAppend; //用来决定远近端变换的
|
|
GeCurveSegment m_segwall; //用来判断远近端的参考墙基线
|
|
ADSGePointList m_lstPts; //所有墙的投影点
|
|
ADSGePointList m_lstPts1; //近端门窗的投影点
|
|
ADSGePointList m_lstPts2; //远端门窗的投影点
|
|
};
|
|
|
|
T2PtDimensionJig::T2PtDimensionJig(AecDbDimension *pDim, const GeCurveSegment& wall,const ADSGePointList& lstPts,
|
|
const ADSGePointList& lstPts1,const ADSGePointList& lstPts2)
|
|
{
|
|
m_pDrawEnt = pDim;
|
|
m_bFlag = 1;
|
|
m_bAppend = FALSE;
|
|
m_segwall = wall;
|
|
m_lstPts.copyFrom(lstPts);
|
|
m_lstPts1.copyFrom(lstPts1);
|
|
m_lstPts2.copyFrom(lstPts2);
|
|
|
|
int nLen = m_lstPts.Length();
|
|
for(int n = 0; n < nLen; n++)
|
|
{
|
|
m_pDrawEnt->AddSegment(*m_lstPts[n]);
|
|
}
|
|
//初始值为墙近端的门窗标注
|
|
nLen = m_lstPts1.Length();
|
|
for(n = 0; n < nLen; n++)
|
|
{
|
|
m_pDrawEnt->AddSegment(*m_lstPts1[n]);
|
|
}
|
|
m_pDrawEnt->SetFixLinePos(m_segwall.StartPoint());
|
|
|
|
}
|
|
|
|
AcEdJig::DragStatus T2PtDimensionJig::doIt()
|
|
{
|
|
setDispPrompt(_T("\n选择标注位置点"));
|
|
return drag();
|
|
}
|
|
|
|
AcEdJig::DragStatus T2PtDimensionJig::sampler()
|
|
{
|
|
setUserInputControls((UserInputControls)
|
|
(AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted));
|
|
|
|
XPoint ptCursor;
|
|
DragStatus stat = acquirePoint(ptCursor);
|
|
if(stat == AcEdJig::kNormal)
|
|
{
|
|
if (ptCursor.Distance2d(m_ptDim) > g_Option::instance()._DIST_SNAP)
|
|
m_ptDim = ptCursor;
|
|
else
|
|
stat = AcEdJig::kNoChange;
|
|
}
|
|
return stat;
|
|
}
|
|
|
|
Adesk::Boolean T2PtDimensionJig::update()
|
|
{
|
|
using namespace GlobalFunc;
|
|
ADSGePoint3d ptProj;
|
|
m_segwall.ProjectToMe(m_ptDim, ptProj);
|
|
int nLen = 0;
|
|
int nNum = 0, n = 0;
|
|
ADSGePoint3d ptSide,ptSide1;
|
|
if (m_bFlag == 1)
|
|
{//当前标注在近端
|
|
if (ptProj.Distance2d(m_segwall.StartPoint()) > ptProj.Distance2d(m_segwall.EndPoint()))
|
|
{
|
|
m_bFlag = 2;
|
|
m_bAppend = TRUE;
|
|
}
|
|
}
|
|
else if (m_bFlag == 2)
|
|
{//当前标注在远端
|
|
if (ptProj.Distance2d(m_segwall.StartPoint()) < ptProj.Distance2d(m_segwall.EndPoint()))
|
|
{
|
|
m_bFlag = 1;
|
|
m_bAppend = TRUE;
|
|
}
|
|
}
|
|
|
|
if (m_bAppend)
|
|
{
|
|
m_bAppend = FALSE;
|
|
double dr = m_segwall.Direction(m_ptDim);
|
|
int ncount = m_pDrawEnt->GetSegmentNum();
|
|
while(m_pDrawEnt->GetSegmentNum() > 0)
|
|
m_pDrawEnt->RemoveSegment(0);
|
|
|
|
m_pDrawEnt->SetLocation(*m_lstPts[0]);
|
|
|
|
nLen = m_lstPts.Length();
|
|
for(n = 0; n < nLen; n++)
|
|
{
|
|
m_pDrawEnt->AddSegment(*m_lstPts[n]);
|
|
}
|
|
if (m_bFlag == 2)
|
|
{
|
|
nLen = m_lstPts2.Length();
|
|
ptSide = m_segwall.EndPoint();
|
|
for(n = 0; n < nLen; n++)
|
|
{
|
|
m_pDrawEnt->AddSegment(*m_lstPts2[n]);
|
|
}
|
|
}
|
|
else if (m_bFlag == 1)
|
|
{
|
|
nLen = m_lstPts1.Length();
|
|
ptSide = m_segwall.StartPoint();
|
|
for(n = 0; n < nLen; n++)
|
|
{
|
|
m_pDrawEnt->AddSegment(*m_lstPts1[n]);
|
|
}
|
|
}
|
|
ADSGePoint3d ptEnd=*m_lstPts[m_lstPts.Length()-1],ptStart=*m_lstPts[0];
|
|
XVector3D vt=ptEnd-ptStart;
|
|
XVector3D vtSeg(m_segwall.EndPoint().x-m_segwall.StartPoint().x,m_segwall.EndPoint().y-m_segwall.StartPoint().y);
|
|
if((vt*vtSeg).z<0)
|
|
dr+=PI/2;
|
|
else
|
|
dr-=PI/2;
|
|
m_pDrawEnt->SetFixLinePos(ptSide);
|
|
}
|
|
|
|
GeCurveSegment seg = m_pDrawEnt->GetDimCurve();
|
|
seg.ProjectToMe(m_ptDim, ptProj);
|
|
double nDistMove = ptProj.Distance2d(m_ptDim);
|
|
int nSideLoc=seg.OnWhichSide(m_pDrawEnt->GetLocation());
|
|
int nSide=seg.OnWhichSide(m_ptDim);
|
|
double nDist2Dim = m_pDrawEnt->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(m_pDrawEnt->IsAngular())
|
|
{ //弧墙有错,不知道原因
|
|
nDist2Dim += nDistMove;
|
|
double nDistRad= m_pDrawEnt->GetDimRadius();
|
|
//seg.GetArc().center.Distance(m_ptDim);
|
|
nDistRad -= nDistMove;
|
|
if(nDistRad>g_Option::instance()._DIST_SNAP)
|
|
{
|
|
m_pDrawEnt->SetDimRadius(nDistRad);
|
|
m_pDrawEnt->SetDist2DimLine(nDist2Dim, FALSE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nDist2Dim += nDistMove;
|
|
m_pDrawEnt->SetDist2DimLine(nDist2Dim, FALSE);
|
|
}
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
AcDbEntity* T2PtDimensionJig::entity() const
|
|
{
|
|
return m_pDrawEnt;
|
|
}
|
|
|
|
//wlw 130529 显示两点标注后的双线标注jig效果,实现距离墙远近不同标注内容
|
|
class T2PtDimensionJig2 : public AcEdJig
|
|
{
|
|
public:
|
|
T2PtDimensionJig2(AecDbDimension *pDim, const GeCurveSegment& wall,const ADSGePointList& lstPts,
|
|
const ADSGePointList& lstPts1,const ADSGePointList& lstPts2, AecDbDimension *pDim2);
|
|
AcEdJig::DragStatus doIt();
|
|
virtual DragStatus sampler();
|
|
virtual Adesk::Boolean update();
|
|
virtual AcDbEntity* entity() const;
|
|
//AecDbDimension *m_pDrawEnt;
|
|
AcGePoint3d m_ptDim;
|
|
int m_bFlag; //判断近端还是远端
|
|
BOOL m_bAppend; //用来决定远近端变换的
|
|
GeCurveSegment m_segwall; //用来判断远近端的参考墙基线
|
|
ADSGePointList m_lstPts; //所有墙的投影点
|
|
ADSGePointList m_lstPts1; //近端门窗的投影点
|
|
ADSGePointList m_lstPts2; //远端门窗的投影点
|
|
|
|
TMulDimEntity1 m_pDim;//标注
|
|
|
|
};
|
|
|
|
T2PtDimensionJig2::T2PtDimensionJig2(AecDbDimension *pDim, const GeCurveSegment& wall,const ADSGePointList& lstPts,
|
|
const ADSGePointList& lstPts1,const ADSGePointList& lstPts2,AecDbDimension *pDim2)
|
|
{
|
|
m_pDim.m_pDrawEnt = pDim;
|
|
m_pDim.m_pDrawEnt2 = pDim2;
|
|
m_bFlag = 1;
|
|
m_bAppend = FALSE;
|
|
m_segwall = wall;
|
|
m_lstPts.copyFrom(lstPts);
|
|
m_lstPts1.copyFrom(lstPts1);
|
|
m_lstPts2.copyFrom(lstPts2);
|
|
|
|
int nLen = m_lstPts.Length();
|
|
for(int n = 0; n < nLen; n++)
|
|
{
|
|
m_pDim.m_pDrawEnt->AddSegment(*m_lstPts[n]);
|
|
}
|
|
//初始值为墙近端的门窗标注
|
|
nLen = m_lstPts1.Length();
|
|
for(n = 0; n < nLen; n++)
|
|
{
|
|
m_pDim.m_pDrawEnt->AddSegment(*m_lstPts1[n]);
|
|
}
|
|
m_pDim.m_pDrawEnt->SetFixLinePos(m_segwall.StartPoint());
|
|
|
|
AcGePoint3d pts,pte;
|
|
m_pDim.m_pDrawEnt->getStartPoint(pts);
|
|
m_pDim.m_pDrawEnt->getEndPoint(pte);
|
|
|
|
m_pDim.m_pDrawEnt2->SetLocation(pts);
|
|
|
|
m_pDim.m_pDrawEnt2->AddSegment(pts);
|
|
m_pDim.m_pDrawEnt2->AppendSegment(pte.distanceTo(pts));
|
|
|
|
m_pDim.m_pDrawEnt2->SetFixLinePos(m_segwall.StartPoint());
|
|
|
|
|
|
}
|
|
|
|
AcEdJig::DragStatus T2PtDimensionJig2::doIt()
|
|
{
|
|
setDispPrompt(_T("\n选择标注位置点"));
|
|
return drag();
|
|
}
|
|
|
|
AcEdJig::DragStatus T2PtDimensionJig2::sampler()
|
|
{
|
|
setUserInputControls((UserInputControls)
|
|
(AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted));
|
|
|
|
XPoint ptCursor;
|
|
DragStatus stat = acquirePoint(ptCursor);
|
|
if(stat == AcEdJig::kNormal)
|
|
{
|
|
if (ptCursor.Distance2d(m_ptDim) > g_Option::instance()._DIST_SNAP)
|
|
m_ptDim = ptCursor;
|
|
else
|
|
stat = AcEdJig::kNoChange;
|
|
}
|
|
return stat;
|
|
}
|
|
|
|
Adesk::Boolean T2PtDimensionJig2::update()
|
|
{
|
|
using namespace GlobalFunc;
|
|
ADSGePoint3d ptProj;
|
|
m_segwall.ProjectToMe(m_ptDim, ptProj);
|
|
int nLen = 0;
|
|
int nNum = 0, n = 0;
|
|
ADSGePoint3d ptSide,ptSide1;
|
|
if (m_bFlag == 1)
|
|
{//当前标注在近端
|
|
if (ptProj.Distance2d(m_segwall.StartPoint()) > ptProj.Distance2d(m_segwall.EndPoint()))
|
|
{
|
|
m_bFlag = 2;
|
|
m_bAppend = TRUE;
|
|
}
|
|
}
|
|
else if (m_bFlag == 2)
|
|
{//当前标注在远端
|
|
if (ptProj.Distance2d(m_segwall.StartPoint()) < ptProj.Distance2d(m_segwall.EndPoint()))
|
|
{
|
|
m_bFlag = 1;
|
|
m_bAppend = TRUE;
|
|
}
|
|
}
|
|
|
|
if (m_bAppend)
|
|
{
|
|
m_bAppend = FALSE;
|
|
double dr = m_segwall.Direction(m_ptDim);
|
|
int ncount = m_pDim.m_pDrawEnt->GetSegmentNum();
|
|
while(m_pDim.m_pDrawEnt->GetSegmentNum() > 0)
|
|
m_pDim.m_pDrawEnt->RemoveSegment(0);
|
|
|
|
while(m_pDim.m_pDrawEnt2->GetSegmentNum() > 0)
|
|
m_pDim.m_pDrawEnt2->RemoveSegment(0);
|
|
|
|
m_pDim.m_pDrawEnt->SetLocation(*m_lstPts[0]);
|
|
|
|
nLen = m_lstPts.Length();
|
|
for(n = 0; n < nLen; n++)
|
|
{
|
|
m_pDim.m_pDrawEnt->AddSegment(*m_lstPts[n]);
|
|
}
|
|
if (m_bFlag == 2)
|
|
{
|
|
nLen = m_lstPts2.Length();
|
|
ptSide = m_segwall.EndPoint();
|
|
for(n = 0; n < nLen; n++)
|
|
{
|
|
m_pDim.m_pDrawEnt->AddSegment(*m_lstPts2[n]);
|
|
}
|
|
}
|
|
else if (m_bFlag == 1)
|
|
{
|
|
nLen = m_lstPts1.Length();
|
|
ptSide = m_segwall.StartPoint();
|
|
for(n = 0; n < nLen; n++)
|
|
{
|
|
m_pDim.m_pDrawEnt->AddSegment(*m_lstPts1[n]);
|
|
}
|
|
}
|
|
ADSGePoint3d ptEnd=*m_lstPts[m_lstPts.Length()-1],ptStart=*m_lstPts[0];
|
|
XVector3D vt=ptEnd-ptStart;
|
|
XVector3D vtSeg(m_segwall.EndPoint().x-m_segwall.StartPoint().x,m_segwall.EndPoint().y-m_segwall.StartPoint().y);
|
|
if((vt*vtSeg).z<0)
|
|
dr+=PI/2;
|
|
else
|
|
dr-=PI/2;
|
|
|
|
m_pDim.m_pDrawEnt->SetFixLinePos(ptSide);
|
|
|
|
m_pDim.m_pDrawEnt->getStartPoint(ptStart);
|
|
m_pDim.m_pDrawEnt->getEndPoint(ptEnd);
|
|
m_pDim.m_pDrawEnt2->SetLocation(ptStart);
|
|
m_pDim.m_pDrawEnt2->AddSegment(ptStart);
|
|
m_pDim.m_pDrawEnt2->AppendSegment(ptEnd.Distance2d(ptStart));
|
|
m_pDim.m_pDrawEnt2->SetFixLinePos(ptSide);
|
|
|
|
}
|
|
|
|
XPoint ptOnSeg;
|
|
GeCurveSegment seg;
|
|
seg = m_pDim.m_pDrawEnt->GetDimCurve();
|
|
if(seg.ProjectToMe(m_ptDim, ptOnSeg) == RTNORM)
|
|
{
|
|
double nDistMove = ptOnSeg.Distance2d(m_ptDim);
|
|
int nSideLoc = seg.OnWhichSide(m_pDim.m_pDrawEnt->GetLocation());
|
|
int nSide = seg.OnWhichSide(m_ptDim);
|
|
double nDist2Dim = m_pDim.m_pDrawEnt->GetDist2DimLine(FALSE);
|
|
double nFactor = nDist2Dim/fabs(nDist2Dim);
|
|
if(fabs(nDist2Dim) > 1.0E-6)
|
|
{
|
|
if(nSide != nSideLoc)
|
|
{
|
|
nDistMove *= nFactor;
|
|
}
|
|
else
|
|
{
|
|
nDistMove *= -nFactor;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(nSideLoc == OFFSET_LEFT)
|
|
nDistMove *= -1;
|
|
}
|
|
nDist2Dim += nDistMove;
|
|
m_pDim.m_pDrawEnt->SetDist2DimLine(nDist2Dim, FALSE);
|
|
double ddis = m_pDim.m_pDrawEnt->GetPScale() * 8;
|
|
if(nDist2Dim >= 0)
|
|
nDist2Dim += ddis;
|
|
else
|
|
nDist2Dim -= ddis;
|
|
m_pDim.m_pDrawEnt2->SetDist2DimLine(nDist2Dim, FALSE);
|
|
|
|
}
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
AcDbEntity* T2PtDimensionJig2::entity() const
|
|
{
|
|
return (AcDbEntity*)&m_pDim;
|
|
}
|
|
|
|
class TLeaderJig : public AcEdJig
|
|
{
|
|
public:
|
|
TLeaderJig(AcGePoint3d pt)
|
|
{
|
|
|
|
m_pEnt = new AcDbLine;
|
|
m_pt = pt;
|
|
m_pEnt->setStartPoint(m_pt);
|
|
}
|
|
~TLeaderJig(){delete m_pEnt;}
|
|
int doIt()
|
|
{
|
|
setDispPrompt(_T("\n选择标注位置点"));
|
|
return drag();
|
|
}
|
|
virtual DragStatus sampler()
|
|
{
|
|
setSpecialCursorType(AcEdJig::kNoSpecialCursor);
|
|
setUserInputControls((UserInputControls)
|
|
(AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted));
|
|
|
|
AcGePoint3d ptCursor;
|
|
return acquirePoint(ptCursor, m_pt);
|
|
}
|
|
|
|
virtual Adesk::Boolean update(){return Adesk::kTrue;}
|
|
virtual AcDbEntity* entity() const{return (AcDbEntity*)m_pEnt;}
|
|
protected:
|
|
AcGePoint3d m_pt;
|
|
AcGePoint3d m_ptE;
|
|
AcDbLine *m_pEnt;
|
|
};
|
|
|
|
Adesk::Boolean isParallelToEnt(EntitySet ent1,EntitySet ent2)
|
|
{
|
|
AcGeTol tol;
|
|
tol.setEqualPoint(0.1);
|
|
tol.setEqualVector(0.1);
|
|
AcGePoint3d pt1s,pt1e,pt2s,pt2e;
|
|
OPENOBJ_BEGIN(ent1, AcDb::kForRead, AcDbCurve, pent1)
|
|
if (pent1 != NULL)
|
|
{
|
|
pent1->getEndPoint(pt1e);
|
|
pent1->getStartPoint(pt1s);
|
|
}
|
|
OPENOBJ_END()
|
|
|
|
OPENOBJ_BEGIN(ent2, AcDb::kForRead, AcDbCurve, pent2)
|
|
if (pent2 != NULL)
|
|
{
|
|
pent2->getEndPoint(pt2e);
|
|
pent2->getStartPoint(pt2s);
|
|
}
|
|
OPENOBJ_END()
|
|
|
|
AcGeVector3d vt1 = pt1s - pt1e,vt2 = pt2s - pt2e;
|
|
return vt1.isParallelTo(vt2, tol);
|
|
}
|
|
|
|
// Command: 尺寸自调
|
|
void DimAdjust()
|
|
{
|
|
RBList mask(RTDXF0, _T("AEC_CHICUNBIAOZHU"), NULL);
|
|
PickEntSet ss(SS_FREE);
|
|
if(GlobalFunc::SelectEntities(_T("\n请选择上华尺寸标注: "), ss, mask)==RTNORM) {
|
|
long lCount=ss.Length();
|
|
for(long i=0L; i<lCount; i++) {
|
|
Entity ent=ss[i];
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecDbDimension, pDim);
|
|
if(pDim) {
|
|
pDim->ResetTextPos();
|
|
pDim->AdjustDim(g_Option::instance().g_nDimAdjust!=2, TRUE);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
}
|
|
|
|
void BreakDim()
|
|
{
|
|
//wlw mod 2013.5.29 引线位置太乱
|
|
RBList mask(RTDXF0, _T("DIMENSION,AEC_CHICUNBIAOZHU"), NULL);
|
|
Entity entMaster;
|
|
ADSGePoint3d ptPick;
|
|
if(GlobalFunc::SelectEntity(_T("\n请选择尺寸标注<退出>: "), entMaster, mask) != RTNORM)
|
|
return;
|
|
|
|
Entity entDim;
|
|
if(entMaster.Is(_T("DIMENSION"))) {
|
|
if(!ConvertDim(entMaster, entDim)) {
|
|
g_Option::instance().adsout << _T("\n不能转化ACAD尺寸标注对象!");
|
|
return;
|
|
} else if(!entDim.Is(_T("AEC_CHICUNBIAOZHU"))) {
|
|
g_Option::instance().adsout << _T("\n不是线性标注!");
|
|
return;
|
|
}
|
|
} else {
|
|
entDim=entMaster;
|
|
}
|
|
|
|
OPENOBJ_BEGIN(entDim, AcDb::kForRead, AecDbDimension, pDim);
|
|
if(pDim!=NULL)
|
|
{
|
|
XPoint ptBase;
|
|
int nSeg = pDim->HitTestOnText(ptPick);
|
|
GePoly2D poly;
|
|
pDim->GetPolySegOnDimLine(poly);
|
|
int nCount = poly.Length();
|
|
ptBase = *poly[nSeg];
|
|
int nRet;
|
|
XPoint ptAdd;
|
|
XString szPrompt;
|
|
XPointList lstAddPoint, lstBasePoint;
|
|
lstBasePoint.Append(new XPoint(ptBase));
|
|
while(1)
|
|
{
|
|
pDim->GetPolySegOnDimLine(poly);
|
|
int nCount = poly.Length();
|
|
int nLen = lstAddPoint.Length();
|
|
if(nLen == 0)
|
|
_stprintf(szPrompt, _T("\n点取待增补的标注点的位置或 [参考点(R)]<退出>:"));
|
|
else
|
|
_stprintf(szPrompt, _T("\n点取待增补的标注点的位置或 [参考点(R)/撤消上一标注点(U)]<退出>:"));
|
|
|
|
INITGET_BEG(0, _T("U R"));
|
|
nRet = acedGetPoint(ptBase, szPrompt, ptAdd);
|
|
INITGET_END();
|
|
if(nRet == RTNORM)
|
|
{
|
|
ptAdd = GlobalFunc::Ucs2Wcs(ptAdd);
|
|
ptBase = ptAdd;
|
|
if(pDim->upgradeOpen() == Acad::eOk)
|
|
{
|
|
if(!pDim->AddSegment(ptAdd))
|
|
g_Option::instance().adsout << _T("\n点取位置不合适!");
|
|
else
|
|
{
|
|
lstAddPoint.Append(new XPoint(ptAdd));
|
|
lstBasePoint.Append(new XPoint(ptBase));
|
|
if(g_Option::instance().g_nDimAdjust)//add by whl on 050530
|
|
pDim->AdjustDim(g_Option::instance().g_nDimAdjust!=2);
|
|
}
|
|
pDim->downgradeOpen();
|
|
}
|
|
GeCurveSegment seg(*poly[0],*poly[nCount-1],0);
|
|
seg.ProjectToMe(ptBase,ptBase);
|
|
}
|
|
else if(nRet == RTKWORD)
|
|
{
|
|
XString sKey;
|
|
acedGetInput(sKey);
|
|
if(sKey[0] == _T('R'))
|
|
acedGetPoint(NULL, _T("\n参考点:"), ptBase);
|
|
else if(sKey[0] == _T('U'))
|
|
{
|
|
if(pDim->upgradeOpen() == Acad::eOk)
|
|
{
|
|
if(nLen > 0)
|
|
{
|
|
ptAdd = *lstAddPoint.Tail();
|
|
lstAddPoint.Remove(nLen-1);
|
|
pDim->HitTestOnPoint(ptAdd);
|
|
pDim->FindAndRemoveSegment(ptAdd);
|
|
lstBasePoint.Remove(nLen);
|
|
ptBase = *lstBasePoint.Tail();
|
|
}
|
|
pDim->downgradeOpen();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
OPENOBJ_END()
|
|
}
|
|
|
|
int EditDim(AcDbObjectId id)
|
|
{
|
|
OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbDimension, pDim);
|
|
if(pDim!=NULL)
|
|
{
|
|
XPoint ptBase=GlobalFunc::Wcs2Ucs(pDim->GetLocation());
|
|
int nRet;
|
|
XPoint ptAdd;
|
|
XString szPrompt;
|
|
XPointList lstAddPoint, lstBasePoint;
|
|
lstBasePoint.Append(new XPoint(ptBase));
|
|
while(1)
|
|
{
|
|
int nLen = lstAddPoint.Length();
|
|
if(nLen == 0)
|
|
_stprintf(szPrompt, _T("\n点取待增补的标注点的位置或 [参考点(R)]<退出>:"));
|
|
else
|
|
_stprintf(szPrompt, _T("\n点取待增补的标注点的位置或 [参考点(R)/撤消上一标注点(U)]<退出>:"));
|
|
|
|
INITGET_BEG(0, _T("U R"));
|
|
nRet = acedGetPoint(ptBase, szPrompt, ptAdd);
|
|
INITGET_END();
|
|
if(nRet == RTNORM)
|
|
{
|
|
ptBase = ptAdd;
|
|
ptAdd = GlobalFunc::Ucs2Wcs(ptAdd);
|
|
if(pDim->upgradeOpen() == Acad::eOk)
|
|
{
|
|
if(!pDim->AddSegment(ptAdd))
|
|
g_Option::instance().adsout << _T("\n点取位置不合适!");
|
|
else
|
|
{
|
|
lstAddPoint.Append(new XPoint(ptAdd));
|
|
lstBasePoint.Append(new XPoint(ptBase));
|
|
if(g_Option::instance().g_nDimAdjust)//add by whl on 050530
|
|
pDim->AdjustDim(g_Option::instance().g_nDimAdjust!=2);
|
|
}
|
|
pDim->downgradeOpen();
|
|
}
|
|
}
|
|
else if(nRet == RTKWORD)
|
|
{
|
|
XString sKey;
|
|
acedGetInput(sKey);
|
|
if(sKey[0] == _T('R'))
|
|
acedGetPoint(NULL, _T("\n参考点:"), ptBase);
|
|
else if(sKey[0] == _T('U'))
|
|
{
|
|
if(pDim->upgradeOpen() == Acad::eOk)
|
|
{
|
|
if(nLen > 0)
|
|
{
|
|
ptAdd = *lstAddPoint.Tail();
|
|
lstAddPoint.Remove(nLen-1);
|
|
pDim->HitTestOnPoint(ptAdd);
|
|
pDim->FindAndRemoveSegment(ptAdd);
|
|
lstBasePoint.Remove(nLen);
|
|
ptBase = *lstBasePoint.Tail();
|
|
}
|
|
pDim->downgradeOpen();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
return RTNORM;
|
|
}
|
|
// Command: 合并尺寸
|
|
// create by lcf 2004/10/25
|
|
class TEntityPoint
|
|
{
|
|
public:
|
|
Entity ent;
|
|
XPoint ptPick;
|
|
};
|
|
|
|
//可以框选合并尺寸wlw130929mod
|
|
void ConbineDim()
|
|
{
|
|
XPushVar<int> vOsMode(_T("OSMODE"), 0);
|
|
Entity ent;
|
|
XPoint ptPick;
|
|
RBList mask(RTDXF0, _T("AEC_CHICUNBIAOZHU"), NULL);
|
|
int nRet;
|
|
DList<TEntityPoint> lstEntPt;
|
|
while(1)
|
|
{
|
|
int nLen = lstEntPt.Length();
|
|
XPoint ptStart, ptEnd;
|
|
Entity ent;
|
|
if(nLen == 0)
|
|
nRet = acedGetPoint(NULL, _T("\n请框选合并区间中的尺寸界线箭头<退出>: "), ptStart);
|
|
else
|
|
{
|
|
INITGET_BEG(0, _T("U"));
|
|
nRet = acedGetPoint(NULL, _T("\n请框选合并区间中的尺寸界线箭头或 [撤消(U)]<退出>: "), ptStart);
|
|
INITGET_END();
|
|
}
|
|
|
|
if(nRet == RTNORM)
|
|
{
|
|
if(GlobalFunc::GetCornerPoint(ptStart,NULL, ptEnd) != RTNORM)
|
|
continue;
|
|
|
|
XPoint ptLowLeft, ptLowRight, ptUpRight, ptUpLeft;
|
|
if(ptStart.x > ptEnd.x)
|
|
{
|
|
ptLowLeft.x = ptEnd.x;
|
|
ptUpLeft.x = ptEnd.x;
|
|
ptLowRight.x = ptStart.x;
|
|
ptUpRight.x = ptStart.x;
|
|
}
|
|
else
|
|
{
|
|
ptLowLeft.x = ptStart.x;
|
|
ptUpLeft.x = ptStart.x;
|
|
ptLowRight.x = ptEnd.x;
|
|
ptUpRight.x = ptEnd.x;
|
|
}
|
|
if(ptStart.y > ptEnd.y)
|
|
{
|
|
ptLowLeft.y = ptEnd.y;
|
|
ptLowRight.y = ptEnd.y;
|
|
ptUpLeft.y = ptStart.y;
|
|
ptUpRight.y = ptStart.y;
|
|
}
|
|
else
|
|
{
|
|
ptLowLeft.y = ptStart.y;
|
|
ptLowRight.y = ptStart.y;
|
|
ptUpLeft.y = ptEnd.y;
|
|
ptUpRight.y = ptEnd.y;
|
|
}
|
|
|
|
XPoly2D poly(1);
|
|
poly.AppendNode(ptLowLeft);
|
|
poly.AppendNode(ptLowRight);
|
|
poly.AppendNode(ptUpRight);
|
|
poly.AppendNode(ptUpLeft);
|
|
|
|
RBList rbRegion = poly.Polygon();
|
|
PickSet ss(SS_FREE);
|
|
if(ss.Get(_T("CP"), rbRegion, NULL, mask) != RTNORM)
|
|
continue;
|
|
|
|
poly.TransUCS(RBGroups(1), RBGroups(0));
|
|
|
|
long num = ss.Length();
|
|
for(long i=0;i<num;i++)
|
|
{
|
|
ent = ss[i];
|
|
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecDbDimension, pDim);
|
|
if(pDim)
|
|
{
|
|
if(pDim->IsBind())
|
|
{
|
|
g_Option::instance().adsout << _T("\n此尺寸标注绑定在其他对象上, 因此不能编辑!");
|
|
return;
|
|
}
|
|
|
|
XPoly2D polyLimit;
|
|
pDim->GetPolySegOnDimLine(polyLimit);
|
|
|
|
for(int j = 1; j < polyLimit.Length() - 1; j++)
|
|
{
|
|
ptPick = *polyLimit[j];
|
|
int rtInside = ptPick & poly;
|
|
if(rtInside != PR_OUTSIDE)
|
|
{
|
|
TEntityPoint *pEntPt = new TEntityPoint;
|
|
pEntPt->ent = ent;
|
|
pEntPt->ptPick = ptPick;
|
|
lstEntPt.Append(pEntPt);
|
|
pDim->FindAndRemoveSegment(ptPick);
|
|
}
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
else if(nRet == RTKWORD)
|
|
{
|
|
TEntityPoint *pEntPt = lstEntPt.Tail();
|
|
if(pEntPt == NULL)
|
|
{
|
|
acutPrintf(_T("\n不能撤销!"));
|
|
continue;
|
|
}
|
|
|
|
ent = pEntPt->ent;
|
|
ptPick = pEntPt->ptPick;
|
|
lstEntPt.Remove(nLen-1);
|
|
|
|
OPENOBJ_BEGIN(ent, AcDb::kForWrite, AecDbDimension, pDim);
|
|
if(pDim)
|
|
{
|
|
if(pDim->IsBind())
|
|
{
|
|
g_Option::instance().adsout << _T("\n此尺寸标注绑定在其他对象上, 因此不能编辑!");
|
|
return;
|
|
}
|
|
pDim->AddSegment(ptPick);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
//拆分区间WLW ADD 13.06.07 仅仅限于一个区间内的自由拆分
|
|
void DivideDimSeg()
|
|
{
|
|
AcAxDocLock doclock;
|
|
EntitySet ent1;
|
|
XPoint ptPick;
|
|
PickEntSet setshow(SS_FREE);
|
|
AcDbObjectId idshow;
|
|
RBList mask(RTDXF0, _T("AEC_CHICUNBIAOZHU"), NULL);
|
|
if (GlobalFunc::SelectEntity(_T("\n选择待拆分的尺寸区间<退出>: "), ent1, ptPick, mask) != RTNORM)
|
|
{
|
|
return;
|
|
}
|
|
GePoly2D polyLimit2(1);
|
|
OPENOBJ_BEGIN(ent1, AcDb::kForRead, AecDbDimension, pDim);
|
|
if(pDim == NULL)
|
|
{
|
|
return;
|
|
}
|
|
if(pDim->IsBind())
|
|
{
|
|
g_Option::instance().adsout << _T("\n此尺寸标注绑定在其他对象上, 因此不能编辑!");
|
|
return;
|
|
}
|
|
|
|
ptPick = GlobalFunc::Ucs2Wcs(ptPick);
|
|
XPoint ptBase;
|
|
int nSeg = -1;
|
|
SubText* psubtext = pDim->HitTestText(ptPick);
|
|
if (psubtext == NULL)
|
|
{
|
|
nSeg = pDim->HitTestOnDimSeg(ptPick);
|
|
}
|
|
else
|
|
{
|
|
nSeg = psubtext->GetIndex();
|
|
delete psubtext;
|
|
psubtext = NULL;
|
|
}
|
|
|
|
GePoly2D poly;
|
|
pDim->GetPolySegOnDimLine(poly);
|
|
|
|
AcDbLine *pln = new AcDbLine(*poly[nSeg],*poly[nSeg+1]);
|
|
pln->setColorIndex(1);
|
|
idshow = GlobalFunc::AddToModelSpace(pln);
|
|
GeCurveSegment segFirst(*poly[nSeg],*poly[nSeg+1],0);
|
|
|
|
int nCount = poly.Length();
|
|
ptBase = *poly[nSeg];
|
|
int nRet;
|
|
XPoint ptAdd;
|
|
XString szPrompt;
|
|
XPointList lstAddPoint, lstBasePoint;
|
|
lstBasePoint.Append(new XPoint(ptBase));
|
|
while(1)
|
|
{
|
|
pDim->GetPolySegOnDimLine(poly);
|
|
int nCount = poly.Length();
|
|
int nLen = lstAddPoint.Length();
|
|
GeCurveSegment seg(*poly[0],*poly[nCount-1],0);
|
|
if(nLen == 0)
|
|
_stprintf(szPrompt, _T("\n点取待增补的标注点的位置<退出>:"));
|
|
else
|
|
_stprintf(szPrompt, _T("\n点取待增补的标注点的位置或[撤消(U)]<退出>:"));
|
|
|
|
INITGET_BEG(0, _T("U"));
|
|
ptBase = GlobalFunc::Wcs2Ucs(ptBase);
|
|
nRet = acedGetPoint(ptBase, szPrompt, ptAdd);
|
|
INITGET_END();
|
|
if(nRet == RTNORM)
|
|
{
|
|
ptAdd = GlobalFunc::Ucs2Wcs(ptAdd);
|
|
|
|
segFirst.ProjectToMe(ptAdd,ptAdd);
|
|
if ((ptAdd & segFirst) != PR_INSIDE)
|
|
{
|
|
g_Option::instance().adsout << _T("\n请点取区域内部!");
|
|
continue;
|
|
}
|
|
ptBase = ptAdd;
|
|
if(pDim->upgradeOpen() == Acad::eOk)
|
|
{
|
|
if(!pDim->AddSegment(ptAdd))
|
|
g_Option::instance().adsout << _T("\n点取位置不合适!");
|
|
else
|
|
{
|
|
lstAddPoint.Append(new XPoint(ptAdd));
|
|
lstBasePoint.Append(new XPoint(ptBase));
|
|
if(g_Option::instance().g_nDimAdjust)//add by whl on 050530
|
|
pDim->AdjustDim(g_Option::instance().g_nDimAdjust!=2);
|
|
}
|
|
pDim->downgradeOpen();
|
|
}
|
|
GeCurveSegment seg(*poly[0],*poly[nCount-1],0);
|
|
seg.ProjectToMe(ptBase,ptBase);
|
|
}
|
|
else if(nRet == RTKWORD)
|
|
{
|
|
XString sKey;
|
|
acedGetInput(sKey);
|
|
if(sKey[0] == _T('U'))
|
|
{
|
|
if(pDim->upgradeOpen() == Acad::eOk)
|
|
{
|
|
if(nLen > 0)
|
|
{
|
|
ptAdd = *lstAddPoint.Tail();
|
|
lstAddPoint.Remove(nLen-1);
|
|
pDim->HitTestOnPoint(ptAdd);
|
|
pDim->FindAndRemoveSegment(ptAdd);
|
|
lstBasePoint.Remove(nLen);
|
|
ptBase = *lstBasePoint.Tail();
|
|
if(g_Option::instance().g_nDimAdjust)//add by whl on 050530
|
|
pDim->AdjustDim(g_Option::instance().g_nDimAdjust!=2);
|
|
seg.ProjectToMe(ptBase,ptBase);
|
|
}
|
|
pDim->downgradeOpen();
|
|
}
|
|
}
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
OPENOBJ_END()
|
|
OPENOBJ_BEGIN(idshow, AcDb::kForWrite, AcDbEntity, pent)
|
|
if (pent)
|
|
{
|
|
pent->erase();
|
|
}
|
|
OPENOBJ_END()
|
|
}
|
|
// Command: 快速标注
|
|
// Create By LCF 2004/10/27
|
|
/////////////////////////////////////////////////////
|
|
int CmpPointByX(const XPoint *pt1, const XPoint *pt2)
|
|
{
|
|
if(pt1->x< pt2->x)
|
|
return -1;
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
int CmpPointByY(const XPoint *pt1, const XPoint *pt2)
|
|
{
|
|
if(pt1->y < pt2->y)
|
|
return -1;
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
////////////////////////////////////////////////////
|
|
class TQuickDimensionJig : public AcEdJig
|
|
{
|
|
public:
|
|
TQuickDimensionJig();
|
|
virtual ~TQuickDimensionJig();
|
|
int doIt();
|
|
virtual DragStatus sampler();
|
|
virtual Adesk::Boolean update();
|
|
virtual AcDbEntity *entity() const;
|
|
|
|
const TCHAR *m_pszKeyword; //关键字
|
|
// AecDbDimension *m_pDrawEnt; //临时实体,
|
|
// AecDbDimension *m_pDrawEntALL;
|
|
AecDbDimension *m_pDrawEntX; //临时实体,
|
|
AecDbDimension *m_pDrawEntY; //临时实体,
|
|
double m_dFactor;
|
|
int m_iFlag;
|
|
XPoint m_ptDim;
|
|
XPoint m_lowPt, m_upPt;
|
|
void SetKeyword(const TCHAR *pszKeyword);
|
|
void SetExtents(XPoint lowPt, XPoint upPt);
|
|
void SetMidPoints(AcGePoint3dArray &dimPoints);
|
|
void SetDimType(int iFlag);
|
|
void AddToDataBase();
|
|
TMulDimEntity m_dimbEntity;
|
|
};
|
|
|
|
TQuickDimensionJig::TQuickDimensionJig()
|
|
{
|
|
m_pszKeyword = NULL;
|
|
m_pDrawEntX = NULL;
|
|
m_pDrawEntY = NULL;
|
|
m_dimbEntity.m_iFlag = m_iFlag;
|
|
m_dFactor = 0.0;
|
|
m_dimbEntity.m_pDrawEntAll = NULL;
|
|
m_dimbEntity.m_pDrawEnt = new AecDbDimension;
|
|
}
|
|
|
|
TQuickDimensionJig::~TQuickDimensionJig()
|
|
{
|
|
if(m_pDrawEntX != NULL)
|
|
delete m_pDrawEntX;
|
|
if(m_pDrawEntY != NULL)
|
|
delete m_pDrawEntY;
|
|
}
|
|
|
|
void TQuickDimensionJig::SetKeyword(const TCHAR *pszKeyword)
|
|
{
|
|
m_pszKeyword = pszKeyword;
|
|
}
|
|
|
|
void TQuickDimensionJig::SetDimType(int iFlag)
|
|
{
|
|
m_iFlag = iFlag;
|
|
m_dimbEntity.m_iFlag = m_iFlag;
|
|
if (m_iFlag == 2 && m_dimbEntity.m_pDrawEntAll == NULL)
|
|
{
|
|
m_dimbEntity.m_pDrawEntAll = new AecDbDimension;
|
|
}
|
|
}
|
|
|
|
void TQuickDimensionJig::SetExtents(XPoint lowPt, XPoint upPt)
|
|
{
|
|
extern TCHAR* LAY_DIM;
|
|
m_lowPt = GlobalFunc::Wcs2Ucs(lowPt);
|
|
m_upPt = GlobalFunc::Wcs2Ucs(upPt);
|
|
|
|
if(m_pDrawEntX != NULL)
|
|
{
|
|
delete m_pDrawEntX;
|
|
m_pDrawEntX = NULL;
|
|
}
|
|
m_pDrawEntX = new AecDbDimension;
|
|
m_pDrawEntX->SetLayoutRotation(GlobalFunc::Ucs2Wcs(0));//add by whl on 060306
|
|
m_pDrawEntX->SetDist2DimLine(6.0);
|
|
m_pDrawEntX->SetLocation(lowPt);
|
|
m_pDrawEntX->SetRotation(GlobalFunc::Ucs2Wcs(0.0));
|
|
double dValX = m_upPt.x - m_lowPt.x;
|
|
if(fabs(dValX) > 1E-3)
|
|
m_pDrawEntX->AppendSegment(dValX);
|
|
|
|
AcDbObjectId idStyle = InitDimStyle(DS_LINEAR);
|
|
m_pDrawEntX->SetStyleId(idStyle);
|
|
m_pDrawEntX->setLayer(LAY_DIM);
|
|
|
|
if(m_pDrawEntY != NULL)
|
|
{
|
|
delete m_pDrawEntY;
|
|
m_pDrawEntY = NULL;
|
|
}
|
|
m_pDrawEntY = new AecDbDimension;
|
|
m_pDrawEntY->SetLayoutRotation(GlobalFunc::Ucs2Wcs(0));//add by whl on 060306
|
|
m_pDrawEntY->SetDist2DimLine(6.0);
|
|
m_pDrawEntY->SetLocation(lowPt);
|
|
m_pDrawEntY->SetRotation(PI/2 + GlobalFunc::Ucs2Wcs(0.0));
|
|
double dValY = m_upPt.y - m_lowPt.y;
|
|
if(fabs(dValY) > 1E-3)
|
|
m_pDrawEntY->AppendSegment(dValY);
|
|
|
|
m_pDrawEntY->SetStyleId(InitDimStyle(DS_LINEAR));
|
|
m_pDrawEntY->setLayer(LAY_DIM);
|
|
|
|
double dTexth = 3.5;
|
|
OPENOBJ_BEGIN(idStyle, AcDb::kForRead, AcDbDimStyleTableRecord, pDimStyle);
|
|
ASSERT(pDimStyle);
|
|
dTexth = pDimStyle->dimtxt() * pDimStyle->dimscale();
|
|
OPENOBJ_END();
|
|
m_dFactor = 2 * dTexth * GlobalFunc::DocGetPScale();
|
|
m_dimbEntity.m_pDrawEnt->SetStyleId(idStyle);
|
|
if (m_iFlag == 2 && m_dimbEntity.m_pDrawEntAll != NULL)
|
|
{
|
|
m_dimbEntity.m_pDrawEntAll->SetStyleId(idStyle);
|
|
}
|
|
|
|
}
|
|
|
|
void TQuickDimensionJig::SetMidPoints(AcGePoint3dArray &dimPoints)
|
|
{
|
|
if(m_iFlag == 0)
|
|
return;
|
|
|
|
long i;
|
|
XPointList lstPointsX, lstPointsY;
|
|
for(i=0; i<dimPoints.length(); i++)
|
|
{
|
|
XPoint ptDim = dimPoints[i];
|
|
lstPointsX.Append(new XPoint(ptDim));
|
|
lstPointsY.Append(new XPoint(ptDim));
|
|
}
|
|
lstPointsX.QuickSort(CmpPointByX);
|
|
lstPointsY.QuickSort(CmpPointByY);
|
|
|
|
if(m_pDrawEntX->GetSegmentNum() > 0)
|
|
{
|
|
for(i=0; i<lstPointsX.Length(); i++)
|
|
m_pDrawEntX->AddSegment(*lstPointsX[i]);
|
|
}
|
|
if(m_pDrawEntY->GetSegmentNum() > 0)
|
|
{
|
|
for(i=0; i<lstPointsY.Length(); i++)
|
|
m_pDrawEntY->AddSegment(*lstPointsY[i]);
|
|
}
|
|
m_pDrawEntX->RemoveZeroSegment();
|
|
m_pDrawEntY->RemoveZeroSegment();
|
|
}
|
|
|
|
void TQuickDimensionJig::AddToDataBase()
|
|
{
|
|
if(m_iFlag == 2 && m_dimbEntity.m_pDrawEntAll != NULL)
|
|
{
|
|
if(g_Option::instance().g_nDimAdjust)
|
|
m_dimbEntity.m_pDrawEntAll->AdjustDim(g_Option::instance().g_nDimAdjust!=2);
|
|
|
|
// sg add 120410,增加布局转角的设置,解决UCS下,文字方向错误的问题
|
|
m_dimbEntity.m_pDrawEntAll->SetLayoutRotation(GlobalFunc::Ucs2Wcs(0.0));
|
|
GlobalFunc::AddToSpace(Adesk::kTrue, m_dimbEntity.m_pDrawEntAll);
|
|
}
|
|
|
|
//add by whl on 060119
|
|
if(g_Option::instance().g_nDimAdjust)
|
|
m_dimbEntity.m_pDrawEnt->AdjustDim(g_Option::instance().g_nDimAdjust!=2);
|
|
|
|
// sg add 120410,增加布局转角的设置,解决UCS下,文字方向错误的问题
|
|
m_dimbEntity.m_pDrawEnt->SetLayoutRotation(GlobalFunc::Ucs2Wcs(0.0));
|
|
|
|
// modify by xly on 110107 支持图层切换
|
|
//m_dimbEntity.m_pDrawEnt->AddToCSpace(Adesk::kTrue);
|
|
GlobalFunc::AddToSpace(Adesk::kTrue, m_dimbEntity.m_pDrawEnt);
|
|
}
|
|
|
|
int TQuickDimensionJig::doIt()
|
|
{
|
|
int ret;
|
|
try
|
|
{
|
|
ret = drag();
|
|
}
|
|
catch(...)
|
|
{
|
|
ret = AcEdJig::kCancel;
|
|
}
|
|
|
|
if (ret == AcEdJig::kCancel)
|
|
ret = RTCAN;
|
|
else if(ret == AcEdJig::kNull)
|
|
ret = RTNONE;
|
|
else if (ret <= 0)
|
|
ret = RTNORM;
|
|
else
|
|
ret = RTKWORD;
|
|
|
|
return ret;
|
|
}
|
|
|
|
AcEdJig::DragStatus TQuickDimensionJig::sampler()
|
|
{
|
|
setUserInputControls((UserInputControls)
|
|
(AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted));
|
|
if (m_pszKeyword)
|
|
setKeywordList(m_pszKeyword);
|
|
|
|
XPoint ptCursor;
|
|
DragStatus stat = acquirePoint(ptCursor);
|
|
ptCursor = ptCursor;
|
|
if(stat == AcEdJig::kNormal)
|
|
{
|
|
if (ptCursor.Distance2d(m_ptDim) > g_Option::instance()._DIST_SNAP)
|
|
m_ptDim = ptCursor;
|
|
else
|
|
stat = AcEdJig::kNoChange;
|
|
}
|
|
return stat;
|
|
}
|
|
|
|
// 更新实体数据
|
|
//modified by whl on 050811
|
|
Adesk::Boolean TQuickDimensionJig::update()
|
|
{
|
|
double nDist2Dim = 0.0;
|
|
BOOL b2 = FALSE;
|
|
while(m_dimbEntity.m_pDrawEnt->GetSegmentNum()>0)
|
|
m_dimbEntity.m_pDrawEnt->RemoveSegment(0);
|
|
if (m_iFlag == 2 && m_dimbEntity.m_pDrawEntAll != NULL)
|
|
{
|
|
b2 = TRUE;
|
|
while(m_dimbEntity.m_pDrawEntAll->GetSegmentNum() > 0)
|
|
m_dimbEntity.m_pDrawEntAll->RemoveSegment(0);
|
|
}
|
|
|
|
|
|
|
|
XPoint ptLoc(m_lowPt);
|
|
XPoint ptDim = GlobalFunc::Wcs2Ucs(m_ptDim);
|
|
double dangle;
|
|
if(ptDim.y < m_upPt.y && ptDim.y > m_lowPt.y && (ptDim.x < m_lowPt.x || ptDim.x > m_upPt.x))
|
|
{
|
|
if(m_pDrawEntY->GetSegmentNum() > 0)
|
|
{
|
|
//m_dimbEntity.m_pDrawEnt->copyFrom(m_pDrawEntY);
|
|
for(long i=0;i<m_pDrawEntY->GetSegmentNum();i++)
|
|
m_dimbEntity.m_pDrawEnt->AppendSegment(m_pDrawEntY->GetSegment(i));
|
|
|
|
dangle = PI/2 + GlobalFunc::Ucs2Wcs(0.0);
|
|
m_dimbEntity.m_pDrawEnt->SetRotation(dangle);
|
|
|
|
if (b2)
|
|
{
|
|
double dValY = m_upPt.y - m_lowPt.y;
|
|
if(fabs(dValY) > 1E-3)
|
|
m_dimbEntity.m_pDrawEntAll->AppendSegment(dValY);
|
|
m_dimbEntity.m_pDrawEntAll->SetRotation(dangle);
|
|
}
|
|
if(ptDim.x < (m_lowPt.x + m_upPt.x) * 0.5)
|
|
ptLoc.x = m_lowPt.x;
|
|
else
|
|
ptLoc.x = m_upPt.x;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(m_pDrawEntX->GetSegmentNum() > 0)
|
|
{
|
|
//m_dimbEntity.m_pDrawEnt->copyFrom(m_pDrawEntX);
|
|
for(long i=0;i<m_pDrawEntX->GetSegmentNum();i++)
|
|
m_dimbEntity.m_pDrawEnt->AppendSegment(m_pDrawEntX->GetSegment(i));
|
|
m_dimbEntity.m_pDrawEnt->SetRotation(GlobalFunc::Ucs2Wcs(0.0));
|
|
|
|
if (b2)
|
|
{
|
|
double dValX = m_upPt.x - m_lowPt.x;
|
|
if(fabs(dValX) > 1E-3)
|
|
m_dimbEntity.m_pDrawEntAll->AppendSegment(dValX);
|
|
m_dimbEntity.m_pDrawEntAll->SetRotation(GlobalFunc::Ucs2Wcs(0.0));
|
|
}
|
|
|
|
if(ptDim.y < (m_lowPt.y + m_upPt.y) * 0.5)
|
|
{
|
|
ptLoc.y = m_lowPt.y;
|
|
}
|
|
else
|
|
{
|
|
|
|
ptLoc.y = m_upPt.y;
|
|
}
|
|
}
|
|
}
|
|
m_dimbEntity.m_pDrawEnt->SetLocation(GlobalFunc::Ucs2Wcs(ptLoc));
|
|
if (b2)
|
|
m_dimbEntity.m_pDrawEntAll->SetLocation(GlobalFunc::Ucs2Wcs(ptLoc));
|
|
|
|
XPoint ptOnSeg;
|
|
GeCurveSegment seg;
|
|
seg = m_dimbEntity.m_pDrawEnt->GetDimCurve();
|
|
if (b2)
|
|
seg = m_dimbEntity.m_pDrawEntAll->GetDimCurve();
|
|
if(seg.ProjectToMe(m_ptDim, ptOnSeg) == RTNORM)
|
|
{
|
|
double nDistMove = m_ptDim.Distance2d(ptOnSeg);
|
|
int nSideLoc = seg.OnWhichSide(m_dimbEntity.m_pDrawEnt->GetLocation());
|
|
int nSide = seg.OnWhichSide(m_ptDim);
|
|
nDist2Dim = m_dimbEntity.m_pDrawEnt->GetDist2DimLine(FALSE);
|
|
if (b2)
|
|
{
|
|
nSideLoc = seg.OnWhichSide(m_dimbEntity.m_pDrawEntAll->GetLocation());
|
|
nDist2Dim = m_dimbEntity.m_pDrawEntAll->GetDist2DimLine(FALSE);
|
|
}
|
|
double nFactor = nDist2Dim/fabs(nDist2Dim);
|
|
if(fabs(nDist2Dim) > 1.0E-6)
|
|
{
|
|
if(nSide != nSideLoc)
|
|
{
|
|
nDistMove *= nFactor;
|
|
}
|
|
else
|
|
{
|
|
nDistMove *= -nFactor;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(nSideLoc == OFFSET_LEFT)
|
|
nDistMove *= -1;
|
|
}
|
|
nDist2Dim += nDistMove;
|
|
if (b2)
|
|
{
|
|
m_dimbEntity.m_pDrawEntAll->SetDist2DimLine(nDist2Dim, FALSE);
|
|
|
|
if(nDist2Dim >= 0)
|
|
nDist2Dim -= m_dFactor;
|
|
else
|
|
nDist2Dim += m_dFactor;
|
|
m_dimbEntity.m_pDrawEnt->SetDist2DimLine(nDist2Dim, FALSE);
|
|
}
|
|
else
|
|
m_dimbEntity.m_pDrawEnt->SetDist2DimLine(nDist2Dim, FALSE);
|
|
|
|
}
|
|
ASSERT(m_dimbEntity.m_pDrawEnt && m_dimbEntity.m_pDrawEnt->IsValid());
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
AcDbEntity* TQuickDimensionJig::entity() const
|
|
{
|
|
return (AcDbEntity*)&m_dimbEntity;
|
|
}
|
|
|
|
// Add By lcf on 2005/03/21
|
|
// 等分标注
|
|
void AverageDim()
|
|
{
|
|
Entity ent;
|
|
XPoint ptPick;
|
|
RBList rbMask(RTDXF0, _T("DIMENSION,AEC_CHICUNBIAOZHU"), NULL);
|
|
while(ent.FilterSelect(_T("\n请选择需要等分的尺寸区间<退出>: "), rbMask, ptPick) == RTNORM)
|
|
{
|
|
Entity entDim;
|
|
if(ent.Is(_T("DIMENSION")))
|
|
{
|
|
if(!ConvertDim(ent, entDim))
|
|
{
|
|
acutPrintf(_T("\n不能转化ACAD尺寸标注对象!"));
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
entDim = ent;
|
|
|
|
OPENOBJ_BEGIN(entDim, AcDb::kForRead, AecDbDimension, pDim);
|
|
ASSERT(pDim);
|
|
int nSeg = pDim->HitTestOnDimSeg(GlobalFunc::Ucs2Wcs(ptPick));
|
|
if(nSeg < 0)
|
|
acutPrintf(_T("\n请正确选取尺寸区间!"));
|
|
else
|
|
{
|
|
int nAverage;
|
|
if(acedGetInt(_T("\n输入等分数<退出>:"), &nAverage) != RTNORM)
|
|
return;
|
|
|
|
if(pDim->upgradeOpen()==Acad::eOk)
|
|
{
|
|
XPoly2D poly;
|
|
pDim->GetPolySegOnDimLine(poly);
|
|
ASSERT(nSeg < poly.TotalSegments());
|
|
GeCurveSegment seg;
|
|
poly.Nth(nSeg, seg);
|
|
for(int i=0; i<nAverage; i++)
|
|
{
|
|
XPointDir2d ptIn;
|
|
seg.Polar(seg.GetLength() * (i+1)/nAverage, ptIn);
|
|
pDim->AddSegment(ptIn);
|
|
if(g_Option::instance().g_nDimAdjust)
|
|
pDim->AdjustDim(g_Option::instance().g_nDimAdjust!=2);
|
|
}
|
|
pDim->downgradeOpen();
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
//add by cwk on 060914
|
|
void DivideDim()
|
|
{
|
|
PickEntSet setshow(SS_FREE);
|
|
EntitySet ent;
|
|
XPoint ptPick;
|
|
RBList rbMask(RTDXF0, _T("DIMENSION,AEC_CHICUNBIAOZHU"), NULL);
|
|
while(ent.FilterSelect(_T("\n请选择需要等分的尺寸区间<退出>: "), rbMask, ptPick) == RTNORM)
|
|
{
|
|
Entity entDim;
|
|
if(ent.Is(_T("DIMENSION")))
|
|
{
|
|
if(!ConvertDim(ent, entDim))
|
|
{
|
|
acutPrintf(_T("\n不能转化ACAD尺寸标注对象!"));
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
entDim = ent;
|
|
OPENOBJ_BEGIN(entDim, AcDb::kForRead, AecDbDimension, pDim);
|
|
if(pDim==NULL)
|
|
break;
|
|
ASSERT(pDim);
|
|
|
|
ptPick = GlobalFunc::Ucs2Wcs(ptPick);
|
|
int nSeg = -1;
|
|
SubText* psubtext = pDim->HitTestText(ptPick);
|
|
if (psubtext == NULL)
|
|
{
|
|
nSeg = pDim->HitTestOnDimSeg(ptPick);
|
|
}
|
|
else
|
|
{
|
|
nSeg = psubtext->GetIndex();
|
|
delete psubtext;
|
|
psubtext = NULL;
|
|
}
|
|
|
|
if(nSeg < 0)
|
|
acutPrintf(_T("\n请正确选取尺寸区间!"));
|
|
else
|
|
{
|
|
GePoly2D poly;
|
|
pDim->GetPolySegOnDimLine(poly);
|
|
if (poly.Length() > nSeg)
|
|
{
|
|
AcDbLine *pln = new AcDbLine(*poly[nSeg],*poly[nSeg+1]);
|
|
|
|
pln->setColorIndex(1);
|
|
setshow += GlobalFunc::AddToModelSpace(pln);
|
|
}
|
|
int nAverage;
|
|
//moidfy by xlc on 070815 等分数不能为0
|
|
//if(acedGetInt(_T("\n输入等分数<退出>:"), &nAverage) != RTNORM)
|
|
// return;
|
|
while(TRUE)
|
|
{
|
|
if(acedGetInt(_T("\n输入等分数<退出>:"), &nAverage) != RTNORM)
|
|
{
|
|
setshow.Erase();
|
|
return;
|
|
}
|
|
|
|
if(abs(nAverage) < 1.0e-6)
|
|
{
|
|
acutPrintf(_T("\n等分数不能为0!"));
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if(pDim->upgradeOpen()==Acad::eOk)
|
|
{
|
|
XString xstr = pDim->GetText(nSeg);
|
|
CString str = (LPCTSTR)xstr;
|
|
if (str.ReverseFind(_T('=')) >= 0)
|
|
{
|
|
int i = str.Find(_T('=')) + 1;
|
|
TCHAR *sText = new TCHAR[str.GetLength()];
|
|
int j = 0;
|
|
do
|
|
{
|
|
sText[j] = str.GetAt(i);
|
|
j++;
|
|
i++;
|
|
} while(i < str.GetLength());
|
|
sText[j] = _T('\0');
|
|
str = sText;
|
|
xstr = str;
|
|
}
|
|
CString s;
|
|
if (str.Find(_T('.')) < 0)
|
|
{
|
|
int i = _ttoi(LPCTSTR(str));
|
|
int j;
|
|
double m;
|
|
if (i % nAverage == 0)
|
|
{
|
|
j = i /nAverage;
|
|
s.Format(_T("%d"),j);
|
|
}
|
|
else
|
|
{
|
|
//modified by yujie
|
|
//m = (double)i / (double)nAverage;
|
|
m = i / (double)nAverage;
|
|
s.Format(_T("%.1f"),m);
|
|
if (s[s.GetLength() - 1] == _T('0'))
|
|
s.Delete(s.GetLength() - 1);
|
|
if (s[s.GetLength() - 1] == _T('.')) //add by yujie
|
|
s.Delete(s.GetLength() - 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
double d = _tstof(LPCTSTR(str));
|
|
double m = d / nAverage;
|
|
s.Format(_T("%.1f"),m);
|
|
if (s[s.GetLength() - 1] == _T('0'))
|
|
s.Delete(s.GetLength() - 1);
|
|
if (s[s.GetLength() - 1] == _T('.')) //add by yujie
|
|
s.Delete(s.GetLength() - 1);
|
|
}
|
|
|
|
str = s;
|
|
str += _T('X');
|
|
s.Format(_T("%d"),nAverage);
|
|
str += s;
|
|
str += _T('=');
|
|
str += xstr;
|
|
pDim->SetTextContent(nSeg,LPCTSTR(str));
|
|
pDim->downgradeOpen();
|
|
}
|
|
}
|
|
OPENOBJ_END()
|
|
setshow.Erase();
|
|
|
|
}
|
|
}
|
|
// Add By lcf on 2005/03/23
|
|
// 对齐标注
|
|
void ArrangeDim()
|
|
{
|
|
// [12/19/2007 nsh]
|
|
//----------begin--------------
|
|
BOOL bChoose=TRUE;//选择的标注是直线标注或是圆弧标注 TRUE为直线标注,FALSE为圆弧标注
|
|
XPoint CenterPoint;
|
|
int WhichSide;
|
|
double dRadius;
|
|
//-----------end---------------
|
|
Entity entFirst;
|
|
RBList rbMask(RTDXF0, _T("DIMENSION,AEC_CHICUNBIAOZHU"), NULL);
|
|
if(GlobalFunc::SelectEntity(_T("\n选择参考标注<退出>: "), entFirst, rbMask) != RTNORM)
|
|
return;
|
|
|
|
Entity entDim;
|
|
if(entFirst.Is(_T("DIMENSION")))
|
|
{
|
|
if(!ConvertDim(entFirst, entDim))
|
|
{
|
|
acutPrintf(_T("\n不能转化ACAD尺寸标注对象!"));
|
|
return;
|
|
}
|
|
}
|
|
else
|
|
entDim = entFirst;
|
|
|
|
double dRotFirst, dDist;
|
|
AcDbObjectId objid;
|
|
GeCurveSegment seg;
|
|
AecDbDimension *pClone = NULL;
|
|
OPENOBJ_BEGIN(entDim, AcDb::kForRead, AecDbDimension, pFirst);
|
|
ASSERT(pFirst);
|
|
// [12/14/2007 nsh]
|
|
//-----------------------begin-----------------------
|
|
if(pFirst->IsAngular())
|
|
{//选择的是圆弧标注
|
|
bChoose =FALSE;
|
|
dDist =pFirst->GetDist2DimLine();
|
|
dRadius =pFirst->GetDimRadius();
|
|
GeCurveSegment se=pFirst->GetDimCurve();
|
|
XArc xa=se.GetArc();
|
|
WhichSide =se.OnWhichSide(pFirst->GetLocation());
|
|
CenterPoint=xa.GetCenterPt();
|
|
}
|
|
//-------------------------end-----------------------
|
|
else
|
|
{//选择的是直线标注
|
|
bChoose =TRUE;
|
|
dRotFirst = pFirst->GetRotation();
|
|
dDist = pFirst->GetDist2DimLine();
|
|
seg = pFirst->GetDimCurve();
|
|
seg = seg.Offset(dDist * GlobalFunc::DocGetPScale(), 1);
|
|
pClone = (AecDbDimension *)pFirst->clone();
|
|
if(pClone == NULL)
|
|
return;
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
PickEntSet ss(SS_FREE);
|
|
const TCHAR *szPrompts[2]={_T("\n选择其它标注<退出>: "), _T("") };
|
|
if(ss.Get(_T(":$"), szPrompts, NULL, rbMask) != RTNORM)
|
|
{
|
|
delete pClone;
|
|
return;
|
|
}
|
|
|
|
if(bChoose)
|
|
{//选择的为直线标注
|
|
for(long i=0; i<ss.Length(); i++)
|
|
{
|
|
Entity entOther = ss[i];
|
|
|
|
Entity entDimOther;
|
|
if(entOther.Is(_T("DIMENSION")))
|
|
{
|
|
if(!ConvertDim(entOther, entDimOther))
|
|
continue;
|
|
}
|
|
else
|
|
entDimOther = entOther;
|
|
|
|
OPENOBJ_BEGIN(entDimOther, AcDb::kForRead, AecDbDimension, pOther);
|
|
ASSERT(pOther);
|
|
if(pOther->IsAngular())
|
|
continue;
|
|
|
|
double dRot = CT_std_angle(dRotFirst) - CT_std_angle(pOther->GetRotation());
|
|
dRot = fabs(dRot);
|
|
if(dRot > 1E-6 && fabs(dRot - PI) > 1E-6)
|
|
continue;
|
|
|
|
XPoint ptRes;
|
|
seg.ProjectToMe(pOther->GetLocation(), ptRes);
|
|
if(pOther->upgradeOpen()==Acad::eOk)
|
|
{
|
|
// add by xly on 110107 支持图层切换,记录其他对象的图层
|
|
CString csLayer = pOther->layer();
|
|
pOther->CopyPropertiesFrom(pClone, AcDbMatchProperties::kSetAllFlagsOn);
|
|
pOther->setLayer(csLayer);
|
|
pOther->SetDist2DimLine((dRot < 1E-6) ? dDist : -dDist);
|
|
pOther->SetLocation(ptRes);
|
|
if(g_Option::instance().g_nDimAdjust)
|
|
pOther->AdjustDim(g_Option::instance().g_nDimAdjust!=2);
|
|
pOther->downgradeOpen();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
// [12/19/2007 nsh]
|
|
//--------------------------begin------------------------------
|
|
else
|
|
{//选择的圆弧标注
|
|
for(long i=0; i<ss.Length(); i++)
|
|
{
|
|
Entity entOther = ss[i];
|
|
|
|
Entity entDimOther;
|
|
if(entOther.Is(_T("DIMENSION")))
|
|
{
|
|
if(!ConvertDim(entOther, entDimOther))
|
|
continue;
|
|
}
|
|
else
|
|
entDimOther = entOther;
|
|
|
|
OPENOBJ_BEGIN(entDimOther, AcDb::kForWrite, AecDbDimension, pOther);
|
|
ASSERT(pOther);
|
|
if(!pOther->IsAngular())
|
|
continue;
|
|
GeCurveSegment seg=pOther->GetDimCurve();
|
|
XArc xarc=seg.GetArc();
|
|
int temp=seg.OnWhichSide(pOther->GetLocation());
|
|
if(xarc.GetCenterPt()!=CenterPoint || seg.OnWhichSide(pOther->GetLocation())!=WhichSide)
|
|
continue;
|
|
AcDbObjectId oID=pOther->GetStyleId();
|
|
if(oID==InitDimStyle(DS_ANGLE))
|
|
{//角度标注的情况下
|
|
double ddd=8.0*GlobalFunc::DocGetPScale();
|
|
GeCurveSegment cv =pOther->GetDimCurve();
|
|
if(!cv.Is(CURVE_LINE))
|
|
{
|
|
XArc arc=cv.GetArc();
|
|
arc.GetCenterPt();
|
|
XPoint ptStart;
|
|
pOther->getStartPoint(ptStart);
|
|
ads_polar(arc.GetCenterPt(),ads_angle(arc.GetCenterPt(),ptStart),dRadius+dDist*GlobalFunc::DocGetPScale(),ptStart);
|
|
pOther->SetLocation(ptStart);
|
|
pOther->SetDimRadius(dRadius);
|
|
pOther->SetDist2DimLine(dDist);
|
|
}
|
|
}
|
|
else
|
|
{//弧长标注的情况
|
|
pOther->SetDimRadius(dRadius);
|
|
pOther->SetDist2DimLine(dDist);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
//--------------------------end---------------------------------
|
|
delete pClone;
|
|
}
|
|
|
|
// add by xly on 101115 在FindAndReplaceDlg中已经去掉了这个函数,所以添加
|
|
//extern TARCH_IMPEXP BOOL g_bTextStyleEx;
|
|
TextPosition FindEntText1(Entity ent, const TCHAR *sSubText, TextPosition &posStart, TextRange *pRange)
|
|
{
|
|
TextPosition posFind;
|
|
if(!sSubText || !sSubText[0])
|
|
return posFind;
|
|
|
|
// sg add 110504,解决查找时,可能受“全字匹配”影响的问题,临时去掉全字匹配的设置
|
|
DWORD dwMaskOld = g_FindParser.GetFindOption(),
|
|
dwMaskNew = dwMaskOld;
|
|
dwMaskNew = dwMaskNew & ~FP_WHOLE_WORD;
|
|
g_FindParser.SetFindOption(dwMaskNew);
|
|
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbEntity, pEnt);
|
|
if(pEnt->isKindOf(AecXDbEntityBaseEx::desc()))
|
|
{
|
|
AecXDbEntityBaseEx *pText= AecXDbEntityBaseEx::cast(pEnt);
|
|
if (pText)
|
|
posFind = pText->FindSubText(sSubText, posStart, pRange);
|
|
}
|
|
else if(pEnt->isKindOf(AcDbText::desc()))
|
|
{
|
|
GlobalFunc::PushMemVar<BOOL> vTemp(g_Option::instance().g_bTextStyleEx, FALSE);
|
|
AecXDbText text;
|
|
AcDbText *pText=AcDbText::cast(pEnt);
|
|
if(text.ConvertFrom(pText))
|
|
{
|
|
posFind = text.FindSubText(sSubText, posStart, pRange);
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
// sg add 110504,解决查找时,可能受“全字匹配”影响的问题,恢复默认
|
|
g_FindParser.SetFindOption(dwMaskOld);
|
|
|
|
return posFind;
|
|
}
|
|
|
|
// add by xly on 100927 为选择到的字符绘制红色外包盒;poly选择到的字符的外包盒的pline线
|
|
void GrdrawPoly(XPoly2D &poly)
|
|
{
|
|
int len = poly.Length();
|
|
for(int i=0;i<len;i++)
|
|
{
|
|
GeCurveSegment seg;
|
|
poly.Nth(i, seg);
|
|
XPoint ptS, ptE;
|
|
ads_grdraw(seg.StartPoint(), seg.EndPoint(), 1, 0);
|
|
}
|
|
}
|
|
|
|
// add by xly on 100927 红色框选选择到的字符,同时将为字符串csText分为两部分;
|
|
// 说明:csText:待选字符串;entSel:选择集;ptPickWcs:点选的位置;csLeft:选择到的字符的左部(包含选择到的字符);
|
|
// csRight:选择到的字符的右部(不包含选择到的字符);
|
|
void HightShow(CString csText, EntitySet entSel, XPoint ptPickWcs,CString &csLeft, CString &csRight)
|
|
{
|
|
// 获得字符串中每个字符的信息
|
|
int len = csText.GetLength();
|
|
TextPosition pos;
|
|
|
|
for(int i=0;i<len;i++)
|
|
{
|
|
CString csUnit;
|
|
#if (ARX < 17)
|
|
int unicode = (int)csText.GetAt(i);
|
|
if((unicode <='9' && unicode >= '0') || (unicode <= 'z' && unicode >= 'a') || (unicode <= 'Z' && unicode >= 'A'))
|
|
{
|
|
TCHAR cUnit = csText[i];
|
|
BYTE byte = (BYTE)cUnit;
|
|
csUnit = cUnit;
|
|
}
|
|
else
|
|
{
|
|
csUnit = csText.Mid(i,2);
|
|
i++;
|
|
}
|
|
#else
|
|
TCHAR cUnit = csText[i];
|
|
BYTE byte = (BYTE)cUnit;
|
|
csUnit = cUnit;
|
|
#endif
|
|
|
|
// 查找字符的位置
|
|
TextRange range;
|
|
TextPosition posFind = FindEntText1(entSel, csUnit, pos, &range);
|
|
|
|
// 反复查找csUnit字符的位置
|
|
while(!!posFind)
|
|
{
|
|
// 获得字符的外包盒
|
|
XPoint ptMin, ptMax;
|
|
if(range.GetExtend(ptMin, ptMax))
|
|
{
|
|
int ll = range.m_lstRanges.Length();
|
|
for(int n=0; n<ll; n++)
|
|
{
|
|
XPoly2D poly = *range.m_lstRanges[n];
|
|
poly.SetElevation(0.0);
|
|
|
|
// 根据用户的拾取点判断本个字符是不是宣道的字符
|
|
int ret = ptPickWcs&poly;
|
|
if(ret == PR_INSIDE)// 点选位置在字符的范围内
|
|
{
|
|
csLeft = csText.Left(pos.m_nTextPos);
|
|
csRight = csText.Right(len - pos.m_nTextPos);
|
|
// add by xly on 101115 选择到的文字为上标或者下标文字时调整返回的左右字符串
|
|
if (csLeft.GetLength()>0)
|
|
{
|
|
if (csLeft.Right(1)==_T('^'))
|
|
{
|
|
csLeft = csText.Left(pos.m_nTextPos+2);
|
|
csRight = csText.Right(len - pos.m_nTextPos-2);
|
|
}
|
|
if (csLeft.Right(2)==_T("^C"))
|
|
{
|
|
csLeft = csText.Left(pos.m_nTextPos+1);
|
|
csRight = csText.Right(len - pos.m_nTextPos-1);
|
|
}
|
|
}
|
|
poly.TransUCS(RBGroups(0), RBGroups(1));
|
|
// 为选择到的字符绘制红色外包盒
|
|
GrdrawPoly(poly);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
posFind = FindEntText1(entSel, csUnit, pos, &range);
|
|
}
|
|
TextPosition posTemp;
|
|
pos = posTemp;
|
|
}
|
|
}
|
|
|
|
// add by xly on 101209 捕获用户输入的取消、右键、回车、点取左键
|
|
// 捕获键盘输入关键字的动作
|
|
static int s_nInputRet;// 键盘输入的返回结果
|
|
static POINT s_ptInPut;// 记录拖拽选择集是点取的位置
|
|
#if ARX > 22
|
|
static bool InputKeyWord(MSG* msg)
|
|
#else
|
|
static BOOL InputKeyWord(MSG* msg)
|
|
#endif
|
|
{
|
|
BOOL bRet = FALSE;
|
|
if (!acdbCurDwg())
|
|
{
|
|
return bRet;
|
|
}
|
|
// 没有关键字输入的时候支持判断结果
|
|
switch(msg->message)
|
|
{
|
|
case WM_KEYDOWN: // 键盘输入关键字
|
|
{
|
|
if (msg->wParam==VK_RETURN || msg->wParam==VK_ESCAPE) // 键盘输入回车
|
|
{
|
|
s_nInputRet = RTNONE;
|
|
}
|
|
}
|
|
break;
|
|
case WM_RBUTTONDOWN: // 鼠标右键
|
|
{
|
|
s_nInputRet = RTNONE;
|
|
}
|
|
break;
|
|
case WM_LBUTTONDOWN :// 捕获move操作最后的点取位置
|
|
{
|
|
s_ptInPut = msg->pt;
|
|
}
|
|
default:
|
|
break;
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////
|
|
// 递增文字命令接口
|
|
// add by xly on 100926
|
|
void PassTextCmd()
|
|
{
|
|
Entity entSel;// 选择到的实体
|
|
XPoint ptPick;// 点选位置
|
|
CString csText, csLeft, csRight;// 拆分的文字,拆分为选中的字符左部分(包括选中的字符),拆分为选中的字符右部分
|
|
XPoint ptPos; // 对象的基点
|
|
PickEntSet ss(SS_FREE);
|
|
|
|
// 标记点取的位置是在名字上
|
|
bool bIsName = true;
|
|
while(1)
|
|
{
|
|
// 定义选择集
|
|
CString csPompt = _T("\n请选择要递增拷贝的文字(注:同时按CTRL键进行递减拷贝,仅对单个选中字符进行操作)<退出>:");
|
|
RBList rb(RTDXF0, _T("AEC_POQIE,AEC_TUMINGBIAOZHU,AEC_DANHTEXT,TEXT,AEC_SUOYINTUMING"), NULL);
|
|
if(GlobalFunc::SelectEntity(csPompt, entSel, ptPick, rb) != RTNORM)
|
|
return;
|
|
|
|
if (entSel.Is(_T("AEC_DANHTEXT"))|| entSel.Is(_T("TEXT")))// 上华单行文字、CAD文字对象
|
|
{
|
|
XText text(entSel);
|
|
csText = text.m_csText;
|
|
ptPos = text.m_ptInsert;
|
|
}
|
|
else if (entSel.Is(_T("AEC_SUOYINTUMING")))// 索引图名
|
|
{
|
|
OPENOBJ_BEGIN(entSel,AcDb::kForRead,AecXDbSymbDrawingIndex,pSymb);
|
|
|
|
// 获得图名索引的中心
|
|
ptPos = pSymb->GetCenter();
|
|
if (ptPick.y>ptPos.y && ptPick.x<ptPos.x+pSymb->GetRadius(FALSE))// 点取位置在中心的上方
|
|
{
|
|
csText =pSymb->GetIndexLabel();
|
|
}
|
|
else if (ptPick.x<ptPos.x+pSymb->GetRadius(FALSE))// 点取位置在中心的下方
|
|
{
|
|
csText =pSymb->GetDrawingLabel();
|
|
|
|
// 没有图号的情况
|
|
if (csText.IsEmpty())
|
|
{
|
|
csText = pSymb->GetIndexLabel();
|
|
}
|
|
}
|
|
else // 点取位置在圆形外部
|
|
{
|
|
csText = pSymb->GetScaleText();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
else if (entSel.Is(_T("AEC_POQIE")))// 剖面,断面剖切
|
|
{
|
|
OPENOBJ_BEGIN(entSel,AcDb::kForWrite,AecXDbSymbSection,pSymb);
|
|
csText = pSymb->GetText();
|
|
|
|
// 获得标注两端的文字
|
|
XPoint pt1,pt2;
|
|
pt1 = pSymb->GetDefaultTextLocation(0);
|
|
pt2 = pSymb->GetDefaultTextLocation(1);
|
|
|
|
if (ptPick.Distance(pt1)<ptPick.Distance(pt2))// 选择起始位置
|
|
{
|
|
pSymb->SetTextLocation(0,pt1);
|
|
pSymb->SetTextLocation(1,pt2);
|
|
ptPos = pt1;
|
|
}
|
|
else // 选择终点位置
|
|
{
|
|
pSymb->SetTextLocation(0,pt2);
|
|
pSymb->SetTextLocation(1,pt1);
|
|
ptPos = pt2;
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
else if (entSel.Is(_T("AEC_TUMINGBIAOZHU")))// 图名标注
|
|
{
|
|
OPENOBJ_BEGIN(entSel,AcDb::kForRead,AecXDbDrawingName,pSymb);
|
|
ptPos = pSymb->GetMidLocation();
|
|
|
|
if (pSymb->GetShowScale())// 显示比例
|
|
{
|
|
// 获得比例文字的位置
|
|
XPoint ptScale = pSymb->GetScaleLocation();
|
|
// 判断选中图名还是选中比例
|
|
if (ptPick.x<ptScale.x)
|
|
{
|
|
csText = pSymb->GetNameText(); // 获得图名文字
|
|
bIsName = true;
|
|
}
|
|
else
|
|
{
|
|
bIsName = false;
|
|
csText = pSymb->GetScaleText();// 获得图名文字
|
|
}
|
|
}
|
|
else // 不显示比例
|
|
{
|
|
csText = pSymb->GetNameText();
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
ss += entSel;
|
|
|
|
XPoint ptPickWcs = GlobalFunc::Ucs2Wcs(ptPick);
|
|
|
|
// 点选到的字符红色框选
|
|
HightShow(csText, entSel, ptPickWcs, csLeft, csRight);
|
|
if(csLeft != _T("") || csRight != _T(""))// 已经选择字符
|
|
break;
|
|
}
|
|
|
|
// 定义基点,默认基点为对象的基点
|
|
XPoint ptBase = ptPos;
|
|
if(ads_getpoint(GlobalFunc::Wcs2Ucs(ptPos), _T("\n请指定基点:"), ptBase) == RTNORM)
|
|
{
|
|
// delete by xly on 110314 使用用户坐标系
|
|
//ptBase = GlobalFunc::Ucs2Wcs(ptBase);
|
|
}
|
|
else // 取消操作
|
|
{
|
|
// add by xly on 101206 刷新屏幕
|
|
acedRedraw(NULL,1);
|
|
return;
|
|
}
|
|
|
|
// 生成递增文字
|
|
while(1)
|
|
{
|
|
// 计算所选的文字的递增文字,ctrl键控制增加或者减少
|
|
// 注:int型数字最大值2,147,483,647 如果超过最大值将变为0
|
|
SHORT nStateCtrl = GetKeyState(VK_CONTROL);
|
|
BOOL bCtrl = (nStateCtrl&256)!=0;
|
|
if(bCtrl)
|
|
csLeft = GlobalFunc::PlusString(csLeft, 1, FALSE, true);
|
|
else
|
|
csLeft = GlobalFunc::PlusString(csLeft, 1, TRUE, true);
|
|
csText = csLeft + csRight;
|
|
|
|
// 复制选择集中的实体信息
|
|
PickEntSet ss1(SS_FREE);
|
|
ss1.IncludeBegin();
|
|
{
|
|
XPushVar<int> tVar(_T("OSMODE"), 0);
|
|
SHads_command(RTSTR, _T("COPY"), RTPICKS, (TLong_ptr *)ss, RTSTR, _T(""),
|
|
RTSTR, _T("0,0"), RTSTR, _T("0,0"), RTNONE);
|
|
}
|
|
ss1.IncludeEnd();
|
|
int n = ss1.Length();
|
|
if (ss1.Length()<1)
|
|
{
|
|
// 选择集为空的时候,将已经做过的字符串递增、减做相反的操作
|
|
if(bCtrl)
|
|
csLeft = GlobalFunc::PlusString(csLeft, 1, TRUE, true);
|
|
else
|
|
csLeft = GlobalFunc::PlusString(csLeft, 1, FALSE, true);
|
|
continue;
|
|
}
|
|
|
|
// 修改生成递增后的文字
|
|
if (entSel.Is(_T("AEC_DANHTEXT"))) // 上华单行文字
|
|
{
|
|
OPENOBJ_BEGIN(ss1[(long)0],AcDb::kForWrite,AecXDbText,pSymb);
|
|
pSymb->SetText(csText);
|
|
OPENOBJ_END();
|
|
}
|
|
else if (entSel.Is(_T("TEXT"))) // CAD文字对象
|
|
{
|
|
OPENOBJ_BEGIN(ss1[(long)0],AcDb::kForWrite,AcDbText,pSymb);
|
|
pSymb->setTextString(csText);
|
|
OPENOBJ_END();
|
|
|
|
}
|
|
else if (entSel.Is(_T("AEC_SUOYINTUMING")))// 索引图名
|
|
{
|
|
OPENOBJ_BEGIN(ss1[(long)0],AcDb::kForWrite,AecXDbSymbDrawingIndex,pSymb);
|
|
// 根据点取的位置的不同,设置相应的文字
|
|
if (ptPick.y>ptPos.y && ptPick.x<ptPos.x +pSymb->GetRadius(FALSE))
|
|
{
|
|
pSymb->SetIndexLabel(csText); // 索引编号
|
|
}
|
|
else if(ptPick.x<ptPos.x+pSymb->GetRadius(FALSE))
|
|
{
|
|
CString csDrawLable = pSymb->GetDrawingLabel();
|
|
if (csDrawLable.IsEmpty())
|
|
{
|
|
pSymb->SetIndexLabel(csText); // 索引编号
|
|
}
|
|
else
|
|
{
|
|
pSymb->SetDrawingLabel(csText); // 图名
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pSymb->SetScaleText(csText); // 比例
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
else if (entSel.Is(_T("AEC_POQIE")))// 剖面剖切
|
|
{
|
|
OPENOBJ_BEGIN(ss1[(long)0],AcDb::kForWrite,AecXDbSymbSection,pSymb);
|
|
pSymb->SetText(csText);
|
|
OPENOBJ_END();
|
|
}
|
|
else if (entSel.Is(_T("AEC_TUMINGBIAOZHU")))// 图名索引
|
|
{
|
|
OPENOBJ_BEGIN(ss1[(long)0], AcDb::kForWrite, AecXDbDrawingName, pEnt);
|
|
if (pEnt->GetShowScale())// 显示比例
|
|
{
|
|
// 获得比例文字的位置
|
|
XPoint ptScale = pEnt->GetScaleLocation();
|
|
|
|
// 判断选中图名还是选中比例
|
|
if (bIsName)
|
|
{
|
|
pEnt->SetNameText(csText);
|
|
}
|
|
else
|
|
{
|
|
pEnt->SetScaleText(csText);
|
|
}
|
|
|
|
}
|
|
else // 不显示比例
|
|
{
|
|
pEnt->SetNameText(csText);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
// modify by xly on 101210 用move命令模拟jig效果
|
|
//// 拖动文字的位置
|
|
//if (DragMovePickSet(ss1, _T("\n请点取插入位置<退出>:"), ptBase, XPoint()) != RTNORM)
|
|
//{
|
|
// // add by xly on 101206 刷新屏幕
|
|
// acedRedraw(NULL,1);
|
|
// ss1.Erase();
|
|
// return;
|
|
//}
|
|
|
|
// 钩子函数监视键盘中输入关键字
|
|
s_nInputRet = 0;
|
|
acedRegisterFilterWinMsg(InputKeyWord);
|
|
|
|
acutPrintf( _T("\n请点取插入位置<退出>:"));
|
|
ss1.Redraw(2);
|
|
|
|
// lgh add.
|
|
// old extents
|
|
AcDbExtents oldExtens;
|
|
OPENOBJ_BEGIN(ss1[(long)0], AcDb::kForRead, AcDbEntity, pEnt);
|
|
if (pEnt != NULL)
|
|
pEnt->getGeomExtents(oldExtens);
|
|
OPENOBJ_END();
|
|
|
|
// 移动实体,实现jig效果
|
|
SHads_command(RTSTR, _T("MOVE"), RTPICKS, (TLong_ptr *)ss1, RTSTR, _T(""),
|
|
RT3DPOINT, &ptBase, RTSTR, _T("\\"), RTNONE);
|
|
if (s_nInputRet == RTNONE)// 按Esc 或者右键、回车退出
|
|
{
|
|
ss1.Erase();
|
|
acedRedraw(NULL,1);
|
|
return;
|
|
}
|
|
|
|
AcDbExtents newExtents;
|
|
OPENOBJ_BEGIN(ss1[(long)0], AcDb::kForRead, AcDbEntity, pEnt);
|
|
if (pEnt != NULL)
|
|
pEnt->getGeomExtents(newExtents);
|
|
OPENOBJ_END();
|
|
|
|
AcGeVector3d vec(newExtents.minPoint() - oldExtens.minPoint());
|
|
|
|
// lgh remmove, 2011-05017
|
|
// // 将屏幕坐标转化为CAD世界坐标
|
|
// XPoint ptLoc;
|
|
// CPoint ptTemp(s_ptInPut);
|
|
// acedGetAcadDwgView()->ScreenToClient(&ptTemp);
|
|
// acedCoordFromPixelToWorld(ptTemp, ptLoc);
|
|
//
|
|
// // modify by xly on 110314 将DCS转化为用户坐标系
|
|
// // 更新基点和选择集
|
|
// //ptBase = ptLoc;
|
|
// struct resbuf fromrb, torb;
|
|
// fromrb.restype = RTSHORT;
|
|
// fromrb.resval.rint = 2; // DCS
|
|
// torb.restype = RTSHORT;
|
|
// torb.resval.rint = 1; // UCS
|
|
//
|
|
// XPoint ptResult;
|
|
// acedTrans(ptLoc, &fromrb, &torb, FALSE, ptResult);
|
|
|
|
// ptBase = ptResult;
|
|
ptBase = (ptBase + vec);
|
|
ss.Free();
|
|
ss += ss1;
|
|
|
|
// 释放函数
|
|
acedRemoveFilterWinMsg(InputKeyWord);
|
|
}
|
|
|
|
// add by xly on 101206 刷新屏幕
|
|
acedRedraw(NULL,1);
|
|
}
|
|
|
|
//add by lgy 20120201 循环提示输入其他标注点
|
|
BOOL InputOtherPt(AcDbObjectId idDim, TDimTwoPointArg &dim)
|
|
{
|
|
XPoint ptOther, ptPosition;
|
|
while(TRUE)
|
|
{
|
|
while(TRUE)
|
|
{
|
|
ptPosition = dim.GetLastPoint();
|
|
if(XGetPoint(ptPosition, _T("\n请输入其他标注点"), ptOther)== RTNORM)
|
|
{
|
|
dim.Step(ptOther);
|
|
dim.AddDim(idDim, ptOther);
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
ptPosition = dim.GetLastPoint();
|
|
int nRet2;
|
|
INITGET_BEG(0, _T("U R"));
|
|
nRet2 = acedGetPoint(ptPosition, _T("\n请输入其他标注点或 [参考点(R)/撤消上一标注点(U)]<退出>:"), ptOther);
|
|
INITGET_END();
|
|
|
|
if (nRet2 == RTKWORD)
|
|
{
|
|
XString sKey;
|
|
acedGetInput(sKey);
|
|
if(sKey[0] == _T('R'))
|
|
acedGetPoint(NULL, _T("\n参考点:"), ptPosition);
|
|
else if(sKey[0] == _T('U'))
|
|
{
|
|
dim.Undo(idDim);
|
|
if(dim.CanUndo())
|
|
ptPosition = dim.GetLastPoint();
|
|
else
|
|
ptPosition = ptOther;
|
|
}
|
|
}
|
|
else if(nRet2 == RTNORM)
|
|
{
|
|
ptPosition = ptOther;
|
|
dim.Step(ptOther);
|
|
dim.AddDim(idDim, ptOther);
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
//add by lgy 20120202 获得poly中的第n条边上的起始点或终止点
|
|
XPoint GetPtOnPoly(XPoly2D poly, int n, BOOL bFalg)
|
|
{
|
|
GeCurveSegment seg;
|
|
poly.Nth(n, seg);
|
|
if (bFalg)
|
|
{
|
|
return seg.EndPoint();
|
|
}
|
|
return seg.StartPoint();
|
|
}
|
|
|
|
//add by lgy 20120314 为楼梯标注写一jig预览效果
|
|
class StairDimJig : public AcEdJig
|
|
{
|
|
public:
|
|
StairDimJig(AecDbDimension *pDim, XPoint pt);
|
|
virtual ~StairDimJig();
|
|
int doIt();
|
|
virtual DragStatus sampler();
|
|
virtual Adesk::Boolean update();
|
|
virtual AcDbEntity *entity() const;
|
|
XPoint GetDimLocalPt(); //返回jig最后获得的点的位置
|
|
AecDbDimension *m_pDrawEnt;
|
|
XPoint m_ptJig;
|
|
};
|
|
|
|
XPoint StairDimJig::GetDimLocalPt()
|
|
{
|
|
return m_ptJig;
|
|
}
|
|
|
|
StairDimJig::StairDimJig(AecDbDimension *pDim, XPoint pt)
|
|
{
|
|
m_pDrawEnt = pDim;
|
|
m_ptJig = pt;
|
|
}
|
|
|
|
StairDimJig::~StairDimJig()
|
|
{
|
|
}
|
|
|
|
int StairDimJig::doIt()
|
|
{
|
|
int ret;
|
|
try
|
|
{
|
|
ret = drag();
|
|
}
|
|
catch(...)
|
|
{
|
|
ret = AcEdJig::kCancel;
|
|
}
|
|
|
|
if (ret == AcEdJig::kCancel)
|
|
{
|
|
ret = RTCAN;
|
|
}
|
|
else if(ret == AcEdJig::kNull)
|
|
{
|
|
ret = RTNONE;
|
|
}
|
|
else if (ret <= 0)
|
|
{
|
|
ret = RTNORM;
|
|
}
|
|
else
|
|
{
|
|
ret = RTKWORD;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
AcEdJig::DragStatus StairDimJig::sampler()
|
|
{
|
|
setUserInputControls((UserInputControls)
|
|
(AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted));
|
|
|
|
XPoint ptCursor;
|
|
DragStatus stat = acquirePoint(ptCursor);
|
|
if(stat == AcEdJig::kNormal)
|
|
{
|
|
if (ptCursor.Distance2d(m_ptJig) > g_Option::instance()._DIST_SNAP)
|
|
{
|
|
m_ptJig = ptCursor;
|
|
}
|
|
else
|
|
{
|
|
stat = AcEdJig::kNoChange;
|
|
}
|
|
}
|
|
return stat;
|
|
}
|
|
|
|
AcDbEntity* StairDimJig::entity() const
|
|
{
|
|
return m_pDrawEnt;
|
|
}
|
|
|
|
Adesk::Boolean StairDimJig::update()
|
|
{
|
|
XPoint ptOnSeg;
|
|
GeCurveSegment seg = m_pDrawEnt->GetDimCurve();
|
|
if(seg.ProjectToMe(m_ptJig, ptOnSeg) == RTNORM)
|
|
{
|
|
double nDistMove = m_ptJig.Distance2d(ptOnSeg);
|
|
int nSideLoc = seg.OnWhichSide(m_pDrawEnt->GetLocation());
|
|
int nSide = seg.OnWhichSide(m_ptJig);
|
|
double nDist2Dim = m_pDrawEnt->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;
|
|
}
|
|
}
|
|
|
|
nDist2Dim += nDistMove;
|
|
m_pDrawEnt->SetDist2DimLine(nDist2Dim, FALSE);
|
|
m_pDrawEnt->AdjustDim(0);
|
|
m_pDrawEnt->SetStyleId(InitDimStyle(DS_LINEAR));
|
|
}
|
|
return Adesk::kTrue;
|
|
}
|
|
|
|
|
|
// add by zyc 20120423 TDimIsometry命令的实现
|
|
static double s_dIsometry = 800.0f;
|
|
struct SDim
|
|
{
|
|
AcGeVector2d vtDirection;
|
|
EntitySet es;
|
|
double dDistance; // 到参考标注的距离
|
|
};
|
|
|
|
// 根据在参考标注的哪一侧,将标注对象分为两组
|
|
void SplitDims(EntitySet setRef, const PickEntSet& pickSet,
|
|
std::vector<SDim>& vtLeft, std::vector<SDim>& vtRight)
|
|
{
|
|
// 获取参考标注所在直线的方向向量
|
|
AcGeVector2d vtRefDir;
|
|
AcGePoint3d ptStart;
|
|
AcGePoint3d ptEnd;
|
|
|
|
OPENOBJ_BEGIN(setRef, AcDb::kForRead, AecDbDimension, pDim);
|
|
if (pDim)
|
|
{
|
|
pDim->getStartPoint(ptStart);
|
|
pDim->getEndPoint(ptEnd);
|
|
vtRefDir.set(ptStart.x-ptEnd.x, ptStart.y-ptEnd.y);
|
|
}
|
|
OPENOBJ_END();
|
|
AcGeLine3d lineRef;
|
|
lineRef.set(ptStart, ptEnd);
|
|
|
|
// 与参考标注垂直的方向向量
|
|
AcGeVector2d vtLeftDir, vtRightDir;
|
|
vtLeftDir = vtRefDir;
|
|
vtLeftDir.rotateBy(PI/2.0f);
|
|
vtLeftDir.normalize();
|
|
vtRightDir = vtRefDir;
|
|
vtRightDir.rotateBy(-PI/2.0f);
|
|
vtRightDir.normalize();
|
|
|
|
// 遍历选择集
|
|
double dDistance;
|
|
SDim sDim;
|
|
// 设置误差范围
|
|
AcGeTol tol;
|
|
tol.setEqualPoint(g_Option::instance()._DIST_SNAP);
|
|
tol.setEqualVector(g_Option::instance()._DIST_SNAP);
|
|
for (int i=0; i<pickSet.Length(); i++)
|
|
{
|
|
OPENOBJ_BEGIN(pickSet[(long)i], AcDb::kForRead, AecDbDimension, pDim);
|
|
if (pDim)
|
|
{
|
|
// 判断是否与参考标注平行
|
|
AcGePoint3d ptStartTemp,ptEndTemp;
|
|
pDim->getStartPoint(ptStartTemp);
|
|
pDim->getEndPoint(ptEndTemp);
|
|
AcGeVector2d vtDir;
|
|
vtDir.set(ptStartTemp.x-ptEndTemp.x,
|
|
ptStartTemp.y-ptEndTemp.y);
|
|
if (Adesk::kTrue != vtDir.isParallelTo(vtRefDir, tol) ||
|
|
pickSet[(long)i] == setRef)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
|
|
// 获取到参考标注的距离
|
|
dDistance = lineRef.distanceTo(ptStartTemp);
|
|
sDim.dDistance = dDistance;
|
|
sDim.es = pickSet[(long)i];
|
|
if (dDistance-0 < g_Option::instance()._DIST_SNAP)
|
|
{
|
|
sDim.vtDirection = vtLeftDir;
|
|
vtLeft.push_back(sDim);
|
|
continue;
|
|
}
|
|
|
|
// 判断在参考标注的哪一边
|
|
AcGeVector2d vtTemp;
|
|
vtTemp.set(ptStartTemp.x-ptEnd.x,
|
|
ptStartTemp.y-ptEnd.y);
|
|
vtTemp.rotateBy(-vtRefDir.angle());
|
|
if (vtTemp.angle() > PI)
|
|
{
|
|
sDim.vtDirection = vtRightDir;
|
|
vtRight.push_back(sDim);
|
|
}
|
|
else
|
|
{
|
|
sDim.vtDirection = vtLeftDir;
|
|
vtLeft.push_back(sDim);
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
|
|
void AdjustDims(std::vector<SDim>& vtDims)
|
|
{
|
|
AcGeMatrix3d matrix;
|
|
AcGeVector3d vec;
|
|
for (int i=0; i<(int)vtDims.size(); i++)
|
|
{
|
|
vec.set(vtDims[i].vtDirection.x,
|
|
vtDims[i].vtDirection.y, 0);
|
|
matrix.setToTranslation(vec *
|
|
(s_dIsometry*(i+1)-vtDims[i].dDistance));
|
|
OPENOBJ_BEGIN(vtDims[i].es, AcDb::kForWrite, AecDbDimension, pDim);
|
|
if (pDim)
|
|
{
|
|
// pDim->TransformBy(matrix);
|
|
pDim->subTransformBy(matrix);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
|
|
bool SortDims(const SDim& dim1, const SDim& dim2)
|
|
{
|
|
return dim1.dDistance < dim2.dDistance;
|
|
}
|
|
|
|
void DimIsometry()
|
|
{
|
|
// 清空初始选择集
|
|
GlobalFunc::DocGetPickFirst().Free();
|
|
|
|
// 选择参考标注
|
|
EntitySet setRef;
|
|
RBList mask = RBList(RTDXF0, _T("AEC_CHICUNBIAOZHU"), NULL);
|
|
int iRet = GlobalFunc::SelectEntity(_T("\n请选择参考标注<退出>:"), setRef, mask);
|
|
if (RTNORM != iRet)
|
|
{
|
|
return;
|
|
}
|
|
|
|
OPENOBJ_BEGIN(setRef, AcDb::kForRead, AecDbDimension, pDim);
|
|
if (pDim)
|
|
{
|
|
if (pDim->IsAngular())
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
OPENOBJ_END();
|
|
|
|
// 选择需要对齐的标注
|
|
PickEntSet setNeedAlign;
|
|
iRet = GlobalFunc::SelectEntities(_T("\n请选择其它标注:"), setNeedAlign, mask);
|
|
if (RTNORM != iRet)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// 将需要对齐的标注根据参考标注的两侧分为两组
|
|
std::vector<SDim> vtLeft, vtRight;
|
|
SplitDims(setRef, setNeedAlign, vtLeft, vtRight);
|
|
setNeedAlign.Free();
|
|
|
|
// 如果两组均为空,退出命令
|
|
if (vtLeft.size() == 0 &&
|
|
vtRight.size()== 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// 提示输入间距
|
|
CString sIsometry;
|
|
sIsometry.Format(_T("%lf"), s_dIsometry);
|
|
sIsometry.TrimRight('0');
|
|
sIsometry.TrimRight('.');
|
|
CString sPrompt;
|
|
sPrompt.Format(_T("\n请输入尺寸线间距<%s>:"), (LPCTSTR)sIsometry);
|
|
iRet = acedGetReal((LPCTSTR)sPrompt, &s_dIsometry);
|
|
if (RTCAN == iRet)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// 对两组分别进行排序(根据与参考标注的距离)
|
|
sort(vtLeft.begin(), vtLeft.end(), SortDims);
|
|
sort(vtRight.begin(), vtRight.end(), SortDims);
|
|
|
|
// 对需要等距处理的标注进行相应的偏移
|
|
AdjustDims(vtLeft);
|
|
AdjustDims(vtRight);
|
|
}
|
|
// end of TDbDimIsometry
|