Files
envi-code/SourceCode/Code2026/tg_shs/shs_kernal/dbstep.cpp
T
2026-09-28 15:28:50 +08:00

1291 lines
37 KiB
C++

#include "stdafx.h"
#include "TDbColumn.h"
/////////////////////////////////////////////////////////////
// 屋顶对象类
/////////////////////////////////////////////////////////////
const Adesk::UInt8 TDbStep::g_nVersion = 1;
ACRX_DXF_DEFINE_MEMBERS(ATSStep, ATSEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_STEP, "ATS_STEP图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbStep);
TDbStep::TDbStep()
:m_polyOutline(1), m_nStepFlag(0)
{
m_nStepWidth=m_nStepHeight=0;
m_nStepNum=0;
}
TDbStep::~TDbStep()
{
}
BOOL TDbStep::IsValid() const
{
BOOL bRet=TDbEntity::IsValid();
if(!bRet)
return bRet;
bRet=(m_polyOutline.Length()>1 &&
//m_nStepNum>1 && //踏步数目
m_nStepNum>0 && //踏步数目,refreshed by whl on 060209
//m_nStepHeight>_DIST_SNAP &&
//m_nStepWidth>_DIST_SNAP); //踏步高和踏步宽
fabs(m_nStepHeight)>_DIST_SNAP &&//refreshed by whl on 051214
fabs(m_nStepWidth)>_DIST_SNAP); //踏步高和踏步宽
return bRet;
}
Acad::ErrorStatus
TDbStep::audit(AcDbAuditInfo* pAuditInfo)
{
Acad::ErrorStatus es = Acad::eOk;
// sg add 090806,解决高版本下修复02图纸,对象丢失的问题
es = TDbEntity::audit(pAuditInfo);
if (es != Acad::eOk)
return es;
if (m_polyOutline.PathArea() >= 0.0) {
pAuditInfo->errorsFound(1);
if (pAuditInfo->fixErrors() == Adesk::kTrue) {
pAuditInfo->printError(_T("柱子"), _T("轮廓"), _T("必须为逆时针"), _T(""));
if(m_polyOutline.PathArea()>0) {
m_polyOutline.Reverse();
int nEdgeNum=GetEdgeNum();
DList<int> lstEdgeFlag;
for(int n=0; n<nEdgeNum; n++)
lstEdgeFlag.Append(new int(HasStepAt(n)));
lstEdgeFlag.Reverse();
for(n=0; n<nEdgeNum; n++)
SetStepAt(n, *lstEdgeFlag[n]);
}
pAuditInfo->errorsFixed(1);
es = Acad::eFixedAllErrors;
} else
es = Acad::eLeftErrorsUnfixed;
}
return es;
}
Acad::ErrorStatus
TDbStep::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
// 提供对格式刷的支持
void TDbStep::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbStep *pSrc=TDbStep::cast(pSrcEntity);
if(pSrc) {
m_nStepNum=pSrc->m_nStepNum; //踏步数目
m_nStepHeight=pSrc->m_nStepHeight;
m_nStepWidth=pSrc->m_nStepWidth; //踏步高和踏步宽
}
}
Acad::ErrorStatus TDbStep::SetPathPoly(const XPoly2D &polyPath,const AcGeVector3d&normal)
{
assertWriteEnabled();
m_polyOutline=polyPath;
return Acad::eOk;
}
Acad::ErrorStatus TDbStep::GetPathPoly(XPoly2D &polyPath,AcGeVector3d&normal) const
{
assertReadEnabled();
polyPath=m_polyOutline;
normal=AcGeVector3d::kZAxis;
return Acad::eOk;
}
// 从DWG读入数据:
Acad::ErrorStatus TDbStep::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(&m_nStepFlag);
double nElev=0.0;
pFiler->readItem(&nElev);
ReadPoly2D(pFiler, m_polyOutline);
m_polyOutline.SetElevation(nElev);
pFiler->readItem(&m_nStepNum);
pFiler->readItem(&m_nStepWidth);
pFiler->readItem(&m_nStepHeight);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbStep::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem(m_nStepFlag);
double nElev=0.0;
if(!!m_polyOutline)
nElev=m_polyOutline[0].z;
pFiler->writeItem(nElev);
WritePoly2D(pFiler, m_polyOutline);
pFiler->writeItem(m_nStepNum);
pFiler->writeItem(m_nStepWidth);
pFiler->writeItem(m_nStepHeight);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbStep::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbEntity::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbStep"))) {
return Acad::eBadDxfSequence;
}
double r1, r2, r3, nAng;
int nFlag;
Adesk::UInt32 nFlag32;
XPoint pt;
Adesk::UInt32 fieldsFlags = 0;
resbuf rb;
DList<AcDbSoftPointerId> lstIds;
AcDbObjectId id;
DList<XPoint> pts;
DList<double> bulges;
while ((es == Acad::eOk)
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
switch (rb.restype) {
case 148:
r1=rb.resval.rreal;
fieldsFlags |= 0x01;
break;
case AcDb::kDxfReal:
fieldsFlags |= 0x02;
r2 = rb.resval.rreal;
break;
case AcDb::kDxfReal+1:
fieldsFlags |= 0x04;
r3 = rb.resval.rreal;
break;
case AcDb::kDxfInt16:
fieldsFlags |= 0x08;
nFlag=rb.resval.rint;
break;
case AcDb::kDxfInt32:
nFlag32=rb.resval.rlong;
fieldsFlags |= 0x10;
break;
case AcDb::kDxfAngle:
nAng=rb.resval.rreal;
bulges.Append(new double(nAng));
break;
case AcDb::kDxfXCoord:
pt=rb.resval.rpoint;
pts.Append(new XPoint(pt));
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 & 0x02)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 40"));
return Acad::eMissingDxfField;
}
if (!(fieldsFlags & 0x04)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 41"));
return Acad::eMissingDxfField;
}
if (!(fieldsFlags & 0x08)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 70"));
return Acad::eMissingDxfField;
}
if (pts.Length()<2 || pts.Length()!=bulges.Length()) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nError DXF group code: 10, 50"));
return Acad::eMissingDxfField;
}
double nElev=0.0;
if(fieldsFlags&0x01)
nElev=r1;
SetStepHeight(r2);
SetStepWidth(r2);
SetStepNum(nFlag);
if(fieldsFlags&0x10)
m_nStepFlag=nFlag;
m_polyOutline.Reset();
for(int i=0; i<pts.Length(); i++) {
m_polyOutline.AppendNode(*pts[i], *bulges[i]);
}
m_polyOutline.SetElevation(nElev);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbStep::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es= TDbEntity::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbStep"));
assert(es == Acad::eOk);
pFiler->writeDouble(148, GetElevation());
pFiler->writeDouble(AcDb::kDxfReal, GetStepHeight());
pFiler->writeDouble(AcDb::kDxfReal+1, GetStepWidth());
pFiler->writeInt16(AcDb::kDxfInt16, GetStepNum());
pFiler->writeInt32(AcDb::kDxfInt32, m_nStepFlag);
for(int i=0; i<m_polyOutline.Length(); i++) {
pFiler->writePoint2d(AcDb::kDxfXCoord, m_polyOutline[i].AsAcGePoint2d());
pFiler->writeDouble(AcDb::kDxfAngle, m_polyOutline.GetBulge(i));
}
return es;
}
// -----------------------------------------------------------------------
// Overriden functions for edit
// to do:
// 允许通过夹点改变边界
Acad::ErrorStatus TDbStep::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
int nEdgeNum=GetEdgeNum();
for(int i=0; i<nEdgeNum; i++) {
gripPoints.append(m_polyOutline[i]);
}
//边上的夹点
for(i=0; i<nEdgeNum; i++) {
XCurveSegment edge;
m_polyOutline.Nth(i, edge);
XPoint ptMid=edge.MidPoint();
gripPoints.append(ptMid);
}
return Acad::eOk;
}
// stretch points is diffrent from grep points, with no midpoint included
Acad::ErrorStatus TDbStep::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
for(int i=0; i<m_polyOutline.Length(); i++) {
stretchPoints.append(m_polyOutline[i]);
}
return Acad::eOk;
}
// Active when being rotated, scaled, moved, etc.
Acad::ErrorStatus TDbStep::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
TDbEntity::subTransformBy(xform);
ads_matrix mat;
memcpy(mat, &xform, sizeof(ads_matrix));
double nElev=0.0;
for(int i=0; i<m_polyOutline.Length(); i++) {
XPoint *pt=m_polyOutline[i];
pt->TransformBy(mat);
//以第一个顶点的z坐标为基准
if(i==0) {
nElev = pt->z;
} else {
pt->z = nElev;
}
}
// Add on 2002/1/30 解决弧段镜像后的问题
if(IsMirrorMatrix(mat)) {
for(int m=0; m<m_polyOutline.Length(); m++)
m_polyOutline.SetBulge(m, -m_polyOutline.GetBulge(m));
}
if(m_polyOutline.PathArea()>0) {
m_polyOutline.Reverse();
int nEdgeNum=GetEdgeNum();
DList<int> lstEdgeFlag;
for(int n=0; n<nEdgeNum; n++)
lstEdgeFlag.Append(new int(HasStepAt(n)));
lstEdgeFlag.Reverse();
for(n=0; n<nEdgeNum; n++)
SetStepAt(n, *lstEdgeFlag[n]);
}
return Acad::eOk;
}
// 功能: 夹点操作
Acad::ErrorStatus TDbStep::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
XPoly2D polyBack(m_polyOutline);
XPoint vtOffset=*(XPoint *)&offset;
vtOffset.z=0;
int nTotalEdge=GetEdgeNum();
for (int i = 0; i < indices.length(); i++) {
int idx = indices[i];
ASSERT(idx<2*nTotalEdge);
if(idx<nTotalEdge) {
*m_polyOutline[idx] += vtOffset;
} else {
int nEdgeIndex=idx-nTotalEdge;
ASSERT(nEdgeIndex<nTotalEdge);
XDirectionCurve cv;
m_polyOutline.Nth(nEdgeIndex, cv);
ASSERT(!!cv);
if(cv.Is(CURVE_LINE)) { // Move
XLine ln=cv.GetLine();
ln.StartPoint() += vtOffset;
ln.EndPoint() += vtOffset;
ln.SetLineFlag(LS_INFINITE);
XDirectionCurve prevSeg, nextSeg;
int nPrev=nEdgeIndex-1, nNext=nEdgeIndex+1;
nPrev=DePeriod(nTotalEdge, nPrev);
nNext=DePeriod(nTotalEdge, nNext);
XPoint ptStart, ptEnd;
BOOL bUpdateIt=TRUE;
//更新起点
if(nPrev>=0 && nPrev<nTotalEdge) {
m_polyOutline.Nth(nPrev, prevSeg);
prevSeg.SetLineFlag(LS_INFINITE);
XPoint ptInt[2];
int nIntNum=prevSeg.Intersection(ln, ptInt[0], ptInt[1]);
if(nIntNum==1) ptStart=ptInt[0];
else if(nIntNum==2) {
ptStart=XLine(ptInt[0], ptInt[1]).NearPoint(ln.StartPoint());
} else bUpdateIt=FALSE;
} else {
ptStart = *m_polyOutline[nEdgeIndex] + vtOffset;
}
// 更新下一点
if(nNext>=0 && nNext<nTotalEdge) {
m_polyOutline.Nth(nNext, nextSeg);
nextSeg.SetLineFlag(LS_INFINITE);
XPoint ptInt[2];
int nIntNum=nextSeg.Intersection(ln, ptInt[0], ptInt[1]);
if(nIntNum==1) ptEnd=ptInt[0];
else if(nIntNum==2) {
ptEnd=XLine(ptInt[0], ptInt[1]).NearPoint(ln.EndPoint());
} else bUpdateIt=FALSE;
} else {
ptEnd = *m_polyOutline[nEdgeIndex+1] + vtOffset;
}
if(bUpdateIt) {
double nPrevBulge=0.0, nNextBulge=0.0;
if(fabs(prevSeg.GetBulge())>1.0E-5) {
XArc prevArc=prevSeg.GetArc();
double nAngBeg=ads_angle(prevArc.GetCenterPt(), prevSeg.StartPoint());
double nAngEnd=ads_angle(prevArc.GetCenterPt(), ptStart);
if(prevSeg.IsMinusArc()) {
nPrevBulge=-CT_std_angle(nAngBeg-nAngEnd);
} else {
nPrevBulge=CT_std_angle(nAngEnd-nAngBeg);
}
}
if(fabs(nextSeg.GetBulge())>1.0E-5) {
XArc nextArc=nextSeg.GetArc();
double nAngBeg=ads_angle(nextArc.GetCenterPt(), ptEnd);
double nAngEnd=ads_angle(nextArc.GetCenterPt(), nextSeg.EndPoint());
if(nextSeg.IsMinusArc()) {
nNextBulge=-CT_std_angle(nAngBeg-nAngEnd);
} else {
nNextBulge=CT_std_angle(nAngEnd-nAngBeg);
}
}
*m_polyOutline[nEdgeIndex] = ptStart;
if(nNext>=0 && nNext<m_polyOutline.Length()) {
*m_polyOutline[nNext] = ptEnd;
m_polyOutline.SetBulge(nNext, nNextBulge);
}
if(nPrev>=0 && nPrev<m_polyOutline.Length())
m_polyOutline.SetBulge(nPrev, nPrevBulge);
}
} else { // Change Arc Segment--bulge
XPoint ptMid=cv.MidPoint();
XPoint ptMidNew= ptMid + vtOffset;
XArc arNew(cv.StartPoint(), ptMidNew, cv.EndPoint());
if(!!arNew) { //新的弧有效
XCurveSegment cvLine(cv.StartPoint(), cv.EndPoint(), 0.0);
int nSideOld=cvLine.OnWhichSide(ptMid);
int nSideNew=cvLine.OnWhichSide(ptMidNew);
double nSignal=cv.GetBulge()/fabs(cv.GetBulge());
if(nSideOld==nSideNew)
{
m_polyOutline.SetBulge(nEdgeIndex, nSignal*arNew.Bulge());
}
else
{
m_polyOutline.SetBulge(nEdgeIndex, -nSignal*arNew.Bulge());
}
}
}
}
}
Acad::ErrorStatus es = Acad::eOk;
if(m_polyOutline.IsSelfIntersect()) {
m_polyOutline=polyBack;
es = Acad::eInvalidInput;
}
return es;
}
// 取得夹点说明
Acad::ErrorStatus TDbStep::GetGripText(int i, CString &cs) const
{
Acad::ErrorStatus es=Acad::eOk;
XString sInfo;
if(i<GetEdgeNum()) {
sInfo << _T("移动第") << (i+1) << _T("个顶点");
} else {
sInfo << _T("移动第") << (i-GetEdgeNum()+1) << _T("条边");
}
cs = sInfo;
return es;
}
#if ADS>15
void TDbStep::CreateGrip()
{
TDbEntity::CreateGrip();
::CreateGrip(this,m_polyOutline,0);
}
Acad::ErrorStatus TDbStep::EntityToDim(long iGrip,long iDim,const AcDbEntity*pEnt)
{
TEntityBase *pCurve=TDbStep::cast(pEnt);
if(pCurve==NULL)
pCurve=this;
XPoly2D polyPath;
AcGeVector3d normal;
pCurve->GetPathPoly(polyPath,normal);
return ::EntityToDim(this,polyPath,iGrip,iDim,0);
}
Acad::ErrorStatus TDbStep::DimToEntity(long iGrip,long iDim,double newValue,const AcGeVector3d& offset)
{
assertWriteEnabled();
TDbStep curve;
curve.CopyPropertiesFrom(this,0);
Acad::ErrorStatus es=::DimToEntity(this,m_polyOutline,iGrip,iDim,newValue,offset,0);
if(es==Acad::eOk&&!IsValid())
{
CopyPropertiesFrom(&curve,0);
return Acad::eInvalidInput;
}
return es;
}
#endif
// 功能: 夹点操作
// 状态: 有待完成修改相关墙体门窗的操作
Acad::ErrorStatus TDbStep::subMoveStretchPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
int nCount=indices.length();
return subMoveGripPointsAt(indices, offset);
}
Acad::ErrorStatus
TDbStep::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
assertReadEnabled();
XPoly2D polyCur(1);
polyCur=m_polyOutline;
//modified by whl on 070213,支持下沉
//if(m_nStepWidth>0)
if((m_nStepWidth>0&&m_nStepHeight>0)||
(m_nStepWidth<0&&m_nStepHeight<0)||
(m_nStepWidth>0&&m_nStepHeight<0))
{//绘制平台
dc.DrawShell(polyCur, DList<XPoly2D> ());
}
// 绘制踏步
for(int i=0; i<m_nStepNum; i++)
{
// 垂直方向的侧面
XPoly poly;
polyCur.AsOpenPoly1(poly, _AS_SYS_UNIT(g_nCirDeviation)); //变成开口的poly, 如果原先封闭, 则起点复制为终点
int nColumn=poly.Length(); //+1;
int nRow=2;
XPoint *ptArray=new XPoint[nColumn*nRow];
for(int m=0; m<nRow; m++)
{
for(int n=0; n<nColumn; n++)
{
int nBase=m*nColumn;
ptArray[nBase+n]=*poly[n];
if(m==1)
ptArray[nBase+n].z -= m_nStepHeight;
}
}
int nEdgeNum=nRow*(nColumn-1)+nColumn*(nRow-1);
Adesk::UInt8 *pEdgeVisArray=new Adesk::UInt8[nEdgeNum];
for(int j=0; j<nEdgeNum; j++)
pEdgeVisArray[j]=kAcGiVisible; //kAcGiInvisible;
if(m_nStepWidth<0 && i==0)
{//没有绘制顶平台
// 第一行的边应当可见
for(j=0; j<nColumn-1; j++)
pEdgeVisArray[j]=kAcGiVisible;
}
if(i==m_nStepNum-1 && m_nStepWidth>0)
{
for(j=nColumn-1; j<2*(nColumn-1); j++)
pEdgeVisArray[j]=kAcGiVisible;
}
// 拐点处的边应当可见
j=nRow*(nColumn-1);
for(int kk=0; kk<nColumn; j++, kk++)
{
XPoint ptVert=ptArray[kk];
BOOL bOnNode=FALSE;
for(int mm=0; mm<polyCur.Length(); mm++)
{
if(polyCur[mm]->Distance(ptVert)<_DIST_SNAP)
{
bOnNode=TRUE;
break;
}
}
if(bOnNode)
pEdgeVisArray[j]=kAcGiVisible;
}
AcGiEdgeData edgeData;
edgeData.setVisibility(pEdgeVisArray);
dc.DrawMesh(nRow, nColumn, (AcGePoint3d *)ptArray, &edgeData);
delete []pEdgeVisArray;
delete []ptArray;
double nNewElev=polyCur[0]->z-m_nStepHeight;
polyCur.SetElevation(nNewElev);
if(i!=m_nStepNum-1) { //绘制平的部分
XPoly2D polyNext(1);
if(!Offset(polyCur, polyNext))
break;
if(m_nStepFlag==0)
{ //所有边都有台阶
DList<XPoly2D> lstPolys;
if(m_nStepWidth>0)
{
lstPolys.Append(new XPoly2D(polyCur));
dc.DrawShell(polyNext, lstPolys);
} else {
lstPolys.Append(new XPoly2D(polyNext));
dc.DrawShell(polyCur, lstPolys);
}
}
else
{
DList<XPoly2D> lstPolys;
if(m_nStepWidth>0)
TchSubExport::Subtract(polyNext, polyCur, lstPolys);
else
TchSubExport::Subtract(polyCur, polyNext, lstPolys);
for(int ii=0; ii<lstPolys.Length(); ii++)
{
XPoly2D &rPoly=*lstPolys[ii];
//rPoly.SetElevation(nNewElev);
dc.DrawShell(rPoly, DList<XPoly2D>());
}
}
polyCur=polyNext;
}
if(i==m_nStepNum-1 )
{
//add by whl on 070213,支持下沉
if((m_nStepWidth>0&&m_nStepHeight>0)||
(m_nStepWidth<0&&m_nStepHeight<0)||
(m_nStepWidth<0&&m_nStepHeight>0))
dc.DrawShell(polyCur, DList<XPoly2D>());
}
}
return Acad::eOk;
}
Acad::ErrorStatus TDbStep::GetClipBoundary(XPoly2D& poly)const
{
return GetOutline2d(poly);
}
bool TDbStep::IsClipMe(const TEntityBase* pEnt)const
{
if(TDbEntity::IsClipMe(pEnt))
return true;
if(pEnt->GetMe()->isKindOf(TDbColumn::desc()))
return true;
return false;
}
Acad::ErrorStatus
TDbStep::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
assertReadEnabled();
XPoly2D polyCur(1);
polyCur=m_polyOutline;
polyCur.SetElevation(0.0);
XCurveStream dcCurve;
// 绘制踏步
for(int i=0; i<m_nStepNum; i++) {
// 垂直方向的侧面
for(int n=0; n<polyCur.TotalSegments(); n++) {
if(!HasStepAt(n))
continue;
XCurveSegment seg;
polyCur.Nth(n, seg);
dcCurve << seg;
}
XPoly2D polyNext(1);
if(!Offset(polyCur, polyNext))
break;
polyCur=polyNext;
}
XPoly2D polyOutline(1);
GetOutline2d(polyOutline);
AcDbObjectId idOwner=ownerId();
AcDbObjectIdArray railArray;
if(!!objectId() && !!polyOutline && !!idOwner && TDbHandRail::GetRailsByCP(polyOutline, idOwner, railArray)) {
int nCount=railArray.length();
for(int cnt=0; cnt<nCount; cnt++) {
AcDbObjectId idRail=railArray[cnt];
OPENOBJ_BEGIN(idRail, AcDb::kForRead, TDbHandRail, pRail);
if(pRail)
pRail->ClipCurveByTrace(dcCurve.m_lstCurves);
OPENOBJ_END();
}
}
dcCurve.CopyTo(dc);
return Acad::eOk;
}
const TCHAR *TDbStep::GetDefaultLayer() const
{
return LAY_STAIR;
}
/* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */
void TDbStep::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("台阶")));
lstInfo.Append(new TObjInfoUnit(_T("踏步宽度"), Dist2Str(fabs(GetStepWidth()))));
lstInfo.Append(new TObjInfoUnit(_T("踏步高度"), Dist2Str(fabs(GetStepHeight()))));
lstInfo.Append(new TObjInfoUnit(_T("踏步数目"), XString(_T("%d"), int(GetStepNum()))));
lstInfo.Append(new TObjInfoUnit(_T("台阶总高"), Dist2Str(fabs(GetTotalHeight()))));
lstInfo.Append(new TObjInfoUnit(_T("平台高度"), Dist2Str(GetElevation())));
lstInfo.Append(new TObjInfoUnit(_T("基面位置"), (GetStepWidth()>0 && GetStepHeight()>0.0)?
_T("在顶部") : _T("在底部")));
}
int
TDbStep::GetEdgeNum() const
{
return m_polyOutline.TotalSegments();
}
BOOL
TDbStep::HasStepAt(int idx) const
{
ASSERT(idx<GetEdgeNum());
int nTestBit=0x01;
nTestBit <<= idx;
return ((m_nStepFlag&nTestBit)==0);
}
double
TDbStep::GetOffsetDist(int idx) const
{
double nDist= HasStepAt(idx)? m_nStepWidth : 0.0;
return nDist;
}
BOOL
TDbStep::Offset(const XPoly2D &src, XPoly2D &dest) const
{
int nTotalSeg=src.TotalSegments();
ASSERT(nTotalSeg==GetEdgeNum());
dest.Reset();
dest.SetFlag(1);
XDirectionCurve finalMidSeg, lastSeg;
src.Nth(nTotalSeg-1, finalMidSeg);
if(!finalMidSeg && fabs(src.GetBulge(nTotalSeg-1))<1.0E-6) {
// 2001/8/20, 有可能出现长度为0的边
XCurveSegment lnTemp;
m_polyOutline.Nth(nTotalSeg-1, lnTemp);
XLine ln1(src[nTotalSeg-1], ads_angle(lnTemp.StartPoint(), lnTemp.EndPoint()));
(XLine &)finalMidSeg=ln1;
}
lastSeg = finalMidSeg.Offset(GetOffsetDist(nTotalSeg-1), LS_INFINITE);
if(!lastSeg)
return FALSE;
XPoint nextPt;
for(int i=0; i<nTotalSeg; i++) {
XDirectionCurve curMidSeg;
src.Nth(i, curMidSeg);
if(!curMidSeg && fabs(src.GetBulge(i))<1.0E-6) {
// 2001/8/20, 有可能出现长度为0的边
XCurveSegment lnTemp;
m_polyOutline.Nth(i, lnTemp);
(XLine &)curMidSeg=XLine(src[i], ads_angle(lnTemp.StartPoint(), lnTemp.EndPoint()));
}
XDirectionCurve curSeg=curMidSeg.Offset(GetOffsetDist(i), LS_INFINITE);
if(!curSeg)
return FALSE;
XPoint pt1, pt2, curPt;
if(!i) { // 求当前点
if(!lastSeg) curPt=curSeg.StartPoint();
else {
int ptNum=curSeg.Intersection(lastSeg, pt1, pt2);
if(ptNum==2) curPt=XLine(pt1,pt2).NearPoint(curSeg.StartPoint());
else if(ptNum==1) curPt=pt1;
else {
//if(lastSeg.EndPoint().Distance2d(curSeg.StartPoint())>_DIST_SNAP)
// dest.AppendNode(lastSeg.EndPoint(), 0.0);
//curPt=curSeg.StartPoint();
return FALSE;
}
}
} else curPt=nextPt; //上次求得的下一点
int nextIndex= i>=nTotalSeg-1? 0 : i+1; // 当前段为最后时, 下一段为起始段
XDirectionCurve nextMidSeg;
src.Nth(nextIndex, nextMidSeg);
if(!nextMidSeg && fabs(src.GetBulge(nextIndex))<1.0E-6) {
// 2001/8/20, 有可能出现长度为0的边
XCurveSegment lnTemp;
m_polyOutline.Nth(nextIndex, lnTemp);
(XLine &)nextMidSeg=XLine(src[nextIndex], ads_angle(lnTemp.StartPoint(), lnTemp.EndPoint()));
}
XDirectionCurve nextSeg=nextMidSeg.Offset(GetOffsetDist(nextIndex), LS_INFINITE);
if(!nextSeg)
return FALSE;
int ptNum=curSeg.Intersection(nextSeg, pt1, pt2);
if(ptNum==2) nextPt=XLine(pt1, pt2).NearPoint(curSeg.EndPoint());
else if(ptNum==1) nextPt=pt1;
else {
return FALSE;
}
lastSeg=curSeg;
if(curSeg.Is(CURVE_ARC)) {
XArc arc=curSeg.GetArc();
if(!curSeg.IsMinusArc()) { //逆时针
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), curPt));
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), nextPt));
curSeg.SetBulge(arc.Bulge());
} else {
arc.SetStarAngle(ads_angle(arc.GetCenterPt(), nextPt));
arc.SetEndAngle(ads_angle(arc.GetCenterPt(), curPt));
curSeg.SetBulge(-arc.Bulge());
}
curSeg.StartPoint()=curPt;
curSeg.EndPoint()=nextPt;
}
//添一段
dest.Append(new XPoint(curPt));
dest.AppendBugle(curSeg.GetBulge());
}
return TRUE;
}
Acad::ErrorStatus
TDbStep::GetExtents2d(XPoint &ptLow, XPoint &ptUp) const
{
assertReadEnabled();
XPoly2D poly2d(1);
GetOutline2d(poly2d);
poly2d.GetExtend(ptLow, ptUp);
return Acad::eOk;
}
Acad::ErrorStatus
TDbStep::GetExtents(XPoint &ptLow, XPoint &ptUp) const
{
Acad::ErrorStatus es=Acad::eOk;
es=GetExtents2d(ptLow, ptUp);
double nElev=GetElevation();
double nElev1=nElev+GetStepHeight();
ptLow.z=min(nElev, nElev1);
ptUp.z=max(nElev, nElev1);
return es;
}
Acad::ErrorStatus
TDbStep::GetOutline2d(XPoly2D &poly2d) const
{
assertReadEnabled();
poly2d=GetStepOutline();
poly2d.SetElevation(0.0);
if(m_nStepWidth>0) {
for(int i=1; i<m_nStepNum; i++) {
XPoly2D polyNext(1);
if(Offset(poly2d, polyNext)) {
poly2d=polyNext;
} else {
return Acad::eInvalidInput;
}
}
}
return Acad::eOk;
}
// 0--没有命中; 1--任意穿越; 2--任意包含; 3--重边穿越; 4--重边包含
// segHit--重边穿越或包含时的纠正位置
int
TDbStep::HitTest(const XCurveSegment &seg, double nTol, XCurveSegment &segHit) const
{
XPoly2D polyMe(1);
GetOutline2d(polyMe);
PointList ptInts(seg.StartPoint(), seg.EndPoint(), seg.GetBulge());
XCurveSegment seg0=seg;
seg0.SetElevation(0.0);
seg0.SetLineFlag(LS_FINITE);
int nIntNum=Intersect(seg0, polyMe, ptInts);
XPoint ptMid=seg0.MidPoint();
if(!nIntNum && (ptMid&polyMe)==PR_OUTSIDE)
return 0;
for(int n=0; n<polyMe.TotalSegments(); n++) {
XDirectionCurve seg1;
polyMe.Nth(n, seg1);
double nOffDist=-nTol/2.0;
if(polyMe.PathArea()>0)
nOffDist=-nOffDist;
XCurveSegment segRail=seg1.Offset(nOffDist, LS_INFINITE).GetCurve();
if(seg1.IsMinusArc() || seg1.Is(CURVE_ARC)) {
XArc ar0=seg0.GetArc();
XArc ar1=seg1.GetArc();
XPoint ptOn;
if(ar0.GetCenterPt().Distance(ar1.GetCenterPt())<_DIST_SNAP &&
fabs(ar0.GetRadius()-ar1.GetRadius())<nTol && seg0.MidPoint().Project(&ar1, ptOn)==RTNORM &&
(ptOn&seg1)==PR_INSIDE) {
XPoint pt1, pt2, ptMid;
segRail.ProjectToMe(seg0.StartPoint(), pt1);
segRail.ProjectToMe(seg0.EndPoint(), pt2);
XPoint ptTemp=seg0.MidPoint();
segRail.ProjectToMe(ptTemp, ptMid);
segHit=XArc(pt1, ptMid, pt2);
segHit.SetLineFlag(LS_FINITE);
return (nIntNum? 3:4);
}
} else {
XLine ln0=seg0.GetLine();
XLine ln1=seg1.GetLine();
XPoint ptOn;
if(CT_IsSameDrt(ln0.Direction(), ln1.Direction(), _angSnap)) {
if(seg0.MidPoint().Project(&ln1, ptOn)==RTNORM &&
seg0.MidPoint().Distance(ptOn)<nTol) {
if((ptOn&seg1)==PR_INSIDE) {
XPoint pt1, pt2, ptMid;
segRail.ProjectToMe(seg0.StartPoint(), pt1);
segRail.ProjectToMe(seg0.EndPoint(), pt2);
segHit=XLine(pt1, pt2);
segHit.SetLineFlag(LS_FINITE);
return (nIntNum? 3:4);
}
}
}
}
}
return (nIntNum? 1 : 2);
}
double
TDbStep::GetStepHeight() const
{
return m_nStepHeight;
}
double
TDbStep::GetStepWidth() const
{
return m_nStepWidth;
}
double
TDbStep::GetTotalHeight() const
{
return fabs(GetStepHeight()*GetStepNum());
}
const XPoly2D &
TDbStep::GetStepOutline() const
{
return m_polyOutline;
}
int
TDbStep::GetStepNum() const
{
return m_nStepNum;
}
void
TDbStep::SetStepNum(int nNum)
{
assertWriteEnabled();
m_nStepNum=nNum;
}
void
TDbStep::SetStepHeight(double h)
{
assertWriteEnabled();
m_nStepHeight=h;
}
void
TDbStep::SetStepWidth(double w)
{
assertWriteEnabled();
m_nStepWidth = w;
}
void
TDbStep::SetPolyOutline(const XPoly2D &poly)
{
assertWriteEnabled();
ASSERT(poly.PathArea()<0.0 && poly.GetFlag()==1);
m_polyOutline = poly;
}
void
TDbStep::SetStepAt(int idx, BOOL bHasStep)
{
assertWriteEnabled();
ASSERT(idx<GetEdgeNum());
int nTestBit=0x01;
nTestBit <<= idx;
if(!bHasStep)
m_nStepFlag |= nTestBit;
else
m_nStepFlag &= ~nTestBit;
}
double
TDbStep::GetElevation() const
{
double nElev=0;
if(!!m_polyOutline)
nElev=m_polyOutline[0].z;
return nElev;
}
void
TDbStep::SetElevation(double nElev)
{
assertWriteEnabled();
m_polyOutline.SetElevation(nElev);
}
// sg add 101119,支持导出XML
CString TDbStep::GetXml(const AcGeMatrix3d& mat) const
{
TXmlTree xmlTree;
POSITION posRoot = xmlTree.Insert(_T("ATS_STEP"), NULL, NULL);
{
xmlTree.SetAttribute(posRoot, _T("name"), _T("台阶"));
xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称"));
}
CString strText;
POSITION posItem = NULL;
POSITION posItem1 = xmlTree.Insert(_T("Object_ID"), posRoot, NULL);
{
xmlTree.SetAttribute(posItem1, _T("name"), _T("对象编号"));
xmlTree.SetAttribute(posItem1, _T("comment"), _T("当前对象的句柄"));
strText.Format(_T("%ld"), objectId());
xmlTree.SetItemText(posItem1, strText);
}
POSITION posItem2 = xmlTree.Insert(_T("Section"), posRoot, NULL);
{
xmlTree.SetAttribute(posItem2, _T("name"), _T("截面参数"));
POSITION posItemRiser = xmlTree.Insert(_T("Riser"), posItem2, NULL);
{
xmlTree.SetAttribute(posItemRiser, _T("name"), _T("台阶踏步高"));
strText.Format(_T("%f"), GetStepHeight());
xmlTree.SetItemText(posItemRiser, strText);
}
POSITION posItemTread = xmlTree.Insert(_T("Tread"), posItem2, posItemRiser);
{
xmlTree.SetAttribute(posItemTread, _T("name"), _T("台阶踏步宽"));
strText.Format(_T("%f"), GetStepWidth());
xmlTree.SetItemText(posItemTread, strText);
}
POSITION posItemSteps = xmlTree.Insert(_T("Steps"), posItem2, posItemTread);
{
xmlTree.SetAttribute(posItemSteps, _T("name"), _T("台阶踏步数"));
strText.Format(_T("%d"), GetStepNum());
xmlTree.SetItemText(posItemSteps, strText);
}
POSITION posItemBaseSet = xmlTree.Insert(_T("Base_set"), posItem2, posItemSteps);
{
xmlTree.SetAttribute(posItemBaseSet, _T("name"), _T("基面设置"));
strText = (GetStepWidth() < 0) ? _T("轮廓面") : _T("平台面");
xmlTree.SetItemText(posItemBaseSet, strText);
}
}
POSITION posItem3 = xmlTree.Insert(_T("Step_REC"), posRoot, posItem2);
{
xmlTree.SetAttribute(posItem3, _T("name"), _T("踏步边记录"));
xmlTree.SetAttribute(posItem3, _T("comment"), _T("记录平台有踏步的边号"));
strText.Format(_T("%d"), m_nStepFlag);
xmlTree.SetItemText(posItem3, strText);
}
POSITION posItem4 = xmlTree.Insert(_T("Baseline"), posRoot, posItem3);
{
xmlTree.SetAttribute(posItem4, _T("name"), _T("基线参数"));
xmlTree.SetAttribute(posItem4, _T("comment"), _T("用于台阶或平台的外轮廓线"));
posItem = NULL;
TADSGePoint3d ptNode;
int iLen = m_polyOutline.Length();
for (int i = 0; i < iLen; i++)
{
ptNode = m_polyOutline[i];
// sg add 120117,对点进行坐标变换
ptNode.TransformBy(mat);
strText.Format(_T("Point_%d"), i + 1);
posItem = xmlTree.Insert(strText, posItem4, posItem);
{
strText.Format(_T("第%d点"), i + 1);
xmlTree.SetAttribute(posItem, _T("name"), strText);
strText.Format(_T("%f,%f,%f"), ptNode.x, ptNode.y, ptNode.z);
xmlTree.SetItemText(posItem, strText);
}
strText.Format(_T("Ang_%d"), i + 1);
posItem = xmlTree.Insert(strText, posItem4, posItem);
{
strText.Format(_T("圆心角%d"), i + 1);
xmlTree.SetAttribute(posItem, _T("name"), strText);
strText.Format(_T("%f"), m_polyOutline.GetBulge(i));
xmlTree.SetItemText(posItem, strText);
}
strText.Format(_T("Step_flag_%d"), i + 1);
posItem = xmlTree.Insert(strText, posItem4, posItem);
{
xmlTree.SetAttribute(posItem, _T("name"), _T("踏步标志"));
strText.Format(_T("%d"), HasStepAt(i));
xmlTree.SetItemText(posItem, strText);
}
}
}
CString strBase = TEntityBase::GetXml(mat);
CString strXml = xmlTree.GetXml();
int nIndex = strXml.Find(_T("<Object_ID"));
strXml.Insert(nIndex, strBase);
return strXml;
}
void InitDbStep(BOOL bTrue)
{
AecObjectEditMethod pOldEdit=NULL;
if(bTrue) {
TDbStep::rxInit();
pOldEdit=TDbStep::SetEditMethod(EditStep0);
acrxBuildClassHierarchy();
TDbStep::InitMatchProtocol(TRUE);
} else {
TDbStep::InitMatchProtocol(FALSE);
TDbStep::SetEditMethod(pOldEdit);
deleteAcRxClass(TDbStep::desc());
}
}
// Command:编辑台阶
int EditStep0(AcDbObjectId id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbStep, pStep);
if(!pStep)
return RTERROR;
while(1) {
const TCHAR *szPrompt1=_T("\n选择 [踏步宽(W)/踏步高(H)/踏步数(N)/平台标高(T)/参数列表(L)]<退出>:");
XString sKeyword;
int nRet=0;
INITGET_BEG(0, _T("W H N T L"));
nRet=ads_getkword(szPrompt1, sKeyword);
INITGET_END();
if(nRet!=RTNORM)
break;
if(sKeyword[0]==_T('W')) {
double nStepWidth=pStep->GetStepWidth();
nRet=GetReal(_T("\n踏步宽度"), nStepWidth);
if(nRet==RTCAN)
break;
if(nRet==RTNORM) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetStepWidth(nStepWidth);
if(nStepWidth>0)
pStep->SetStepHeight(fabs(pStep->GetStepHeight()));
else
pStep->SetStepHeight(-fabs(pStep->GetStepHeight()));
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('H')) {
double nStepHeight=pStep->GetStepHeight();
nRet=GetReal(_T("\n踏步高度"), nStepHeight);
if(nRet==RTCAN)
break;
if(nRet==RTNORM) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetStepHeight(nStepHeight);
if(nStepHeight>0)
pStep->SetStepWidth(fabs(pStep->GetStepWidth()));
else
pStep->SetStepWidth(-fabs(pStep->GetStepWidth()));
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('N')) {
int nStepNum=pStep->GetStepNum();
ads_initget(RSG_NOZERO|RSG_NONEG, NULL);
adsout << _T("\n踏步数目<") << nStepNum << _T(">:");
nRet=ads_getint(_T(""), &nStepNum);
if(nRet==RTCAN)
break;
if(nRet==RTNORM) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetStepNum(nStepNum);
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('T')) {
double nElev=pStep->GetElevation();
nRet=GetReal(_T("\n平台标高"), nElev);
if(nRet==RTCAN)
break;
if(nRet==RTNORM) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetElevation(nElev);
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('L')) {
pStep->list();
}
}
OPENOBJ_END();
return RTNORM;
}