📄 gspreviewctrl.cpp
字号:
//
// (C) Copyright 2002 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//
// GsPreviewCtrl.cpp : implementation file
//
#include "stdafx.h"
#include "resource.h"
#include "GsPreviewCtrl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CGsPreviewCtrl
BEGIN_MESSAGE_MAP(CGsPreviewCtrl, CStatic)
//{{AFX_MSG_MAP(CGsPreviewCtrl)
ON_WM_PAINT()
ON_WM_SIZE()
ON_WM_MOUSEWHEEL()
ON_WM_LBUTTONDOWN()
ON_WM_MBUTTONDOWN()
ON_WM_MBUTTONUP()
ON_WM_MOUSEMOVE()
ON_WM_NCHITTEST()
ON_WM_SETFOCUS()
ON_WM_LBUTTONUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGsPreviewCtrl message handlers
void CGsPreviewCtrl::OnPaint()
{
CPaintDC dc(this);
//update the gs view
mpView->invalidate();
mpView->update();
}
// Erase view and delete model
void CGsPreviewCtrl::erasePreview()
{
if (mpView)
mpView->eraseAll();
if (mpManager && mpModel) {
mpManager->destroyAutoCADModel (mpModel);
mpModel = NULL;
}
}
void CGsPreviewCtrl::setModel(AcGsModel* pModel)
{
erasePreview();
mpModel = pModel;
mbModelCreated =false;
}
void CGsPreviewCtrl::clearAll()
{
if (mpView)
{
mpView->eraseAll();
}
if (mpDevice)
{
bool b = mpDevice->erase(mpView);
RXASSERT(b);
}
if (mpFactory)
{
if (mpView)
{
mpFactory->deleteView(mpView);
mpView = NULL;
}
if (mpGhostModel)
{
mpFactory->deleteModel(mpGhostModel);
mpGhostModel = NULL;
}
mpFactory = NULL;
}
if (mpManager)
{
if (mpModel)
{
if (mbModelCreated)
mpManager->destroyAutoCADModel(mpModel);
mpModel = NULL;
}
if (mpDevice)
{
mpManager->destroyAutoCADDevice(mpDevice);
mpDevice = NULL;
}
mpManager = NULL;
}
}
void CGsPreviewCtrl::init(AcDbDatabase *pDb,HMODULE hRes, bool bCreateModel)
{
//Load our special cursors
// mhPanCursor = LoadCursor(hRes,MAKEINTRESOURCE(IDI_PAN));
// mhCrossCursor = LoadCursor(hRes,MAKEINTRESOURCE(IDI_CROSS));
// mhOrbitCursor = LoadCursor(hRes,MAKEINTRESOURCE(IDI_ORBIT));
// ::SetClassLong(m_hWnd,GCL_HCURSOR,NULL);
//Instantiate view, a device and a model object
CRect rect;
if (!mpManager)
{
// get the AcGsManager object for a specified AutoCAD MDI Client CView
mpManager = acgsGetGsManager();
RXASSERT(mpManager);
// get the GS class factory
mpFactory = mpManager->getGSClassFactory();
RXASSERT(mpFactory);
// create an AcGsDevice object. The window handle passed in to this
// function is the display surface onto which the graphics system draws
//a device with standard autocad color palette
mpDevice = mpManager->createAutoCADDevice(m_hWnd);
RXASSERT(mpDevice);
// get the size of the window that we are going to draw in
GetClientRect( &rect);
// make sure the gs device knows how big the window is
mpDevice->onSize(rect.Width(), rect.Height());
// construct a simple view
mpView = mpFactory->createView();
RXASSERT(mpView);
if (bCreateModel)
{
RXASSERT(mpModel==NULL);
// create an AcGsModel object with the AcGsModel::kMain RenderType
// (which is a hint to the graphics system that the geometry in this
// model should be rasterized into its main frame buffer). This
// AcGsModel is created with get and release functions that will open and close AcDb objects.
mpModel = mpManager->createAutoCADModel();
RXASSERT(mpModel);
mbModelCreated = true;
}
//another model without open/close for the orbit gadget
mpGhostModel = mpFactory->createModel(AcGsModel::kDirect,0,0,0);
mpView->add(&mOrbitGadget,mpGhostModel);
mOrbitGadget.setGsView(mpView);
mpDevice->add(mpView);
// get the view port information - see parameter list
ads_real height = 0.0, width = 0.0, viewTwist = 0.0;
AcGePoint3d targetView;
AcGeVector3d viewDir;
GetActiveViewPortInfo (pDb,height, width, targetView, viewDir, viewTwist, true);
//pDb->ucsxdir().crossProduct(pDb->ucsydir())
//pView->setView(position, target,
mpView->setView(targetView + viewDir, targetView,
AcGeVector3d(0.0, 1.0, 0.0), // upvector
1.0, 1.0);
/*mpView->setView(AcGePoint3d(0.0, 0.0, 1.0),
AcGePoint3d(0.0, 0.0, 0.0),
AcGeVector3d(0.0, 1.0, 0.0),
1.0, 1.0); */
}
}
void CGsPreviewCtrl::OnSize(UINT nType, int cx, int cy)
{
CRect rect;
if (mpDevice) {
GetClientRect( &rect);
mpDevice->onSize(rect.Width(), rect.Height());
}
}
//应用 CGsPreviewCtrl
//初始化CAD图元预控件
//mPreviewCtrl - 预览控件,初始化后返回初始化值
//pDb - 要预览的CAD图元的库
//space - 要预览库中的空间 (模型空间/图纸空间,默认模型空间)
Acad::ErrorStatus InitDrawingControl (CGsPreviewCtrl &mPreviewCtrl,AcDbDatabase *pDb, const TCHAR *space)
{
// have we got a valid drawing
if (pDb == NULL)
return Acad::eNullBlockName;
// get the blocktable
AcDbBlockTable *pTab = NULL;
Acad::ErrorStatus es = pDb->getBlockTable (pTab, AcDb::kForRead);
// if ok
if (es == Acad::eOk)
{
// get the space required
AcDbBlockTableRecord *pRec = NULL;
es = pTab->getAt (space, pRec, AcDb::kForRead);
// if ok
if (es == Acad::eOk)
{
pTab->close();
// initialize the preview control
mPreviewCtrl.init(pDb,theArxDLL.ModuleResourceInstance(),true);
// we are going to set the view to the current view of the drawing
// The overall approach is to calculate the extents of the database in the coordinate system of the view
// Calculate the extents in WCS
//遍历块表,得到最大点与最小点
double maxx,minx,maxy,miny,maxz,minz;
AcDbBlockTableRecordIterator *pIterator;
AcDbExtents extents;
int num=0;
maxx=minx=maxy=miny=maxz=minz=0;
pRec->newIterator(pIterator);
for(pIterator->start(); !pIterator->done(); pIterator->step())
{
AcDbEntity *pEnt;
if(pIterator->getEntity(pEnt,AcDb::kForRead)==Acad::eOk)
{
num++;
pEnt->getGeomExtents(extents);
if(num==1)
{
maxx=extents.maxPoint().x;
minx=extents.minPoint().x;
maxy=extents.maxPoint().y;
miny=extents.minPoint().y;
maxz=extents.maxPoint().z;
minz=extents.minPoint().z;
}
else
{
maxx=max(maxx,extents.maxPoint().x);
minx=min(minx,extents.minPoint().x);
maxy=max(maxy,extents.maxPoint().y);
miny=min(miny,extents.minPoint().y);
maxz=max(maxz,extents.maxPoint().z);
minz=min(minz,extents.minPoint().z);
}
pEnt->close();
}
}
delete pIterator;
AcGePoint3d extMax = AcGePoint3d(maxx+(maxx-minx)/10,maxy+(maxy-miny)/10,maxz+(maxz-minz)/10); //pDb->extmax();
AcGePoint3d extMin = AcGePoint3d(minx-(maxx-minx)/10,miny-(maxy-miny)/10,minz-(maxz-minz)/10); //pDb->extmin();
// get the view port information - see parameter list
ads_real height = 0.0, width = 0.0, viewTwist = 0.0;
AcGePoint3d targetView;
AcGeVector3d viewDir;
GetActiveViewPortInfo (pDb,height, width, targetView, viewDir, viewTwist, true);
// we are only interested in the directions of the view, not the sizes, so we normalise.
viewDir = viewDir.normal();
//**********************************************
// Our view coordinate space consists of z direction
// get a perp vector off the z direction
// Make sure its normalised
AcGeVector3d viewXDir = viewDir.perpVector ().normal();
// correct the x angle by applying the twist
viewXDir = viewXDir.rotateBy (viewTwist, -viewDir);
// now we can work out y, this is of course perp to the x and z directions. No need to normalise this,
// as we know that x and z are of unit length, and perpendicular, so their cross product must be on unit length
AcGeVector3d viewYDir = viewDir.crossProduct (viewXDir);
// find a nice point around which to transform the view. We'll use the same point as the center of the view.
AcGePoint3d boxCenter = extMin + 0.5 * ( extMax - extMin );
//**********************************************
// create a transform from WCS to View space
// this represents the transformation from WCS to the view space. (Actually not quite since
// we are keeping the fixed point as the center of the box for convenience )
AcGeMatrix3d viewMat;
viewMat = AcGeMatrix3d::alignCoordSys (boxCenter, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis,
boxCenter, viewXDir, viewYDir, viewDir).inverse();
AcDbExtents wcsExtents(extMin, extMax);
// now we have the view Extents
AcDbExtents viewExtents = wcsExtents;
// transforms the extents in WCS->view space
viewExtents.transformBy (viewMat);
//**********************************************
// get the extents of the AutoCAD view
double xMax = fabs(viewExtents.maxPoint ().x - viewExtents.minPoint ().x);
double yMax = fabs(viewExtents.maxPoint ().y - viewExtents.minPoint ().y);
//**********************************************
// setup the view
AcGsView *pView = mPreviewCtrl.view();
AcGePoint3d eye = boxCenter + viewDir;
// upvector
pView->setView(eye, boxCenter, viewYDir, xMax, yMax);
pView->add(pRec, mPreviewCtrl.model());
pRec->close();
}
}
return es;
}
//
bool GetActiveViewPortInfo (AcDbDatabase *pDb,ads_real &height, ads_real &width, AcGePoint3d &target, AcGeVector3d &viewDir, ads_real &viewTwist, bool getViewCenter)
{
// make sure the active view port is uptodate
acedVports2VportTableRecords();
// get the working db
//AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
// if not ok
if (pDb == NULL)
return false;
// open the view port records
AcDbViewportTable *pVTable = NULL;
Acad::ErrorStatus es = pDb->getViewportTable (pVTable, AcDb::kForRead);
// if we opened them ok
if (es == Acad::eOk)
{
AcDbViewportTableRecord *pViewPortRec = NULL;
es = pVTable->getAt (_T("*Active"), pViewPortRec, AcDb::kForRead);
if (es == Acad::eOk)
{
// get the height of the view
height = pViewPortRec->height ();
// get the width
width = pViewPortRec->width ();
// if the user wants the center of the viewport used
if (getViewCenter == true)
{
struct resbuf rb;
memset (&rb, 0, sizeof (struct resbuf));
// get the system var VIEWCTR
acedGetVar (_T("VIEWCTR"), &rb);
// set that as the target
target = AcGePoint3d (rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]);
}
// we want the viewports camera target setting
else
{
// get the target of the view
target = pViewPortRec->target ();
}
// get the view direction
viewDir = pViewPortRec->viewDirection ();
// get the view twist of the viewport
viewTwist = pViewPortRec->viewTwist ();
}
// close after use
pVTable->close ();
pViewPortRec->close();
}
return (true);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -