#include "stdafx.h" #include "ArcRadDimStyle.h" extern AcDbObjectId AddToSpace(Adesk::Boolean bClosed, TDbEntity *pEntSymb) ; EDimState g_eDimState = eSingleDim; extern TARCH_IMPEXP BOOL g_bTextDefaultLayer; namespace { #if ADS <= 18 double _ttof(LPCTSTR psz) { if (!psz) return .0; USES_CONVERSION; return atof(W2A(psz)); } #endif } CArcRadDimStyle::CArcRadDimStyle(void) { } CArcRadDimStyle::~CArcRadDimStyle(void) { } CString GetDimPostfix(AcDbObjectId & dimStyleId) { CString strPostfix = _T(""); if (dimStyleId) { OPENOBJ_BEGIN(dimStyleId, AcDb::kForRead, AcDbDimStyleTableRecord, pStyle); if (pStyle != NULL) { strPostfix = pStyle->dimpost(); } OPENOBJ_END(); } return strPostfix; } void CArcRadDimStyle::ArcRadDimensioning() { EDimState eDimState = g_eDimState; int iOsMode = 0; TGGetVar(_T("OSMODE"), &iOsMode); iOsMode %= 0x4000; // 在对象捕捉关闭时,打开对象捕捉 iOsMode |= OS_NEA; XPushVar vOsMode(_T("OSMODE"), iOsMode | OS_NEA); CRoadCornerRadiusDlg *pDlg = new CRoadCornerRadiusDlg; while (1) { switch (eDimState) { case eBatchDim: { eDimState = BatchDimensioning(pDlg); g_eDimState = eBatchDim; break; } case eSingleDim: { eDimState = SingleDimensioning(pDlg); g_eDimState = eSingleDim; break; } case eCancle: delete pDlg; return; } } } EDimState CArcRadDimStyle::BatchDimensioning(CRoadCornerRadiusDlg* dlg) { PickSet ss(SS_FREE); TRBList rbFilter(acutBuildList(RTDXF0, _T("POLYLINE,LWPOLYLINE,ARC"), NULL)); TCHAR chRet; const TCHAR *kword=_T("Q S"); THookMsg hookmsg; while (1) { acedGetAcadFrame()->SetFocus(); TDPtrList lstSegArc; int iRetCode = SelectEntities(_T("\n请批量选择待标注的圆弧或[单个标注(Q)/设置(S)]<退出>:"), ss, rbFilter, kword, chRet);//方块 int vn = hookmsg.GetValue(); if (iRetCode == RTNORM)//选择标注 { CStringList lstLayer; dlg->GetSelectLayer(lstLayer); int iIndex(0); for (long n = 0; n < ss.Length(); ++n) { Entity ssEnt=ss[n]; OPENOBJ_BEGIN(ssEnt,AcDb::kForRead,AcDbEntity,pEntity); if(pEntity) { CString strLayer = pEntity->layer(); //add tyj 20160905: 道路半径图层为空时,对所有选中的并且程序支持的对象均进行半径标注 if(lstLayer.IsEmpty()) { AnalysisTgEntToCircle(pEntity, lstSegArc); } else { if (!lstLayer.GetSize() || lstLayer.Find(strLayer)) AnalysisTgEntToCircle(pEntity, lstSegArc); else iIndex++; } } OPENOBJ_END(); if (iIndex == ss.Length()) acutPrintf(_T("选择对象图层无效,请重新选择!")); } for (int i = 0; i < lstSegArc.Length(); ++i) { TGGeCurveSegment seg = *lstSegArc[i]; XArc xArc = seg.GetArc(); TADSGePoint3d mid(xArc.MidPoint()); if (dlg->GetRadiusLabel()) DimArcRadDim(dlg, xArc.MidPoint(), xArc); else DimArcTextDim(dlg, mid, xArc); } } else if (iRetCode == RTKWORD) { switch(chRet) { case _T('Q'): return eSingleDim; case _T('S'): { if (IDOK == dlg->DoModal()) { } } break; } } else { //当前焦点在CAD上,并且没有选中 if(vn == 0 && GetFocus() == acedGetAcadDwgView()->GetSafeHwnd()) { acutPrintf(_T("\n请选择弧线!")); continue; } else return eCancle; } } } EDimState CArcRadDimStyle::SingleDimensioning(CRoadCornerRadiusDlg* dlg) { AcDbEntity *pEntity=NULL; Entity ent; int nRet;//PickSet的返回码 THookMsg hookmsg; XPoint ptSel; while (1) { TDPtrList lstSegArc; acedGetAcadFrame()->SetFocus(); TCHAR cRet; int vn = hookmsg.GetValue(); TRBList rbFilter(acutBuildList(RTDXF0, _T("POLYLINE,LWPOLYLINE,ARC"), NULL)); INITGET_BEG(0, _T("Q S"),) nRet = SelectEntity1(_T("\n请点取待标注的圆弧或[批量标注(Q)/设置(S)]<退出>:"),ent, ptSel, rbFilter); INITGET_END(); if (nRet==RTNORM) { //单选无限制,屏蔽 //CStringList lstLayer; //dlg->GetSelectLayer(lstLayer); OPENOBJ_BEGIN(ent,AcDb::kForRead,AcDbEntity,pEntity); if(pEntity) { //单选无限制,屏蔽 //CString strLayer = pEntity->layer(); //if (!lstLayer.GetSize() || lstLayer.Find(strLayer)) AnalysisTgEntToCircle(pEntity, lstSegArc); } OPENOBJ_END(); //tyj 20160825 修改:将下面这句转换坐标放到for循环外面,解决重复转换造成的错误 ptSel = Ucs2Wcs(ptSel); for (int i = 0; i < lstSegArc.Length(); ++i) { TGGeCurveSegment seg = *lstSegArc[i]; XArc xArc = seg.GetArc(); XPoint ptCloseSelPt; if (dlg->GetRadiusLabel())//半径标注 { if (xArc.PtOnArc(ptSel))//世界坐标系进行切换 DimArcRadDim(dlg, ptSel, xArc); } else//文字标注 { if (xArc.PtOnArc(ptSel)) DimArcTextDim(dlg, ptSel, xArc); } } } else if (nRet==RTKWORD) { XString sKeyword; VERIFY(ads_getinput(sKeyword)==RTNORM); if(sKeyword[0]==_T('Q')) return eBatchDim; else if(sKeyword[0] == _T('S')) { dlg->DoModal(); } } else { //当前焦点在CAD上,并且没有选中 /* if(vn == 0 && GetFocus() == acedGetAcadDwgView()->GetSafeHwnd()) { acutPrintf(_T("\n请选择弧线!")); continue; } else */ return eCancle; } } } void CArcRadDimStyle::AnalysisTgEntToCircle(const AcDbEntity* pEnt, TDPtrList &lstResult) { if(pEnt->isKindOf(AcDbArc::desc())) { AcDbArc *pArc = AcDbArc::cast(pEnt); TADSGePoint3d ptCen; (AcGePoint3d &)ptCen = pArc->center(); TGGeArc ar(ptCen, pArc->radius(), pArc->startAngle(), pArc->endAngle()); TADSGePoint3d ptStart, ptEnd, ptMid; ar.GetStartPoint(ptStart); ar.GetEndPoint(ptEnd); ar.MidPoint(ptMid); TGGeCurveSegment *pSeg = new TGGeCurveSegment; *pSeg = TGGeArc(ptStart, ptMid, ptEnd); lstResult.Append(pSeg); } else if (pEnt->isKindOf(AcDbPolyline::desc()) || pEnt->isKindOf(AcDb2dPolyline::desc()))//add tyj 20160909:二维多段线也可以进行半径标注 { AcDbPolyline pline; TEntitySet ent; if(acdbGetAdsName(ent.name, pEnt->objectId()) == Acad::eOk) { TGGePoly2D poly(ent); for (int i = 0; i < poly.TotalSegments(); i++) { TGGeCurveSegment *pSeg = new TGGeCurveSegment; poly.Nth(i, *pSeg); if (abs(pSeg->GetBulge()) > 1.0e-6) lstResult.Append(pSeg); else delete pSeg; } } } } void CArcRadDimStyle::DimArcRadDim(CRoadCornerRadiusDlg* dlg, const XPoint &ptOnArc, XArc &xArc) { XPoint ptCenter; AcGePoint3d ptText; CString strPostfix; int nDimLength; ptCenter = xArc.GetCenterPt(); double dRad = xArc.GetRadius(); CString strPrefix,strDimText; if (dlg->GetEqu()) { strPrefix = _T("R="); nDimLength = 20; } else { strPrefix = _T("R"); nDimLength = 17; } AcDbObjectId dimStyleId = dlg->InitLabelStyle(dlg->GetDrawUnit()); strPostfix = GetDimPostfix(dimStyleId); switch(dlg->GetAccuracy()) { case 0: { strDimText.Format(_T("%s%.0f%s"), strPrefix, _AS_METER(dRad), strPostfix); break; } case 1: { strDimText.Format(_T("%s%.1f%s"), strPrefix, _AS_METER(dRad), strPostfix); break; } case 2: { strDimText.Format(_T("%s%.2f%s"), strPrefix, _AS_METER(dRad), strPostfix); break; } case 3: { strDimText.Format(_T("%s%.3f%s"), strPrefix, _AS_METER(dRad), strPostfix); break; } } TDbRadiusDim *pDim=new TDbRadiusDim; // jsx add 160914,增加布局转角的设置,解决UCS下,文字方向错误的问题 pDim->SetLayoutRotation(Ucs2Wcs(0.0)); pDim->SetStyleId(dimStyleId); pDim->SetDimCenter(xArc.GetCenterPt()); pDim->SetDimEndPoint(ptOnArc); pDim->SetDimLen(nDimLength); if (dlg->GetEqu()) { pDim->SetText(strDimText); } double nDimDist=pDim->GetDimLen(FALSE); //del tyj 20160909:需求变更,无论圆弧半径多大,道路半径标注始终默认在圆弧内侧标注。 //if(nDimDist>xArc.GetCenterPt().Distance2d(ptOnArc)) // pDim->SetDimLen(-nDimDist, FALSE); pDim->SetDiameter(FALSE); pDim->setLayer(InitLayer(LAY_DIM)); // AcGeVector3d vec = ptCenter - ptOnArc;//向量 // XPoint ptPos = pDim->GetTextPos(); //获取文字位置 // ptPos = ptPos + (DocGetPScale() * 2)* vec / vec.length(); // pDim->SetTextPos(ptPos); //调整文字位置 AddToSpace(Adesk::kTrue, (TDbEntity*)pDim); SHacedCommand(RTSTR, _T("REGEN"), RTNONE); } void CArcRadDimStyle::DimArcTextDim(CRoadCornerRadiusDlg* dlg, XPoint &ptOnArc, XArc &xArc)//ptOnArc是世界坐标系的点 { XPoint ptCenter; AcGePoint3d ptText; ptCenter = xArc.GetCenterPt(); double dir = xArc.GetRadius()/2; double angle = 0.0; XPoint ptLocation = ptOnArc; TDbText *pText = new TDbText; CString strPrefix, sValue, strPostfix; AcDbObjectId dimStyleId = dlg->InitLabelStyle(dlg->GetDrawUnit()); strPostfix = GetDimPostfix(dimStyleId); if (dlg->GetEqu()) { strPrefix = _T("R="); } else { strPrefix = _T("R"); } switch(dlg->GetAccuracy()) { case 0: sValue.Format(_T("%s%.0f%s"), strPrefix, _AS_METER(xArc.GetRadius()), strPostfix); break; case 1: sValue.Format(_T("%s%.1f%s"), strPrefix, _AS_METER(xArc.GetRadius()), strPostfix); break; case 2: sValue.Format(_T("%s%.2f%s"), strPrefix, _AS_METER(xArc.GetRadius()), strPostfix); break; case 3: sValue.Format(_T("%s%.3f%s"), strPrefix, _AS_METER(xArc.GetRadius()), strPostfix); break; } XPoint ptMin, ptMax; pText->SetText(sValue); pText->SetHeight(_ttof(dlg->GetTextHeigh())); AcDbObjectId idTextStyle = GetTextStyleId(dlg->GetTextStyle()); if (idTextStyle.isValid()) pText->SetStyleId(idTextStyle); else pText->SetStyleId(acdbCurDwg()->textstyle()); pText->setLayer(InitLayer(LAY_TEXT));//公文图层 //计算文字插入位置和旋转方向 if (dlg->GetTextDir())//文字方向为沿切线 { //在1:500,字高3.5的时候,文字中心距离圆弧线2000;在1:100,字高3.5的时候,文字中心距离圆弧线400;在1:500,字高5.0的时候,文字中心距离圆弧线2857,以此类推 double dDisPtLoc2Arc = (DocGetPScale() / 500.0 * _ttof(dlg->GetTextHeigh()) / 3.5) * 2000;//(字高/3.5 * 比例/500)*2000 AcGeVector3d vec = ptCenter - ptOnArc; ptLocation = ptOnArc + vec * dDisPtLoc2Arc / vec.length(); pText->SetAlignment(XExplodeDraw::kMiddleCenter); pText->SetLocation(ptLocation); angle = ads_angle(XPoint(ptCenter), XPoint(ptOnArc)); //用户坐标系下进行文字的翻转 ptOnArc = Wcs2Ucs(ptOnArc); ptCenter = Wcs2Ucs(ptCenter); if (ptOnArc.y < ptCenter.y) angle += 0.5 * PI; else angle -= 0.5 * PI; pText->SetRotation(angle); } else//文字方向沿Y轴 { //add tyj 20160824:计算在用户坐标系下,文字的方向角度 AcGeVector3d vtYAxisUCS = Ucs2Wcs(AcGeVector3d::kYAxis, true); // Ucs的Y轴在Wcs下X轴方向的角度 double dRot = acutAngle(asDblArray(AcGePoint3d::kOrigin), asDblArray(vtYAxisUCS)); angle = dRot - 0.5*PI; XPoint ptAng = pText->GetExtents();//获取到的点的X是文字的宽度,Y为文字的高度 XPoint ptss(0, 0, 0); ptAng = Ucs2Wcs(ptAng); ptAng = (ptAng.x / 2, ptAng.y / 2); AcGeVector3d vec = ptCenter - ptOnArc;//向量 AcGeVector3d vecs = ptss - ptAng;// double angles = vec.angleTo(vecs);//向量与向量夹角 double dMins = angles; XPoint ptTemp = (ptAng.x, -ptAng.y); vecs = ptss - ptTemp;// angles = vec.angleTo(vecs); dMins < angles ? dMins : dMins = angles; ptTemp = (-ptAng.x, -ptAng.y); vecs = ptss - ptTemp;// angles = vec.angleTo(vecs); dMins < angles ? dMins : dMins = angles; ptTemp = (-ptAng.x, ptAng.y); vecs = ptss - ptTemp;// angles = vec.angleTo(vecs); dMins < angles ? dMins : dMins = angles; angles = dMins; //pText->GetExtents2d(ptMin, ptMax);//获取包围盒,必须在最后,要不什么也获取不到,获取值为相对文字中心点的 //double dXWidth = (ptMax.x - ptMin.x), // dYHeigh = (ptMax.y - ptMin.y);//计算大小 //在1:500时,无论字高多少,文字外包围框离圆弧线最近点的距离为1000;在1:100时,无论字高多少,文字外包围框离圆弧线最近点的距离为200,以此类推。 double dDisPtLoc2Arc = DocGetPScale() / 500.0 * 1000; vec = ptCenter - ptOnArc; ptLocation = ptOnArc + vec * dDisPtLoc2Arc / vec.length(); ptOnArc = Wcs2Ucs(ptOnArc); ptCenter = Wcs2Ucs(ptCenter); AcGeVector3d vecQuadrant = ptOnArc - ptCenter; if (vecQuadrant.x <= 0 && vecQuadrant.y >= 0) pText->SetAlignment(XExplodeDraw::kTopLeft); else if (vecQuadrant.x >= 0 && vecQuadrant.y >= 0) pText->SetAlignment(XExplodeDraw::kTopRight); else if (vecQuadrant.x <= 0 && vecQuadrant.y <= 0) pText->SetAlignment(XExplodeDraw::kBottomLeft); else if (vecQuadrant.x >= 0 && vecQuadrant.y <= 0) pText->SetAlignment(XExplodeDraw::kBottomRight); else pText->SetAlignment(XExplodeDraw::kCenter); pText->SetRotation(angle); pText->SetLocation(ptLocation); } AddToModelSpace(pText, Adesk::kTrue); }