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

453 lines
11 KiB
C++

#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<double>::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<double>::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<double>::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);
}