#include "stdafx.h" #include "TTempZoom.h" #include "dbxutil.h" #include "math.h" #include "actrans.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #define UP PI/2.0 #define DOWN PI+PI/2.0 // mcl changed, 2010.04.19.跟建筑底层定义重复 //#define LEFT PI //#define RIGHT 0.0 #define LEFT_ZOOM PI #define RIGHT_ZOOM 0.0 static BOOL GetScreenLimits(AcGePoint3d &lowerLeft, AcGePoint3d &upperLeft, AcGePoint3d &upperRight, AcGePoint3d &lowerRight) { // create a resbuf so that we can examine a few system vars struct resbuf rb; memset (&rb, 0, sizeof (struct resbuf)); // get the centre point of the display acedGetVar (_T("VIEWCTR"), &rb); AcGePoint3d cen (rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]); // get the size of the viewport in coords memset (&rb, 0, sizeof (struct resbuf)); acedGetVar (_T("VIEWSIZE"), &rb); ads_real height = rb.resval.rreal; // get the size of the screen in pixels memset (&rb, 0, sizeof (struct resbuf)); acedGetVar (_T("SCREENSIZE"), &rb); ads_real ratio = height / rb.resval.rpoint[Y]; ads_real width = ratio * rb.resval.rpoint[X]; // create the 4 corner points acutPolar (asDblArray (cen), LEFT_ZOOM, width/2.0, asDblArray (lowerLeft)); acutPolar (asDblArray (lowerLeft), DOWN, height/2.0, asDblArray (lowerLeft)); acutPolar (asDblArray (lowerLeft), UP, height, asDblArray (upperLeft)); acutPolar (asDblArray (upperLeft), RIGHT_ZOOM, width, asDblArray (upperRight)); acutPolar (asDblArray (upperRight), DOWN, height, asDblArray (lowerRight)); return TRUE; } TTempZoom::TTempZoom() { m_iCmdEcho = 0; m_bAllInSide = TRUE; m_bRestore = FALSE; } TTempZoom::TTempZoom(const ads_point pt1, const ads_point pt2,BOOL bPtIsUcs) { m_bRestore = FALSE; m_bAllInSide = FALSE; ads_point pt11,pt22; ads_point_set(pt1,pt11); ads_point_set(pt2,pt22); if (bPtIsUcs) { acdbUcs2Wcs(pt11,pt11,false); acdbUcs2Wcs(pt22,pt22,false); } //得到ucs 的屏幕范围点 ScrCorner(m_pt1, m_pt2); ads_point pt111,pt222; acdbWcs2Ucs(pt11,pt111,false); acdbWcs2Ucs(pt22,pt222,false); ads_point ptMin,ptMax; Min(pt111, m_pt1,ptMin); Max(pt222, m_pt2,ptMax); if (PointInSide(pt111,m_pt1,m_pt2) && PointInSide(pt222,m_pt1,m_pt2)) { m_bAllInSide = TRUE; return; } acedGetVar(_T("ELEVATION"),&m_rbElevation); //保存当前的ucs 坐标系 acedGetAcadDwgView()->SetRedraw(FALSE); struct resbuf rb; acedGetVar(_T("CMDECHO"), &rb); m_iCmdEcho = rb.resval.rint; rb.resval.rint = 0; acedSetVar(_T("CMDECHO"), &rb); acedCommand(RTSTR, _T("UCS"), RTSTR, _T("S"), RTSTR, _T("TTempZoom"), RTNONE); //回复为世界坐标系进行比较 acedCommand(RTSTR, _T("UCS"), RTSTR, _T(""), RTNONE); acedSetVar(_T("ELEVATION"),&m_rbElevation); ScrCorner(m_pt1, m_pt2); m_bRestore = (AssureInCurrentView(pt11, pt22) == Acad::eOk); acedGetAcadDwgView()->SetRedraw(TRUE); acTransactionManagerPtr()->enableGraphicsFlush(true); acedUpdateDisplay(); acTransactionManagerPtr()->flushGraphics(); } TTempZoom::~TTempZoom() { if (!m_bAllInSide) { if(m_bRestore) { arxZoom(m_pt1, m_pt2); } acedGetAcadDwgView()->SetRedraw(FALSE); acedCommand(RTSTR, _T("UCS"), RTSTR, _T("R"), RTSTR, _T("TTempZoom"), RTNONE); acedCommand(RTSTR, _T("UCS"), RTSTR, _T("D"), RTSTR, _T("TTempZoom"), RTNONE); struct resbuf rb; rb.restype = RTSHORT; rb.resval.rint = m_iCmdEcho; acedSetVar(_T("CMDECHO"), &rb); acedSetVar(_T("ELEVATION"),&m_rbElevation); acedGetAcadDwgView()->SetRedraw(TRUE); acTransactionManagerPtr()->enableGraphicsFlush(true); acedUpdateDisplay(); acTransactionManagerPtr()->flushGraphics(); } } void TTempZoom::SetPoint(ads_point pt, double x, double y, double z) { pt[0] = x; pt[1] = y; pt[2] = z; } void TTempZoom::Mid(const ads_point p1, const ads_point p2, ads_point dest) { dest[0] = (p1[0] + p2[0]) / 2.0; dest[1] = (p1[1] + p2[1]) / 2.0; dest[2] = (p1[2] + p2[2]) / 2.0; } int TTempZoom::ScrCorner(ads_point lowerpt, ads_point upperpt) { AcGePoint3d lowerLeft,upperLeft,upperRight,lowerRight; GetScreenLimits(lowerLeft,upperLeft,upperRight,lowerRight); SetPoint(lowerpt,lowerLeft.x,lowerLeft.y,lowerLeft.z); SetPoint(upperpt,upperRight.x,upperRight.y,upperRight.z); return RTNORM; } void TTempZoom::Max(const ads_point pt1, const ads_point pt2,ads_point pt3) { pt3[0] = max(pt1[0], pt2[0]); pt3[1] = max(pt1[1], pt2[1]); pt3[2] = max(pt1[2], pt2[2]); } void TTempZoom::Min(const ads_point pt1, const ads_point pt2,ads_point pt3) { pt3[0] = min(pt1[0], pt2[0]); pt3[1] = min(pt1[1], pt2[1]); pt3[2] = min(pt1[2], pt2[2]); } int TTempZoom::ScrSize(ads_real *width, ads_real *height) { struct resbuf screensize, viewsize; ads_getvar(_T("SCREENSIZE"), &screensize); ads_getvar(_T("VIEWSIZE"), &viewsize); *height = viewsize.resval.rreal; *width = screensize.resval.rpoint[X] / screensize.resval.rpoint[Y]*(*height); return RTNORM; } void TTempZoom::InitView(AcDbViewTableRecord& view) { struct resbuf rb0,rb1,rb2; rb0.restype = RTSHORT; rb0.resval.rint = 0; rb0.rbnext = NULL; rb1.restype = RTSHORT; rb1.resval.rint = 1; rb1.rbnext = NULL; rb2.restype = RTSHORT; rb2.resval.rint = 2; rb2.rbnext = NULL; struct resbuf rb; acedGetVar(_T("VIEWMODE"),&rb); int viewmode = rb.resval.rint; ads_point ptViewCtr; acedGetVar(_T("VIEWCTR"),&rb); ads_point_set(rb.resval.rpoint,ptViewCtr); ads_point ptDcs; acedTrans(ptViewCtr, &rb1, &rb2, 0, ptDcs); acedGetVar(_T("CVPORT"),&rb); int nCurVp = rb.resval.rint; view.setIsPaperspaceView(nCurVp==1); view.setCenterPoint(asPnt2d(ptDcs)); double nWidth, nHeight; ScrSize(&nWidth, &nHeight); view.setHeight( nHeight); view.setWidth( nWidth ); ads_point vtViewDir; acedGetVar(_T("VIEWDIR"),&rb); ads_point_set(rb.resval.rpoint,vtViewDir); acedTrans(vtViewDir, &rb1, &rb2, 1, vtViewDir); view.setViewDirection(asPnt3d(vtViewDir).asVector()); acedGetVar(_T("VIEWTWIST"),&rb); double viewtwist = rb.resval.rreal; view.setViewTwist(viewtwist); ads_point target; acedGetVar(_T("TARGET"),&rb); ads_point_set(rb.resval.rpoint,target); acedTrans(target, &rb1, &rb0, 0, target); view.setTarget(asPnt3d(target)); if(viewmode & 0x01) { view.setPerspectiveEnabled(true); if(viewmode & 0x04) { acedGetVar(_T("BACKZ"),&rb); double backz = rb.resval.rreal; view.setBackClipEnabled(true); view.setBackClipDistance(backz); } if(viewmode & 0x02) { view.setFrontClipEnabled(true); if(viewmode & 0x10) { view.setFrontClipAtEye(false); acedGetVar(_T("FRONTZ"),&rb); double frontz = rb.resval.rreal; view.setFrontClipDistance(frontz); } else { view.setFrontClipAtEye(true); } } acedGetVar(_T("LENSLENGTH"),&rb); double lenslength = rb.resval.rreal; view.setLensLength(lenslength); } } Acad::ErrorStatus TTempZoom::arxPan(AcGeVector2d& vtPan) { AcDbViewTableRecord view; InitView(view); AcGePoint2d ptViewCtr = view.centerPoint(); ptViewCtr += vtPan; view.setCenterPoint(ptViewCtr); return acedSetCurrentView( &view, NULL ); } Acad::ErrorStatus TTempZoom::arxZoomTo(const ads_point ptCen, double nWidth, double nHeight) { AcDbViewTableRecord view; InitView(view); struct resbuf rb0,rb2; rb0.restype = RTSHORT; rb0.resval.rint = 0; rb0.rbnext = NULL; rb2.restype = RTSHORT; rb2.resval.rint = 2; rb2.rbnext = NULL; ads_point ptDcs; acedTrans(ptCen, &rb0, &rb2, 0, ptDcs); view.setCenterPoint(asPnt2d(ptDcs)); view.setHeight( nHeight); view.setWidth( nWidth ); return acedSetCurrentView( &view, NULL ); } Acad::ErrorStatus TTempZoom::arxZoom(const ads_point ptLow, const ads_point ptUp) { AcDbViewTableRecord view; InitView(view); AcGePoint2d max_2d = asPnt2d(ptUp), min_2d = asPnt2d(ptLow); ads_point ptCen; Mid(ptLow, ptUp, ptCen); struct resbuf rb0,rb2; rb0.restype = RTSHORT; rb0.resval.rint = 0; rb0.rbnext = NULL; rb2.restype = RTSHORT; rb2.resval.rint = 2; rb2.rbnext = NULL; ads_point ptDcs; ads_trans(ptCen, &rb0, &rb2, 0, ptDcs); view.setCenterPoint(asPnt2d(ptDcs)); view.setHeight( fabs(ptUp[1] - ptLow[1]) ); view.setWidth( fabs(ptUp[0] - ptLow[0]) ); return acedSetCurrentView( &view, NULL ); } BOOL TTempZoom::PointInSide(const ads_point pt,const ads_point ptLow, const ads_point ptUp) { if ( (pt[X] - ptLow[X] > 1.e-10 && pt[Y] - ptLow[Y] > 1.e-10) && (pt[X] - ptUp[X] < 1.e-10 && pt[Y] - ptUp[Y] < 1.e-10) ) { return TRUE; } return FALSE; } Acad::ErrorStatus TTempZoom::AssureInCurrentView(const ads_point ptLow, const ads_point ptUp) { ads_point pt1,pt2; ads_point_set(ptLow,pt1); ads_point_set(ptUp,pt2); pt1[2] = pt2[2] = m_pt1[2]; ads_point ptMin,ptMax; Min(pt1, m_pt1,ptMin); Max(pt2, m_pt2,ptMax); Acad::ErrorStatus es = Acad::eNotApplicable; if (PointInSide(ptUp,m_pt1,m_pt2) && PointInSide(ptLow,m_pt1,m_pt2)) { //点都在屏幕范围内 } else //点不在屏幕当前视图之内 { double dScrNW = m_pt2[0] - m_pt1[0]; double dScrnH = m_pt2[1] - m_pt1[1]; double dPickW = ptMax[0] - ptMin[0]; double dPickH = ptMax[1] - ptMin[1]; if (dPickW - dScrNW < 1.e-10 && dPickH - dScrnH < 1.e-10) { //目标矩形的尺寸小于当前视图的尺寸, 用PAN的方式 ads_point ptFrom, ptTo; Mid(m_pt1, m_pt2, ptFrom); Mid(ptLow, ptUp, ptTo); AcGeVector2d vtPan; vtPan.set(ptTo[0] - ptFrom[0],ptTo[1] - ptFrom[1]); es = arxPan(vtPan); } else { //目标矩形的尺寸大于当前视图的尺寸, 用ZOOM的方式 es = arxZoom(ptMin,ptMax); } } return es; }