Files
envi-code/SourceCode/Code2026/AdsXRx/XAcGiViewDraw.cpp
T
2026-09-28 15:28:50 +08:00

1415 lines
31 KiB
C++

//-----------------------------------------------------------------------------+
// Copyright (C), 1998-2007, SH Software Co. Ltd.
// = FileName : XAcGiViewDraw 类
// = Version : ver2.0
// = Author : zjq
// = CreateDate : 2002-09-09
// = Description: XAcGiViewDraw 定义
// = Maintainers:
//
//-----------------------------------------------------------------------------+
#include "StdAfx.h"
#include "XAcGiViewDraw.h"
#include "XPathParser.h"
#include "XDbObject.h"
#include "dbhatch.h"
#include "AecEntity.h"
#include "XExplodeStream.h"
#include "XGlobalFunc.h"
#include "XAsdkCustomWorldDraw.h"
#include "XGlobalCurveFunc.h"
#include "XPrivateGlobalFunc.h"
// 画拉伸圆
inline void DrawCircle(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const XCircle &cir, ads_real nHeight)
{
AcDbPolyline line;
line.setElevation(cir.GetCenterPt().z);
line.setThickness(nHeight);
XPoint ptStart, ptEnd;
ads_polar(cir.GetCenterPt(), 0.0, cir.GetRadius(), ptStart);
ads_polar(cir.GetCenterPt(), PI, cir.GetRadius(), ptEnd);
line.addVertexAt(0, ptStart, tan(PI / 4.0));
line.addVertexAt(1, ptEnd, tan(PI / 4.0));
line.setClosed(Adesk::kTrue);
if (pWd)
{
line.worldDraw(pWd);
}
else
{
line.viewportDraw(pVd);
}
}
// 显示3d弧段
// 参数: pWd, pVd -- 必须有一个非NULL
// ar -- 待显示的弧段
// nHeight -- 厚度
// bShowStart -- 是否绘制起始边界线
// bShowEnd -- 是否绘制终止边界线
inline void DrawArcSeg(XExplodeDraw &dc, const XArc &ar, ads_real nHeight, int bShowStart, int bShowEnd)
{
// Modify on 2002/4/12 by , 避免大圆弧的出现
if (ar.Bulge() > 2 * PI - _angSnap || ar.GetLength() < _DIST_SNAP)
{
return;
}
if (_tcsicmp(dc.Desc(), XExplodeStream::Descriptor()) == 0)
{
dc.DrawArc(ar, nHeight);
return; //希望有渐变线
}
int nCirDiv = GetCirDivNum(ar.GetRadius(), _AS_SYS_UNIT(g_nCirDeviation));
ads_real intAng = fabs(ar.Bulge());
int n = AS_INT(intAng / PI / 2.0 * nCirDiv); //一个圆分解为50份
if (n < 1)
{
n = 1;
}
ads_real ang = intAng / n;
int nVertexNum = 2 * n + 2;
XPoint *ptArray = new XPoint[nVertexNum];
for (int i = 0; i < n + 1; i++)
{
ads_real drt = ar.GetStarAngle() + i * ang;
ads_polar(ar.GetCenterPt(), drt, ar.GetRadius(), ptArray[i]);
ptArray[i + n + 1] = ptArray[i];
ptArray[i + n + 1].z += nHeight;
}
AcGiEdgeData edge;
Adesk::UInt8 *visibleData = new Adesk::UInt8[3 * n + 1];
for (int j = 0; j < 2 * n; j++)
{
visibleData[j] = kAcGiVisible;
}
visibleData[2 * n] = bShowStart ? kAcGiVisible:kAcGiInvisible;
visibleData[3 * n] = bShowEnd ? kAcGiVisible:kAcGiInvisible;
for (int j = 2 * n + 1; j < 3 * n; j++)
{
visibleData[j] = kAcGiInvisible;
}
edge.setVisibility(visibleData);
dc.DrawMesh(2, n + 1, (AcGePoint3d *)ptArray, &edge);
delete [] ptArray;
delete [] visibleData;
}
// 显示3d线段
// 参数: pWd, pVd -- 必须有一个非NULL
// ln -- 待显示的线段
// nHeight -- 厚度
// bShowStart -- 是否绘制起始边界线
// bShowEnd -- 是否绘制终止边界线
inline void DrawLineSeg(XExplodeDraw &dc, const XLine &ln,
ads_real nHeight, int bShowStart, int bShowEnd)
{
int nVertexNum = 4;
XPoint *ptArray = new XPoint[nVertexNum];
ptArray[0] = ln.StartPoint();
ptArray[1] = ln.EndPoint();
ptArray[2] = ptArray[0];
ptArray[2].z += nHeight;
ptArray[3] = ptArray[1];
ptArray[3].z += nHeight;
AcGiEdgeData edge;
Adesk::UInt8 *visibleData = new Adesk::UInt8[4];
for (int j = 0; j < 2; j++)
{
visibleData[j] = kAcGiVisible;
}
visibleData[2] = bShowStart ? kAcGiVisible : kAcGiInvisible;
visibleData[3] = bShowEnd ? kAcGiVisible : kAcGiInvisible;
edge.setVisibility(visibleData);
dc.DrawMesh(2, 2, (AcGePoint3d *)ptArray, &edge);
delete [] ptArray;
delete [] visibleData;
}
//绘制二维直线
inline void DrawLineSeg(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const XLine &ln)
{
AcGePoint3d line[2] = {ln.StartPoint(), ln.EndPoint()};
if (pWd)
{
pWd->geometry().polyline(2, line);
}
else
{
pVd->geometry().polyline(2, line);
}
}
//绘制二维弧线
inline void DrawArcSeg(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const XArc &ar)
{
XPoint ptStart, ptEnd, ptMid;
ar.GetStartPoint(ptStart);
ar.GetEndPoint(ptEnd);
ar.MidPoint(ptMid);
if (pWd)
{
pWd->geometry().circularArc(ptStart, ptMid, ptEnd);
}
else
{
pVd->geometry().circularArc(ptStart, ptMid, ptEnd);
}
}
// 绘制二维圆
inline void DrawCircle(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const XCircle &cir)
{
if (pWd)
{
pWd->geometry().circle(cir.GetCenterPt(), cir.GetRadius(), AcGeVector3d(0.0,0.0,1.0));
}
else
{
pVd->geometry().circle(cir.GetCenterPt(), cir.GetRadius(), AcGeVector3d(0.0,0.0,1.0));
}
}
inline int MakeArcWallSeg(XExplodeDraw &dc, const XArc &arc,
ads_real height, ads_real iDist, ads_real oDist, int bShowStart, int bShowEnd)
{
if (height <= 0)
{
height = 0;
}
if (iDist >= arc.GetRadius() || oDist >= arc.GetRadius())
{
return RTERROR;
}
XArc iArc = arc.Offset(-iDist);
XArc oArc = arc.Offset(oDist);
::DrawArcSeg(dc, iArc, height, bShowStart, bShowEnd);
::DrawArcSeg(dc, oArc, height, bShowStart, bShowEnd);
return RTNORM;
}
inline void MakeArcWallSeg(XExplodeDraw &dc, const XArc &iArc, const XArc &oArc, ads_real height, int bShowStart, int bShowEnd)
{
::DrawArcSeg(dc, iArc, height, bShowStart, bShowEnd);
::DrawArcSeg(dc, oArc, height, bShowStart, bShowEnd);
}
XAcGiViewDraw::XAcGiViewDraw(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd)
: m_pWd(pWd), m_pVd(pVd), m_nGsMark(0)
{
}
XAcGiViewDraw::~XAcGiViewDraw()
{
while (HasClip())
{
PopClip();
}
}
AcGiCommonDraw * XAcGiViewDraw::GetCommonDraw()
{
if (m_pWd)
{
return m_pWd;
}
return m_pVd;
}
BOOL XAcGiViewDraw::IsFullExplode() const
{
return TRUE;
}
BOOL XAcGiViewDraw::IsPlotGeneration() const
{
AcGiCommonDraw *pCommon = ((XAcGiViewDraw *)this)->GetCommonDraw();
ASSERT(pCommon);
AcGiContext *pContext = pCommon->context();
ASSERT(pContext);
return pContext->isPlotGeneration();
}
void XAcGiViewDraw::SetColor1(Adesk::UInt16 nColor)
{
SetColor(nColor);
}
void XAcGiViewDraw::PushClip(const XPoly2D &poly,int flag)
{
if (IsDragging())
{
return;
}
if ((flag & XDcClip::kClipOut) != 0)
{
if (!poly.HasArcSegment())
{
XDcStream::PushClip(poly,flag | XDcClip::kAcGiClip);
AcGiGeometry *geom = GetCommonDraw()->rawGeometry();
if (m_lstClip.GetSize() > 0) //lify
{
geom->pushClipBoundary( ((XDcClip*)m_lstClip[m_lstClip.GetSize() - 1])->GetAcGiClip());
}
return;
}
}
XDcStream::PushClip(poly,flag);
}
void XAcGiViewDraw::PopClip()
{
if (m_lstClip.GetSize() < 1)
{
return;
}
XDcClip *pDcClip = (XDcClip *)m_lstClip[m_lstClip.GetSize() - 1];
if ((pDcClip->GetClipType()&XDcClip::kAcGiClip) != 0)
{
AcGiGeometry *geom = GetCommonDraw()->rawGeometry();
geom->popClipBoundary();
}
XDcStream::PopClip();
}
//设置图层和颜色(取图层)
void XAcGiViewDraw::SetColorLayer(Adesk::UInt16 iObjColor, const AcDbObjectId &id)
{
if (id.isValid())
{
SetLayer(id);
//0层对象不设置颜色
if (iObjColor == 256 && _tcscmp(XExport::GetSymbolName(id), _T("0")) != 0)
{
SetColor(GetLayerColor(id));
}
else if (iObjColor >= 1 && iObjColor <= 255)
{
SetColor(iObjColor);
}
//add by W on 060313
else if (iObjColor == 0)
{
SetColor(GetLayerColor(id));
}
}
}
void XAcGiViewDraw::SetPropertiesFrom(const AcDbEntity *pEnt)
{
AcDbObjectId idLay = pEnt->layerId();
if (!!idLay)
{
XString sName = XExport::GetSymbolName(idLay);
if (_tcscmp(sName, _T("0")) != 0)
{
SetLayer(idLay);
}
}
AcDbObjectId idLinetype = pEnt->linetypeId();
if (!!idLinetype)
{
SetLineType(idLinetype);
}
#if ARX > 17
AcDbObjectId idMaterial = pEnt->materialId();
if (!!idMaterial)
{
SetMaterial(idMaterial);
}
#endif
Adesk::UInt16 nColor = pEnt->colorIndex();
if (nColor == 256)
{
if (idLay.isValid())
{
SetColor(GetLayerColor(idLay));
}
}
else if (nColor > 0)
{
SetColor(nColor);
}
}
void XAcGiViewDraw::SetSelectionMarker(int nMark)
{
m_nGsMark = nMark;
if (m_pWd)
{
m_pWd->subEntityTraits().setSelectionMarker(nMark);
}
else
{
m_pVd->subEntityTraits().setSelectionMarker(nMark);
}
}
// LINE,3DFACE,INSERT,AEC_,ARC,SOLID
// 颜色,线型
void XAcGiViewDraw::DrawEntity(const AcDbEntity &ent)
{
TCHAR *layer = ent.layer();
if (layer && _tcsicmp(layer, _T("_AEC_BOUNDARY")) == 0)
{
delete []layer;
return;
}
delete []layer;
XMasterProperties prop;
BackUpProperties(prop);
SetPropertiesFrom(&ent);
if (ent.isA() == AcDbFace::desc())
{
AcDbFace *pFace = (AcDbFace *)(&ent);
DrawFace(pFace);
AcGePoint3d ptArray[4];
Adesk::UInt8 edgeVisible[4];
AcGiEdgeData edge;
pFace->getVertexAt(0, ptArray[0]);
pFace->getVertexAt(1, ptArray[1]);
pFace->getVertexAt(2, ptArray[3]);
pFace->getVertexAt(3, ptArray[2]);
Adesk::Boolean bVisible = Adesk::kTrue;
pFace->isEdgeVisibleAt(0, bVisible); edgeVisible[0] = bVisible;
pFace->isEdgeVisibleAt(1, bVisible); edgeVisible[3] = bVisible;
pFace->isEdgeVisibleAt(2, bVisible); edgeVisible[1] = bVisible;
pFace->isEdgeVisibleAt(3, bVisible); edgeVisible[2] = bVisible;
edge.setVisibility(edgeVisible);
DrawMesh(2,2, (AcGePoint3d *)ptArray, &edge);
}
else if (ent.isA() == AcDbSolid::desc())
{
XPoint pt[4];
AcDbSolid &solid = (AcDbSolid &)ent;
XPoly2D poly2d(1);
for (int n = 0; n < 4; n++)
{
solid.getPointAt(n, pt[n]);
}
poly2d.AppendNode(pt[0]);
poly2d.AppendNode(pt[1]);
poly2d.AppendNode(pt[3]);
if (pt[2].Distance2d(pt[3]) > _DIST_SNAP)
{
poly2d.AppendNode(pt[2]);
}
DrawSolid(poly2d);
}
else if (ent.isA() == AcDbLine::desc())
{
AcDbLine *pLine = (AcDbLine *)(&ent);
XLine ln;
ln.SetStartPoint(pLine->startPoint());
ln.SetEndPoint(pLine->endPoint());
*this << ln;
}
else if (ent.isA() == AcDbArc::desc())
{
AcDbArc &dbArc = (AcDbArc &)ent;
XPoint ptCen = dbArc.center();
XArc ar(ptCen, dbArc.radius(), dbArc.startAngle(), dbArc.endAngle());
*this << ar;
}
else if (ent.isKindOf(AcDbBlockReference::desc()))
{
XMasterProperties prop;
AcGiSubEntityTraits &traits = GetCommonDraw()->subEntityTraits();
prop.m_idLayer = traits.layerId();
prop.m_nColor = traits.color();
prop.m_idLineType = traits.lineTypeId();
#if ARX > 17
prop.m_idMaterial = traits.materialId();
#endif
AcDbVoidPtrArray entSet;
InitModel(prop, &ent, NULL, entSet);
int nLen = entSet.length();
for (int i = 0; i < nLen; i++)
{
AcDbEntity *pEnt = (AcDbEntity *)entSet[i];
DrawEntity(*pEnt);
}
ReleaseEntSet(entSet);
}
else if (ent.isA() == AcDbText::desc())//add by W,080818支持XAcGiViewDraw::DrawEntity(AcDbText)
{
AcDbText&text = (AcDbText&)ent;
//
/*AecDbText ttext;
if (ttext.ConvertFrom(&text))
{
ttext.setPropertiesFrom(&text);
if (m_pWd)
{
ttext.subWorldDraw(m_pWd);
}
else
{
ttext.subViewportDraw(m_pVd);
}
}
else
{
if (m_pWd)
{
((AcDbEntity&)ent).worldDraw(m_pWd);
}
else
{
((AcDbEntity&)ent).viewportDraw(m_pVd);
}
}
*/
bool bFailed = false;
AcRxClass* pDbTextRx = AcRxClass::cast(acrxClassDictionary->at(_T("TDbText")));
if (pDbTextRx != NULL)
{
AecEntity *pText = (AecEntity*)pDbTextRx->create();
if (pText != NULL)
{
if (pText->TBaseConvertFrom(&text))
{
pText->setPropertiesFrom(&text);
if (m_pWd)
{
pText->subWorldDraw(m_pWd);
}
else
{
pText->subViewportDraw(m_pVd);
}
bFailed = true;
}
delete pText;
}
}
if (!bFailed)
{
if (m_pWd)
{
((AcDbEntity&)ent).worldDraw(m_pWd);
}
else
{
((AcDbEntity&)ent).viewportDraw(m_pVd);
}
}
}
else
{
if (m_pWd)
{
((AcDbEntity&)ent).worldDraw(m_pWd);
}
else
{
((AcDbEntity&)ent).viewportDraw(m_pVd);
}
}
RestoreProperties(prop);
}
void XAcGiViewDraw::DrawBlock(const AcDbBlockTableRecord &blockRec, const XPoint &ptInsert,
const AcGeScale3d &scales, double nRot, BOOL bMakeBlock)
{
AcDbBlockReference insert(ptInsert, blockRec.objectId());
insert.setScaleFactors(scales);
insert.setRotation(nRot);
insert.setLayer(GetLayerId());
AcDbVoidPtrArray entSet;
if (bMakeBlock)
{
XMasterProperties prop;
BackUpProperties(prop);
AcGiGeometry *geom=GetCommonDraw()->rawGeometry();
#if ARX == 16 //modified by W on 020615
AcGiContext *pContext=GetCommonDraw()->context();
if(pContext->isPlotGeneration())//打印正常,Block命令不对
{
prop.SetTo(&insert);
geom->draw(&insert);
}
else//Block命令正常,但打印不对
{
AcGeMatrix3d mat = BlockTransform(&insert);
geom->pushModelTransform(mat);
geom->draw(&(AcDbBlockTableRecord &)blockRec);
geom->popModelTransform();
}
#else
AcGeMatrix3d mat = BlockTransform(&insert);
geom->pushModelTransform(mat);
geom->draw(&(AcDbBlockTableRecord &)blockRec);
geom->popModelTransform();
#endif
RestoreProperties(prop);
}
else
{
XMasterProperties prop;
AcGiSubEntityTraits &traits = GetCommonDraw()->subEntityTraits();
prop.m_idLayer = traits.layerId();
prop.m_nColor = traits.color();
prop.m_idLineType = traits.lineTypeId();
#if ARX > 17
prop.m_idMaterial = traits.materialId();
#endif
prop.SetTo(&insert);
InitModel(prop, &insert, NULL, entSet);
int nLen = entSet.length();
for (int i = 0; i < nLen; i++)
{
AcDbEntity *pEnt = (AcDbEntity *)entSet[i];
DrawEntity(*pEnt);
}
ReleaseEntSet(entSet);
}
}
void XAcGiViewDraw::Polyline(AcDbPolyline &pline)
{
int nOldColor = GetColor();
double nConstWidth;
BOOL bHasConstWidth = (pline.getConstantWidth(nConstWidth) == Acad::eOk);
AcDbObjectId idLineType = pline.linetypeId();
AcDbObjectId idOldLineType = GetLineTypeId();
#if ARX > 17
AcDbObjectId idMaterial = pline.materialId();
AcDbObjectId idOldMaterial = GetMaterialId();
#endif
int nColorIndex = pline.colorIndex();
if (nColorIndex > 0)
{
SetColor(nColorIndex);
}
if (!!idLineType)
{
SetLineType(idLineType);
}
#if ARX > 17
if (!!idMaterial)
{
SetMaterial(idMaterial);
}
#endif
if (bHasConstWidth && nConstWidth < _DIST_SNAP) //等粗细
{
XPoly2D poly2d;
PolyConvert(pline, poly2d);
*this<<poly2d;
}
else
{
if (m_pWd)
{
pline.worldDraw(m_pWd);
}
else
{
pline.viewportDraw(m_pVd);
}
}
if (nColorIndex > 0)
{
SetColor(nOldColor);
}
if (!!idLineType)
{
SetLineType(idOldLineType);
}
#if ARX > 17
if (!!idMaterial)
{
SetMaterial(idOldMaterial);
}
#endif
}
void XAcGiViewDraw::DrawLine(const XLine &ln, double nThickness)
{
if (nThickness < 1.0E-8)
{
::DrawLineSeg(m_pWd, m_pVd, ln);
}
else
{
::DrawLineSeg(*this, ln, nThickness, 1, 1);
}
}
void XAcGiViewDraw::DrawArc(const XArc &ar, double nThickness)
{
if (nThickness < 1.0E-8)
{
::DrawArcSeg(m_pWd, m_pVd, ar);
}
else
{
::DrawArcSeg(*this, ar, nThickness, 1, 1);
}
}
void XAcGiViewDraw::DrawCircle(const XCircle &cir, double nThickness)
{
if (nThickness < 1.0E-8)
{
::DrawCircle(m_pWd, m_pVd, cir);
}
else
{
::DrawCircle(m_pWd, m_pVd, cir, nThickness);
}
}
// 对polyOutline的方向没有规定
void XAcGiViewDraw::DrawSolid(const XPoly2D &polyOutline)
{
if (polyOutline.Area() < 1E-6) //add by W on 070306
{
return;
}
AcGiFillType fillMode = GetCommonDraw()->subEntityTraits().fillType();
GetCommonDraw()->subEntityTraits().setFillType(kAcGiFillAlways);
XExplodeDraw::DrawShell(polyOutline);
GetCommonDraw()->subEntityTraits().setFillType(fillMode);
}
static Acad::ErrorStatus ExplodeHatch(const AcDbHatch *pEnt, XDcStream *pDc)
{
Acad::ErrorStatus es = Acad::eOk;
XAsdkCustomWorldDraw dc;
dc.setStreamDc(pDc);
dc.setDeviation(_AS_SYS_UNIT(g_nCirDeviation));
((AcDbHatch *)pEnt)->worldDraw(&dc);
return es;
}
void XAcGiViewDraw::DrawHatch(const XPoly2D &polyOutline, const TCHAR *pszPattern, double nScale)
{
if (polyOutline.Area() < 1E-6)//add by W on 070306
{
return;
}
if (!pszPattern)
{
return;
}
AcDbHatch *pHatch = NewHatchFromPoly2D(polyOutline, pszPattern, nScale);
if (!pHatch)
{
return;
}
pHatch->setColorIndex(GetColor());
pHatch->setLayer(GetLayerId());
if (m_pWd)
{
pHatch->worldDraw(m_pWd);
}
else
{
ExplodeHatch(pHatch, this);
}
delete pHatch;
}
void XAcGiViewDraw::DrawHatchEx(const XPoly2D &polyOutline, const TCHAR *pszPattern, double nScale,double rotation)
{
if (polyOutline.Area() < 1E-6) //add by w on 070306
{
return;
}
if (!pszPattern)
{
return;
}
AcDbHatch *pHatch = NewHatchFromPoly2D(polyOutline, pszPattern, nScale,rotation);
if (!pHatch)
{
return;
}
pHatch->setColorIndex(GetColor());
pHatch->setLayer(GetLayerId());
if (m_pWd)
{
pHatch->worldDraw(m_pWd);
}
else
{
ExplodeHatch(pHatch, this);
}
delete pHatch;
}
// 根据给定的内外边界, 绘制三维外壳
void XAcGiViewDraw::DrawShell(const XPoly2D &polyOut1, const DList<XPoly2D> &lstPolyIn0)
{
ASSERT(polyOut1.IsClosed());
XPoly polyOut;
((XPoly2D &)polyOut1).MapToPolygon1(polyOut, _AS_SYS_UNIT(g_nCirDeviation));
DList<XPoly> lstPolyIn1;
for (int mm = 0; mm < lstPolyIn0.Length(); mm++)
{
XPoly *pPoly = new XPoly;
const XPoly2D &rPoly = lstPolyIn0[mm];
((XPoly2D &)rPoly).MapToPolygon1(*pPoly, _AS_SYS_UNIT(g_nCirDeviation));
lstPolyIn1.Append(pPoly);
}
int nLen = polyOut.Length();
Adesk::UInt32 nVertex = nLen;
Adesk::UInt32 nFace = lstPolyIn1.Length() + 1;
for (int i = 0; i < lstPolyIn1.Length(); i++)
{
nVertex += lstPolyIn1[i]->Length();
}
XPoint *pVertexList = new XPoint[nVertex];
Adesk::Int32 *pFaceList = new Adesk::Int32[nFace + nVertex];
// 第一个面
Adesk::Int32 *pFace = pFaceList;
*pFace = polyOut.Length();
int nIdVertex = 0;
for (int i = 0; i < nLen; i++, nIdVertex++)
{
pFace++;
*pFace = nIdVertex;
pVertexList[nIdVertex] = *polyOut[i];
}
// 洞
for (int i = 0; i < lstPolyIn1.Length(); i++)
{
XPoly &poly = *lstPolyIn1[i];
int nnn = poly.Length();
pFace++;
*pFace = -nnn; //顶点数
for (int j = 0; j < nnn; j++,nIdVertex++)
{
pVertexList[nIdVertex] = *poly[j];
pFace++;
*pFace = nIdVertex;
}
}
if (m_pWd)
{
m_pWd->geometry().shell(nVertex, (AcGePoint3d *)pVertexList, nFace + nVertex, pFaceList);
}
else
{
m_pVd->geometry().shell(nVertex, (AcGePoint3d *)pVertexList, nFace + nVertex, pFaceList);
}
// Add on 2002/3/28 by Z, 修复内存泄漏
delete [] pVertexList;
delete [] pFaceList;
}
void XAcGiViewDraw::DrawShell(Adesk::UInt32 nbVertex, const AcGePoint3d* pVertexList, Adesk::UInt32 faceListSize, const Adesk::Int32* pFaceList, const AcGiEdgeData* pEdgeData)
{
if (m_pWd)
{
m_pWd->geometry().shell(nbVertex, pVertexList, faceListSize, pFaceList, pEdgeData);
}
else
{
m_pVd->geometry().shell(nbVertex, pVertexList, faceListSize, pFaceList, pEdgeData);
}
}
void XAcGiViewDraw::DrawMesh( const Adesk::UInt32 rows, const Adesk::UInt32 columns, const AcGePoint3d* pVertexList, const AcGiEdgeData* pEdgeData)
{
if (m_pWd)
{
m_pWd->geometry().mesh(rows, columns, pVertexList, pEdgeData);
}
else
{
m_pVd->geometry().mesh(rows, columns, pVertexList, pEdgeData);
}
}
// 根据给定的边界和凸起方向, 绘制三维外壳
void XAcGiViewDraw::DrawMesh(const XPoly2D &polyOut, const XVector3D &vtOffset)
{
XPoly poly;
polyOut.AsOpenPoly1(poly, _AS_SYS_UNIT(g_nCirDeviation)); //变成开口的poly, 如果原先封闭, 则起点复制为终点
int nColumn = poly.Length();
int nRow = 2;
XPoint *ptArray = new XPoint[nColumn * nRow];
for (int m = 0; m < nRow; m++)
{
for (int n = 0; n < nColumn; n++)
{
int nBase = m * nColumn;
ptArray[nBase + n] = *poly[n];
if (m == 1)
{
ptArray[nBase + n] += vtOffset;
}
}
}
if (m_pWd)
{
m_pWd->geometry().mesh(nRow, nColumn, (AcGePoint3d *)ptArray);
}
else
{
m_pVd->geometry().mesh(nRow, nColumn, (AcGePoint3d *)ptArray);
}
delete [] ptArray;
}
// 显示分别连接两个区域的边缘构成的侧面
void XAcGiViewDraw::DrawMesh(const XPoly2D &polyRegion1, const XPoly2D &polyRegion2)
{
XPoly poly1, poly2;
polyRegion1.AsOpenPoly(poly1); //变成开口的poly, 如果原先封闭, 则起点复制为终点
polyRegion2.AsOpenPoly(poly2);
if (poly1.Length() != poly2.Length())
{
return;
}
int nColumn = poly1.Length();
int nRow = 2;
XPoint *ptArray = new XPoint[nColumn * nRow];
for (int m = 0; m < nRow; m++)
{
for (int n = 0; n < nColumn; n++)
{
int nBase = m * nColumn;
if (!m)
{
ptArray[nBase + n] = *poly1[n];
}
else
{
ptArray[nBase + n] = *poly2[n];
}
}
}
if (m_pWd)
{
m_pWd->geometry().mesh(nRow, nColumn, (AcGePoint3d *)ptArray);
}
else
{
m_pVd->geometry().mesh(nRow, nColumn, (AcGePoint3d *)ptArray);
}
delete [] ptArray;
}
// polySrc 已经离散过
void XAcGiViewDraw::DrawBody(const XPoly2D &polySrc, const XVector3D &vtOffset)
{
DList<XPoly2D> lstPoly;
DrawBody(polySrc, lstPoly, vtOffset);
}
// polySrc 已经离散过
void XAcGiViewDraw::DrawBody(const XPoly2D &polyOut, const XPoly2D &polyIn, const XVector3D &vtOffset)
{
DList<XPoly2D> lstPoly;
lstPoly.Append(new XPoly2D(polyIn));
DrawBody(polyOut, lstPoly, vtOffset);
}
void XAcGiViewDraw::DrawBody(const XPoly2D &polyOut, const DList<XPoly2D> &lstHoles,const XVector3D &vt)
{
DrawShell(polyOut, lstHoles);
XPoly2D polyUp(polyOut);
for (int i = 0; i < polyUp.Length(); i++)
{
*polyUp[i] += vt;
}
DList<XPoly2D> lstHoleUp;
for (int n = 0; n < lstHoles.Length(); n++)
{
XPoly2D *pHole = new XPoly2D(lstHoles[n]);
for (int j = 0; j < pHole->Length(); j++)
{
*(*pHole)[j] += vt;
}
lstHoleUp.Append(pHole);
}
DrawShell(polyUp, lstHoleUp);
DrawMesh(polyOut, vt);
for (int i = 0; i < lstHoles.Length(); i++)
{
DrawMesh(lstHoles[i], vt);
}
}
void XAcGiViewDraw::DrawFace(const X3DFace &face)
{
XPoint ptArray[4] = {face.GetVertex(0), face.GetVertex(1), face.GetVertex(3), face.GetVertex(2)};
Adesk::UInt8 edgeVisible[4];
AcGiEdgeData edge;
Adesk::Boolean bVisible = Adesk::kTrue;
edgeVisible[0] = ((face.GetFlag() & 0x01) == 0);
edgeVisible[1] = ((face.GetFlag() & 0x04) == 0);
edgeVisible[2] = ((face.GetFlag() & 0x08) == 0);
edgeVisible[3] = ((face.GetFlag() & 0x02) == 0);
edge.setVisibility(edgeVisible);
if (m_pWd)
{
m_pWd->geometry().mesh(2, 2, (AcGePoint3d *)ptArray, &edge);
}
else
{
m_pVd->geometry().mesh(2, 2, (AcGePoint3d *)ptArray, &edge);
}
}
void XAcGiViewDraw::DrawTextFit(const TCHAR *pszText, XPoint pt1, XPoint pt2, double nTextHeight)
{
ASSERT(m_bInitStyle);
double nRot = ads_angle(pt1, pt2);
AcGeVector3d vDirection(cos(nRot), sin(nRot), 0.0);
double nTextSize = nTextHeight;
if (nTextSize < 1.0E-5)
{
return;
}
double nWidthFactor = m_textStyle.xScale();
double nOldXScale = nWidthFactor;
double nOldSize = m_textStyle.textSize();
m_textStyle.setTextSize(nTextSize);
Adesk::Boolean bIncludeSpace = Adesk::kTrue;
// Windows字体,都需要包括前后空隙
TCHAR *pTypeface = NULL;
Adesk::Boolean bBold, bItalic;
#if ARX < 21
int tmp0, tmp1;
BOOL bWinFont = (m_textStyle.font(pTypeface, bBold, bItalic, tmp0, tmp1) == Acad::eOk);
#else
Autodesk::AutoCAD::PAL::FontUtils::FontPitch tmp0;
Autodesk::AutoCAD::PAL::FontUtils::FontFamily tmp1;
Charset charset;
BOOL bWinFont = (m_textStyle.font(pTypeface, bBold, bItalic, charset, tmp0, tmp1) == Acad::eOk);
#endif
if (bWinFont)
{
if (!pTypeface || !pTypeface[0])
{
bWinFont = FALSE;
}
}
if (pTypeface)
{
delete[] pTypeface;
}
if (bWinFont)
{
bIncludeSpace = Adesk::kTrue;
}
else
{
bIncludeSpace = Adesk::kFalse;
const TCHAR *pShxFile = m_textStyle.fileName();
if (pShxFile)
{
XPathParser paser(pShxFile);
_tcsupr(paser.m_sFileName);
TCHAR sFilter[] = _T("GBE*,GOTH*,ISO*,SCRIPT*,ROMAN*");
if (ads_wcmatch(paser.m_sFileName, sFilter) == RTNORM)
{
bIncludeSpace = Adesk::kTrue;
}
}
}
AcGePoint2d ptExt = m_textStyle.extents(pszText, bIncludeSpace, -1, Adesk::kFalse);
double nWidth = ptExt[0];
double nHeight = ptExt[1];
nWidthFactor *= pt1.Distance2d(pt2) / nWidth;
m_textStyle.setXScale(nWidthFactor);
// 091105,解决在08、09、10平台下,打印时,索引符号中的索引圆圈文字颜色错误的问题
if (g_nAcadVer > 17.01)
{
AcDbObjectId idCurLayer = GetLayerId();
int nCurColor = GetColor();
BOOL bIsOff = FALSE;
OPENOBJ_BEGIN(idCurLayer, AcDb::kForRead, AcDbLayerTableRecord, pLayer);
if (pLayer != NULL)
{
bIsOff = pLayer->isOff() || pLayer->isFrozen();
}
OPENOBJ_END();
if (!bIsOff)
{
SetColor(nCurColor);
SetLayer(idCurLayer);
}
}
if (m_pWd)
{
m_pWd->geometry().text(pt1, m_vtNormal, vDirection, pszText, -1, Adesk::kFalse, m_textStyle);
}
else
{
m_pVd->geometry().text(pt1, m_vtNormal, vDirection, pszText, -1, Adesk::kFalse, m_textStyle);
}
m_textStyle.setXScale(nOldXScale);
m_textStyle.setTextSize(nOldSize);
}
// 显示文字
void XAcGiViewDraw::DrawText(const TCHAR *pszContent)
{
ASSERT(m_bInitStyle && pszContent);
AcGeVector3d vDirection(cos(m_nRotation), sin(m_nRotation), 0.0);
double nOldSize = m_textStyle.textSize();
double nOldXScale = m_textStyle.xScale();
double nTextSize = m_nHeight;
if (nTextSize < 1.0E-5)
{
nTextSize = nOldSize;
}
m_textStyle.setTextSize(nTextSize);
if (m_nControlFlag & EDF_XSCALE) //Modify on 2002/10/13
{
m_textStyle.setXScale(m_nWidthFactor);
}
AcGePoint2d ptExt = m_textStyle.extents(pszContent, Adesk::kFalse, -1, Adesk::kFalse);
double nWidth = ptExt[0];
double nHeight = ptExt[1];
XPoint ptBase = Align2Base(m_align, m_ptLocation, XPoint(nWidth, nTextSize, nHeight));
ads_matrix mat;
m_ptLocation.GetRotationMatrix(m_nRotation, mat);
ptBase.TransformBy(mat);
if (m_pWd)
{
m_pWd->geometry().text(ptBase, m_vtNormal, vDirection,
pszContent, -1, Adesk::kFalse, m_textStyle);
}
else
{
//测试查看上下文的图层---------------------------------------------
/*LPCTSTR pszLayName = NULL;
AcDbObjectId id = m_pVd->subEntityTraits().layerId();
OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbLayerTableRecord, pLayer);
if (pLayer != NULL)
{
pLayer->getName(pszLayName);
}
OPENOBJ_END();*/
//------------------------------------------------------------------
m_pVd->geometry().text(ptBase, m_vtNormal, vDirection,
pszContent, -1, Adesk::kFalse, m_textStyle);
}
m_textStyle.setTextSize(nOldSize);
m_textStyle.setXScale(nOldXScale);
}
const TCHAR * XAcGiViewDraw::Descriptor()
{
return _T("XAcGiViewDraw");
}
const TCHAR * XAcGiViewDraw::Desc()
{
return Descriptor();
}
void XAcGiViewDraw::DrawFace(const AcDbFace *pFace, const AcGeMatrix3d *mat)
{
AcGePoint3d ptArray[4];
Adesk::UInt8 edgeVisible[4];
AcGiEdgeData edge;
pFace->getVertexAt(0, ptArray[0]);
pFace->getVertexAt(1, ptArray[1]);
pFace->getVertexAt(2, ptArray[3]);
pFace->getVertexAt(3, ptArray[2]);
Adesk::Boolean bVisible = Adesk::kTrue;
pFace->isEdgeVisibleAt(0, bVisible);
edgeVisible[0] = bVisible;
pFace->isEdgeVisibleAt(1, bVisible);
edgeVisible[3] = bVisible;
pFace->isEdgeVisibleAt(2, bVisible);
edgeVisible[1] = bVisible;
pFace->isEdgeVisibleAt(3, bVisible);
edgeVisible[2] = bVisible;
edge.setVisibility(edgeVisible);
if (mat)
{
for (int i = 0; i < 4; i++)
{
ptArray[i].transformBy(*mat);
}
}
DrawMesh(2, 2, (AcGePoint3d *)ptArray, &edge);
}
void XAcGiViewDraw::DrawAtomicEntSet(const AcDbVoidPtrArray &entSet, const AcGeMatrix3d &matTrans)
{
int nCount = entSet.length();
for (int i = 0; i < nCount; i++)
{
AcDbEntity *pEntity = (AcDbEntity *)entSet[i];
XMasterProperties prop;
BackUpProperties(prop);
SetPropertiesFrom(pEntity);
if (pEntity->isKindOf(AcDbFace::desc())) // 3DFACE
{
AcDbFace *pFace = AcDbFace::cast(pEntity);
ASSERT(pFace);
DrawFace(pFace, &matTrans);
}
else
{
AcDbPolyline *pline = AsPolyline(pEntity);
if (pline)
{
XPoly2D poly2d;
PolyConvert(*pline, poly2d);
XVector3D vtNormal;
(AcGeVector3d &)vtNormal = pline->normal();
double nElev = 0.0;
AcGeMatrix2d xform2d(matTrans.convertToLocal(vtNormal,nElev));
ads_matrix mat0 =
{
{xform2d(0,0), xform2d(0,1), 0, xform2d(0,2)},
{xform2d(1,0), xform2d(1,1), 0, xform2d(1,2)},
{0,0,1, nElev},
{0,0,0,1}
};
poly2d.TransUCS(mat0);
PolyConvert(poly2d, *pline);
((AcGeVector3d &)vtNormal).normalize();
pline->setNormal(vtNormal);
pline->setLayer(GetLayerId());
pline->setColorIndex(GetColor());
if (m_pWd)
{
pline->worldDraw(m_pWd);
}
else
{
pline->viewportDraw(m_pVd);
}
delete pline;
}
else
{
AcDbEntity *pEntCloned = NULL;
Acad::ErrorStatus es = pEntity->getTransformedCopy(matTrans, pEntCloned);
if (es == Acad::eOk)
{
ASSERT(pEntCloned);
pEntCloned->setLayer(GetLayerId());
pEntCloned->setColorIndex(GetColor());
if (m_pWd)
{
pEntCloned->worldDraw(m_pWd);
}
else
{
pEntCloned->viewportDraw(m_pVd);
}
delete pEntCloned;
}
}
}
BackUpProperties(prop);
}
}
Adesk::Boolean XAcGiViewDraw::IsDragging() const
{
if (m_pWd)
{
return m_pWd->isDragging();
}
if (m_pVd)
{
return m_pVd->isDragging();
}
return Adesk::kFalse;
}
//add by zjq on 100629 TArch8.5
//COLORREF XAcGiViewDraw::GetTrueColor() const
AcCmColor XAcGiViewDraw::GetTrueColor() const
{
AcCmEntityColor cmEntColor;
if (m_pWd)
{
cmEntColor = m_pWd->subEntityTraits().trueColor();
}
else
{
cmEntColor = m_pVd->subEntityTraits().trueColor();
}
AcCmColor cmColor;
cmColor.setRGB(cmEntColor.red(), cmEntColor.green(), cmEntColor.blue());
return cmColor;
}
//void XAcGiViewDraw::SetTrueColor(COLORREF crRef)
void XAcGiViewDraw::SetTrueColor(AcCmColor crRef)
{
#if ARX == 15
AcCmEntityColor cmEntColor;
cmEntColor.setRGB(crRef.red(), crRef.green(), crRef.blue());
#else
AcCmEntityColor cmEntColor = crRef.entityColor();
#endif
if (m_pWd)
{
m_pWd->subEntityTraits().setTrueColor(cmEntColor);
}
else
{
m_pVd->subEntityTraits().setTrueColor(cmEntColor);
}
}