#include "stdafx.h" #include "AecDbsludgepipe.h" #include "GiDrawUtility.h" #include "AecDb3dRoadAxisLine.h" #include "CoreTools.h" ACRX_DXF_DEFINE_MEMBERS(AecDbSludgePipe, AecDbEwPipeBase, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, AcDbProxyEntity::kNoOperation | AcDbProxyEntity::kDisableProxyWarning, AEC_SLUDGEPIPE, "AecDbSludgePipe" "|Product Desc: shanghua earthworm app obj" "|Company: shanghua inc" "|WEB Address: www.shanghuasoft.com") Adesk::UInt32 AecDbSludgePipe::kCurrentVersionNumber = 1; IMP_XDATA_KEY(AecDbSludgePipe,_INNER_D_); IMP_XDATA_KEY(AecDbSludgePipe,_OUTER_D_); IMP_XDATA_KEY(AecDbSludgePipe,_HOLD_D_); IMP_XDATA_KEY(AecDbSludgePipe,_SPACING_); IMP_XDATA_KEY(AecDbSludgePipe,_HEAD_SPACING_); IMP_XDATA_KEY(AecDbSludgePipe,_TAIL_SPACING_); AecDbSludgePipe::AecDbSludgePipe() { m_mapSpecXData.SetAt(KEY_NAME,_T("排泥管")); } AecDbSludgePipe::~AecDbSludgePipe() { } Acad::ErrorStatus AecDbSludgePipe::subExplode(AcDbVoidPtrArray & entitySet) const { return Acad::eNotImplementedYet; } void AecDbSludgePipe::subList() const { acutPrintf(_T("\n内径:%s"), GetInner()); acutPrintf(_T("\n外径:%.1f mm"), GetOuter()); acutPrintf(_T("\n头部安装距离:%.1f mm"), GetHeadSpa()); acutPrintf(_T("\n尾部安装距离:%.1f mm"), GetTailSpa()); acutPrintf(_T("\n孔径:%.1f mm"), GetHoldD()); acutPrintf(_T("\n孔距:%.1f mm"), GetSpacing()); } Acad::ErrorStatus AecDbSludgePipe::copyFrom(const AcRxObject * pSrc) { return AecDbEwPipeBase::copyFrom(pSrc); } Acad::ErrorStatus AecDbSludgePipe::subTransformBy(const AcGeMatrix3d & xform) { return AecDbEwPipeBase::subTransformBy(xform); } Acad::ErrorStatus AecDbSludgePipe::subGetGripPoints(AcDbGripDataPtrArray & grips , const double curViewUnitSize , const int gripSize , const AcGeVector3d & curViewDir , const int bitflags) const { return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDbSludgePipe::subGetGripPoints(AcGePoint3dArray &gripPoints , AcDbIntArray &osnapModes , AcDbIntArray & geomIds) const { assertReadEnabled(); return Acad::eOk; } Acad::ErrorStatus AecDbSludgePipe::subMoveGripPointsAt(const AcDbVoidPtrArray & appData , const AcGeVector3d & offset , const int bitflags) { return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDbSludgePipe::subMoveGripPointsAt(const AcDbIntArray & indices , const AcGeVector3d & offset) { AssertWriteEnabled(); return Acad::eOk; } Acad::ErrorStatus AecDbSludgePipe::subGetOsnapPoints(AcDb::OsnapMode osnapMode , INT_PTR gsSelectionMark , const AcGePoint3d & pickPoint , const AcGePoint3d & lastPoint , const AcGeMatrix3d & viewXform , AcGePoint3dArray & snapPoints , AcDbIntArray & geomIds) const { return Acad::eOk; } Acad::ErrorStatus AecDbSludgePipe::subGetGeomExtents(AcDbExtents & extents) const { return Acad::eOk; } Acad::ErrorStatus AecDbSludgePipe::subIntersectWith(const AcDbEntity * pEnt , AcDb::Intersect intType , AcGePoint3dArray & points , INT_PTR thisGsMarker , INT_PTR otherGsMarker) const { return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDbSludgePipe::subIntersectWith(const AcDbEntity * pEnt , AcDb::Intersect intType , const AcGePlane & projPlane , AcGePoint3dArray & points , INT_PTR thisGsMarker , INT_PTR otherGsMarker) const { return Acad::eNotImplementedYet; } Acad::ErrorStatus AecDbSludgePipe::dwgInFields(AcDbDwgFiler * pFiler) { AssertWriteEnabled(); //----- Read parent class information first. Acad::ErrorStatus es = Acad::eOk; es = AecDbEwPipeBase::dwgInFields(pFiler); if (es != Acad::eOk) return (es); //----- Object version number needs to be read first Adesk::UInt32 version(0); if ((es = pFiler->readUInt32(&version)) != Acad::eOk) return (es); if (version > AecDbSludgePipe::kCurrentVersionNumber) return Acad::eMakeMeProxy; m_angles.clear(); Adesk::UInt64 len(0); pFiler->readUInt64(&len); double angle(.0); for (Adesk::UInt64 i = 0; i < len; ++i) { pFiler->readDouble(&angle); m_angles.insert(angle); } return Acad::eOk; } Acad::ErrorStatus AecDbSludgePipe::dwgOutFields(AcDbDwgFiler * pFiler) const { assertReadEnabled(); //----- Save parent class information first. Acad::ErrorStatus es = Acad::eOk; es = AecDbEwPipeBase::dwgOutFields(pFiler); if (es != Acad::eOk) return (es); //----- Object version number needs to be saved first if ((es = pFiler->writeUInt32(AecDbSludgePipe::kCurrentVersionNumber)) != Acad::eOk) return (es); pFiler->writeUInt64(m_angles.size()); std::set::const_iterator it(m_angles.begin()); for (; it != m_angles.end(); ++it) pFiler->writeDouble(*it); return Acad::eOk; } Acad::ErrorStatus AecDbSludgePipe::dxfInFields(AcDbDxfFiler * pFiler) { return AecDbEwPipeBase::dxfInFields(pFiler); } Acad::ErrorStatus AecDbSludgePipe::dxfOutFields(AcDbDxfFiler * pFiler) const { return AecDbEwPipeBase::dxfOutFields(pFiler); } void AecDbSludgePipe::GetGripText(int nPos, CString & sText) { //switch (nPos) //{ //case 0: // sText = _T("移动起点"); // break; //case 1: // sText = _T("平移"); // break; //case 2: // sText = _T("移动终点"); //default: // break; //} } Acad::ErrorStatus AecDbSludgePipe::Draw2d(AcGiDraw & dc) const { assertReadEnabled(); if (Has2DBuffer()) { Draw2DBuffers(dc); return Acad::eOk; } AecDbEwPipeBase::Draw2d(dc); double dLen(.0); AcGePoint3d ptE; m_pBaseCurve->getEndPoint(ptE); m_pBaseCurve->getDistAtPoint(ptE, dLen); int len = (int)(dLen - GetHeadSpa() - GetTailSpa()); AcGePlane plane; AcGeMatrix3d mat; AcGePoint3d ptO(AcGePoint3d::kOrigin), pt(AcGePoint3d::kOrigin) , pt1(AcGePoint3d::kOrigin), pt2(AcGePoint3d::kOrigin); double dist(GetHeadSpa()), spac(GetSpacing()), D(GetOuter()) , r(GetHoldD()), alpha(.0), major(GetHoldD()), minor(.0); AcGeVector3d vtX(AcGeVector3d::kXAxis), vtNormal; int num = (int)(dLen / spac); if (dLen - num * spac > 2 * r) // 检查剩余部分,是否还能画一个 num++; for (int i = 0; i < num; i++) { if (m_pBaseCurve->getPointAtDist(dist + r + (i * spac), ptO) != Acad::eOk) continue; if (m_pBaseCurve->getFirstDeriv(ptO, vtNormal) != Acad::eOk) continue; plane.set(ptO, vtNormal); mat.setToPlaneToWorld(plane); vtNormal.normalize(); std::set::const_iterator it(m_angles.begin()); for (; it != m_angles.end(); ++it) { vtX = AcGeVector3d::kXAxis; vtX.transformBy(mat); vtX.rotateBy(*it, vtNormal); vtX.normalize(); pt = ptO + vtX * D; // 椭圆中心 pt.z = .0; alpha = asin((r * .5) / D); // 孔所对应圆心角的一半 // pt1, pt2 为孔对应的弦的两端 vtX.rotateBy(-alpha, vtNormal); pt1 = ptO + vtX * D; // 顺时针转半个角 取点 vtX.rotateBy(2 * alpha, vtNormal); pt2 = ptO + vtX * D; // 再转回去整个角 取点 // 取出 pt1,pt2线段在 xy 平观的投影长,即为椭圆的短轴 minor = pt1.convert2d(AcGePlane::kXYPlane).distanceTo(pt2.convert2d(AcGePlane::kXYPlane)); AcDbEllipse *pC = new AcDbEllipse(pt, AcGeVector3d::kZAxis, vtNormal * major, minor / major); dc.DrawEntity(*pC); Add2DBuffer(pC); AcDbLine *pL = new AcDbLine(pt, pt + pC->majorAxis() * 1.5); dc.DrawEntity(*pL); Add2DBuffer(pL); pL = new AcDbLine(pt, pt - pC->majorAxis() * 1.5); dc.DrawEntity(*pL); Add2DBuffer(pL); pL = new AcDbLine(pt, pt + pC->minorAxis() * 1.5); dc.DrawEntity(*pL); Add2DBuffer(pL); pL = new AcDbLine(pt, pt - pC->minorAxis() * 1.5); dc.DrawEntity(*pL); Add2DBuffer(pL); } } return Acad::eOk; } Acad::ErrorStatus AecDbSludgePipe::Draw3d(AcGiDraw & dc) const { assertReadEnabled(); if (Has3DBuffer()) { Draw3DBuffers(dc); return Acad::eOk; } if (!m_pBaseCurve) return Acad::eInvalidInput; AcDbRegion *pReg = MakeSection(); if (!pReg) return Acad::eInvalidInput; AcDbEntity* p3dEnt(NULL); AcDb3dSolid *pSolid(NULL), *pSub(NULL); AecDb3dRoadAxisLine* pALn = AecDb3dRoadAxisLine::cast(m_pBaseCurve); if (pALn != NULL) { AcDbCurve* pCurve = NULL; int nCount = pALn->GetCurveSegCount(); for (int i = 0; i < nCount; i++) { pCurve = pALn->GetCurveSeg(i); p3dEnt = GiDrawUtility::DrawPipe(pCurve, pReg, AcGePoint3d::kOrigin); if (!i) { pSolid = AcDb3dSolid::cast(p3dEnt); if (!pSolid) { DELETE_PTR(p3dEnt); return Acad::eInvalidInput; } } else { pSub = AcDb3dSolid::cast(p3dEnt); if (!pSub) { DELETE_PTR(p3dEnt); return Acad::eInvalidInput; } CoreTools::booleanOper(pSolid, pSub, AcDb::kBoolUnite); DELETE_PTR(pSub); } } p3dEnt = pSolid; } else { p3dEnt = GiDrawUtility::DrawPipe(m_pBaseCurve, pReg, AcGePoint3d::kOrigin); } if (!p3dEnt) return Acad::eInvalidInput; pSolid = AcDb3dSolid::cast(p3dEnt); if (!pSolid) { DELETE_PTR(p3dEnt); return Acad::eInvalidInput; } double dLen(.0); AcGePoint3d ptE; m_pBaseCurve->getEndPoint(ptE); m_pBaseCurve->getDistAtPoint(ptE, dLen); int len = (int)(dLen - GetHeadSpa() - GetTailSpa()); AcGePlane plane; AcGeMatrix3d mat; AcGePoint3d ptO(AcGePoint3d::kOrigin); double dist(GetHeadSpa()), spac(GetSpacing()), h(GetOuter() * 1.5), r(GetHoldD()); AcGeVector3d vtX(AcGeVector3d::kXAxis), vtNormal; int num = (int)(dLen / spac); if (dLen - num * spac > 2 * r) // 检查剩余部分,是否还能画一个 num++; for (int i = 0; i < num; i++) { if (m_pBaseCurve->getPointAtDist(dist + r + (i * spac), ptO) != Acad::eOk) continue; if (m_pBaseCurve->getFirstDeriv(ptO, vtNormal) != Acad::eOk) continue; plane.set(ptO, vtNormal); mat.setToPlaneToWorld(plane); std::set::const_iterator it(m_angles.begin()); for (; it != m_angles.end(); ++it) { vtX = AcGeVector3d::kXAxis; vtX.transformBy(mat); vtX.rotateBy(*it, vtNormal); vtX.normalize(); AcDbEntity *pEnt = GiDrawUtility::DrawCylinder(ptO, ptO + vtX * h, r); if (!pEnt) continue; pSub = AcDb3dSolid::cast(pEnt); if (!pSub) { DELETE_PTR(pEnt); continue; } CoreTools::booleanOper(pSolid, pSub, AcDb::kBoolSubtract); DELETE_PTR(pSub); } } dc.DrawEntity(*pSolid); Add3DBuffer(pSolid); return Acad::eOk; } void AecDbSludgePipe::InitPipeBase() { m_mapSpecXData.SetAt(KEY_2DSTYLE, 2); // 双线 m_mapSpecXData.SetAt(KEY_SECSHAPE, 2); // 圆 m_mapSpecXData.SetAt(KEY_DRAWGRAD, 0); // 不绘坡度线 m_mapSpecXData.SetAt(PIPE_DN, GetOuter()); // 公称 m_mapSpecXData.SetAt(PIPE_D, GetOuter()); // 公称 AcDbRegion *pReg = MakeSection(); SetSection(pReg, AcGePoint3d::kOrigin); } AcDbRegion* AecDbSludgePipe::MakeSection() const { double dB(GetOuter()), dS(GetInner()); if (dB <= dS) return NULL; AcDbCircle Cir1(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, dB); if (!CoreTools::createRegion(&Cir1)) return NULL; AcDbRegion *pBig = CoreTools::createRegion(&Cir1); if (!pBig) return NULL; AcDbRegion *pSml(NULL); if (!EQUAL_ZERO(dB - dS)) { AcDbCircle Cir2(AcGePoint3d::kOrigin, AcGeVector3d::kZAxis, dS); pSml = CoreTools::createRegion(&Cir2); if (!pSml) return NULL; } // 这里做一个布尔减 if (pBig && pSml) { if (pBig->booleanOper(AcDb::kBoolSubtract, pSml) != Acad::eOk) { acutPrintf(_T("\n DrawPipe booleanOper failed.")); DELETE_PTR(pBig); DELETE_PTR(pSml); return NULL; } } return pBig; } void AecDbSludgePipe::AppendAngle(const double & a) { m_angles.insert(a); }