#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; }