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

910 lines
21 KiB
C++

#include "stdafx.h"
#include "AecDbZLineXOpening.h"
#include "AecDbZLineXOpeningDraw.h"
#include "AecComplexCurveDraw.h"
#include "AecDbEwPipeBase.h"
#include "AcDbX3dSolid.h"
#include "CoreTools.h"
#include <KTCadUtility.h>
DLLIMPEXP AcDbPolyline* FormatPolyline(AcGePoint3d* ppPts,int nCount);
namespace
{
AcDbCurve* makeOffsetCurveByDir(AcDbPolyline *pCurve
, const double &dOffset
, const AcGeVector3d &vtDir )
{
if (!pCurve) return NULL;
int len(pCurve->numVerts());
if (len < 2) return NULL;
AcGeVector3d vt(vtDir);
vt.normalize();
AcDbVoidPtrArray ar, ar2;
pCurve->getOffsetCurves(dOffset, ar);
pCurve->getOffsetCurves(-dOffset, ar2);
// 没有都成功,那么,哪个成功用哪个。
if (!(!ar2.isEmpty() && !ar.isEmpty()))
{
AcDbVoidPtrArray &arr(ar.isEmpty() ? ar2 : ar);
if (arr.isEmpty()) return NULL;
AcDbCurve *pNew((AcDbCurve *)((AcDbCurve *)arr.first())->clone());
deleteArrayVoidPtrs< AcDbEntity>(arr);
return pNew;
}
AcDbPolyline *pNewCurve1 = (AcDbPolyline*)(((AcDbEntity*)ar.first())->clone());
deleteArrayVoidPtrs< AcDbEntity>(ar);
AcDbPolyline *pNewCurve2 = (AcDbPolyline*)(((AcDbEntity*)ar2.first())->clone());
deleteArrayVoidPtrs< AcDbEntity>(ar2);
AcDbCurve *pSelect(NULL);
double d1, d2;
AcDbLine line1, line2;
AcGePoint3d pt, pt1, pt2;
AcGeLineSeg3d seg, seg1, seg2;
for (int i(0); i < len - 1; ++i)
{
pCurve->getLineSegAt(i, seg);
pt = seg.startPoint();
pt += vt * 1;
pNewCurve1->getLineSegAt(i, seg1);
pNewCurve2->getLineSegAt(i, seg2);
line1.setStartPoint(seg1.startPoint());
line1.setEndPoint(seg1.endPoint());
line2.setStartPoint(seg2.startPoint());
line2.setEndPoint(seg2.endPoint());
line1.getClosestPointTo(pt, pt1, Adesk::kTrue);
line2.getClosestPointTo(pt, pt2, Adesk::kTrue);
d1 = pt.distanceTo(pt1);
d2 = pt.distanceTo(pt2);
if (EQUAL(d1, d2))
continue;
if (d1 > d2)
pSelect = (AcDbCurve*)pNewCurve2->clone();
else
pSelect = (AcDbCurve*)pNewCurve1->clone();
break;
}
if (!pSelect)
pSelect = (AcDbCurve*)pNewCurve1->clone();
DELETE_PTR(pNewCurve1);
DELETE_PTR(pNewCurve2);
return pSelect;
}
AcDbCurve* makeCurve(AcDbPolyline *pPline, const std::vector<double> &arOffset, const AcGeVector3d &vtDir)
{
if (!pPline) return NULL;
if (!pPline->isOnlyLines()) return NULL;
int nSeg(pPline->numVerts() - 1);
if (nSeg > arOffset.size()) return NULL;
AcDbVoidPtrArray arCurves;
std::vector<AcGeLineSeg3d> segs;
AcGeLineSeg3d seg;
for (int i(0); i < nSeg; ++i)
{
AcDbPolyline *pCurve = (AcDbPolyline*)makeOffsetCurveByDir(pPline, arOffset[i], vtDir);
// 是第几个 polyline 就把自己的第几段seg取出来
if (pCurve)
{
pCurve->getLineSegAt(i, seg);
segs.push_back(seg);
DELETE_PTR(pCurve);
}
}
if (segs.empty()) return NULL;
AcGePoint3dArray arpts, ar;
AcGeLineSeg3d seg1, seg2;
AcDbLine line1, line2;
for (int i(0); i < segs.size() - 1; ++i)
{
ar.removeAll();
line1.setStartPoint(segs[i].startPoint());
line1.setEndPoint(segs[i].endPoint());
line2.setStartPoint(segs[i + 1].startPoint());
line2.setEndPoint(segs[i + 1].endPoint());
if (line1.intersectWith(&line2, AcDb::kExtendBoth, ar) == Acad::eOk && !ar.isEmpty())
arpts.append(ar.first());
}
arpts.insertAt(0, segs[0].startPoint());
arpts.append(segs.rbegin()->endPoint());
return FormatPolyline(arpts.asArrayPtr(), arpts.length());
}
void extendCurve(AcDbPolyline *pPline, const double &dExt1, const double &dExt2)
{
if (!pPline) return;
int len(pPline->numVerts());
if (len < 2) return;
AcDb::Planarity epl;
AcGePlane pln;
pPline->getPlane(pln, epl);
pln.set(AcGePoint3d::kOrigin, pPline->normal());
AcGePoint3d ptFirst, ptSecond, ptLast, ptSecLast;
pPline->getPointAt(0, ptFirst);
pPline->getPointAt(1, ptSecond);
pPline->getPointAt(len - 1, ptLast);
pPline->getPointAt(len - 2, ptSecLast);
AcGeVector3d vt1(ptFirst - ptSecond), vt2(ptLast - ptSecLast);
vt1.normalize();
vt2.normalize();
ptFirst += vt1 * dExt1;
ptLast += vt2 * dExt2;
pPline->setPointAt(0, ptFirst.convert2d(pln));
pPline->setPointAt(len - 1, ptLast.convert2d(pln));
}
AcDbRegion* makeRegion(const int count, va_list ap)
{
AcDbVoidPtrArray ar;
AcGePoint3dArray pts;
for (int i = 0; i < count; ++i)
{
pts.append(va_arg(ap, AcGePoint3d));
}
if (pts.length() < 3) return NULL;
pts.append(pts[0]);
for (int i = 0; i < pts.length() - 1; ++i)
ar.append(new AcDbLine(pts[i], pts[i + 1]));
AcDbRegion *pReg = CoreTools::createRegion(ar);
deleteArrayVoidPtrs< AcDbEntity>(ar);
return pReg;
}
AcDbRegion* makeRegion2(const int count, ...)
{
va_list vlist;
va_start(vlist, count);
AcDbRegion *pReg = makeRegion(count, vlist);
va_end(vlist);
return pReg;
}
void drawSolid(AcGiDraw &dc, AcDbRegion *pReg, const AcGeVector3d &vt)
{
if (!pReg) return;
AcDbExtents ext;
pReg->getGeomExtents(ext);
AcGePoint3d ptCen(CoreTools::MidPt(ext.maxPoint(), ext.minPoint()));
AcDbLine ln(ptCen, ptCen + vt);
AcDbX3dSolid xSolid;
if (xSolid.CreateExtrude(pReg, ln))
{
AcDb3dSolid* pSolid = xSolid.GetDraw3dSolid();
if (pSolid != NULL)
{
dc.DrawEntity(pSolid);
dc.Add3dBuffer(pSolid);
}
}
}
AcDbCurve* addSECurve(AcDbPolyline *pPolyS, AcDbPolyline *pPolyE)
{
if (!pPolyS || !pPolyS->isOnlyLines()) return NULL;
if (!pPolyE || !pPolyE->isOnlyLines()) return NULL;
int nlen(pPolyS->numVerts());
if (nlen < 1) return NULL;
AcGePoint3d ptS, ptE, pt;
pPolyS->getStartPoint(ptS);
pPolyS->getEndPoint(ptE);
AcGePoint3dArray ar;
ar.removeAll();
pPolyE->getClosestPointTo(ptS, pt);
ar.append(pt);
for (int i(0); i < nlen; ++i)
{
pPolyS->getPointAt(i, pt);
ar.append(pt);
}
pPolyE->getClosestPointTo(ptE, pt);
ar.append(pt);
return FormatPolyline(ar.asArrayPtr(), ar.length());
}
AcDbRegion* makeRegionBy2PLine(AcDbPolyline *p1, AcDbPolyline *p2)
{
if (!p1 || !p2) return NULL;
AcGePoint3d pt1S, pt2S, pt1E, pt2E;
p1->getStartPoint(pt1S);
p2->getStartPoint(pt2S);
p1->getEndPoint(pt1E);
p2->getEndPoint(pt2E);
AcDbLine l1(pt1S, pt2S);
AcDbLine l2(pt1E, pt2E);
AcDbVoidPtrArray ar;
ar.append(&l1);
ar.append(&l2);
ar.append(p1);
ar.append(p2);
return CoreTools::createRegion(ar);
}
AcGePoint3d getClosestPoint(AcDbPolyline *p, const AcGePoint3d &ptGive)
{
if (!p) return AcGePoint3d::kOrigin;
AcGePoint3d pt(AcGePoint3d::kOrigin);
p->getClosestPointTo(ptGive, pt);
return pt;
}
AcGePoint3d getClosestPoint(AcDbPolyline *p, AcDbPolyline *pGive, const int &idx)
{
AcGePoint3d pt(AcGePoint3d::kOrigin);
if (!p || !pGive) return pt;
if (pGive->numVerts() <= idx) return pt;
pGive->getPointAt(idx, pt);
return getClosestPoint(p, pt);
}
void insertPt2PLine(AcDbPolyline *p, const AcGePoint3d &pt, const int &idx)
{
if (!p) return;
if (p->numVerts() < idx) return;
AcDb::Planarity epl;
AcGePlane pln;
p->getPlane(pln, epl);
pln.set(AcGePoint3d::kOrigin, p->normal());
p->addVertexAt(idx, pt.convert2d(pln));
}
AcGeVector3d getDirByPt(AcDbPolyline *p, const int &idx1, const int &idx2)
{
AcGeVector3d vt(AcGeVector3d::kXAxis);
if (!p) return vt;
int idx = idx1 < idx2 ? idx2 : idx1;
if (p->numVerts() <= idx) return vt;
AcGePoint3d pt1, pt2;
p->getPointAt(idx1, pt1);
p->getPointAt(idx2, pt2);
return (pt1 - pt2).normalize();
}
}
static const Adesk::UInt16 kBlue = 5;
static const Adesk::UInt16 kWhite = 7;
static const Adesk::UInt16 kColorByLayer = 256;
ACRX_CONS_DEFINE_MEMBERS(AecDbZLineXOpeningDraw,AecDbXDraw,0);
AecDbZLineXOpeningDraw::AecDbZLineXOpeningDraw(void)
{
}
AecDbZLineXOpeningDraw::~AecDbZLineXOpeningDraw(void)
{
}
Acad::ErrorStatus AecDbZLineXOpeningDraw::Draw2d(AcGiDraw &dc) const
{
const AecDbObjXDataMap* pXDataMap = GetSpecialtyData();
if (pXDataMap == NULL)
{
return Acad::eOk;
}
//带型窗,角窗,角凸窗
int nFlag = 0;
pXDataMap->GetAt(KEY_FLAG,nFlag);
switch(nFlag)
{
case 0://带型窗
{
DrawZOpening2d(dc);
break;
}
case 1://角窗
{
DrawZCornerOpening2d(dc);
break;
}
case 2://角凸窗
{
DrawZConvexOpening2d(dc);
break;
}
default:
break;
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbZLineXOpeningDraw::Draw3d(AcGiDraw &dc) const
{
const AecDbObjXDataMap* pXDataMap = GetSpecialtyData();
if (pXDataMap == NULL)
{
return Acad::eOk;
}
//带型窗,角窗,角凸窗
int nFlag = 0;
pXDataMap->GetAt(KEY_FLAG,nFlag);
switch(nFlag)
{
case 0://带型窗
{
DrawZOpening3d(dc);
break;
}
case 1://角窗
{
DrawZCornerOpening3d(dc);
break;
}
case 2://角凸窗
{
DrawZConvexOpening3d(dc);
break;
}
default:
break;
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbZLineXOpeningDraw::DrawZOpening2d(AcGiDraw &dc) const
{
AcDbObjectId idCurLay = dc.GetLayerId();
AcDbObjectId idCurLty = dc.GetLineTypeId();
AcDbEntity* pEntReal = GetAttach();
if (pEntReal == NULL)
return Acad::eOk;
AecDbZLineXOpening* pZLineXOpening = AecDbZLineXOpening::cast(pEntReal);
if (pZLineXOpening == NULL)
return Acad::eOk;
Adesk::UInt16 nCrBk = 256;
nCrBk = pEntReal->colorIndex();
dc.SetLayer(pEntReal->layerId());
int nColor = nCrBk;
if ( GetSpecialtyData()->GetAt(_T("COLOR"),nColor) )
{
dc.SetColor(nColor);
}
AcGePoint3dArray arZLines;
pZLineXOpening->GetZLinePoints(arZLines);
//门的裁剪墙线预先在插入门的时候;
AecComplexCurve win2d;
pZLineXOpening->GetStandardDraw2d(win2d,true);
//测试
/*AcDbLine* pLn = NULL;
for (int i = 0;i < win2d.length();i++)
{
AecEqui::AecCurveElement& el = win2d.atByRef(i);
if ( AecComplexCurve::MakeLine(el,pLn) )
{
pLn->setColorIndex(3);
CKTCadUtility::AddToBlockTableRecord(pLn);
pLn->close();
}
}*/
AcDbVoidPtrArray arEntPtrs;
AecComplexCurveDraw win2dDraw;
win2dDraw.SetEdage(win2d);
win2dDraw.Draw2d(dc,pEntReal->layerId(),pEntReal->layerId(),pEntReal->layerId());
win2dDraw.explode(arEntPtrs,pEntReal->layerId(),pEntReal->layerId(),pEntReal->layerId());
win2d.removeAll();
pZLineXOpening->GetSideLines(win2d,AcGeVector3d::kIdentity);
//设置为墙体的图层
AcDbObjectId idWallLay = KTSetting::InitLayer(_T("LAY_WALL"),true);
win2dDraw.RemoveEdage();
win2dDraw.SetEdage(win2d);
win2dDraw.Draw2d(dc,idWallLay,idWallLay,idWallLay);
win2dDraw.explode(arEntPtrs,idWallLay,idWallLay,idWallLay);
dc.SetColor(nCrBk);
dc.SetLayer(idCurLay);
dc.SetLineType(idCurLty);
dc.Add2dBuffer(arEntPtrs);
return Acad::eOk;
}
Acad::ErrorStatus AecDbZLineXOpeningDraw::DrawZCornerOpening2d(AcGiDraw &dc) const
{
DrawZOpening2d(dc);
return Acad::eOk;
}
Acad::ErrorStatus AecDbZLineXOpeningDraw::DrawZConvexOpening2d(AcGiDraw& dc) const
{
AcDbObjectId idCurLay = dc.GetLayerId();
AcDbObjectId idCurLty = dc.GetLineTypeId();
AcDbEntity* pEntReal = GetAttach();
if (pEntReal == NULL)
return Acad::eOk;
AecDbZLineXOpening* pZLineXOpening = AecDbZLineXOpening::cast(pEntReal);
if (pZLineXOpening == NULL)
return Acad::eOk;
Adesk::UInt16 nCrBk = 255;
nCrBk = pEntReal->colorIndex();
dc.SetLayer(pEntReal->layerId());
int nColor = nCrBk;
if (GetSpecialtyData()->GetAt(_T("COLOR"), nColor))
{
dc.SetColor(nColor);
}
OpeningData data;
pZLineXOpening->GetOpeningData(data);
AcGePoint3dArray arZLines;
pZLineXOpening->GetZLinePoints(arZLines);
AcDbPolyline* pPl = FormatPolyline(arZLines.asArrayPtr(), arZLines.length());
if (!pPl) return Acad::eOk;
AcGeVector3d vtDir(AcGeVector3d::kYAxis);
GetSpecialtyData()->GetAt(KEY_StartDir, vtDir);
AcDbPolyline* pPoly1 = (AcDbPolyline*)makeOffsetCurveByDir(pPl, data.dThick * .5, vtDir);
if (!pPoly1)
{
DELETE_PTR(pPl);
return Acad::eOk;
}
std::vector<double> arDoubles;
arDoubles.clear();
arDoubles.push_back(data.dXData[5]);
arDoubles.push_back(data.dXData[6]);
AcDbPolyline* pPoly2 = (AcDbPolyline*)makeCurve(pPoly1, arDoubles, vtDir);
AcDbPolyline* pPoly3 = (AcDbPolyline*)makeOffsetCurveByDir(pPoly2, data.dXData[9] * .5, -vtDir);
AcDbPolyline* pPoly4 = (AcDbPolyline*)makeOffsetCurveByDir(pPoly3, data.dXData[9] * .5, -vtDir);
AcDbPolyline* pPoly5 = (AcDbPolyline*)makeOffsetCurveByDir(pPl, data.dThick * .5, -vtDir);
if (!pPoly2 || !pPoly3 || !pPoly4 || !pPoly5)
{
DELETE_PTR(pPoly5);
DELETE_PTR(pPoly4);
DELETE_PTR(pPoly3);
DELETE_PTR(pPoly2);
DELETE_PTR(pPoly1);
DELETE_PTR(pPl);
return Acad::eOk;
}
if (!data.bAddBaf1)
{
extendCurve(pPoly2, data.dXData[7], .0);
extendCurve(pPoly3, data.dXData[9] * .5, .0);
if (data.dXData[7] >= data.dXData[9] * .5)
{
extendCurve(pPoly1, data.dXData[7], data.dXData[8]);
}
else
{
extendCurve(pPoly1, data.dXData[9] * .5, .0);
}
}
if (!data.bAddBaf2)
{
extendCurve(pPoly2, .0, data.dXData[8]);
extendCurve(pPoly3, .0, data.dXData[9] * .5);
if (data.dXData[7] >= data.dXData[9] * .5)
{
extendCurve(pPoly1, data.dXData[7], data.dXData[8]);
}
else
{
extendCurve(pPoly1, .0, data.dXData[9] * .5);
}
}
AcDbPolyline *pPoly(NULL);
pPoly = (AcDbPolyline*)addSECurve(pPoly2, pPoly1);
if (pPoly)
{
DELETE_PTR(pPoly2);
pPoly2 = pPoly;
}
pPoly = (AcDbPolyline*)addSECurve(pPoly3, pPoly1);
if (pPoly)
{
DELETE_PTR(pPoly3);
pPoly3 = pPoly;
}
pPoly = (AcDbPolyline*)addSECurve(pPoly4, pPoly1);
if (pPoly)
{
DELETE_PTR(pPoly4);
pPoly4 = pPoly;
}
pPoly = (AcDbPolyline*)addSECurve(pPoly5, pPoly1);
if (pPoly)
{
DELETE_PTR(pPoly5);
pPoly5 = pPoly;
}
if (!pPoly2 || !pPoly3 || !pPoly4 || !pPoly5)
{
DELETE_PTR(pPoly5);
DELETE_PTR(pPoly4);
DELETE_PTR(pPoly3);
DELETE_PTR(pPoly2);
DELETE_PTR(pPoly1);
DELETE_PTR(pPl);
return Acad::eOk;
}
dc.DrawEntity(pPoly2);
dc.Add2dBuffer(pPoly2);
dc.DrawEntity(pPoly3);
dc.Add2dBuffer(pPoly3);
dc.DrawEntity(pPoly4);
dc.Add2dBuffer(pPoly4);
dc.DrawEntity(pPoly5);
dc.Add2dBuffer(pPoly5);
DELETE_PTR(pPoly1);
DELETE_PTR(pPl);
return Acad::eOk;
}
Acad::ErrorStatus AecDbZLineXOpeningDraw::DrawZOpening3d(AcGiDraw &dc) const
{
AcDbObjectId idCurLay = dc.GetLayerId();
AcDbObjectId idCurLty = dc.GetLineTypeId();
AcDbEntity* pEntReal = GetAttach();
if (pEntReal == NULL)
return Acad::eOk;
AecDbZLineXOpening* pZLineXOpening = AecDbZLineXOpening::cast(pEntReal);
if (pZLineXOpening == NULL)
return Acad::eOk;
Adesk::UInt16 nCrBk = pEntReal->colorIndex();
dc.SetLayer(pEntReal->layerId());
int nColor = nCrBk;
if ( GetSpecialtyData()->GetAt(_T("COLOR"),nColor) )
{
dc.SetColor(nColor);
}
OpeningData data;
pZLineXOpening->GetOpeningData(data);
AcGePoint3dArray arZLines;
pZLineXOpening->GetZLinePoints(arZLines);
AcDbPolyline* pPl = FormatPolyline((AcGePoint3d *)arZLines.asArrayPtr(),arZLines.length());
DrawGlass(dc, pPl, data, pEntReal->layerId());
delete pPl;
return Acad::eOk;
}
void AecDbZLineXOpeningDraw::DrawGlass(AcGiDraw &dc, AcDbPolyline *pPl, const OpeningData &data, const AcDbObjectId &layerId) const
{
if (!pPl) return;
AecDbEwPipeBase wall;
double dBomEl = data.ptPos.z + data.dBomEl;
pPl->setElevation(dBomEl);
wall.setLayer(layerId);
wall.SetBaseCurve(pPl);
wall.SetSection(data.dXData[4], data.dHeight, 0.0, kMid);
wall.Draw3d(dc);
dc.Add3dBuffer(wall.Get3DBuffer());
wall.Clean3DBufferNoDel();
//下框架
wall.SetSection(data.dXData[2], data.dXData[2], 0.0, kMid);
wall.GetSpecialtyData()->SetAt(_T("COLOR"), 8);
wall.Draw3d(dc);
dc.Add3dBuffer(wall.Get3DBuffer());
wall.Clean3DBufferNoDel();
//第一格
double dEl1 = dBomEl + data.dXData[1];
pPl->setElevation(dEl1);
wall.SetSection(data.dXData[3], data.dXData[2], 0.0, kMid);
wall.SetSection(data.dXData[3], data.dXData[2], 0.0);
wall.SetBaseCurve(pPl);
wall.Draw3d(dc);
dc.Add3dBuffer(wall.Get3DBuffer());
wall.Clean3DBufferNoDel();
//顶框架
double dTopBom = dBomEl + data.dHeight - data.dXData[2];
pPl->setElevation(dTopBom);
wall.SetBaseCurve(pPl);
wall.Draw3d(dc);
dc.Add3dBuffer(wall.Get3DBuffer());
wall.Clean3DBufferNoDel();
//列框
double dSta = 0, dEnd = 0, dLen = 0;
pPl->getStartParam(dSta);
pPl->getEndParam(dEnd);
pPl->getDistAtParam(dEnd, dLen);
int nCols = (int)(dLen / data.dXData[0]);
double dStep = (dEnd - dSta) / nCols;
//恢复到底标高
pPl->setElevation(dBomEl);
AcDbLine ln;
AcGePoint3d ptSta, ptEnd;
wall.SetSection(data.dXData[2], data.dXData[2], 0.0);
wall.GetSpecialtyData()->SetAt(_T("COLOR"), 8);
//框架
AcGePoint3d ptOn;
for (int i = 0; i < nCols; i++)
{
pPl->getPointAtParam(dSta, ptSta);
ptSta.z = dBomEl;
ptEnd = ptSta;
ptEnd.z = ptSta.z + data.dHeight;
ln.setStartPoint(ptSta);
ln.setEndPoint(ptEnd);
wall.SetBaseCurve(&ln);
wall.Draw3d(dc);
dc.Add3dBuffer(wall.Get3DBuffer());
wall.Clean3DBufferNoDel();
dSta += dStep;
}
//拐点
for (int i = 1; i < pPl->numVerts() - 1; i++)
{
pPl->getPointAt(i, ptSta);
ptSta.z = dBomEl;
ptEnd = ptSta;
ptEnd.z = ptSta.z + data.dHeight;
ln.setStartPoint(ptSta);
ln.setEndPoint(ptEnd);
wall.SetBaseCurve(&ln);
wall.Draw3d(dc);
dc.Add3dBuffer(wall.Get3DBuffer());
wall.Clean3DBufferNoDel();
}
}
Acad::ErrorStatus AecDbZLineXOpeningDraw::DrawZCornerOpening3d(AcGiDraw &dc) const
{
DrawZOpening3d(dc);
return Acad::eOk;
}
Acad::ErrorStatus AecDbZLineXOpeningDraw::DrawZConvexOpening3d(AcGiDraw &dc) const
{
//AcAxDocLock lock;
AcDbObjectId idCurLay = dc.GetLayerId();
AcDbObjectId idCurLty = dc.GetLineTypeId();
AcDbEntity* pEntReal = GetAttach();
if (pEntReal == NULL)
return Acad::eOk;
AecDbZLineXOpening* pZLineXOpening = AecDbZLineXOpening::cast(pEntReal);
if (pZLineXOpening == NULL)
return Acad::eOk;
Adesk::UInt16 nCrBk = pEntReal->colorIndex();
dc.SetLayer(pEntReal->layerId());
int nColor = nCrBk;
if (GetSpecialtyData()->GetAt(_T("COLOR"), nColor))
{
dc.SetColor(nColor);
}
OpeningData data;
pZLineXOpening->GetOpeningData(data);
AcGeVector3d vtDir(0, 0, 0);
GetSpecialtyData()->GetAt(KEY_StartDir, vtDir);
AcGePoint3dArray arZLines;
pZLineXOpening->GetZLinePoints(arZLines);
AcDbPolyline* pPl = FormatPolyline((AcGePoint3d*)arZLines.asArrayPtr(), arZLines.length());
if (!pPl) return Acad::eOk;
pPl->setElevation(data.dBomEl);
// 两边延长
extendCurve(pPl, data.dXData[7], data.dXData[8]);
std::vector<double> arDoubles;
arDoubles.clear();
arDoubles.push_back(data.dXData[5]);
arDoubles.push_back(data.dXData[6]);
// 板外边线
AcDbPolyline *pBayLine = (AcDbPolyline*)makeCurve(pPl, arDoubles, vtDir);// 板
if (!pBayLine)
{
DELETE_PTR(pPl);
return Acad::eOk;
}
// 墙外边线
AcDbPolyline* pWallLine = (AcDbPolyline*)makeOffsetCurveByDir(pPl, data.dThick * .5, vtDir);
if (!pWallLine)
{
DELETE_PTR(pBayLine);
DELETE_PTR(pPl);
return Acad::eOk;
}
AcDbRegion* pReg = makeRegionBy2PLine(pBayLine, pWallLine);
AcGeVector3d vt(AcGeVector3d::kZAxis * data.dXData[10]);
if (pReg)
{
// 绘制地板
drawSolid(dc, pReg, -vt);
// 绘制顶板
AcGeMatrix3d mat;
mat.setTranslation(AcGeVector3d::kZAxis * data.dHeight);
pReg->transformBy(mat);
drawSolid(dc, pReg, vt);
DELETE_PTR(pReg);
}
// 窗线
AcDbPolyline *pWinLine = (AcDbPolyline*)makeOffsetCurveByDir(pBayLine, data.dXData[9], -vtDir);// 窗
if (pWinLine)
{
if (!data.bAddBaf1) // 起点无挡板
{
// 无挡板不画到延伸位置
// 缩短一个半个窗框架厚和一个延伸
extendCurve(pWinLine, -data.dXData[2] * .5 - data.dXData[7], .0);
// 然后封闭
AcGePoint3d pt = getClosestPoint(pWallLine, pWinLine, 0);
insertPt2PLine(pWinLine, pt, 0);
}
else
{ // 有挡板,直接绘制到延伸位置,无须封闭
// 只缩短半个窗框即可
extendCurve(pWinLine, -data.dXData[2] * .5, .0);
// 挡板
AcGePoint3d pt1, pt2;
pBayLine->getStartPoint(pt1);
pWallLine->getStartPoint(pt2);
AcDbRegion *pReg = makeRegion2(4
, pt1
, pt2
, pt2 + AcGeVector3d::kZAxis * (data.dHeight + data.dXData[10])
, pt1 + AcGeVector3d::kZAxis * (data.dHeight + data.dXData[10]));
if (pReg)
{
drawSolid(dc, pReg, getDirByPt(pWinLine, 0, 1) * data.dXData[10]);
DELETE_PTR(pReg);
}
}
if (!data.bAddBaf2) // 终点无挡板
{
// 无挡板不画到延伸位置
// 缩短一个半个窗框架厚和一个延伸
extendCurve(pWinLine, .0, -data.dXData[2] * .5 - data.dXData[8]);
// 然后封闭
AcGePoint3d pt = getClosestPoint(pWallLine, pWinLine, pWinLine->numVerts() - 1);
insertPt2PLine(pWinLine, pt, pWinLine->numVerts());
}
else
{ // 有挡板,直接绘制到延伸位置,无须封闭
// 只缩短半个窗框即可
extendCurve(pWinLine, -data.dXData[2] * .5, .0);
// 挡板
AcGePoint3d pt1, pt2;
pBayLine->getEndPoint(pt1);
pWallLine->getEndPoint(pt2);
AcDbRegion *pReg = makeRegion2(4
, pt1
, pt2
, pt2 + AcGeVector3d::kZAxis * (data.dHeight + data.dXData[10])
, pt1 + AcGeVector3d::kZAxis * (data.dHeight + data.dXData[10]));
if (pReg)
{
drawSolid(dc
, pReg
, getDirByPt(pWinLine
, pWinLine->numVerts() - 1
, pWinLine->numVerts() - 2) * data.dXData[10]);
DELETE_PTR(pReg);
}
}
DrawGlass(dc, pWinLine, data, idCurLay);
DELETE_PTR(pWinLine);
}
DELETE_PTR(pPl);
DELETE_PTR(pBayLine);
DELETE_PTR(pWallLine);
return Acad::eOk;
}