988 lines
25 KiB
C++
988 lines
25 KiB
C++
#include "stdafx.h"
|
|
#include "stdarx.h"
|
|
#include "resource.h"
|
|
#include "GsPreviewCtrl.h"
|
|
#include "dbsymtb.h "
|
|
#include"acgs.h "
|
|
#include "dbents.h "
|
|
#include"acutmem.h "
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#ifndef GCL_HCURSOR
|
|
#define GCL_HCURSOR (-12)
|
|
#endif
|
|
|
|
|
|
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_SETFOCUS()
|
|
ON_WM_LBUTTONUP()
|
|
ON_WM_LBUTTONDBLCLK()
|
|
// ON_MESSAGE(WM_MOUSELEAVE,OnMouseLeave)
|
|
ON_WM_DESTROY()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CGsPreviewCtrl message handlers
|
|
//获得一个数据库活动视图的信息,如宽,高,视点等
|
|
bool GetViewPortInfoByPath(AcDbDatabase *pDb, ads_real &height, ads_real &width, AcGePoint3d &target, AcGeVector3d &viewDir, ads_real &viewTwist, bool getViewCenter)
|
|
{
|
|
AcGiViewportDraw *pDraw = NULL;
|
|
// acedVports2VportTableRecords();
|
|
AcDbObjectId RcdId;
|
|
AcDbViewportTable *pVTable = NULL;
|
|
Acad::ErrorStatus es = pDb->getViewportTable(pVTable, AcDb::kForRead); //视区表
|
|
if (es == Acad::eOk)
|
|
{
|
|
AcDbViewportTableRecord *pViewPortRec = NULL;
|
|
es = pVTable->getAt(_T("*Active"), pViewPortRec, AcDb::kForRead);//活动视区表记录
|
|
if (es == Acad::eOk)
|
|
{
|
|
height = pViewPortRec->height(); //视区宽度
|
|
width = pViewPortRec->width(); //视区高度
|
|
if (getViewCenter == true) //获得当前数据库中模型空间的视点
|
|
{
|
|
struct resbuf rb;
|
|
memset(&rb, 0, sizeof(struct resbuf));
|
|
acedGetVar(_T("VIEWCTR"), &rb);
|
|
target = AcGePoint3d(rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]);
|
|
}
|
|
else //获得pViewPortRec视区的视点
|
|
{
|
|
target = pViewPortRec->target(); //视点
|
|
}
|
|
|
|
viewDir = pViewPortRec->viewDirection(); //三伪观察时的观看方向,如CAD中的东南轴测,西南轴测方向
|
|
viewTwist = pViewPortRec->viewTwist();
|
|
}
|
|
pVTable->close();
|
|
pViewPortRec->close();
|
|
}
|
|
return (true);
|
|
}
|
|
|
|
void CGsPreviewCtrl::OnPaint()
|
|
{
|
|
CPaintDC dc(this);
|
|
|
|
CView *pView = acedGetAcadDwgView();
|
|
if (!pView)
|
|
{
|
|
mpDevice = NULL;
|
|
|
|
return;
|
|
}
|
|
if (!mpView)
|
|
return;
|
|
mpView->invalidate();
|
|
mpView->update();
|
|
}
|
|
void CGsPreviewCtrl::ReleaseDb()
|
|
{
|
|
if (pDescDb!=NULL)
|
|
{
|
|
delete pDescDb;
|
|
pDescDb = NULL;
|
|
}
|
|
}
|
|
// Erase view and delete model
|
|
void CGsPreviewCtrl::erasePreview()
|
|
{
|
|
if (mpView)
|
|
mpView->eraseAll();
|
|
if (mpManager && mpModel) {
|
|
mpManager->destroyAutoCADModel(mpModel);
|
|
mpModel = NULL;
|
|
}
|
|
if (pDescDb!=NULL)
|
|
{
|
|
delete pDescDb;
|
|
pDescDb = 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 CAD_GetVarInt(CString sMode, int &nRet)
|
|
{
|
|
resbuf *pRb = acutBuildList(RTSHORT, 23, 0);
|
|
acedGetVar(sMode, pRb);
|
|
if (pRb == NULL)
|
|
{
|
|
acutRelRb(pRb);
|
|
return;
|
|
}
|
|
nRet = pRb->resval.rint;
|
|
acutRelRb(pRb);
|
|
}
|
|
|
|
void CAD_SetvarInt(CString sMode, int nRet)
|
|
{
|
|
resbuf *pNewRb = acutBuildList(RTSHORT, nRet, 0);
|
|
acedSetVar(sMode, pNewRb);
|
|
acutRelRb(pNewRb);
|
|
}
|
|
|
|
void CGsPreviewCtrl::setBkGroundColor()
|
|
{
|
|
// 设置背景色
|
|
// 设置背景色
|
|
if (mpDevice==NULL||mpView==NULL)return;
|
|
AcColorSettings pColorSettings;
|
|
// get the AutoCAD current colour settings
|
|
acedGetCurrentColors(&pColorSettings);
|
|
Adesk::UInt32 colorDW; // get the background colour
|
|
int nMode;
|
|
CAD_GetVarInt(_T("TILEMODE"), nMode);
|
|
if (nMode==0)
|
|
colorDW = Adesk::UInt32(pColorSettings.dwGfxLayoutBkColor);
|
|
else
|
|
colorDW = Adesk::UInt32(pColorSettings.dwGfxModelBkColor);
|
|
AcGsColor color;// = mpDevice->getBackgroundColor();
|
|
color.m_blue = GetBValue(colorDW);
|
|
color.m_green = GetGValue(colorDW);
|
|
color.m_red = GetRValue(colorDW);
|
|
color.m_filler = 0;
|
|
BOOL bRet = mpDevice->setBackgroundColor(color);
|
|
mpView->invalidate();
|
|
mpView->update();
|
|
}
|
|
void CGsPreviewCtrl::init(HMODULE hRes, bool bCreateModel)
|
|
{
|
|
mbModelCreated = bCreateModel;
|
|
mhPanCursor = LoadCursor(hRes, MAKEINTRESOURCE(IDI_PAN));
|
|
mhCrossCursor = LoadCursor(hRes, MAKEINTRESOURCE(IDI_CROSS));
|
|
mhOrbitCursor = LoadCursor(hRes, MAKEINTRESOURCE(IDI_ORBIT));
|
|
::SetClassLong(m_hWnd, GCL_HCURSOR, NULL);
|
|
|
|
CRect rect;
|
|
{
|
|
mpManager = acgsGetGsManager();
|
|
#if (ARX >= 20)
|
|
AcGsKernelDescriptor desc;
|
|
desc.addRequirement(AcGsKernelDescriptor::k3DDrawing);
|
|
mpFactory = AcGsManager::acquireGraphicsKernel(desc);
|
|
if (!mpFactory) return;
|
|
mpDevice = mpManager->createAutoCADDevice(*mpFactory, m_hWnd);
|
|
#else
|
|
mpFactory = mpManager->getGSClassFactory();
|
|
mpDevice = mpManager->createAutoCADDevice(m_hWnd);
|
|
#endif
|
|
|
|
GetClientRect(&rect);
|
|
mpDevice->onSize(rect.Width(), rect.Height());
|
|
|
|
|
|
mpView = mpFactory->createView();
|
|
|
|
#ifndef ZWCAD
|
|
#if ARX < 20
|
|
mpView->setMode(AcGsView::k2DOptimized);
|
|
#else
|
|
AcGiVisualStyle style;
|
|
style.setType(AcGiVisualStyle::k2DWireframe);
|
|
mpView->setVisualStyle(style);
|
|
#endif
|
|
#else
|
|
#if defined(R24)
|
|
mpView->setMode(AcGsView::k2DOptimized);
|
|
#else
|
|
AcGiVisualStyle style;
|
|
style.setType(AcGiVisualStyle::k2DWireframe);
|
|
mpView->setVisualStyle(style);
|
|
#endif
|
|
#endif
|
|
|
|
{
|
|
#if (ARX >= 20)
|
|
mpModel = mpManager->createAutoCADModel(*mpFactory);
|
|
#else
|
|
mpModel = mpManager->createAutoCADModel();
|
|
#endif
|
|
mbModelCreated = true;
|
|
}
|
|
mpDevice->add(mpView);
|
|
}
|
|
}
|
|
|
|
|
|
void CGsPreviewCtrl::OnSize(UINT nType, int cx, int cy)
|
|
{
|
|
CRect rect;
|
|
if (mpDevice)
|
|
{
|
|
GetClientRect(&rect);
|
|
if (rect.Width()<10000&&acedGetAcadDwgView()!=NULL)
|
|
{
|
|
mpDevice->onSize(rect.Width(), rect.Height());
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CGsPreviewCtrl::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
|
|
{
|
|
if (mpView)
|
|
{
|
|
if (zDelta<0)
|
|
mpView->zoom(0.5);
|
|
else
|
|
mpView->zoom(1.5);
|
|
Invalidate();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void CGsPreviewCtrl::OnLButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
SetFocus();
|
|
mbOrbiting = true;
|
|
SetCapture();
|
|
::SetClassLong(m_hWnd, GCL_HCURSOR, NULL);
|
|
::SetCursor(mhOrbitCursor);
|
|
mStartPt = point;
|
|
}
|
|
|
|
void CGsPreviewCtrl::OnLButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
|
|
mbOrbiting = false;
|
|
::SetClassLong(m_hWnd, GCL_HCURSOR, (long)mhCrossCursor);
|
|
ReleaseCapture();
|
|
if (acedGetAcadDwgView()!=NULL)
|
|
acedGetAcadDwgView()->SetFocus();
|
|
}
|
|
|
|
void CGsPreviewCtrl::OnMButtonDown(UINT nFlags, CPoint point)
|
|
{
|
|
SetFocus();
|
|
mbPanning = true;
|
|
SetCapture();
|
|
::SetClassLong(m_hWnd, GCL_HCURSOR, NULL);
|
|
::SetCursor(mhPanCursor);
|
|
mStartPt = point;
|
|
}
|
|
|
|
void CGsPreviewCtrl::OnMButtonUp(UINT nFlags, CPoint point)
|
|
{
|
|
ReleaseCapture();
|
|
mbPanning = false;
|
|
::SetClassLong(m_hWnd, GCL_HCURSOR, (long)mhCrossCursor);
|
|
if (acedGetAcadDwgView()!=NULL)
|
|
acedGetAcadDwgView()->SetFocus();
|
|
}
|
|
|
|
void CGsPreviewCtrl::OnMouseMove(UINT nFlags, CPoint point)
|
|
{
|
|
if (acDocManagerPtr()->documentCount()<1)
|
|
return;
|
|
SetFocus();
|
|
if (mpView)
|
|
{
|
|
if (mbPanning) //平移
|
|
{
|
|
AcGeVector3d pan_vec(-(point.x-mStartPt.x), point.y-mStartPt.y, 0);
|
|
pan_vec.transformBy(mpView->viewingMatrix() * mpView->worldToDeviceMatrix().inverse());
|
|
mpView->dolly(pan_vec);
|
|
Invalidate();
|
|
mStartPt = point;
|
|
}
|
|
if (mbOrbiting) //旋转
|
|
{
|
|
const double Half_Pi = 1.570796326795;
|
|
AcGsDCRect view_rect;
|
|
mpView->getViewport(view_rect);
|
|
int nViewportX = (view_rect.m_max.x - view_rect.m_min.x) + 1;
|
|
int nViewportY = (view_rect.m_max.y - view_rect.m_min.y) + 1;
|
|
int centerX = int(nViewportX / 2.0f + view_rect.m_min.x);
|
|
int centerY = int(nViewportY / 2.0f + view_rect.m_min.y);
|
|
const double radius = min(nViewportX, nViewportY) * 0.4f;
|
|
AcGeVector3d last_vector((mStartPt.x - centerX) / radius,
|
|
-(mStartPt.y - centerY) / radius,
|
|
0.0);
|
|
|
|
if (last_vector.lengthSqrd() > 1.0) // outside the radius
|
|
last_vector.normalize();
|
|
else
|
|
last_vector.z = sqrt(1.0 - last_vector.x * last_vector.x - last_vector.y * last_vector.y);
|
|
|
|
AcGeVector3d new_vector((point.x - centerX) / radius,
|
|
-(point.y - centerY) / radius,
|
|
0.0);
|
|
|
|
if (new_vector.lengthSqrd() > 1.0) // outside the radius
|
|
new_vector.normalize();
|
|
else
|
|
new_vector.z = sqrt(1.0 - new_vector.x * new_vector.x - new_vector.y * new_vector.y);
|
|
AcGeVector3d rotation_vector(last_vector);
|
|
rotation_vector = rotation_vector.crossProduct(new_vector); // rotation_vector = last_vector x new_vector
|
|
|
|
AcGeVector3d work_vector(rotation_vector);
|
|
work_vector.z = 0.0f; // projection of rotation_vector onto xy plane
|
|
|
|
double roll_angle = atan2(work_vector.x,
|
|
work_vector.y);
|
|
double length = rotation_vector.length();
|
|
double orbit_y_angle = (length != 0.0) ? acos(rotation_vector.z / length) + Half_Pi : Half_Pi; // represents inverse cosine of the dot product of the
|
|
if (length > 1.0f) // rotation_vector and the up_vector divided by the
|
|
length = 1.0f; // magnitude of both vectors. We add pi/2 because we
|
|
// are making the up-vector parallel to the the rotation
|
|
double rotation_angle = asin(length); // vector ... up-vector is perpin. to the eye-vector.
|
|
|
|
mpView->roll(roll_angle); // 1: roll camera to make up vector coincident with rotation vector
|
|
mpView->orbit(0.0f, orbit_y_angle); // 2: orbit along y to make up vector parallel with rotation vector
|
|
mpView->orbit(rotation_angle, 0.0f); // 3: orbit along x by rotation angle
|
|
mpView->orbit(0.0f, -orbit_y_angle); // 4: orbit along y by the negation of 2
|
|
mpView->roll(-roll_angle); // 5: roll camera by the negation of 1
|
|
Invalidate();
|
|
mStartPt = point;
|
|
}
|
|
}
|
|
if (!m_bTracking)
|
|
{
|
|
TRACKMOUSEEVENT tme;
|
|
tme.cbSize = sizeof(tme);
|
|
tme.hwndTrack = m_hWnd;
|
|
tme.dwFlags = TME_LEAVE | TME_HOVER;
|
|
tme.dwHoverTime = 1;
|
|
m_bTracking = _TrackMouseEvent(&tme);
|
|
}
|
|
|
|
}
|
|
|
|
LRESULT CGsPreviewCtrl::OnNcHitTest(CPoint point)
|
|
{
|
|
return HTCLIENT;
|
|
}
|
|
|
|
|
|
void CGsPreviewCtrl::OnSetFocus(CWnd *pOldWnd)
|
|
{
|
|
::SetClassLong(m_hWnd, GCL_HCURSOR, (long)mhCrossCursor);
|
|
|
|
}
|
|
BOOL GetAttdefByBlockIdNew(AcDbObjectId BlockId, CStringArray &strTags, CStringArray &strPromts, CStringArray &strContents)
|
|
{
|
|
// 如果我们在这里结束程序,我们将看到当前图形中source.dwg已经被作为图块插入.但是图块中没有source.dwg所定义的Attibute. 因此我们还要做工作.后面的事情就简单了.
|
|
// acDocManagerPtr()->lockDocument(curDoc());
|
|
|
|
AcDbBlockTableRecord *pBlockDef;
|
|
if (acdbOpenObject(pBlockDef, BlockId, AcDb::kForRead) != Acad::eOk)
|
|
return FALSE;
|
|
|
|
AcDbBlockTableRecordIterator *pIterator;
|
|
pBlockDef->newIterator(pIterator);
|
|
AcGePoint3d basePoint;
|
|
AcDbEntity *pEnt;
|
|
AcDbAttributeDefinition *pAttdef;
|
|
for (pIterator->start(); !pIterator->done();
|
|
pIterator->step())//将source.dwg中所有的Attibute进行遍历
|
|
{
|
|
pIterator->getEntity(pEnt, AcDb::kForRead);
|
|
pAttdef = AcDbAttributeDefinition::cast(pEnt);
|
|
if (pAttdef != NULL && !pAttdef->isConstant())
|
|
{
|
|
strTags.Add(pAttdef->tag());
|
|
strPromts.Add(pAttdef->prompt());
|
|
strContents.Add(pAttdef->textString());
|
|
}
|
|
pEnt->close(); // use pEnt... pAttdef might be NULL
|
|
}
|
|
pBlockDef->close();
|
|
delete pIterator;
|
|
if (strTags.GetSize() > 0)
|
|
return TRUE;
|
|
else
|
|
return FALSE;
|
|
}
|
|
|
|
void GetRcdWidthAndHeight(AcDbObjectId BlockId, AcGePoint3d &extMax, AcGePoint3d &extMin)
|
|
{
|
|
AcDbExtents ex;
|
|
BOOL bAtt = FALSE;// 判断是不是属性快
|
|
if (BlockId==NULL)
|
|
return;
|
|
|
|
AcDbBlockReference *pBlkRef = new AcDbBlockReference(AcGePoint3d(0, 0, 0), BlockId);
|
|
|
|
pBlkRef->setScaleFactors(AcGeScale3d(1, 1, 1));
|
|
pBlkRef->setRotation(0);
|
|
|
|
pBlkRef->getGeomExtents(ex);
|
|
|
|
extMax = ex.maxPoint();
|
|
extMin = ex.minPoint();
|
|
extMax.z = 0;
|
|
extMin.z = 0;
|
|
//
|
|
|
|
CStringArray strTags;
|
|
CStringArray strPromts;
|
|
CStringArray strContents;
|
|
CStringArray strContentsNew;
|
|
CString sPrompt;
|
|
acDocManagerPtr()->unlockDocument(curDoc());
|
|
//判断是不是属性块
|
|
if (!GetAttdefByBlockIdNew(BlockId, strTags, strPromts, strContents))
|
|
{
|
|
delete pBlkRef;
|
|
return;
|
|
}
|
|
int nLen = 0;
|
|
AcDbObjectId newEntId;
|
|
CString strTag;
|
|
CString strPromt;
|
|
|
|
AcDbBlockTableRecord *pBlockDef;
|
|
acdbOpenObject(pBlockDef, BlockId, AcDb::kForRead);
|
|
|
|
|
|
AcDbBlockTableRecordIterator *pIterator;
|
|
pBlockDef->newIterator(pIterator);
|
|
AcGePoint3d basePoint;
|
|
AcDbEntity *pEnt;
|
|
AcDbAttributeDefinition *pAttdef;
|
|
AcDbObjectIdArray attIds;
|
|
AcGePoint3d ptMax;
|
|
AcGePoint3d ptMin;
|
|
AcGePoint3d pt1;
|
|
AcGePoint3d pt2;
|
|
for (pIterator->start(); !pIterator->done();
|
|
pIterator->step())//将source.dwg中所有的Attibute进行遍历
|
|
{
|
|
pIterator->getEntity(pEnt, AcDb::kForRead);
|
|
pAttdef = AcDbAttributeDefinition::cast(pEnt);
|
|
if (pAttdef != NULL && !pAttdef->isConstant()) {
|
|
AcDbAttribute *pAtt = new AcDbAttribute();
|
|
pAtt->setPropertiesFrom(pAttdef);
|
|
double dHeight = pAttdef->height();
|
|
double dWidth = pAttdef->widthFactor()*dHeight*strContents[nLen++].GetLength();
|
|
pAtt->setInvisible(pAttdef->isInvisible());
|
|
basePoint = pAttdef->position();
|
|
basePoint += pBlkRef->position().asVector();
|
|
pt1 = basePoint;
|
|
pt2 = basePoint;
|
|
if (nLen==1)
|
|
{
|
|
ptMax.x = pt1.x+dWidth;
|
|
ptMax.y = pt1.y+dHeight;
|
|
ptMin = pt2;
|
|
}
|
|
else
|
|
{
|
|
pt1.x += dWidth;
|
|
pt1.y += dHeight;
|
|
if (ptMax.x<pt1.x)
|
|
ptMax.x = pt1.x;
|
|
if (ptMax.y<pt1.y)
|
|
ptMax.y = pt1.y;
|
|
if (ptMin.x>pt2.x)
|
|
ptMin.x = pt2.x;
|
|
if (ptMin.y>pt2.y)
|
|
ptMin.y = pt2.y;
|
|
|
|
}
|
|
|
|
pAtt->setPosition(basePoint);
|
|
pAtt->setHeight(pAttdef->height());
|
|
pAtt->setTextStyle(pAttdef->textStyle());
|
|
pAtt->setWidthFactor(pAttdef->widthFactor());
|
|
pAtt->setRotation(pAttdef->rotation());
|
|
pAtt->setTag(pAttdef->tag());
|
|
pAtt->setFieldLength(pAttdef->fieldLength());
|
|
AcDbObjectId attId;
|
|
pBlkRef->appendAttribute(attId, pAtt);
|
|
pAtt->getGeomExtents(ex);
|
|
pAtt->close();
|
|
attIds.append(attId);
|
|
}
|
|
pEnt->close();
|
|
}
|
|
pBlockDef->close();
|
|
delete pBlkRef;
|
|
|
|
delete pIterator;
|
|
if (extMax.x<ptMax.x)
|
|
extMax.x = ptMax.x;
|
|
if (extMax.y<ptMax.y)
|
|
extMax.y = ptMax.y;
|
|
if (extMin.x>ptMin.x)
|
|
extMin.x = ptMin.x;
|
|
if (extMin.y>ptMin.y)
|
|
extMin.y = ptMin.y;
|
|
|
|
}
|
|
//得到某个块表记录中所有实体
|
|
void GetRecordExterns(AcDbBlockTableRecord *pRcd, AcGePoint3d &ptMax, AcGePoint3d &ptMin);
|
|
//在数据库pDb中插入内部块名为sBlkName(在m_sDwgName文件中) 并获得数据库的中所有实体的最大外接矩形范围
|
|
BOOL CGsPreviewCtrl::Asdkaddblock(AcDbDatabase *&pDb, AcGePoint3d &extMax, AcGePoint3d &extMin, CString sBlkName)
|
|
{
|
|
AcDbObjectId RcdId;
|
|
AcDbObjectId BlockId;
|
|
AcDbObjectIdArray RcdIds;
|
|
AcDbBlockTableRecord *pRec = NULL;
|
|
AcDbBlockTable *pBlockTable = NULL;
|
|
//{{modify by hrpacdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable,AcDb::kForRead);
|
|
if (pDb->getSymbolTable(pBlockTable, AcDb::kForRead)!=Acad::eOk)
|
|
return FALSE;
|
|
//
|
|
/*
|
|
if(pBlockTable->getAt(sBlkName,RcdId,FALSE )!=Acad::eOk)
|
|
return ;
|
|
m_RcdId=RcdId;
|
|
pBlockTable->close();
|
|
GetRcdWidthAndHeight(RcdId,extMax,extMin);*/
|
|
Acad::ErrorStatus es;
|
|
if ((es = pBlockTable->getAt(sBlkName, RcdId, FALSE))!=Acad::eOk)
|
|
return FALSE;
|
|
pBlockTable->close();
|
|
pBlockTable = NULL;
|
|
if (acdbOpenObject(pRec, RcdId, AcDb::kForRead)!=Acad::eOk)
|
|
return FALSE;
|
|
ACHAR *cmts;
|
|
pRec->comments(cmts);
|
|
m_sContent = cmts;
|
|
m_sContent.TrimLeft();
|
|
m_sContent.TrimRight();
|
|
free(cmts);
|
|
if (m_sContent==_T(""))
|
|
m_sContent = _T("未找到图块说明");
|
|
GetRecordExterns(pRec, extMax, extMin);
|
|
pRec->close();
|
|
pRec = NULL;
|
|
return TRUE;
|
|
}
|
|
|
|
//得到某个块表记录中所有实体
|
|
void GetRecordExterns(AcDbBlockTableRecord *pRcd, AcGePoint3d &extMax, AcGePoint3d &extMin)
|
|
{
|
|
AcGePoint3d ptMax;
|
|
AcGePoint3d ptMin;
|
|
BOOL bInit = TRUE;
|
|
AcDbExtents ex;
|
|
AcDbEntity *pEnt;
|
|
AcDbBlockTableRecordIterator *pIterator;
|
|
pRcd->newIterator(pIterator);
|
|
BOOL bFirst = TRUE;
|
|
|
|
CString strcontent;
|
|
for (pIterator->start(); !pIterator->done(); pIterator->step())
|
|
{
|
|
if (pIterator->getEntity(pEnt, AcDb::kForRead)!=Acad::eOk)
|
|
continue;
|
|
if (pEnt->getGeomExtents(ex)!=Acad::eOk)
|
|
{
|
|
AcGePoint3d pt1;
|
|
AcGePoint3d pt2;
|
|
if (pEnt->isKindOf(AcDbAttributeDefinition::desc()))
|
|
{
|
|
AcDbAttributeDefinition *pAttdef = AcDbAttributeDefinition::cast(pEnt);
|
|
double dHeight = pAttdef->height();
|
|
strcontent = pAttdef->textString();
|
|
double dWidth = pAttdef->widthFactor()*dHeight*strcontent.GetLength();
|
|
AcGePoint3d basePoint;
|
|
basePoint = pAttdef->position();
|
|
AcGePoint3d ptBase = AcGePoint3d(0, 0, 0);
|
|
basePoint += ptBase.asVector();
|
|
pt1 = basePoint;
|
|
pt2 = basePoint;
|
|
if (bFirst)
|
|
{
|
|
bFirst = FALSE;
|
|
ptMax.x = pt1.x+dWidth;
|
|
ptMax.y = pt1.y+dHeight;
|
|
ptMin = pt2;
|
|
}
|
|
else
|
|
{
|
|
pt1.x += dWidth;
|
|
pt1.y += dHeight;
|
|
if (ptMax.x<pt1.x)
|
|
ptMax.x = pt1.x;
|
|
if (ptMax.y<pt1.y)
|
|
ptMax.y = pt1.y;
|
|
if (ptMin.x>pt2.x)
|
|
ptMin.x = pt2.x;
|
|
if (ptMin.y>pt2.y)
|
|
ptMin.y = pt2.y;
|
|
|
|
}
|
|
|
|
pEnt->close();
|
|
pEnt = NULL;
|
|
}
|
|
continue;
|
|
}
|
|
pEnt->close();
|
|
pEnt = NULL;
|
|
if (bInit)
|
|
{
|
|
extMax = ex.maxPoint();
|
|
extMin = ex.minPoint();
|
|
bInit = FALSE;
|
|
}
|
|
else
|
|
{
|
|
AcGePoint3d pt1 = ex.maxPoint();
|
|
AcGePoint3d pt2 = ex.minPoint();
|
|
if (extMax.x<pt1.x)
|
|
extMax.x = pt1.x;
|
|
if (extMax.y<pt1.y)
|
|
extMax.y = pt1.y;
|
|
if (extMin.x>pt2.x)
|
|
extMin.x = pt2.x;
|
|
if (extMin.y>pt2.y)
|
|
extMin.y = pt2.y;
|
|
|
|
}
|
|
}
|
|
delete pIterator;
|
|
if (!bFirst)
|
|
{
|
|
if (extMax.x<ptMax.x)
|
|
extMax.x = ptMax.x;
|
|
if (extMax.y<ptMax.y)
|
|
extMax.y = ptMax.y;
|
|
if (extMin.x>ptMin.x)
|
|
extMin.x = ptMin.x;
|
|
if (extMin.y>ptMin.y)
|
|
extMin.y = ptMin.y;
|
|
}
|
|
}
|
|
void RcdtoDb(AcDbDatabase *pOrgDb, CString sBlockName, AcDbDatabase *&pDesDb)
|
|
{
|
|
AcDbBlockTable *pBlockTable;
|
|
AcDbObjectId BlockId;
|
|
if (pOrgDb->getSymbolTable(pBlockTable, AcDb::kForRead)!=Acad::eOk)
|
|
return;
|
|
#if ARX > 24
|
|
if (pBlockTable->getAt(sBlockName, BlockId)!=Acad::eOk)
|
|
#else
|
|
if (pBlockTable->getAt(sBlockName, BlockId, AcDb::kForRead)!=Acad::eOk)
|
|
#endif
|
|
return;
|
|
pBlockTable->close();
|
|
Acad::ErrorStatus es = pOrgDb->wblock(pDesDb, BlockId);
|
|
}
|
|
bool GetActiveViewPortInfo(ads_real &height, ads_real &width, AcGePoint3d &target, AcGeVector3d &viewDir, ads_real &viewTwist, bool getViewCenter)
|
|
{
|
|
// acedVports2VportTableRecords();
|
|
AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
|
|
if (pDb == NULL)
|
|
return false;
|
|
AcDbViewportTable *pVTable = NULL;
|
|
Acad::ErrorStatus es = pDb->getViewportTable(pVTable, AcDb::kForRead);
|
|
if (es == Acad::eOk)
|
|
{
|
|
AcDbViewportTableRecord *pViewPortRec = NULL;
|
|
es = pVTable->getAt(_T("*Active"), pViewPortRec, AcDb::kForRead);
|
|
if (es == Acad::eOk)
|
|
{
|
|
height = pViewPortRec->height();
|
|
width = pViewPortRec->width();
|
|
if (getViewCenter == true)
|
|
{
|
|
struct resbuf rb;
|
|
memset(&rb, 0, sizeof(struct resbuf));
|
|
acedGetVar(_T("VIEWCTR"), &rb);
|
|
target = AcGePoint3d(rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]);
|
|
}
|
|
else
|
|
{
|
|
target = pViewPortRec->target();
|
|
}
|
|
|
|
viewDir = pViewPortRec->viewDirection();
|
|
viewTwist = pViewPortRec->viewTwist();
|
|
}
|
|
pVTable->close();
|
|
pViewPortRec->close();
|
|
}
|
|
|
|
return (true);
|
|
}
|
|
|
|
BOOL IsOpenFile(CString strFileName, AcApDocument *&pOpenDoc);
|
|
//显示名称为sName的内部块
|
|
void CGsPreviewCtrl::ViewBlock(CString sDwgName, CString sName)
|
|
{
|
|
if (pDescDb!=NULL)
|
|
{
|
|
delete pDescDb;
|
|
pDescDb = NULL;
|
|
}
|
|
if (acDocManagerPtr()->documentCount()<1)
|
|
return;
|
|
|
|
CFileFind find;
|
|
if (!find.FindFile(sDwgName))
|
|
{
|
|
find.Close();
|
|
return;
|
|
}
|
|
find.Close();
|
|
|
|
//
|
|
|
|
AcDbObjectId BlockId;
|
|
AcGePoint3d extMax;
|
|
AcGePoint3d extMin;
|
|
m_sContent = _T("未找到图块说明");
|
|
init(_hdllInstance, TRUE);
|
|
setBkGroundColor();
|
|
acDocManagerPtr()->lockDocument(curDoc());
|
|
AcDbBlockTableRecord *pRcd = NULL;
|
|
AcDbBlockTable *pBlockTable = NULL;
|
|
m_sDwgName = sDwgName;
|
|
BOOL bIsOpenFile = FALSE;
|
|
AcApDocument *pDoc = NULL;
|
|
if (bIsOpenFile = IsOpenFile(sDwgName, pDoc))
|
|
{
|
|
pDescDb = pDoc->database();
|
|
}
|
|
else
|
|
{
|
|
pDescDb = new AcDbDatabase(Adesk::kFalse);
|
|
Acad::ErrorStatus es = pDescDb->readDwgFile(sDwgName);
|
|
if (es!=Acad::eOk)
|
|
{
|
|
acutPrintf(_T("\n无法读取文件信息"));
|
|
delete pDescDb;
|
|
pDescDb = NULL;
|
|
acDocManagerPtr()->unlockDocument(curDoc());
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!Asdkaddblock(pDescDb, extMax, extMin, sName))
|
|
{
|
|
acDocManagerPtr()->unlockDocument(curDoc());
|
|
if (!bIsOpenFile)
|
|
{
|
|
delete pDescDb;
|
|
pDescDb = NULL;
|
|
}
|
|
acutPrintf(_T("\n没有找到内部块"));
|
|
acDocManagerPtr()->unlockDocument(curDoc());
|
|
return;
|
|
}
|
|
|
|
if (pDescDb->getBlockTable(pBlockTable, AcDb::kForRead)==Acad::eOk)
|
|
{
|
|
pBlockTable->getAt(sName, pRcd, AcDb::kForRead);
|
|
pBlockTable->close();
|
|
pBlockTable = NULL;
|
|
}
|
|
ads_real height = 0.0, width = 0.0, viewTwist = 0.0;
|
|
AcGePoint3d targetView;
|
|
AcGeVector3d viewDir;
|
|
//modify by hrp
|
|
BOOL bRet = GetActiveViewPortInfo(height, width, targetView, viewDir, viewTwist, true);
|
|
|
|
viewDir = viewDir.normal();
|
|
AcGeVector3d viewXDir = viewDir.perpVector().normal();
|
|
viewXDir = viewXDir.rotateBy(viewTwist, -viewDir);
|
|
AcGeVector3d viewYDir = viewDir.crossProduct(viewXDir);
|
|
AcGePoint3d boxCenter = extMin + 0.5 * (extMax - extMin);
|
|
AcGeMatrix3d viewMat;
|
|
viewMat = AcGeMatrix3d::alignCoordSys(boxCenter, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis,
|
|
boxCenter, viewXDir, viewYDir, viewDir).inverse();
|
|
AcDbExtents wcsExtents(extMin, extMax);
|
|
AcDbExtents viewExtents = wcsExtents;
|
|
viewExtents.transformBy(viewMat);
|
|
double xMax = fabs(viewExtents.maxPoint().x - viewExtents.minPoint().x);
|
|
double yMax = fabs(viewExtents.maxPoint().y - viewExtents.minPoint().y);
|
|
AcGePoint3d eye = boxCenter + viewDir;
|
|
mpView->setView(eye, boxCenter, viewYDir,
|
|
xMax, yMax);
|
|
|
|
if (pRcd)
|
|
{
|
|
mpView->add(pRcd, model());
|
|
mpView->invalidate();
|
|
mpView->update();
|
|
pRcd->close();
|
|
pRcd = NULL;
|
|
}
|
|
|
|
/*if(pDescDb!=NULL)
|
|
{
|
|
delete pDescDb;
|
|
pDescDb=NULL;
|
|
} */
|
|
acDocManagerPtr()->unlockDocument(curDoc());
|
|
}
|
|
|
|
BOOL GetBlockId(CString sDwgFilePath, AcDbObjectId &BlockId)
|
|
{
|
|
acDocManagerPtr()->lockDocument(curDoc());
|
|
CString sFileName;
|
|
sFileName = sDwgFilePath.Right(sDwgFilePath.GetLength() - sDwgFilePath.ReverseFind('\\') - 1);
|
|
// sFileName.TrimRight(".dwg");
|
|
// sFileName.TrimRight(".DWG");
|
|
AcDbDatabase *pNewDb = new AcDbDatabase(Adesk::kFalse);
|
|
pNewDb->readDwgFile(sDwgFilePath);
|
|
AcDbBlockTable *pBlkTable = NULL;
|
|
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlkTable, AcDb::kForWrite);
|
|
if (pBlkTable->has(sFileName))
|
|
{
|
|
pBlkTable->getAt(sFileName, BlockId);
|
|
pBlkTable->close();
|
|
acDocManagerPtr()->unlockDocument(curDoc());
|
|
return TRUE;
|
|
}
|
|
pBlkTable->close();
|
|
acdbHostApplicationServices()->workingDatabase()->insert(BlockId, sFileName, pNewDb);
|
|
delete pNewDb;
|
|
acDocManagerPtr()->unlockDocument(curDoc());
|
|
return TRUE;
|
|
}
|
|
|
|
//设置控件要显示的DWG名称
|
|
void CGsPreviewCtrl::ViewDwg(CString sDwgName)
|
|
{
|
|
m_sDwgName = sDwgName;
|
|
mpView->eraseAll();
|
|
AcDbObjectIdArray RcdIds;
|
|
AcDbBlockTableRecord *pRec = NULL;
|
|
AcDbBlockTable *pTab = NULL;
|
|
Acad::ErrorStatus es;
|
|
AcDbDatabase *pDb = NULL;
|
|
pDb = new AcDbDatabase(Adesk::kFalse);
|
|
pDb->readDwgFile(m_sDwgName);
|
|
if (pDb==NULL)
|
|
return;
|
|
if ((es = pDb->getBlockTable(pTab, AcDb::kForRead))!=Acad::eOk)
|
|
return;
|
|
if ((es = pTab->getAt(ACDB_MODEL_SPACE, pRec, AcDb::kForWrite))!=Acad::eOk)
|
|
{
|
|
pTab->close();
|
|
return;
|
|
}
|
|
pTab->close();
|
|
RcdIds.setLogicalLength(0);
|
|
ads_real height = 0.0, width = 0.0, viewTwist = 0.0;
|
|
AcGePoint3d targetView;
|
|
AcGeVector3d viewDir;
|
|
GetActiveViewPortInfo(height, width, targetView, viewDir, viewTwist, true);
|
|
|
|
viewDir = viewDir.normal();
|
|
AcGePoint3d extMax = pDb->extmax();
|
|
AcGePoint3d extMin = pDb->extmin();
|
|
AcGeVector3d viewXDir = viewDir.perpVector().normal();
|
|
viewXDir = viewXDir.rotateBy(viewTwist, -viewDir);
|
|
AcGeVector3d viewYDir = viewDir.crossProduct(viewXDir);
|
|
AcGePoint3d boxCenter = extMin + 0.5 * (extMax - extMin);
|
|
AcGeMatrix3d viewMat;
|
|
viewMat = AcGeMatrix3d::alignCoordSys(boxCenter, AcGeVector3d::kXAxis, AcGeVector3d::kYAxis, AcGeVector3d::kZAxis,
|
|
boxCenter, viewXDir, viewYDir, viewDir).inverse();
|
|
AcDbExtents wcsExtents(extMin, extMax);
|
|
AcDbExtents viewExtents = wcsExtents;
|
|
viewExtents.transformBy(viewMat);
|
|
double xMax = fabs(viewExtents.maxPoint().x - viewExtents.minPoint().x);
|
|
double yMax = fabs(viewExtents.maxPoint().y - viewExtents.minPoint().y);
|
|
AcGePoint3d eye = boxCenter + viewDir;
|
|
|
|
mpView->setView(eye, boxCenter, viewYDir,
|
|
xMax, yMax);
|
|
mpView->add(pRec, model());
|
|
mpView->invalidate();
|
|
mpView->update();
|
|
Invalidate();
|
|
pRec->close();
|
|
GetBlockId(m_sDwgName, m_RcdId);
|
|
return;
|
|
}
|
|
|
|
void CGsPreviewCtrl::OnLButtonDblClk(UINT nFlags, CPoint point)
|
|
{
|
|
CStatic::OnLButtonDblClk(nFlags, point);
|
|
}
|
|
/*
|
|
LRESULT CGsPreviewCtrl::OnMouseLeave(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
m_bTracking = FALSE;
|
|
if(acedGetAcadDwgView()!=NULL)
|
|
acedGetAcadDwgView()->SetFocus();
|
|
return 0;
|
|
}
|
|
*/
|
|
|
|
void CGsPreviewCtrl::OnDestroy()
|
|
{
|
|
|
|
// clearAll();
|
|
/*if(pDescDb!=NULL)
|
|
{
|
|
delete pDescDb;
|
|
pDescDb = NULL;
|
|
} */
|
|
CStatic::OnDestroy();
|
|
|
|
}
|