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

472 lines
9.8 KiB
C++

#include "stdafx.h"
#include "AecDbXStepDraw.h"
#include "AecDbXStep.h"
#include "AecDbEarthWorm.h"
#include "AcDbX3dSolid.h"
#include "CoreTools.h"
ACRX_CONS_DEFINE_MEMBERS(AecDbXStepDraw, AecDbXDraw, 0);
DLLIMPEXP AcDbPolyline* FormatPolyline(AcGePoint3d* ppPts, int nCount);
DLLIMPEXP AcDbCurve* GetMinOffsetCurve(AcDbCurve* pPl, double dOff);
DLLIMPEXP AcDbCurve* GetMaxOffsetCurve(AcDbCurve* pPl, double dOff);
DLLIMPEXP AcGePoint3d MidPoint(AcGePoint3d& pt1, AcGePoint3d& pt2);
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();
AcGePoint3d ptS;
pCurve->getStartPoint(ptS);
AcDbRay ray;
ray.setUnitDir(vt);
ray.setBasePoint(ptS);
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;
}
AcDbCurve *pFir0 = (AcDbCurve *)ar.first();
AcDbCurve *pFir1 = (AcDbCurve *)ar2.first();
AcGePoint3dArray pts1, pts2;
pFir0->intersectWith(&ray, AcDb::kOnBothOperands, pts1);
pFir1->intersectWith(&ray, AcDb::kOnBothOperands, pts2);
AcDbCurve *pNewCurve = NULL;
if (!pts1.isEmpty())
{
pNewCurve = (AcDbCurve *)pFir0->clone();
deleteArrayVoidPtrs< AcDbEntity>(ar);
deleteArrayVoidPtrs< AcDbEntity>(ar2);
return pNewCurve;
}
if (!pts2.isEmpty())
{
pNewCurve = (AcDbCurve *)pFir1->clone();
deleteArrayVoidPtrs< AcDbEntity>(ar);
deleteArrayVoidPtrs< AcDbEntity>(ar2);
return pNewCurve;
}
return pNewCurve;
}
AcDbRegion* makeRegByPoly(AcDbPolyline* pPlS
, AcDbPolyline* pPlE)
{
if (!pPlS)
{
return NULL;
}
if (!pPlE)
{
return NULL;
}
AcGePoint3d pt;
AcGePoint3dArray ptAr;
ptAr.removeAll();
for (int i(0); i < pPlS->numVerts(); ++i)
{
pPlS->getPointAt(i, pt);
ptAr.append(pt);
}
for (int i(pPlS->numVerts() - 1); i >= 0; --i)
{
pPlE->getPointAt(i, pt);
ptAr.append(pt);
}
ptAr.append(ptAr.first());
return AecDbEarthWorm::CreatePolygonRegionOnly(ptAr.asArrayPtr(), ptAr.length());
}
AcDbPolyline* EditPolySE(AcDbPolyline* pPl
, XStepData &data
, double &dDist)
{
if (!pPl)
{
return NULL;
}
AcGePoint3d ptGe[10];
AcGeVector3d vt;
AcGePoint3d pt;
AcGePoint3dArray ptAr;
ptAr.removeAll();
int nLen= pPl->numVerts();
pPl->getStartPoint(ptGe[0]);
pPl->getPointAt(1, ptGe[1]);
vt = (ptGe[0] - ptGe[1]).normalize();
ptGe[2] = ptGe[0] - vt * dDist;
ptAr.append(ptGe[2]);
for (int i = 1; i < (nLen - 1); ++i)
{
pPl->getPointAt(i, pt);
ptAr.append(pt);
}
pPl->getEndPoint(ptGe[3]);
pPl->getPointAt(nLen - 2, ptGe[4]);
vt = (ptGe[3] - ptGe[4]).normalize();
ptGe[5] = ptGe[3] - vt * dDist;
ptAr.append(ptGe[5]);
return FormatPolyline(ptAr.asArrayPtr(), ptAr.length());
}
AcDbPolyline* makePolyByPoly(AcDbPolyline* pPlS
, AcDbPolyline* pPlE)
{
if (!pPlS)
{
return NULL;
}
if (!pPlE)
{
return NULL;
}
AcGePoint3d pt;
AcGePoint3dArray ptAr;
ptAr.removeAll();
for (int i(0); i < pPlS->numVerts(); ++i)
{
pPlS->getPointAt(i, pt);
ptAr.append(pt);
}
for (int i(pPlS->numVerts() - 1); i >= 0; --i)
{
pPlE->getPointAt(i, pt);
ptAr.append(pt);
}
ptAr.append(ptAr.first());
return FormatPolyline(ptAr.asArrayPtr(), ptAr.length());
}
AcDbPolyline* addPolySE(AcDbPolyline* pPl
, XStepData& data
, double& dDist)
{
if (!pPl)
{
return NULL;
}
AcGePoint3d ptGe[10];
AcGeVector3d vt, vtDir;
AcGePoint3d pt;
AcGePoint3dArray ptAr;
ptAr.removeAll();
int nLen = pPl->numVerts();
pPl->getStartPoint(ptGe[0]);
pPl->getPointAt(1, ptGe[1]);
vt = (ptGe[0] - ptGe[1]).normalize();
vtDir = vt;
vtDir.rotateBy(-PI / 2.0, AcGeVector3d::kZAxis);
vtDir.normalize();
ptGe[2] = ptGe[0] - vtDir * dDist;
ptAr.append(ptGe[2]);
for (int i(0); i < nLen; ++i)
{
pPl->getPointAt(i, pt);
ptAr.append(pt);
}
pPl->getEndPoint(ptGe[3]);
pPl->getPointAt(nLen - 2, ptGe[4]);
vt = (ptGe[3] - ptGe[4]).normalize();
vtDir = vt;
vtDir.rotateBy(-PI / 2.0, AcGeVector3d::kZAxis);
vtDir.normalize();
ptGe[5] = ptGe[3] + vtDir * dDist;
ptAr.append(ptGe[5]);
return FormatPolyline(ptAr.asArrayPtr(), ptAr.length());
}
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()));
AecDbEwPipeBase base;
base.SetSection(pReg, ptCen);
base.SetBaseCurve(ptCen, ptCen + vt);
base.Draw3d(dc);
dc.Add3dBuffer(base.Get3DBuffer());
base.Clean3DBufferNoDel();
}
}
AecDbXStepDraw::AecDbXStepDraw(void)
{
}
AecDbXStepDraw::~AecDbXStepDraw(void)
{
}
Acad::ErrorStatus AecDbXStepDraw::Draw2d(AcGiDraw &dc) const
{
AcDbEntity *pEntReal = GetAttach();
if (pEntReal == NULL)
return Acad::eOk;
AecDbXStep *pStep = AecDbXStep::cast(pEntReal);
if (pStep == NULL)
return Acad::eOk;
XStepData data;
memset(&data, 0, sizeof(XStepData));
pStep->GetXStepData(data);
AcGeVector3d vtDir(0, 0, 0);
GetSpecialtyData()->GetAt(KEY_StartDir, vtDir);
AcDbCurve *pBaseCrv = pStep->GetBaseCurve();
if (!pBaseCrv)
{
return Acad::eOk;
}
AcDbPolyline* pPl = AcDbPolyline::cast(pBaseCrv);
if (!pPl)
{
DELETE_PTR(pBaseCrv);
return Acad::eOk;
}
double dWallThick(100), dStwepW(.0), dStwepH(.0);
AcDbPolyline* pPlOff(NULL);
if (data.nBaseA)
{
for (int i(0); i < data.nSteepS; ++i)
{
pPlOff = (AcDbPolyline*)makeOffsetCurveByDir(pPl, dWallThick + data.dBaseW - data.dSteepW * i, vtDir);
if (!pPlOff)
{
return Acad::eOk;
}
if (data.nStpStyle)
{
// 台阶方式:三面台阶
dStwepW = data.dSteepW * i;
pPlOff = EditPolySE(pPlOff, data, dStwepW);
dStwepH = data.dBaseW - data.dSteepW * i;
pPlOff = addPolySE(pPlOff, data, dStwepH);
}
dc.DrawEntity(pPlOff);
dc.Add2dBuffer(pPlOff);
}
}
else
{
for (int i(0); i < data.nSteepS; ++i)
{
pPlOff = (AcDbPolyline*)makeOffsetCurveByDir(pPl, dWallThick + data.dBaseW + data.dSteepW * i, vtDir);
if (!pPlOff)
{
return Acad::eOk;
}
if (data.nStpStyle)
{
// 台阶方式:三面台阶
dStwepW = data.dSteepW * i * (-1);
pPlOff = EditPolySE(pPlOff, data, dStwepW);
dStwepH = data.dBaseW + data.dSteepW * i;
pPlOff = addPolySE(pPlOff, data, dStwepH);
}
dc.DrawEntity(pPlOff);
dc.Add2dBuffer(pPlOff);
}
}
return Acad::eOk;
}
Acad::ErrorStatus AecDbXStepDraw::Draw3d(AcGiDraw& dc) const
{
AcDbEntity* pEntReal = GetAttach();
if (pEntReal == NULL)
return Acad::eOk;
AecDbXStep* pStep = AecDbXStep::cast(pEntReal);
if (pStep == NULL)
return Acad::eOk;
XStepData data;
memset(&data, 0, sizeof(XStepData));
pStep->GetXStepData(data);
AcGeVector3d vtDir(0, 0, 0);
GetSpecialtyData()->GetAt(KEY_StartDir, vtDir);
AcDbCurve* pBaseCrv = pStep->GetBaseCurve();
if (!pBaseCrv)
{
return Acad::eOk;
}
AcDbPolyline* pPl = AcDbPolyline::cast(pBaseCrv);
if (!pPl)
{
DELETE_PTR(pBaseCrv);
return Acad::eOk;
}
AcGePoint3d ptGe[5];
double dWallThick(100);
AcGeVector3d Z(AcGeVector3d::kZAxis);
AcDbPolyline* pPlBase = (AcDbPolyline*)makeOffsetCurveByDir(pPl, dWallThick * .5, vtDir);
if (!pPlBase)
{
return Acad::eOk;
}
AcDbPolyline* pPoly(NULL), * pPlTriIn(NULL), * pPlTriOut(NULL);
AcDbRegion* pReg(NULL), * pRegTri(NULL);
AcGeMatrix3d mat;
double dDist(.0), dStepW(.0);
pPlBase->setElevation(data.dBaseEl);
// 结构样式
if (data.nStrStyle)
{
// 台面基面
if (data.nBaseA)
{
// 台面基面为轮廓面
dStepW = data.dBaseW - data.nSteepS * data.dSteepW;
}
else
{
// 台面基面为平台面
dStepW = data.dBaseW - data.dSteepW;
}
double dStep = data.dSteepH;
// 结构样式:下沉台阶
for (int i(0); i < data.nSteepS; ++i)
{
pPoly = (AcDbPolyline*)makeOffsetCurveByDir(pPlBase, dStepW + data.dSteepW * i, vtDir);
if (!pPoly)
{
return Acad::eOk;
}
pPlTriIn = (AcDbPolyline*)pPoly->clone();
pPlTriOut = (AcDbPolyline*)makeOffsetCurveByDir(pPlTriIn, data.dSteepW, vtDir);
if (data.nStpStyle)
{
// 台阶方式:三面台阶
dDist = data.dSteepW * data.nSteepS - data.dSteepW * i;
pPlTriIn = EditPolySE(pPlTriIn, data, dDist);
dDist -= data.dSteepW;
pPlTriOut = EditPolySE(pPlTriOut, data, dDist);
dDist = dStepW + data.dSteepW * i;
pPlTriIn = addPolySE(pPlTriIn, data, dDist);
dDist += data.dSteepW;
pPlTriOut = addPolySE(pPlTriOut, data, dDist);
}
pReg = makeRegByPoly(pPlTriIn, pPlTriOut);
if (!pReg)
{
return Acad::eOk;
}
drawSolid(dc, pReg, Z * dStep);
dStep += data.dSteepH;
}
}
else
{
if (data.nBaseA)
{
// 台面基面为轮廓面
dStepW = data.dBaseW;
}
else
{
// 台面基面为平台面
dStepW = data.dBaseW + (data.nSteepS - 1) * data.dSteepW;
}
// 结构样式:普通台阶
for (int i(0); i < data.nSteepS; ++i)
{
pPoly = (AcDbPolyline*)makeOffsetCurveByDir(pPlBase, dStepW - data.dSteepW * i, vtDir);
if (!pPoly)
{
return Acad::eOk;
}
if (data.nStpStyle)
{
// 台阶方式:三面台阶
dDist = data.dSteepW * i;
pPlTriIn = EditPolySE(pPlBase, data, dDist);
pPlTriOut = EditPolySE(pPoly, data, dDist);
}
else
{
// 台阶方式:单面台阶
pPlTriIn = (AcDbPolyline*)pPlBase->clone();
pPlTriOut = (AcDbPolyline*)pPoly->clone();
}
pReg = makeRegByPoly(pPlTriIn, pPlTriOut);
if (!pReg)
{
return Acad::eOk;
}
mat.setToIdentity();
mat.setTranslation(Z * data.dSteepH * i);
pReg->transformBy(mat);
drawSolid(dc, pReg, Z * data.dSteepH);
}
}
return Acad::eOk;
}