Files
envi-code/SourceCode/Code2026/tg_shs/shs_geLib/TGGiWorldViewportDraw.cpp
T
2026-09-28 15:28:50 +08:00

1465 lines
31 KiB
C++

//-----------------------------------------------------------------------------+
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
// = FileName : TGGiWorldViewportDraw 类
// = Version : ver2.0
// = Author : wlw
// = CreateDate : 2002-09-09
// = Description: TGGiWorldViewportDraw 定义
// = Maintainers:
//
//-----------------------------------------------------------------------------+
#include "StdAfx.h"
#include "TGGiWorldViewportDraw.h"
#include "TSplitpathOperator.h"
#include "TAcDbObjectPtr.h"
#include "dbhatch.h"
#include "TDbEntity.h"
#include "TGGiExplodeDraw.h"
#include "TchGlobalFunc.h"
#include "TGGiCustomWorldDraw.h"
#include "TchGlobalCurveFunc.h"
#include "TchPrivateGlobalFunc.h"
// 画拉伸圆
inline void DrawCircle(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const TGGeCircle &cir, ads_real nHeight)
{
AcDbPolyline line;
line.setElevation(cir.GetCenterPt().z);
line.setThickness(nHeight);
TADSGePoint3d 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 if (pVd != NULL)
{
line.viewportDraw(pVd);
}
}
// 显示3d弧段
// 参数: pWd, pVd -- 必须有一个非NULL
// ar -- 待显示的弧段
// nHeight -- 厚度
// bShowStart -- 是否绘制起始边界线
// bShowEnd -- 是否绘制终止边界线
inline void DrawArcSeg(TGGiExplodeDrawBase &dc, const TGGeArc &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(), TGGiExplodeDraw::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;
TADSGePoint3d *ptArray = new TADSGePoint3d[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 (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(TGGiExplodeDrawBase &dc, const TGGeLine &ln,
ads_real nHeight, int bShowStart, int bShowEnd)
{
int nVertexNum = 4;
TADSGePoint3d *ptArray = new TADSGePoint3d[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 TGGeLine &ln)
{
AcGePoint3d line[2] = { ln.StartPoint(), ln.EndPoint() };
//add by xlc on 120425 解决墙内线图案裁剪的问题
if (g_bWallLinepatClip)
{
line[0].x += _DIST_SNAP;
line[0].y += _DIST_SNAP;
line[1].x -= _DIST_SNAP;
line[1].y -= _DIST_SNAP;
}
if (pWd)
{
pWd->geometry().polyline(2, line);
}
else if (pVd != NULL)
{
pVd->geometry().polyline(2, line);
}
}
//绘制二维弧线
inline void DrawArcSeg(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const TGGeArc &ar)
{
TADSGePoint3d ptStart, ptEnd, ptMid;
ar.GetStartPoint(ptStart);
ar.GetEndPoint(ptEnd);
ar.MidPoint(ptMid);
if (pWd)
{
pWd->geometry().circularArc(ptStart, ptMid, ptEnd);
}
else if (pVd != NULL)
{
pVd->geometry().circularArc(ptStart, ptMid, ptEnd);
}
}
// 绘制二维圆
inline void DrawCircle(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd, const TGGeCircle &cir)
{
if (pWd)
{
pWd->geometry().circle(cir.GetCenterPt(), cir.GetRadius(), AcGeVector3d(0.0, 0.0, 1.0));
}
else if (pVd != NULL)
{
pVd->geometry().circle(cir.GetCenterPt(), cir.GetRadius(), AcGeVector3d(0.0, 0.0, 1.0));
}
}
inline int MakeArcWallSeg(TGGiExplodeDrawBase &dc, const TGGeArc &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;
}
TGGeArc iArc = arc.Offset(-iDist);
TGGeArc oArc = arc.Offset(oDist);
::DrawArcSeg(dc, iArc, height, bShowStart, bShowEnd);
::DrawArcSeg(dc, oArc, height, bShowStart, bShowEnd);
return RTNORM;
}
inline void MakeArcWallSeg(TGGiExplodeDrawBase &dc, const TGGeArc &iArc, const TGGeArc &oArc, ads_real height, int bShowStart, int bShowEnd)
{
::DrawArcSeg(dc, iArc, height, bShowStart, bShowEnd);
::DrawArcSeg(dc, oArc, height, bShowStart, bShowEnd);
}
TGGiWorldViewportDraw::TGGiWorldViewportDraw(AcGiWorldDraw *pWd, AcGiViewportDraw *pVd)
: m_pWd(pWd), m_pVd(pVd), m_nGsMark(0)
{
}
TGGiWorldViewportDraw::~TGGiWorldViewportDraw()
{
while (HasClip())
{
PopClip();
}
}
AcGiCommonDraw * TGGiWorldViewportDraw::GetCommonDraw()
{
if (m_pWd)
{
return m_pWd;
}
return m_pVd;
}
BOOL TGGiWorldViewportDraw::IsFullExplode() const
{
return TRUE;
}
BOOL TGGiWorldViewportDraw::IsPlotGeneration() const
{
AcGiCommonDraw *pCommon = ((TGGiWorldViewportDraw *)this)->GetCommonDraw();
ASSERT(pCommon);
AcGiContext *pContext = pCommon->context();
ASSERT(pContext);
return pContext->isPlotGeneration();
}
void TGGiWorldViewportDraw::SetColor1(Adesk::UInt16 nColor)
{
SetColor(nColor);
}
void TGGiWorldViewportDraw::PushClip(const TGGePoly2D &poly, int flag)
{
if (IsDragging())
{
return;
}
if ((flag & TGGiClipBoundary::kClipOut) != 0)
{
if (!poly.HasArcSegment())
{
TGGiDrawStreamBase::PushClip(poly, flag | TGGiClipBoundary::kAcGiClip);
AcGiGeometry *geom = GetCommonDraw()->rawGeometry();
if (m_lstClip.GetSize() > 0) //lify
{
geom->pushClipBoundary(((TGGiClipBoundary*)m_lstClip[m_lstClip.GetSize() - 1])->GetAcGiClip());
}
return;
}
}
TGGiDrawStreamBase::PushClip(poly, flag);
}
void TGGiWorldViewportDraw::PopClip()
{
if (m_lstClip.GetSize() < 1)
{
return;
}
TGGiClipBoundary *pDcClip = (TGGiClipBoundary *)m_lstClip[m_lstClip.GetSize() - 1];
if ((pDcClip->GetClipType()&TGGiClipBoundary::kAcGiClip) != 0)
{
AcGiGeometry *geom = GetCommonDraw()->rawGeometry();
geom->popClipBoundary();
}
TGGiDrawStreamBase::PopClip();
}
//设置图层和颜色(取图层)
void TGGiWorldViewportDraw::SetColorLayer(Adesk::UInt16 iObjColor, const AcDbObjectId &id)
{
if (id.isValid())
{
SetLayer(id);
//0层对象不设置颜色
if (iObjColor == 256 && _tcscmp(TchExport::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 TGGiWorldViewportDraw::SetPropertiesFrom(const AcDbEntity *pEnt)
{
AcDbObjectId idLay = pEnt->layerId();
if (!!idLay)
{
TCString sName = TchExport::GetSymbolName(idLay);
if (_tcscmp(sName, _T("0")) != 0)
{
SetLayer(idLay);
}
}
AcDbObjectId idLinetype = pEnt->linetypeId();
if (!!idLinetype)
{
SetLineType(idLinetype);
}
#if ADS > 16
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 TGGiWorldViewportDraw::SetSelectionMarker(int nMark)
{
m_nGsMark = nMark;
if (m_pWd)
{
m_pWd->subEntityTraits().setSelectionMarker(nMark);
}
else if (m_pVd != NULL)
{
m_pVd->subEntityTraits().setSelectionMarker(nMark);
}
}
// LINE,3DFACE,INSERT,TCH_,ARC,SOLID
// 颜色,线型
void TGGiWorldViewportDraw::DrawEntity(const AcDbEntity &ent)
{
TCHAR *layer = ent.layer();
if (layer)
{
if (_tcsicmp(layer, _T("_TCH_BOUNDARY")) == 0)
{
delete[]layer;
return;
}
delete[]layer;
}
TMasterProperties 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())
{
TADSGePoint3d pt[4];
AcDbSolid &solid = (AcDbSolid &)ent;
TGGePoly2D 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);
TGGeLine ln;
ln.SetStartPoint(pLine->startPoint());
ln.SetEndPoint(pLine->endPoint());
*this << ln;
}
else if (ent.isA() == AcDbArc::desc())
{
AcDbArc &dbArc = (AcDbArc &)ent;
TADSGePoint3d ptCen = dbArc.center();
TGGeArc ar(ptCen, dbArc.radius(), dbArc.startAngle(), dbArc.endAngle());
*this << ar;
}
else if (ent.isKindOf(AcDbBlockReference::desc()))
{
TMasterProperties prop;
AcGiSubEntityTraits &traits = GetCommonDraw()->subEntityTraits();
prop.m_idLayer = traits.layerId();
prop.m_nColor = traits.color();
prop.m_idLineType = traits.lineTypeId();
#if ADS>16
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;
//
/*TDbText 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)
{
TDbEntity *pText = (TDbEntity*)pDbTextRx->create();
if (pText != NULL)
{
if (pText->TBaseConvertFrom(&text))
{
pText->setPropertiesFrom(&text);
if (m_pWd)
{
pText->subWorldDraw(m_pWd);
}
else if (m_pVd != NULL)
{
pText->subViewportDraw(m_pVd);
}
bFailed = true;
}
delete pText;
}
}
if (!bFailed)
{
if (m_pWd)
{
((AcDbEntity&)ent).worldDraw(m_pWd);
}
else if (m_pVd != NULL)
{
((AcDbEntity&)ent).viewportDraw(m_pVd);
}
}
}
else
{
if (m_pWd)
{
((AcDbEntity&)ent).worldDraw(m_pWd);
}
else if (m_pVd != NULL)
{
((AcDbEntity&)ent).viewportDraw(m_pVd);
}
}
RestoreProperties(prop);
}
void TGGiWorldViewportDraw::DrawBlock(const AcDbBlockTableRecord &blockRec, const TADSGePoint3d &ptInsert,
const AcGeScale3d &scales, double nRot, BOOL bMakeBlock)
{
AcDbBlockReference insert(ptInsert, blockRec.objectId());
insert.setScaleFactors(scales);
insert.setRotation(nRot);
AcDbVoidPtrArray entSet;
if (bMakeBlock)
{
TMasterProperties prop;
BackUpProperties(prop);
AcGiGeometry *geom = GetCommonDraw()->rawGeometry();
#if ADS == 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
{
TMasterProperties prop;
AcGiSubEntityTraits &traits = GetCommonDraw()->subEntityTraits();
prop.m_idLayer = traits.layerId();
prop.m_nColor = traits.color();
prop.m_idLineType = traits.lineTypeId();
#if ADS > 16
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 TGGiWorldViewportDraw::Polyline(AcDbPolyline &pline)
{
int nOldColor = GetColor();
double nConstWidth;
BOOL bHasConstWidth = (pline.getConstantWidth(nConstWidth) == Acad::eOk);
AcDbObjectId idLineType = pline.linetypeId();
AcDbObjectId idOldLineType = GetLineTypeId();
#if ADS > 16
AcDbObjectId idMaterial = pline.materialId();
AcDbObjectId idOldMaterial = GetMaterialId();
#endif
int nColorIndex = pline.colorIndex();
if (nColorIndex > 0)
{
SetColor(nColorIndex);
}
if (!!idLineType)
{
SetLineType(idLineType);
}
#if ADS > 16
if (!!idMaterial)
{
SetMaterial(idMaterial);
}
#endif
if (bHasConstWidth && nConstWidth < _DIST_SNAP) //等粗细
{
TGGePoly2D poly2d;
PolyConvert(pline, poly2d);
*this << poly2d;
}
else
{
if (m_pWd)
{
pline.worldDraw(m_pWd);
}
else if (m_pVd != NULL)
{
pline.viewportDraw(m_pVd);
}
}
if (nColorIndex > 0)
{
SetColor(nOldColor);
}
if (!!idLineType)
{
SetLineType(idOldLineType);
}
#if ADS > 16
if (!!idMaterial)
{
SetMaterial(idOldMaterial);
}
#endif
}
void TGGiWorldViewportDraw::DrawLine(const TGGeLine &ln, double nThickness)
{
if (nThickness < 1.0E-8)
{
::DrawLineSeg(m_pWd, m_pVd, ln);
}
else
{
::DrawLineSeg(*this, ln, nThickness, 1, 1);
}
}
void TGGiWorldViewportDraw::DrawArc(const TGGeArc &ar, double nThickness)
{
if (nThickness < 1.0E-8)
{
::DrawArcSeg(m_pWd, m_pVd, ar);
}
else
{
::DrawArcSeg(*this, ar, nThickness, 1, 1);
}
}
void TGGiWorldViewportDraw::DrawCircle(const TGGeCircle &cir, double nThickness)
{
if (nThickness < 1.0E-8)
{
::DrawCircle(m_pWd, m_pVd, cir);
}
else
{
::DrawCircle(m_pWd, m_pVd, cir, nThickness);
}
}
// 对polyOutline的方向没有规定
void TGGiWorldViewportDraw::DrawSolid(const TGGePoly2D &polyOutline)
{
if (polyOutline.Area() < 1E-6) //add by W on 070306
{
return;
}
AcGiFillType fillMode = GetCommonDraw()->subEntityTraits().fillType();
GetCommonDraw()->subEntityTraits().setFillType(kAcGiFillAlways);
TGGiExplodeDrawBase::DrawShell(polyOutline);
GetCommonDraw()->subEntityTraits().setFillType(fillMode);
}
static Acad::ErrorStatus ExplodeHatch(const AcDbHatch *pEnt, TGGiDrawStreamBase *pDc)
{
Acad::ErrorStatus es = Acad::eOk;
TGGiCustomWorldDraw dc;
dc.setStreamDc(pDc);
dc.setDeviation(_AS_SYS_UNIT(g_nCirDeviation));
((AcDbHatch *)pEnt)->worldDraw(&dc);
return es;
}
void TGGiWorldViewportDraw::DrawHatch(const TGGePoly2D &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
{
#if ADS > 19
pHatch->viewportDraw(m_pVd);
#else
ExplodeHatch(pHatch, this);
#endif
}
delete pHatch;
}
void TGGiWorldViewportDraw::DrawHatchEx(const TGGePoly2D &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
{
#if ADS > 19
pHatch->viewportDraw(m_pVd);
#else
ExplodeHatch(pHatch, this);
#endif
}
delete pHatch;
}
void TGGiWorldViewportDraw::DrawHatchEx(const TGGeHatch &hatch)
{
if (hatch.GetPolys().size() == 1) // 非房间填充
{
DrawHatchEx(hatch.GetHatchPoly(), hatch.GetHatchName(), hatch.GetHatchScale(), hatch.GetHatchRotation());
return;
}
// 这里只检测第一个。
if (hatch.GetHatchPoly().Area() < 1E-6) //add by w on 070306
return;
if (hatch.GetHatchName().IsEmpty()) return;
AcDbHatch *pHatch = NewHatchFromPoly2D(hatch);
if (!pHatch) return;
pHatch->setColorIndex(GetColor());
pHatch->setLayer(GetLayerId());
if (m_pWd)
{
pHatch->worldDraw(m_pWd);
}
else
{
#if ADS > 19
pHatch->viewportDraw(m_pVd);
#else
ExplodeHatch(pHatch, this);
#endif
}
delete pHatch;
}
// 根据给定的内外边界, 绘制三维外壳
void TGGiWorldViewportDraw::DrawShell(const TGGePoly2D &polyOut1, const TDPtrList<TGGePoly2D> &lstPolyIn0)
{
ASSERT(polyOut1.IsClosed());
TGGePoly polyOut;
((TGGePoly2D &)polyOut1).MapToPolygon1(polyOut, _AS_SYS_UNIT(g_nCirDeviation));
TDPtrList<TGGePoly> lstPolyIn1;
for (int mm = 0; mm < lstPolyIn0.Length(); mm++)
{
TGGePoly *pPoly = new TGGePoly;
const TGGePoly2D &rPoly = lstPolyIn0[mm];
((TGGePoly2D &)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();
}
TADSGePoint3d *pVertexList = new TADSGePoint3d[nVertex];
Adesk::Int32 *pFaceList = new Adesk::Int32[nFace + nVertex];
// 第一个面
Adesk::Int32 *pFace = pFaceList;
*pFace = polyOut.Length();
int nIdVertex = 0;
for (i = 0; i < nLen; i++, nIdVertex++)
{
pFace++;
*pFace = nIdVertex;
pVertexList[nIdVertex] = *polyOut[i];
}
// 洞
for (i = 0; i < lstPolyIn1.Length(); i++)
{
TGGePoly &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 if (m_pVd != NULL)
{
m_pVd->geometry().shell(nVertex, (AcGePoint3d *)pVertexList, nFace + nVertex, pFaceList);
}
// Add on 2002/3/28 by Z, 修复内存泄漏
delete[] pVertexList;
delete[] pFaceList;
}
void TGGiWorldViewportDraw::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 if (m_pVd != NULL)
{
m_pVd->geometry().shell(nbVertex, pVertexList, faceListSize, pFaceList, pEdgeData);
}
}
void TGGiWorldViewportDraw::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 if (m_pVd != NULL)
{
m_pVd->geometry().mesh(rows, columns, pVertexList, pEdgeData);
}
}
// 根据给定的边界和凸起方向, 绘制三维外壳
void TGGiWorldViewportDraw::DrawMesh(const TGGePoly2D &polyOut, const TVector3D &vtOffset)
{
TGGePoly poly;
polyOut.AsOpenPoly1(poly, _AS_SYS_UNIT(g_nCirDeviation)); //变成开口的poly, 如果原先封闭, 则起点复制为终点
int nColumn = poly.Length();
int nRow = 2;
TADSGePoint3d *ptArray = new TADSGePoint3d[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 if (m_pVd != NULL)
{
m_pVd->geometry().mesh(nRow, nColumn, (AcGePoint3d *)ptArray);
}
delete[] ptArray;
}
// 显示分别连接两个区域的边缘构成的侧面
void TGGiWorldViewportDraw::DrawMesh(const TGGePoly2D &polyRegion1, const TGGePoly2D &polyRegion2)
{
TGGePoly poly1, poly2;
polyRegion1.AsOpenPoly(poly1); //变成开口的poly, 如果原先封闭, 则起点复制为终点
polyRegion2.AsOpenPoly(poly2);
if (poly1.Length() != poly2.Length())
{
return;
}
int nColumn = poly1.Length();
int nRow = 2;
TADSGePoint3d *ptArray = new TADSGePoint3d[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 if (m_pVd != NULL)
{
m_pVd->geometry().mesh(nRow, nColumn, (AcGePoint3d *)ptArray);
}
delete[] ptArray;
}
// polySrc 已经离散过
void TGGiWorldViewportDraw::DrawBody(const TGGePoly2D &polySrc, const TVector3D &vtOffset)
{
TDPtrList<TGGePoly2D> lstPoly;
DrawBody(polySrc, lstPoly, vtOffset);
}
// polySrc 已经离散过
void TGGiWorldViewportDraw::DrawBody(const TGGePoly2D &polyOut, const TGGePoly2D &polyIn, const TVector3D &vtOffset)
{
TDPtrList<TGGePoly2D> lstPoly;
lstPoly.Append(new TGGePoly2D(polyIn));
DrawBody(polyOut, lstPoly, vtOffset);
}
void TGGiWorldViewportDraw::DrawBody(const TGGePoly2D &polyOut, const TDPtrList<TGGePoly2D> &lstHoles, const TVector3D &vt)
{
DrawShell(polyOut, lstHoles);
TGGePoly2D polyUp(polyOut);
for (int i = 0; i < polyUp.Length(); i++)
{
*polyUp[i] += vt;
}
TDPtrList<TGGePoly2D> lstHoleUp;
for (int n = 0; n < lstHoles.Length(); n++)
{
TGGePoly2D *pHole = new TGGePoly2D(lstHoles[n]);
for (int j = 0; j < pHole->Length(); j++)
{
*(*pHole)[j] += vt;
}
lstHoleUp.Append(pHole);
}
DrawShell(polyUp, lstHoleUp);
DrawMesh(polyOut, vt);
for (i = 0; i < lstHoles.Length(); i++)
{
DrawMesh(lstHoles[i], vt);
}
}
void TGGiWorldViewportDraw::DrawFace(const TGGe3DFace &face)
{
TADSGePoint3d 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 if (m_pVd != NULL)
{
m_pVd->geometry().mesh(2, 2, (AcGePoint3d *)ptArray, &edge);
}
}
void TGGiWorldViewportDraw::DrawTextFit(const TCHAR *pszText, TADSGePoint3d pt1, TADSGePoint3d 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 ADS < 21
int tmp0, tmp1;
BOOL bWinFont = (m_textStyle.font(pTypeface, bBold, bItalic, tmp0, tmp1) == Acad::eOk);
#else
Autodesk::AutoCAD::PAL::FontUtils::FontPitch pitch;
Autodesk::AutoCAD::PAL::FontUtils::FontFamily family;
Charset charset;
BOOL bWinFont = (m_textStyle.font(pTypeface, bBold, bItalic, charset, pitch, family) == 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)
{
TSplitpathOperator 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);
// sg add 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 if (m_pVd != NULL)
{
m_pVd->geometry().text(pt1, m_vtNormal, vDirection, pszText, -1, Adesk::kFalse, m_textStyle);
}
m_textStyle.setXScale(nOldXScale);
m_textStyle.setTextSize(nOldSize);
}
// 显示文字
void TGGiWorldViewportDraw::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];
TADSGePoint3d ptBase = Align2Base(m_align, m_ptLocation, TADSGePoint3d(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 if (m_pVd != NULL)
{
m_pVd->geometry().text(ptBase, m_vtNormal, vDirection,
pszContent, -1, Adesk::kFalse, m_textStyle);
}
m_textStyle.setTextSize(nOldSize);
m_textStyle.setXScale(nOldXScale);
}
const TCHAR * TGGiWorldViewportDraw::Descriptor()
{
return _T("TGGiWorldViewportDraw");
}
const TCHAR * TGGiWorldViewportDraw::Desc()
{
return Descriptor();
}
void TGGiWorldViewportDraw::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 TGGiWorldViewportDraw::DrawAtomicEntSet(const AcDbVoidPtrArray &entSet, const AcGeMatrix3d &matTrans)
{
int nCount = entSet.length();
for (int i = 0; i < nCount; i++)
{
AcDbEntity *pEntity = (AcDbEntity *)entSet[i];
TMasterProperties 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)
{
TGGePoly2D poly2d;
PolyConvert(*pline, poly2d);
TVector3D 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 if (m_pVd != NULL)
{
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 if (m_pVd != NULL)
{
pEntCloned->viewportDraw(m_pVd);
}
delete pEntCloned;
}
}
}
BackUpProperties(prop);
}
}
Adesk::Boolean TGGiWorldViewportDraw::IsDragging() const
{
if (m_pWd)
{
return m_pWd->isDragging();
}
if (m_pVd)
{
return m_pVd->isDragging();
}
return Adesk::kFalse;
}
//add by xlc on 100629 TArch8.5
//COLORREF TGGiWorldViewportDraw::GetTrueColor() const
AcCmColor TGGiWorldViewportDraw::GetTrueColor() const
{
AcCmColor cmColor;
//modify by xlc on 101108
#if ADS == 15
return cmColor; //R15不支持真彩
#endif
AcCmEntityColor cmEntColor;
if (m_pWd)
{
cmEntColor = m_pWd->subEntityTraits().trueColor();
}
else
{
cmEntColor = m_pVd->subEntityTraits().trueColor();
}
cmColor.setRGB(cmEntColor.red(), cmEntColor.green(), cmEntColor.blue());
return cmColor;
}
//void TGGiWorldViewportDraw::SetTrueColor(COLORREF crRef)
void TGGiWorldViewportDraw::SetTrueColor(AcCmColor crRef)
{
#if ADS == 15
return; //modify by xlc on 101108 R15不支持真彩
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 if (m_pVd != NULL)
{
m_pVd->subEntityTraits().setTrueColor(cmEntColor);
}
}