- UID
- 1
- 积分
- 15892
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-1-3
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
- PAN & ZOOM USING ACGSVIEW
- Product AUTOCAD Author LEE,HENRY
- Date 30-APR-99 Document ID 32452
- Expiration date Attachments 32452.zip
- Keywords API_TAHOE_OK
- Developer Consulting Group technical solution. Autodesk confidential, for ADN members only. Please read the disclaimer
- Question
- ObjectARX 2000 has AcGs classes specially the AcGsView object. Can I use
- AcGsView to pan and zoom programmatically?
- Answer
- The key to the pan and zoom capability of AcGsView is to initialize the
- object properly. There is a global function acgsGetGsView() which will help
- you to do so. However, it is design to retrieve the persistently shaded
- AcGsView associated with the specified viewport. This method will return NULL
- if there is no such view unless the bCreateIfNone flag is set to true; in
- this case, an AcGsView will be created and linked to the specified viewport.
- Moreover, it is designed to work in 3D view. But, 2D view is just a special
- case of 3D view. We can certainly mimic the 2D view situation.
- So, the very first thing is asking AutoCAD to generate an AcGsView object
- under all circumstances.
- bool getGsViewObj(AcGsView*& pView, int& vportNum)
- {
- struct resbuf rb;
- int rt = acedGetVar("CVPORT", &rb);
- if(rt != RTNORM)
- {
- acutPrintf("\nError acquiring sysvar "CVPORT" value.");
- return false;
- }
- vportNum = rb.resval.rint;
- pView = acgsGetGsView(vportNum, true);
- if(!pView)
- {
- acutPrintf("\nError obtaining AcGsView object.");
- return false;
- }
- return true;
- }
- Secondly, we need to verify if we are dealing with paper space or not. This
- is mainly because, paper space is a 2D space.
- //
- // see solution 1881
- //
- bool purePaperSpace()
- {
- struct resbuf rb;
- int nTileMode, nVport;
- acedGetVar("tilemode", &rb);
- nTileMode = rb.resval.rint;
- acedGetVar("cvport", &rb);
- nVport = rb.resval.rint;
- if(nTileMode == 0 && nVport == 1)
- return true;
- else
- return false;
- }
- In the case of panning, it is a matter of transforming the view target point
- based on the user input.
- void myPan()
- {
- acedDwgPoint pt1, pt2;
- if(!get2Points(pt1, pt2, false))
- return;
- AcGsView* pView = NULL;
- int vportNum;
- if(!getGsViewObj(pView, vportNum))
- return;
- AcGePoint3d camaraPt = pView->position();
- AcGeVector3d upVector = pView->upVector();
- double fieldWd = pView->fieldWidth();
- double fieldHt = pView->fieldHeight();
- double xShift = pt1[X] - pt2[X];
- double yShift = pt1[Y] - pt2[Y];
-
- AcGePoint3d targetOrinPt = pView->target();
- AcGePoint3d targetPt(targetOrinPt.x + xShift,
- targetOrinPt.y + yShift, targetOrinPt.z);
- AcGsView::Projection projType = pView->isPerspective() ?
- AcGsView::Projection::kPerspective :
- AcGsView::Projection::kParallel;
- pView->setView(camaraPt, targetPt, upVector, fieldWd, fieldHt,
- projType);
- pView->update();
-
- if(purePaperSpace())
- {
- tweakToUpdateWindow();
- acgsSetViewParameters(vportNum, pView, false, true);
- }
- else
- acgsSetViewParameters(vportNum, pView, true, true);
- }
- In the case of zooming, it is a matter of resetting the view target point and
- also the view window size based on the use input.
- void myZoom()
- {
- acedDwgPoint pt1, pt2;
- if(!get2Points(pt1, pt2, true))
- return;
- AcGsView* pView = NULL;
- int vportNum;
- if(!getGsViewObj(pView, vportNum))
- return;
- AcGePoint3d camaraPt = pView->position();
- AcGeVector3d upVector = pView->upVector();
- double xMin = min(pt1[X], pt2[X]);
- double xMax = max(pt1[X], pt2[X]);
- double yMin = min(pt1[Y], pt2[Y]);
- double yMax = max(pt1[Y], pt2[Y]);
- double fieldWd = xMax - xMin;
- double fieldHt = yMax - yMin;
- AcGePoint3d targetPt(xMin+fieldWd/2, yMin+fieldHt/2, 0);
- AcGsView::Projection projType = pView->isPerspective() ?
-
- AcGsView::Projection::kPerspective :
- AcGsView::Projection::kParallel;
- pView->setView(camaraPt, targetPt, upVector, fieldWd, fieldHt,
- projType);
- pView->update();
-
- if(purePaperSpace())
- {
- tweakToUpdateWindow();
- acgsSetViewParameters(vportNum, pView, false, true);
- }
- else
- acgsSetViewParameters(vportNum, pView, true, true);
- }
- You probably wondering at this point, why there is a tweakToUpdateWindow();
- function call if it is paper space?
- Well, that is where the limitation of AcGsView generated from the
- acgsGetGsView() coming in. The view parameters are calculated properly, but
- the view is not update by the setView(), update() and
- acgsSetViewParameters(). Nor it will be updated by acedUpdateDisplay(). So
- the workaround that I can come up with, is to calculated the view window
- client area size and move the window just slightly to force AutoCAD to update
- the paper space viewport.
- void tweakToUpdateWindow()
- {
- CView* pActiveView =
- acedGetAcadFrame()->GetActiveFrame()->GetActiveView();
- CRect rect;
- pActiveView->GetClientRect(&rect);
- rect.InflateRect(1,0,16,0);
- pActiveView->MoveWindow(rect, TRUE);
- }
- Please find the attached project for all the related code in its entirety.
- See also,
- solution 8781 - HOW TO SIMULATE ZOOM WINDOW IN OBJECTARX WITHOUT
- ADS_COMMAND()
- solution 1881 - HOW DO I KNOW I'M IN PAPERSPACE FOR SURE
复制代码 |
|