Files
envi-code/SourceCode/Code2026/tg_shs/shs_kernal/dbVertSlab.cpp
T

1022 lines
25 KiB
C++
Raw Normal View History

2026-10-04 00:04:20 +08:00
#include "stdafx.h"
2026-09-28 15:28:50 +08:00
/////////////////////////////////////////////////////////////
2026-10-04 00:04:20 +08:00
// 竖板对象类
2026-09-28 15:28:50 +08:00
/////////////////////////////////////////////////////////////
const Adesk::UInt8 TDbVertSlab::g_nVersion = 1;
ACRX_DXF_DEFINE_MEMBERS(ATSVertSlab, ATSEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
2026-10-04 00:04:20 +08:00
1, ATS_VERTSLAB, "ATS_VERTSLAB图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
2026-09-28 15:28:50 +08:00
IMPLEMENT_TENTBASE(TDbVertSlab);
TDbVertSlab::TDbVertSlab()
{
m_nThickness = 0;
m_nHeightS = m_nHeightE = 0;
}
TDbVertSlab::~TDbVertSlab()
{
}
BOOL TDbVertSlab::IsValid() const
{
BOOL bRet = TDbEntity::IsValid();
if (!bRet)
return bRet;
bRet = (m_ptStart.Distance2d(m_ptEnd)>_DIST_SNAP &&
m_nThickness>_DIST_SNAP &&
2026-10-04 00:04:20 +08:00
m_nHeightS*m_nHeightE>_DIST_SNAP*_DIST_SNAP); // 起点高度和终点高度, 必须全>0或<0
2026-09-28 15:28:50 +08:00
return bRet;
}
Acad::ErrorStatus
TDbVertSlab::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
2026-10-04 00:04:20 +08:00
// 提供对格式刷的支持
2026-09-28 15:28:50 +08:00
void TDbVertSlab::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbVertSlab *pSrc = TDbVertSlab::cast(pSrcEntity);
if (pSrc)
{
m_nThickness = pSrc->m_nThickness;
m_bShow2d = pSrc->m_bShow2d;
}
}
2026-10-04 00:04:20 +08:00
// 从DWG读入数据:
2026-09-28 15:28:50 +08:00
Acad::ErrorStatus TDbVertSlab::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbEntity::dwgInFields(pFiler);
if (es != Acad::eOk)
return es;
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
if (nVer>g_nVersion) // Version is too new
{
return Acad::eMakeMeProxy;
}
pFiler->readItem((AcGePoint3d *)&m_ptStart);
pFiler->readItem((AcGePoint3d *)&m_ptEnd);
pFiler->readItem(&m_nThickness);
pFiler->readItem(&m_nHeightS);
pFiler->readItem(&m_nHeightE);
pFiler->readItem(&m_bShow2d);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbVertSlab::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler);
if (es != Acad::eOk)
return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem((AcGePoint3d &)m_ptStart);
pFiler->writeItem((AcGePoint3d &)m_ptEnd);
pFiler->writeItem(m_nThickness);
pFiler->writeItem(m_nHeightS);
pFiler->writeItem(m_nHeightE);
pFiler->writeItem(m_bShow2d);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbVertSlab::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbEntity::dxfInFields(pFiler);
if (es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbVertSlab")))
{
return Acad::eBadDxfSequence;
}
double r1, r2, r3;
int nFlag;
XPoint pt1, pt2;
Adesk::UInt32 fieldsFlags = 0;
resbuf rb;
while ((es == Acad::eOk)
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk))
{
switch (rb.restype)
{
case AcDb::kDxfXCoord:
pt1=rb.resval.rpoint;
fieldsFlags |= 0x01;
break;
case AcDb::kDxfXCoord+1:
pt2=rb.resval.rpoint;
fieldsFlags |= 0x02;
break;
case AcDb::kDxfReal:
r1=rb.resval.rreal;
fieldsFlags |= 0x04;
break;
case AcDb::kDxfReal+1:
fieldsFlags |= 0x08;
r2 = rb.resval.rreal;
break;
case AcDb::kDxfReal+2:
fieldsFlags |= 0x10;
r3 = rb.resval.rreal;
break;
case AcDb::kDxfInt16:
fieldsFlags |= 0x20;
nFlag = rb.resval.rint;
break;
//fall through intentional
default:
// An unrecognized group. Push it back so that
// the subclass can read it again.
pFiler->pushBackItem();
es = Acad::eEndOfFile;
break;
}
}
// At this point the es variable must contain eEndOfFile
// - either from readResBuf() or from pushback. If not,
// it indicates that an error happened and we should
// return immediately.
//
if (es != Acad::eEndOfFile)
return Acad::eInvalidResBuf;
if (!(fieldsFlags & 0x01)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 10"));
return Acad::eMissingDxfField;
}
if (!(fieldsFlags & 0x02)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 11"));
return Acad::eMissingDxfField;
}
if (!(fieldsFlags & 0x04)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 40"));
return Acad::eMissingDxfField;
}
if (!(fieldsFlags & 0x08)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 41"));
return Acad::eMissingDxfField;
}
if (!(fieldsFlags & 0x10)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 42"));
return Acad::eMissingDxfField;
}
m_ptStart=pt1;
m_ptEnd=pt2;
m_nThickness=r1;
m_nHeightS=r2;
m_nHeightE=r3;
if (fieldsFlags&0x20)
m_bShow2d=nFlag;
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbVertSlab::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es=TDbEntity::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbVertSlab"));
assert(es == Acad::eOk);
pFiler->writePoint2d(AcDb::kDxfXCoord, m_ptStart.AsAcGePoint2d());
pFiler->writePoint2d(AcDb::kDxfXCoord+1, m_ptEnd.AsAcGePoint2d());
pFiler->writeDouble(AcDb::kDxfReal, m_nThickness);
pFiler->writeDouble(AcDb::kDxfReal+1, m_nHeightS);
pFiler->writeDouble(AcDb::kDxfReal+2, m_nHeightE);
pFiler->writeInt16(AcDb::kDxfInt16, m_bShow2d);
return es;
}
// -----------------------------------------------------------------------
// Overriden functions for edit
// to do:
2026-10-04 00:04:20 +08:00
// 允许通过夹点改变边界
2026-09-28 15:28:50 +08:00
Acad::ErrorStatus TDbVertSlab::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
gripPoints.append(m_ptStart);
gripPoints.append(m_ptEnd);
return Acad::eOk;
}
// stretch points is diffrent from grep points, with no midpoint included
Acad::ErrorStatus TDbVertSlab::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
assertReadEnabled();
stretchPoints.append(m_ptStart);
stretchPoints.append(m_ptEnd);
return Acad::eOk;
}
// Active when being rotated, scaled, moved, etc.
Acad::ErrorStatus TDbVertSlab::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
TDbEntity::subTransformBy(xform);
((AcGePoint3d &)m_ptStart).transformBy(xform);
((AcGePoint3d &)m_ptEnd).transformBy(xform);
return Acad::eOk;
}
2026-10-04 00:04:20 +08:00
// 功能: 夹点操作
2026-09-28 15:28:50 +08:00
Acad::ErrorStatus TDbVertSlab::subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
XPoint vtOffset = *(XPoint *)&offset;
vtOffset.z = 0;
for (int i = 0; i < indices.length(); i++)
{
int idx = indices[i];
if (idx==0)
{
m_ptStart += vtOffset;
m_ptEnd += vtOffset;
}
else if (idx==1)
{
m_ptEnd += vtOffset;
}
}
Acad::ErrorStatus es = Acad::eOk;
return es;
}
2026-10-04 00:04:20 +08:00
// 取得夹点说明
2026-09-28 15:28:50 +08:00
Acad::ErrorStatus TDbVertSlab::GetGripText(int i, CString &cs) const
{
Acad::ErrorStatus es = Acad::eOk;
XString sInfo;
if (i == 0)
{
2026-10-04 00:04:20 +08:00
sInfo << _T("平移起点");
2026-09-28 15:28:50 +08:00
}
else
{
2026-10-04 00:04:20 +08:00
sInfo << _T("拉伸终点");
2026-09-28 15:28:50 +08:00
}
cs = sInfo;
return es;
}
2026-10-04 00:04:20 +08:00
// 功能: 夹点操作
// 状态: 有待完成修改相关墙体门窗的操作
2026-09-28 15:28:50 +08:00
Acad::ErrorStatus TDbVertSlab::subMoveStretchPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
int nCount = indices.length();
return subMoveGripPointsAt(indices, offset);
}
Acad::ErrorStatus
TDbVertSlab::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
assertReadEnabled();
2026-10-04 00:04:20 +08:00
// sg add 100926,支持竖板开洞,首先判断是否带有洞口信息
2026-09-28 15:28:50 +08:00
int nLength = GetHolesNum();
if (nLength > 0)
{
return Draw3dHole(dc);
}
XLine ln(m_ptStart, m_ptEnd);
ln.SetElevation(0.0);
XLine lnLeft = ln.Offset(-m_nThickness/2);
XLine lnRight = ln.Offset(m_nThickness/2);
lnLeft.StartPoint().z = lnRight.StartPoint().z = m_ptStart.z;
lnLeft.EndPoint().z = lnRight.EndPoint().z = m_ptEnd.z;
XLine lnLeftUp = lnLeft;
XLine lnRightUp = lnRight;
lnLeftUp.StartPoint().z += m_nHeightS;
lnRightUp.StartPoint().z += m_nHeightS;
lnLeftUp.EndPoint().z += m_nHeightE;
lnRightUp.EndPoint().z += m_nHeightE;
XPoly2D polyLeft(1), polyRight(1);
polyLeft.AppendNode(lnLeft.StartPoint());
polyLeft.AppendNode(lnLeft.EndPoint());
polyLeft.AppendNode(lnLeftUp.EndPoint());
polyLeft.AppendNode(lnLeftUp.StartPoint());
polyRight.AppendNode(lnRight.StartPoint());
polyRight.AppendNode(lnRight.EndPoint());
polyRight.AppendNode(lnRightUp.EndPoint());
polyRight.AppendNode(lnRightUp.StartPoint());
dc.DrawShell(polyLeft, DList<XPoly2D>());
dc.DrawShell(polyRight, DList<XPoly2D>());
dc.DrawMesh(polyLeft, polyRight);
return Acad::eOk;
}
2026-10-04 00:04:20 +08:00
// sg add 100927,三维绘制,支持竖板上带洞(截面拉伸)
2026-09-28 15:28:50 +08:00
Acad::ErrorStatus TDbVertSlab::Draw3dHole(XExplodeDraw &dc) const
{
Acad::ErrorStatus es = Acad::eOk;
2026-10-04 00:04:20 +08:00
// 获取起点、终点
2026-09-28 15:28:50 +08:00
AcGePoint3d ptStart = m_ptStart.AsAcGePoint3d(),
ptEnd = m_ptEnd.AsAcGePoint3d(),
ptUpStart = ptStart,
ptUpEnd = ptEnd;
ptUpStart.z += m_nHeightS;
ptUpEnd.z += m_nHeightE;
2026-10-04 00:04:20 +08:00
// 构造起点、终点所在面
2026-09-28 15:28:50 +08:00
AcGePlane plane(ptEnd, ptStart, ptUpStart);
AcGeVector3d vec = plane.normal();
vec.normalize();
2026-10-04 00:04:20 +08:00
// 备份一分
2026-09-28 15:28:50 +08:00
AcGeVector3d vecSpare(vec);
double dThick = m_nThickness * (-0.5);
vec = vec * dThick;
2026-10-04 00:04:20 +08:00
// 中心截面PLine线
2026-09-28 15:28:50 +08:00
ptStart += TVector3D(vec);
ptEnd += TVector3D(vec);
ptUpEnd += TVector3D(vec);
ptUpStart += TVector3D(vec);
TGGePoly2D polyElev(1);
polyElev.AppendNode(ptStart);
polyElev.AppendNode(ptEnd);
polyElev.AppendNode(ptUpEnd);
polyElev.AppendNode(ptUpStart);
2026-10-04 00:04:20 +08:00
// 获得竖板上的开洞信息
2026-09-28 15:28:50 +08:00
TDPtrList<TGGePoly2D> lstHoles;
GetAllHoles(lstHoles);
2026-10-04 00:04:20 +08:00
// 将圆洞的轮廓离散
2026-09-28 15:28:50 +08:00
TDPtrList<TGGePoly2D> lstHolesTmp;
int nLength = lstHoles.Length();
for (int i=0; i<nLength; i++)
{
TGGePoly2D *pHoleOnSide = new TGGePoly2D(*lstHoles[i]);
for (int k = 0; k < pHoleOnSide->Length(); k++)
{
*(*pHoleOnSide)[k] += TVector3D(vec);
}
lstHolesTmp.Append(pHoleOnSide);
}
vecSpare.normalize();
vecSpare = vecSpare*m_nThickness;
dc.DrawBody(polyElev, lstHolesTmp, TVector3D(vecSpare));
return es;
}
Acad::ErrorStatus TDbVertSlab::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
if (m_bShow2d)
{
XLine ln(m_ptStart, m_ptEnd);
ln.SetElevation(0.0);
XLine lnLeft = ln.Offset(-m_nThickness/2);
XLine lnRight = ln.Offset(m_nThickness/2);
dc << lnLeft << lnRight << XLine(lnLeft.StartPoint(), lnRight.StartPoint())
<< XLine(lnLeft.EndPoint(), lnRight.EndPoint());
2026-10-04 00:04:20 +08:00
// sg add 100926,支持竖板开洞
2026-09-28 15:28:50 +08:00
TDPtrList<TGGePoly2D> lstHoles;
GetAllHoles(lstHoles);
TADSGePoint3d ptStart,
ptEnd;
int nLength = lstHoles.Length();
for (int i=0; i<nLength; i++)
{
const TGGePoly2D &pline = *lstHoles[i];
GetHolePtOnMidLine(pline, ptStart, ptEnd);
TGGeLine midLine(ptStart, ptEnd, LS_INFINITE);
midLine.SetElevation(0.0);
TGGeLine line1 = midLine.Offset(-m_nThickness*0.5),
line2 = midLine.Offset(m_nThickness*0.5);
2026-10-04 00:04:20 +08:00
// 保存旧的线型
2026-09-28 15:28:50 +08:00
AcDbObjectId idOldLineType = dc.GetLineTypeId();
2026-10-04 00:04:20 +08:00
// 设置新的线型
2026-09-28 15:28:50 +08:00
dc.SetLineType(InitLineType(_T("DASH"), database()));
dc << TGGeLine(line1.StartPoint(), line2.StartPoint()) <<
TGGeLine(line1.EndPoint(), line2.EndPoint());
2026-10-04 00:04:20 +08:00
// 还原为旧的线型
2026-09-28 15:28:50 +08:00
dc.SetLineType(idOldLineType);
}
}
return Acad::eOk;
}
2026-10-04 00:04:20 +08:00
// sg add 100927,将polyHole投影到XLine(m_ptStart, m_ptEnd)上,获取外轮廓
2026-09-28 15:28:50 +08:00
void TDbVertSlab::GetHolePtOnMidLine(const TGGePoly2D &polyHole,
TADSGePoint3d &ptStart, TADSGePoint3d &ptEnd) const
{
2026-10-04 00:04:20 +08:00
// 记录最大、最小点长度
2026-09-28 15:28:50 +08:00
double dMin = m_ptStart.Distance(m_ptEnd),
dMax = 0.0,
dDist = 0.0;
2026-10-04 00:04:20 +08:00
// 中线
2026-09-28 15:28:50 +08:00
TGGeCurveSegment seg(m_ptStart, m_ptEnd, LS_INFINITE);
TADSGePoint3d ptLoc;
int nLength = polyHole.Length();
for (int i=0; i<nLength; i++)
{
2026-10-04 00:04:20 +08:00
ptLoc = polyHole.GetAt(i); // 逐个获得顶点坐标
2026-09-28 15:28:50 +08:00
2026-10-04 00:04:20 +08:00
// 求到端点的沿曲线线位移
2026-09-28 15:28:50 +08:00
dDist = seg.PathDistance(ptLoc, 1);
if (dDist > dMax - _DIST_SNAP)
{
dMax = dDist;
ptEnd = ptLoc;
}
if (dDist < dMin + _DIST_SNAP)
{
dMin = dDist;
ptStart = ptLoc;
}
}
}
const TCHAR *TDbVertSlab::GetDefaultLayer() const
{
return NULL;
}
2026-10-04 00:04:20 +08:00
/* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */
2026-09-28 15:28:50 +08:00
void TDbVertSlab::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
2026-10-04 00:04:20 +08:00
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("竖板")));
lstInfo.Append(new TObjInfoUnit(_T("板厚"), Dist2Str(GetThickness())));
lstInfo.Append(new TObjInfoUnit(_T("起点标高"), Dist2Str(m_ptStart.z)));
lstInfo.Append(new TObjInfoUnit(_T("终点标高"), Dist2Str(m_ptEnd.z)));
lstInfo.Append(new TObjInfoUnit(_T("起点高度"), Dist2Str(m_nHeightS)));
lstInfo.Append(new TObjInfoUnit(_T("终点高度"), Dist2Str(m_nHeightE)));
lstInfo.Append(new TObjInfoUnit(_T("二维显示"), m_bShow2d? _T("开启") : _T("关闭")));
2026-09-28 15:28:50 +08:00
2026-10-04 00:04:20 +08:00
//lstInfo.Append(new TObjInfoUnit(_T("周长"), Dist2Str(GetPerimeter())));
//lstInfo.Append(new TObjInfoUnit(_T("底面积"),
2026-09-28 15:28:50 +08:00
// XString(_T("%.2f"), _AS_SQMETER(GetBottomArea()))));
2026-10-04 00:04:20 +08:00
//lstInfo.Append(new TObjInfoUnit(_T("侧面积"),
2026-09-28 15:28:50 +08:00
// XString(_T("%.2f"), _AS_SQMETER(GetSideArea()))));
2026-10-04 00:04:20 +08:00
lstInfo.Append(new TObjInfoUnit(_T("体积"),
2026-09-28 15:28:50 +08:00
XString(_T("%.3f"), _AS_CUMETER(GetVolume()))));
}
BOOL
TDbVertSlab::Is2DVisible() const
{
return m_bShow2d;
}
double
TDbVertSlab::GetThickness() const
{
return m_nThickness;
}
double
TDbVertSlab::GetHeightS() const
{
return m_nHeightS;
}
double
TDbVertSlab::GetHeightE() const
{
return m_nHeightE;
}
XPoint
TDbVertSlab::GetStartPoint() const
{
return m_ptStart;
}
XPoint
TDbVertSlab::GetEndPoint() const
{
return m_ptEnd;
}
void
TDbVertSlab::SetThickness(double h)
{
assertWriteEnabled();
m_nThickness = h;
}
void
TDbVertSlab::SetHeightS(double s)
{
assertWriteEnabled();
m_nHeightS = s;
}
void
TDbVertSlab::SetHeightE(double e)
{
assertWriteEnabled();
m_nHeightE = e;
}
void
TDbVertSlab::Set2DVisible(BOOL bTrue)
{
assertWriteEnabled();
m_bShow2d=bTrue;
}
void
TDbVertSlab::SetStartPoint(const XPoint &pt)
{
assertWriteEnabled();
m_ptStart=pt;
}
void
TDbVertSlab::SetEndPoint(const XPoint &pt)
{
assertWriteEnabled();
m_ptEnd = pt;
}
2026-10-04 00:04:20 +08:00
// 工程量
2026-09-28 15:28:50 +08:00
double TDbVertSlab::GetPerimeter() const
{
XPoint ptS1=GetStartPoint()+GetHeightS();
XPoint ptE1=GetEndPoint()+GetHeightE();
double nDist1=GetStartPoint().Distance(GetEndPoint()) +
GetHeightE() +
ptS1.Distance(ptE1) +
GetHeightS();
return nDist1;
}
double TDbVertSlab::GetBottomArea() const
{
double nVal=(GetHeightS()+GetHeightE())*GetStartPoint().Distance2d(GetEndPoint())/2.0;
return nVal;
}
double TDbVertSlab::GetSideArea() const
{
return (GetPerimeter()*GetThickness());
}
double TDbVertSlab::GetVolume() const
{
return (GetBottomArea()*GetThickness());
}
2026-10-04 00:04:20 +08:00
// sg add 100925,支持竖板上开洞
// 如果是圆洞,dWidth为直径,dHeight为0
2026-09-28 15:28:50 +08:00
bool TDbVertSlab::AddHole(TADSGePoint3d ptLoc, double dWidth, double dHeight)
{
2026-10-04 00:04:20 +08:00
// 构造起点、终点所在面
2026-09-28 15:28:50 +08:00
AcGePoint3d ptStart = m_ptStart.AsAcGePoint3d(),
ptEnd = m_ptEnd.AsAcGePoint3d(),
ptUpStart = ptStart,
ptUpEnd = ptEnd;
ptUpStart.z += m_nHeightS;
ptUpEnd.z += m_nHeightE;
2026-10-04 00:04:20 +08:00
// 获得ptLoc投影到面上的投影点
2026-09-28 15:28:50 +08:00
AcGePlane plane(ptEnd, ptStart, ptUpStart);
AcGePoint3d ptSpare = ptLoc.AsAcGePoint3d(),
ptProject = ptSpare.orthoProject(plane);
2026-10-04 00:04:20 +08:00
// 中心截面PLine线
2026-09-28 15:28:50 +08:00
TGGePoly2D polyElev(1);
polyElev.AppendNode(ptStart);
polyElev.AppendNode(ptEnd);
polyElev.AppendNode(ptUpEnd);
polyElev.AppendNode(ptUpStart);
2026-10-04 00:04:20 +08:00
// 构造洞的PLine线
2026-09-28 15:28:50 +08:00
TGGePoly2D polyHole(1);
GetHolePline(ptProject, dWidth, dHeight, polyHole);
2026-10-04 00:04:20 +08:00
// 判断两个PLine线是否相交
2026-09-28 15:28:50 +08:00
int nLength1 = polyHole.TotalSegments(),
nLength2 = polyElev.TotalSegments();
TADSGePoint3d ptInt1, ptInt2;
for (int i=0; i<nLength1; i++)
{
TGGeCurveSegment seg1;
polyHole.Nth(i, seg1);
for (int j=0; j<nLength2; j++)
{
TGGeCurveSegment seg2;
polyElev.Nth(j, seg2);
2026-10-04 00:04:20 +08:00
// 梁上开洞,必须是完整的洞,如果相交,则不添加洞,直接返回
2026-09-28 15:28:50 +08:00
if (seg1.Intersection(seg2, ptInt1, ptInt2))
{
return false;
}
}
}
2026-10-04 00:04:20 +08:00
// 获得对象中保存的洞口数据
2026-09-28 15:28:50 +08:00
PlusHolesNum(1);
2026-10-04 00:04:20 +08:00
// 添加动态数据,存储新的洞口数据
2026-09-28 15:28:50 +08:00
SetHolePLine(polyHole);
return true;
}
2026-10-04 00:04:20 +08:00
// sg add 100926,根据传入的中间立面上的开洞位置点,以及洞口尺寸,返回中间立面上的洞口轮廓线
// 如果是圆洞,dWidth为直径,dHeight为0
2026-09-28 15:28:50 +08:00
void TDbVertSlab::GetHolePline(TADSGePoint3d ptLoc, double dWidth, double dHeight, TGGePoly2D &poly) const
{
2026-10-04 00:04:20 +08:00
poly.Reset(); // 清空
poly.SetFlag(1); // 设置闭合
2026-09-28 15:28:50 +08:00
2026-10-04 00:04:20 +08:00
// 构造起点、终点所在面
2026-09-28 15:28:50 +08:00
AcGePoint3d ptStart = m_ptStart.AsAcGePoint3d(),
ptEnd = m_ptEnd.AsAcGePoint3d(),
ptUpStart = ptStart;
ptUpStart.z += m_nHeightS;
AcGePlane plane(ptEnd, ptStart, ptUpStart);
double dW = dWidth*0.5;
2026-10-04 00:04:20 +08:00
// 圆洞
2026-09-28 15:28:50 +08:00
if (fabs(dHeight) < _DIST_SNAP)
{
AcGeVector3d vec = plane.normal();
2026-10-04 00:04:20 +08:00
// 构造圆,获得等分点
2026-09-28 15:28:50 +08:00
AcGeCircArc3d circle(ptLoc, vec, dW);
AcGePoint3dArray pointArray;
2026-10-04 00:04:20 +08:00
circle.getSamplePoints(40, pointArray); // 暂时分成40份
2026-09-28 15:28:50 +08:00
int nLength = pointArray.length();
for (int i=0; i<nLength; i++)
{
poly.AppendNode(pointArray[i]);
}
return;
}
TVector3D vtXAxis = m_ptEnd - m_ptStart,
vtYAxis = TADSGePoint3d(ptUpStart) - m_ptStart;
vtXAxis.Normalize();
vtYAxis.Normalize();
vtXAxis.Scale(dW);
vtYAxis.Scale(dW);
TADSGePoint3d pt1 = ptLoc + vtXAxis,
pt2 = ptLoc - vtXAxis;
2026-10-04 00:04:20 +08:00
// 方洞
2026-09-28 15:28:50 +08:00
double dH = dHeight*0.5;
vtXAxis.Normalize();
vtYAxis.Normalize();
vtXAxis.Scale(dH);
vtYAxis.Scale(dH);
pt1 = pt1 + vtYAxis;
pt2 = pt2 + vtYAxis;
vtXAxis.Scale(2);
vtYAxis.Scale(2);
TADSGePoint3d pt3 = pt1 - vtYAxis,
pt4 = pt2 - vtYAxis;
poly.AppendNode(pt1);
poly.AppendNode(pt2);
poly.AppendNode(pt4);
poly.AppendNode(pt3);
}
2026-10-04 00:04:20 +08:00
// 开洞的数量
2026-09-28 15:28:50 +08:00
Adesk::UInt16 TDbVertSlab::GetHolesNum() const
{
assertReadEnabled();
const TEntityFields &fd = GetFields();
Adesk::UInt16 nLength = 0;
2026-10-04 00:04:20 +08:00
fd.GFD(_T("竖板开洞数量"), nLength);
2026-09-28 15:28:50 +08:00
return nLength;
}
void TDbVertSlab::PlusHolesNum(Adesk::UInt16 nPlusNum)
{
Adesk::UInt16 nNum = GetHolesNum();
assertWriteEnabled();
TEntityFields &fd = Fields();
nNum += nPlusNum;
2026-10-04 00:04:20 +08:00
fd.SFD(_T("竖板开洞数量"), nNum);
2026-09-28 15:28:50 +08:00
}
2026-10-04 00:04:20 +08:00
// sg add 100926,获取所有洞口的轮廓线
2026-09-28 15:28:50 +08:00
void TDbVertSlab::GetAllHoles(TDPtrList<TGGePoly2D> &lstHoles) const
{
lstHoles.Reset();
assertReadEnabled();
const TEntityFields &fd = GetFields();
AcGePoint3d point;
double dBulge = 0;
Adesk::UInt8 bIsClosed = 0;
2026-10-04 00:04:20 +08:00
// 逐个读取洞口轮廓线PLine线信息
2026-09-28 15:28:50 +08:00
long lNum = fd.GetSubFieldNum();
for (long l=0; l<lNum; l++)
{
const TEntityField &subFd = fd.GetSubField(l);
TEntityField::DataType type = subFd.GetDataType();
if (type != TEntityField::kGroup)
{
2026-10-04 00:04:20 +08:00
continue; // 竖板开洞数量
2026-09-28 15:28:50 +08:00
}
2026-10-04 00:04:20 +08:00
// 取一个洞口轮廓线PLine线信息
2026-09-28 15:28:50 +08:00
TEntityFields *holeFds = NULL;
subFd.GetData(holeFds);
long lLength = holeFds->GetSubFieldNum();
if (lLength == 0)
{
2026-10-04 00:04:20 +08:00
continue; // 空集合
2026-09-28 15:28:50 +08:00
}
2026-10-04 00:04:20 +08:00
// 构造一个洞口轮廓线
2026-09-28 15:28:50 +08:00
TGGePoly2D *pHole = new TGGePoly2D(1);
pHole->Reset();
for (int i=0; i<lLength; i++)
{
const TEntityField &pointFd = holeFds->GetSubField(i);
if (pointFd.GetDataType() != TEntityField::kGroup)
{
2026-10-04 00:04:20 +08:00
if (_tcscmp(pointFd.GetName(), _T("洞口线闭合")) != 0)
2026-09-28 15:28:50 +08:00
{
2026-10-04 00:04:20 +08:00
continue; // 洞口线点数
2026-09-28 15:28:50 +08:00
}
pointFd.GetData(bIsClosed);
2026-10-04 00:04:20 +08:00
pHole->SetFlag(bIsClosed); // 设置轮廓线闭合
2026-09-28 15:28:50 +08:00
continue;
}
2026-10-04 00:04:20 +08:00
// 取一个洞口轮廓线PLine线信息
2026-09-28 15:28:50 +08:00
TEntityFields *pointFds = NULL;
pointFd.GetData(pointFds);
if (pointFds->GetSubFieldNum() == 0)
{
2026-10-04 00:04:20 +08:00
continue; // 空集合
2026-09-28 15:28:50 +08:00
}
2026-10-04 00:04:20 +08:00
pointFds->GFD(_T("点"), point); // 取点坐标
pointFds->GFD(_T("凸度"), dBulge); // 取Bulge值
2026-09-28 15:28:50 +08:00
pHole->AppendNode(TADSGePoint3d(point[0], point[1], point[2]), dBulge);
}
lstHoles.Append(pHole);
}
}
2026-10-04 00:04:20 +08:00
// sg add 100926,增加洞口的动态数据
2026-09-28 15:28:50 +08:00
void TDbVertSlab::SetHolePLine(const TGGePoly2D &polyHole)
{
assertWriteEnabled();
TEntityFields &fd = Fields();
2026-10-04 00:04:20 +08:00
// 将一个洞口的数据,保存成一个TEntityField(组),存入动态数据
2026-09-28 15:28:50 +08:00
TEntityField *pHole = new TEntityField(_T(""), TEntityField::kGroup);
fd.Add(pHole);
TEntityFields *pNewFds = NULL;
pHole->GetData(pNewFds);
2026-10-04 00:04:20 +08:00
// 保存洞口轮廓线是否闭合
2026-09-28 15:28:50 +08:00
Adesk::UInt8 bIsClosed = polyHole.GetFlag();
2026-10-04 00:04:20 +08:00
pNewFds->SFD(_T("洞口线闭合"), bIsClosed);
2026-09-28 15:28:50 +08:00
2026-10-04 00:04:20 +08:00
// 保存构成洞口轮廓线的点数
2026-09-28 15:28:50 +08:00
Adesk::UInt16 nVertexCount = polyHole.Length();
2026-10-04 00:04:20 +08:00
pNewFds->SFD(_T("洞口线点数"), nVertexCount);
2026-09-28 15:28:50 +08:00
AcGePoint3d point;
double dBulge = 0;
for (long l=0; l<nVertexCount; l++)
{
2026-10-04 00:04:20 +08:00
// 将点的坐标和Bulge值保存成一个节点的动态数据
2026-09-28 15:28:50 +08:00
TEntityField *pVertex = new TEntityField(_T(""), TEntityField::kGroup);
pNewFds->Add(pVertex);
TEntityFields *pTempFds = NULL;
pVertex->GetData(pTempFds);
2026-10-04 00:04:20 +08:00
// 保存点坐标
2026-09-28 15:28:50 +08:00
point = polyHole.GetAt(l).AsAcGePoint3d();
2026-10-04 00:04:20 +08:00
pTempFds->SFD(_T("点"), point);
2026-09-28 15:28:50 +08:00
2026-10-04 00:04:20 +08:00
// 保存Bulge值
2026-09-28 15:28:50 +08:00
dBulge = polyHole.GetBulge(l);
2026-10-04 00:04:20 +08:00
pTempFds->SFD(_T("凸度"), dBulge);
2026-09-28 15:28:50 +08:00
}
}
int EditVertSlab0(AcDbObjectId id);
void InitDbVertSlab(BOOL bTrue)
{
AecObjectEditMethod pOldEdit=NULL;
if (bTrue) {
TDbVertSlab::rxInit();
pOldEdit=TDbVertSlab::SetEditMethod(EditVertSlab0);
TDbVertSlab::InitMatchProtocol(TRUE);
} else {
TDbVertSlab::InitMatchProtocol(FALSE);
TDbVertSlab::SetEditMethod(pOldEdit);
deleteAcRxClass(TDbVertSlab::desc());
}
}
2026-10-04 00:04:20 +08:00
// Command:编辑竖板
2026-09-28 15:28:50 +08:00
int EditVertSlab0(AcDbObjectId id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbVertSlab, pStep);
if (!pStep)
return RTERROR;
2026-10-04 00:04:20 +08:00
//判断是不是上海城建梁实体
2026-09-28 15:28:50 +08:00
CString strCmdName(_T(""));
TDbXDataMap map;
map.Read(pStep, _T("TGZZCL"));
map.GetAt(_T("cmdName"), strCmdName);
if (strCmdName == _T("TGZZCLKL")||
strCmdName == _T("TGZZCLLL")||
strCmdName == _T("TGZZCLTL")||
strCmdName == _T("TGZZCLXL"))
{
struct resbuf rbUr;
rbUr.restype = RTSTR;
rbUr.resval.rstring = _tcsdup(_T("EditObj"));
rbUr.rbnext = NULL;
acedSetVar(_T("USERS3"), &rbUr);
acedPostCommand(strCmdName);
acedPostCommand(_T("\n"));
return RTNORM;
}
else
{
while(1) {
2026-10-04 00:04:20 +08:00
const TCHAR *szPrompt1=_T("\n选择 [起点标高(A)/起边高度(S)/终点标高(D)/终边高度(F)/开关二维(G)/板厚(H)]<退出>:");
2026-09-28 15:28:50 +08:00
XString sKeyword;
int nRet=0;
INITGET_BEG(0, _T("A S D F G H L"));
nRet=ads_getkword(szPrompt1, sKeyword);
INITGET_END();
if (nRet!=RTNORM)
break;
if (sKeyword[0]==_T('H')) {
double nRailHeight=pStep->GetThickness();
2026-10-04 00:04:20 +08:00
nRet=GetReal(_T("\n板厚"), nRailHeight);
2026-09-28 15:28:50 +08:00
if (nRet==RTCAN)
break;
if (nRet==RTNORM) {
if (pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetThickness(nRailHeight);
pStep->downgradeOpen();
}
} else if (sKeyword[0]==_T('A')) {
XPoint ptStart=pStep->GetStartPoint();
double nElev=ptStart.z;
2026-10-04 00:04:20 +08:00
nRet=GetReal(_T("\n起点标高"), nElev);
2026-09-28 15:28:50 +08:00
if (nRet==RTCAN)
break;
if (nRet==RTNORM) {
ptStart.z = nElev;
if (pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetStartPoint(ptStart);
pStep->downgradeOpen();
}
} else if (sKeyword[0]==_T('S')) {
double h=pStep->GetHeightS();
2026-10-04 00:04:20 +08:00
nRet=GetReal(_T("\n起边高度"), h);
2026-09-28 15:28:50 +08:00
if (nRet==RTCAN)
break;
if (nRet==RTNORM) {
if (pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetHeightS(h);
pStep->downgradeOpen();
}
} else if (sKeyword[0]==_T('D')) {
XPoint ptEnd=pStep->GetEndPoint();
double nElev=ptEnd.z;
2026-10-04 00:04:20 +08:00
nRet=GetReal(_T("\n终点标高"), nElev);
2026-09-28 15:28:50 +08:00
if (nRet==RTCAN)
break;
if (nRet==RTNORM) {
ptEnd.z = nElev;
if (pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetEndPoint(ptEnd);
pStep->downgradeOpen();
}
} else if (sKeyword[0]==_T('F')) {
double h=pStep->GetHeightE();
2026-10-04 00:04:20 +08:00
nRet=GetReal(_T("\n终边高度"), h);
2026-09-28 15:28:50 +08:00
if (nRet==RTCAN)
break;
if (nRet==RTNORM) {
if (pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetHeightE(h);
pStep->downgradeOpen();
}
} else if (sKeyword[0]==_T('L')) {
pStep->list();
} else if (sKeyword[0]==_T('G')) {
BOOL bShow2d=pStep->Is2DVisible();
bShow2d = !bShow2d;
if (bShow2d)
2026-10-04 00:04:20 +08:00
adsout << _T("\n开启二维显示!");
2026-09-28 15:28:50 +08:00
else
2026-10-04 00:04:20 +08:00
adsout << _T("\n关闭二维显示!");
2026-09-28 15:28:50 +08:00
if (pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->Set2DVisible(bShow2d);
pStep->downgradeOpen();
}
}
}
OPENOBJ_END();
return RTNORM;
}