399 lines
9.5 KiB
C++
399 lines
9.5 KiB
C++
#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;
|
|
} |