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

1588 lines
40 KiB
C++
Raw Normal View History

2026-09-28 15:28:50 +08:00
#include "stdafx.h"
#include "TDbColumn.h"
#include "slab_xdata_key.h"
/////////////////////////////////////////////////////////////
// 屋顶对象类
/////////////////////////////////////////////////////////////
// ver:1-TArch5; 2-TArch6
const Adesk::UInt8 TDbSlab::g_nVersion = 2;
ACRX_DXF_DEFINE_MEMBERS(ATSSlab, ATSEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_SLAB, "ATS_SLAB图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbSlab);
TDbSlab::TDbSlab()
:m_polyOutline(1), m_nInvisibleEdge(0), m_vtNormal(0,0,1)
{
m_nThickness=0;
}
TDbSlab::~TDbSlab()
{
}
BOOL TDbSlab::IsValid() const
{
BOOL bRet=TDbEntity::IsValid();
if(!bRet)
return bRet;
bRet=(m_polyOutline.Length()>1 && m_polyOutline.IsClosed());
return bRet;
}
Acad::ErrorStatus
TDbSlab::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
// 提供对格式刷的支持
void TDbSlab::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbSlab *pSrc=TDbSlab::cast(pSrcEntity);
if(pSrc) {
m_nThickness=pSrc->m_nThickness; //<0, 则基准面在顶部
}
}
Acad::ErrorStatus
TDbSlab::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet, BOOL *bErase)
{
if(g_nSaveTArchVer==5)
{
Acad::ErrorStatus es=Acad::eOk;
if(m_vtNormal.AsAcGeVector3d()!=AcGeVector3d(0,0,1))
{
assertWriteEnabled();
_SetNormal(m_vtNormal);
}
}
return TDbEntity::DownGradeSave(nDrawMode,entSet,bErase);
}
Acad::ErrorStatus
TDbSlab::GetPathPoly(XPoly2D&poly,AcGeVector3d&normal)const
{
assertReadEnabled();
poly=m_polyOutline;
normal=m_vtNormal.AsAcGeVector3d();
return Acad::eOk;
}
Acad::ErrorStatus
TDbSlab::SetPathPoly(const XPoly2D&poly,const AcGeVector3d&normal)
{
assertWriteEnabled();
m_polyOutline=poly;
if(m_polyOutline.PathArea()>0)
m_polyOutline.Reverse();
m_vtNormal=normal;
return Acad::eOk;
}
// 从DWG读入数据:
Acad::ErrorStatus TDbSlab::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_nThickness);
pFiler->readItem(&m_nInvisibleEdge);
double nElev=0.0;
pFiler->readItem(&nElev);
m_polyOutline.Reset();
ReadPoly2D(pFiler, m_polyOutline);
m_polyOutline.SetElevation(nElev);
m_lstHoles.Reset();
Adesk::UInt16 nHole=0;
pFiler->readItem(&nHole);
for(Adesk::UInt16 i=0; i<nHole; i++) {
XPoly2D *pHole=new XPoly2D(1);
ReadPoly2D(pFiler, *pHole);
pHole->SetElevation(nElev);
m_lstHoles.Append(pHole);
}
if(nVer>1) {
pFiler->readItem((AcGeVector3d *)&m_vtNormal);
} else {
m_vtNormal = _GetNormal();
}
// pFiler->readItem(&m_idLayerHatch2d);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSlab::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
if(g_nSaveTArchVer==5)
pFiler->writeItem((Adesk::UInt8)1);
else
pFiler->writeItem(g_nVersion);
pFiler->writeItem(m_nThickness);
pFiler->writeItem(m_nInvisibleEdge);
double nElev=0.0;
if(!!m_polyOutline)
nElev=m_polyOutline[0].z;
pFiler->writeItem(nElev);
WritePoly2D(pFiler, m_polyOutline);
Adesk::UInt16 num=m_lstHoles.Length();
pFiler->writeItem(num);
for(Adesk::UInt16 i=0; i<num; i++) {
WritePoly2D(pFiler, m_lstHoles[i]);
}
if(g_nSaveTArchVer!=5)
pFiler->writeItem((const AcGeVector3d &)m_vtNormal);
//pFiler->writeItem(m_idLayerHatch2d);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSlab::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbEntity::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbSlab"))) {
return Acad::eBadDxfSequence;
}
int fieldsFlags=0;
resbuf rb;
int n1;
double r1=0.0, r2=0.0;
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 149:
r2=rb.resval.rreal;
fieldsFlags |= 0x02;
break;
case AcDb::kDxfInt32:
n1=rb.resval.rlong;
fieldsFlags |= 0x04;
break;
case AcDb::kDxfXCoord:
pts.Append(new XPoint(rb.resval.rpoint));
break;
case AcDb::kDxfAngle:
bulges.Append(new double(rb.resval.rreal));
break;
case 210:
m_vtNormal=rb.resval.rpoint;
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(pts.Length()<2 || pts.Length()!=bulges.Length()) {
pFiler->setError(_T("\nError DXF group code: 10, 50"));
return Acad::eMissingDxfField;
}
m_nThickness=r2;
if(fieldsFlags&0x04)
m_nInvisibleEdge=n1;
m_polyOutline.Reset();
for(int i=0; i<pts.Length(); i++) {
m_polyOutline.AppendNode(*pts[i], *bulges[i]);
}
m_polyOutline.SetFlag(1);
if(fieldsFlags&0x01)
m_polyOutline.SetElevation(r1);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSlab::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es;
es = TDbEntity::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbSlab"));
assert(es == Acad::eOk);
pFiler->writeDouble(148, GetElevation());
pFiler->writeDouble(149, m_nThickness);
pFiler->writeInt32(AcDb::kDxfInt32, m_nInvisibleEdge);
for(int i=0; i<m_polyOutline.Length(); i++) {
pFiler->writePoint2d(AcDb::kDxfXCoord, m_polyOutline[i]);
pFiler->writeDouble(AcDb::kDxfAngle, m_polyOutline.GetBulge(i));
}
pFiler->writeVector3d(210, m_vtNormal);
return pFiler->filerStatus();
}
// -----------------------------------------------------------------------
// Overriden functions for edit
// to do:
// 允许通过夹点改变边界
Acad::ErrorStatus TDbSlab::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
int nEdgeNum=GetEdgeNum();
XVector3D vtNormal=GetNormal();
for(int i=0; i<nEdgeNum; i++) {
XPoint pt=Ecs2Wcs(m_polyOutline[i], vtNormal);
gripPoints.append(pt);
}
//边上的夹点
for(i=0; i<nEdgeNum; i++) {
XCurveSegment edge;
m_polyOutline.Nth(i, edge);
XPoint ptMid=Ecs2Wcs(edge.MidPoint(), vtNormal);
gripPoints.append(ptMid);
}
return Acad::eOk;
}
// stretch points is diffrent from grep points, with no midpoint included
Acad::ErrorStatus TDbSlab::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
for(int i=0; i<m_polyOutline.Length(); i++) {
XPoint pt=m_polyOutline[i];
stretchPoints.append(pt);
}
return Acad::eOk;
}
// Active when being rotated, scaled, moved, etc.
Acad::ErrorStatus TDbSlab::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
TDbEntity::subTransformBy(xform);
XVector3D vtNormal=GetNormal();
//((AcGeVector3d &)vtNormal).transformBy(xform);
double nElev=0.0;
//ads_matrix mat;
AcGeMatrix2d xform2d(xform.convertToLocal(vtNormal,nElev));
ads_matrix mat={{xform2d(0,0), xform2d(0,1), 0, xform2d(0,2)},
{xform2d(1,0), xform2d(1,1), 0, xform2d(1,2)},
{0,0,1, nElev},
{0,0,0,1}};
//memcpy(mat, mat0, sizeof(ads_matrix));
AcGeMatrix3d mat3d=AsAcGeMatrix3d(mat);
m_polyOutline.TransformBy(mat3d);
//m_polyOutline.SetElevation(nElev);
BOOL bMirror=IsMirrorMatrix(mat);
if(bMirror && m_polyOutline.PathArea()>0) {
m_polyOutline.Reverse();
int nEdgeNum=GetEdgeNum();
DList<int> lstEdgeFlag;
for(int n=0; n<nEdgeNum; n++)
lstEdgeFlag.Append(new int(GetVisibilityAt(n)));
lstEdgeFlag.Reverse();
for(n=0; n<nEdgeNum; n++)
SetVisibilityAt(n, *lstEdgeFlag[n]);
}
for(int j=0; j<m_lstHoles.Length(); j++) {
XPoly2D &rHole=*m_lstHoles[j];
rHole.TransformBy(mat3d);
//rHole.SetElevation(nElev);
if(bMirror && rHole.PathArea()>0)
rHole.Reverse();
}
SetNormal(vtNormal);
/*
ads_matrix mat;
memcpy(mat, &xform, sizeof(ads_matrix));
BOOL bMirror=IsMirrorMatrix(mat);
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;
}
}
if(bMirror && m_polyOutline.PathArea()>0) {
m_polyOutline.Reverse();
int nEdgeNum=GetEdgeNum();
DList<int> lstEdgeFlag;
for(int n=0; n<nEdgeNum; n++)
lstEdgeFlag.Append(new int(GetVisibilityAt(n)));
lstEdgeFlag.Reverse();
for(n=0; n<nEdgeNum; n++)
SetVisibilityAt(n, *lstEdgeFlag[n]);
}
for(int j=0; j<m_lstHoles.Length(); j++) {
XPoly2D &rHole=*m_lstHoles[j];
for(int i=0; i<rHole.Length(); i++) {
XPoint *pt=rHole[i];
pt->TransformBy(mat);
//以第一个顶点的z坐标为基准
pt->z = nElev;
}
if(bMirror && rHole.PathArea()>0)
rHole.Reverse();
}
*/
return Acad::eOk;
}
void TDbSlab::UnionScale(double nScale)
{
assertWriteEnabled();
double nOldElev=GetElevation();
TDbEntity::UnionScale(nScale);
SetElevation(nOldElev*nScale);
m_nThickness*=nScale;
}
// 功能: 夹点操作
Acad::ErrorStatus TDbSlab::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
XPoly2D polyBack(m_polyOutline);
//XPoint vtOffset=*(XPoint *)&offset;
XVector3D vtNormal=GetNormal();
XPoint vtOffset=Wcs2Ecs(*(XPoint *)&offset, vtNormal);
//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 TDbSlab::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 TDbSlab::CreateGrip()
{
TDbEntity::CreateGrip();
::CreateGrip(this,m_polyOutline,0);
}
Acad::ErrorStatus TDbSlab::EntityToDim(long iGrip,long iDim,const AcDbEntity*pEnt)
{
TEntityBase *pCurve=TDbSlab::cast(pEnt);
if(pCurve==NULL)
pCurve=this;
XPoly2D polyPath;
AcGeVector3d normal;
pCurve->GetPathPoly(polyPath,normal);
return ::EntityToDim(this,polyPath,iGrip,iDim,0);
}
Acad::ErrorStatus TDbSlab::DimToEntity(long iGrip,long iDim,double newValue,const AcGeVector3d& offset)
{
assertWriteEnabled();
TDbSlab 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 TDbSlab::subMoveStretchPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
int nCount=indices.length();
return subMoveGripPointsAt(indices, offset);
}
Acad::ErrorStatus
TDbSlab::GetExtents2d(XPoint &ptLow, XPoint &ptUp) const
{
AcGeVector3d vtStd(0,0,1);
AcGeVector3d vtNorm;
vtNorm=(AcGeVector3d &)GetNormal();
Acad::ErrorStatus es=Acad::eOk;
if(vtNorm==vtStd) {
XPoly2D poly(m_polyOutline);
poly.SetElevation(0.0);
poly.GetExtend(ptLow, ptUp);
ptLow.z=ptUp.z=0.0;
} else {
es=TDbEntity::GetExtents2d(ptLow, ptUp);
}
return es;
}
Acad::ErrorStatus
TDbSlab::GetExtents(XPoint &ptLow, XPoint &ptUp) const
{
AcGeVector3d vtStd(0,0,1);
AcGeVector3d vtNorm;
vtNorm=(AcGeVector3d &)GetNormal();
Acad::ErrorStatus es=Acad::eOk;
if(vtNorm==vtStd) {
XPoly2D poly(m_polyOutline);
poly.SetElevation(0.0);
poly.GetExtend(ptLow, ptUp);
double nThick=GetThickness();
double nElev=GetElevation();
double nElev1=nElev+nThick;
ptLow.z=min(nElev, nElev1);
ptUp.z=max(nElev, nElev1);
} else {
es=TDbEntity::GetExtents(ptLow, ptUp);
}
return es;
}
Acad::ErrorStatus
TDbSlab::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
assertReadEnabled();
//TPushProperty vProp(this, dc);
XVector3D vtNormal=GetNormal();
if(((AcGeVector3d &)vtNormal)!=AcGeVector3d(0,0,1)) {
XPoly2D polyOutline(1);
m_polyOutline.Disperse1(polyOutline, _AS_SYS_UNIT(g_nCirDeviation));
for(int i=0; i<polyOutline.Length(); i++) {
*polyOutline[i]=Ecs2Wcs(*polyOutline[i], vtNormal);
}
DList<XPoly2D> lstHoles;
for(i=0; i<m_lstHoles.Length(); i++) {
XPoly2D *pHole=new XPoly2D(1);
XPoly2D &hole=*pHole;
m_lstHoles[i].Disperse1(hole, _AS_SYS_UNIT(g_nCirDeviation));
for(int j=0; j<hole.Length(); j++) {
*hole[j]=Ecs2Wcs(*hole[j], vtNormal);
}
lstHoles.Append(pHole);
}
XVector3D vt(0,0,m_nThickness);
vt=Ecs2Wcs(vt, vtNormal, TRUE);
if(fabs(m_nThickness)>_DIST_SNAP)
dc.DrawBody(polyOutline, lstHoles, vt);
else
dc.DrawShell(polyOutline, lstHoles);
/*
dc.DrawShell(polyOutline, lstHoles);
if(fabs(m_nThickness)>_DIST_SNAP) {
XPoly2D polyUp(polyOutline);
for(i=0; i<polyUp.Length(); i++) {
*polyUp[i] += vt;
}
DList<XPoly2D> lstHoleUp;
for(int n=0; n<lstHoles.Length(); n++) {
XPoly2D *pHole=new XPoly2D(*lstHoles[n]);
for(int j=0; j<pHole->Length(); j++) {
*(*pHole)[j] += vt;
}
lstHoleUp.Append(pHole);
}
dc.DrawShell(polyUp, lstHoleUp);
dc.DrawMesh(polyOutline, vt);
for(i=0; i<lstHoles.Length(); i++)
dc.DrawMesh(*lstHoles[i], vt);
}*/
} else {
XVector3D vt(0,0,m_nThickness);
if(fabs(m_nThickness)>_DIST_SNAP)
dc.DrawBody(m_polyOutline, m_lstHoles, vt);
else
dc.DrawShell(m_polyOutline, m_lstHoles);
/*
dc.DrawShell(m_polyOutline, m_lstHoles);
if(fabs(m_nThickness)>_DIST_SNAP) {
XPoly2D polyUp(m_polyOutline);
double nElev = GetElevation()+m_nThickness;
polyUp.SetElevation(nElev);
DList<XPoly2D> lstHoleUp;
for(int n=0; n<m_lstHoles.Length(); n++) {
XPoly2D *pHole=new XPoly2D(m_lstHoles[n]);
pHole->SetElevation(nElev);
lstHoleUp.Append(pHole);
}
dc.DrawShell(polyUp, lstHoleUp);
dc.DrawMesh(m_polyOutline, vt);
for(int i=0; i<m_lstHoles.Length(); i++)
dc.DrawMesh(m_lstHoles[i], vt);
}*/
}
return Acad::eOk;
}
bool TDbSlab::IsClipMe(const TEntityBase* pEnt)const
{
if(TDbEntity::IsClipMe(pEnt))
return true;
if(pEnt->GetMe()->isKindOf(TDbColumn::desc()))
return true;
return false;
}
Acad::ErrorStatus
TDbSlab::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
//TPushProperty vProp(this, dc);
XVector3D vt=GetNormal();
if(((AcGeVector3d &)vt)!=AcGeVector3d(0,0,1))
return ExplodeOrDraw3d(dc);//解决平板出现无二维的情况,按三维绘制,add by whl on 041108
int nVisEdge=0;
if (_tcscmp(dc.Desc(), TGGiWorldViewportDraw::Descriptor()) == 0 && !ownerId())
{
XPoly2D poly1(m_polyOutline);
poly1.SetElevation(0.0);
for(int i=0; i<poly1.TotalSegments(); i++)
{
if(GetVisibilityAt(i))
{
XCurveSegment seg;
poly1.Nth(i, seg);
dc << seg;
nVisEdge++;
}
}
return Acad::eOk;
}
nVisEdge=0;
XCurveStream dcSrc;
XPoly2D poly(m_polyOutline);
poly.SetElevation(0.0);
for(int i=0; i<poly.TotalSegments(); i++) {
if(GetVisibilityAt(i)) {
XCurveSegment seg;
poly.Nth(i, seg);
dcSrc << seg;
nVisEdge++;
}
}
if(!nVisEdge)
return Acad::eOk;
for(i=0; i<m_lstHoles.Length(); i++)
((XDcStream &)dcSrc) << m_lstHoles[i];
// 扶手裁剪
if(!m_tempRailArray.isEmpty()) {
int num=m_tempRailArray.length();
for(int n=0; n<num; n++) {
TDbHandRail *pRail=(TDbHandRail *)m_tempRailArray[n];
pRail->ClipCurveByTrace(dcSrc.m_lstCurves);
}
} else {
XPoly2D polyOutline(m_polyOutline);
polyOutline.SetElevation(0.0);
AcDbObjectId idOwner=ownerId();
AcDbObjectIdArray railArray;
if(!!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(dcSrc.m_lstCurves);
OPENOBJ_END();
}
}
}
dcSrc.CopyTo(dc);
if (!g_bOsnapExpl)
{ //板新增填充功能
int nisFill = 0;
m_XDataMap.GetAt(bKEY_SLAB_FILL, nisFill);
if (nisFill > 0)
{
double dscale(100.0);
int ncolor(256);
CString sPatname = _T("ANSI31");
m_XDataMap.GetAt(sKEY_PAT_PATPICNAME, sPatname);
m_XDataMap.GetAt(dKEY_PAT_DENSITY, dscale);
m_XDataMap.GetAt(dwKEY_PAT_COLOR, ncolor);
AcGeDoubleArray bulges;
AcGePoint2dArray vertices;
int nVert = poly.Length();
AcDbHatch pHatch;
pHatch.setAssociative(Adesk::kFalse);
pHatch.setPatternScale(dscale);
pHatch.setHatchStyle(AcDbHatch::kNormal);
pHatch.setPattern(AcDbHatch::kPreDefined, sPatname);
bulges.setPhysicalLength(0).setLogicalLength(nVert+1);
vertices.setPhysicalLength(0).setLogicalLength(nVert+1);
for (i = 0; i < nVert; i++)
{
vertices[i] = *poly[i];
bulges[i] = tan(poly.GetBulge(i)/4);
}
vertices[i] = vertices[0];
bulges[i] = bulges[0];
Acad::ErrorStatus es = pHatch.appendLoop(AcDbHatch::kSelfIntersecting, vertices, bulges);
for(i = 0; i < m_lstHoles.Length(); i++)
{
poly = m_lstHoles[i];
nVert = poly.Length();
bulges.setPhysicalLength(0).setLogicalLength(nVert+1);
vertices.setPhysicalLength(0).setLogicalLength(nVert+1);
for (int j = 0; j < nVert; j++)
{
vertices[j] = *poly[j];
bulges[j] = tan(poly.GetBulge(j)/4);
}
vertices[j] = vertices[0];
bulges[j] = bulges[0];
es = pHatch.insertLoopAt(i+1,AcDbHatch::kSelfIntersecting , vertices, bulges);
}
pHatch.evaluateHatch();
AcDbObjectId idlay;
m_XDataMap.GetAt(idKEY_PAT_LAYER, idlay);
if (idlay.isValid())
{
pHatch.setLayer(idlay);
pHatch.setColorIndex(ncolor);
}
dc.DrawEntity(pHatch);
}
}
return Acad::eOk;
}
const TCHAR *TDbSlab::GetDefaultLayer() const
{
return LAY_SLAB;
}
/* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */
void TDbSlab::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("平板")));
lstInfo.Append(new TObjInfoUnit(_T("平板厚度"), Dist2Str(GetThickness())));
lstInfo.Append(new TObjInfoUnit(_T("底标高"), Dist2Str(GetElevation())));
if(!m_lstHoles) {
lstInfo.Append(new TObjInfoUnit(_T("周长"), Dist2Str(GetPerimeter0())));
lstInfo.Append(new TObjInfoUnit(_T("底面积"),
XString(_T("%.2f"), _AS_SQMETER(GetBottomArea0()))));
lstInfo.Append(new TObjInfoUnit(_T("侧面积"),
XString(_T("%.2f"), _AS_SQMETER(GetSideArea0()))));
lstInfo.Append(new TObjInfoUnit(_T("体积"),
XString(_T("%.3f"), _AS_CUMETER(GetVolume0()))));
} else {
lstInfo.Append(new TObjInfoUnit(_T("周长(不含洞)"), Dist2Str(GetPerimeter0())));
lstInfo.Append(new TObjInfoUnit(_T("周长(含洞)"), Dist2Str(GetPerimeter())));
lstInfo.Append(new TObjInfoUnit(_T("底面积(不扣洞)"),
XString(_T("%.2f"), _AS_SQMETER(GetBottomArea0()))));
lstInfo.Append(new TObjInfoUnit(_T("底面积(扣洞)"),
XString(_T("%.2f"), _AS_SQMETER(GetBottomArea()))));
lstInfo.Append(new TObjInfoUnit(_T("侧面积(不含洞)"),
XString(_T("%.2f"), _AS_SQMETER(GetSideArea0()))));
lstInfo.Append(new TObjInfoUnit(_T("侧面积(含洞)"),
XString(_T("%.2f"), _AS_SQMETER(GetSideArea()))));
lstInfo.Append(new TObjInfoUnit(_T("体积(不扣洞)"),
XString(_T("%.3f"), _AS_CUMETER(GetVolume0()))));
lstInfo.Append(new TObjInfoUnit(_T("体积(扣洞)"),
XString(_T("%.3f"), _AS_CUMETER(GetVolume()))));
}
}
void
TDbSlab::AddTempRail(TDbHandRail *pRail)
{
m_tempRailArray.append(pRail);
}
int
TDbSlab::GetEdgeNum() const
{
return m_polyOutline.TotalSegments();
}
BOOL
TDbSlab::GetVisibilityAt(int idx) const
{
ASSERT(idx<GetEdgeNum());
int nTestBit=0x01;
nTestBit <<= idx;
return ((m_nInvisibleEdge&nTestBit)==0);
}
double
TDbSlab::GetThickness() const
{
return m_nThickness;
}
const XPoly2D &
TDbSlab::GetOutline() const
{
return m_polyOutline;
}
void
TDbSlab::SetThickness(double h)
{
assertWriteEnabled();
m_nThickness=h;
}
// 没有判断是否在边界范围内
BOOL
TDbSlab::AddHole(const XPoly2D &polyHole)
{
assertWriteEnabled();
XPoly2D *pHole=new XPoly2D(polyHole);
pHole->SetElevation(GetElevation());
m_lstHoles.Append(pHole);
return TRUE;
}
BOOL
TDbSlab::RemoveHole(int idx)
{
assertWriteEnabled();
if(idx<m_lstHoles.Length()) {
m_lstHoles.Remove(idx);
return TRUE;
}
return FALSE;
}
void
TDbSlab::SetOutline(const XPoly2D &poly)
{
assertWriteEnabled();
ASSERT(poly.PathArea()<0.0 && poly.GetFlag()==1);
m_polyOutline = poly;
}
void
TDbSlab::SetVisibilityAt(int idx, BOOL bTrue)
{
assertWriteEnabled();
ASSERT(idx<GetEdgeNum());
int nTestBit=0x01;
nTestBit <<= idx;
if(!bTrue)
m_nInvisibleEdge |= nTestBit;
else
m_nInvisibleEdge &= ~nTestBit;
}
void TDbSlab::SetVisibilityAll(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nInvisibleEdge=0;
else {
int nEdgeNum=GetEdgeNum();
for(int idx=0; idx<nEdgeNum; idx++) {
int nTestBit=0x01;
nTestBit <<= idx;
m_nInvisibleEdge |= nTestBit;
}
}
}
double
TDbSlab::GetElevation() const
{
double nElev=0;
if(!!m_polyOutline)
nElev=m_polyOutline[0].z;
return nElev;
}
void
TDbSlab::SetElevation(double nElev)
{
assertWriteEnabled();
m_polyOutline.SetElevation(nElev);
for(int i=0; i<m_lstHoles.Length(); i++)
m_lstHoles[i]->SetElevation(nElev);
}
XVector3D TDbSlab::GetNormal() const
{
return m_vtNormal;
}
// Upgrade from TArch5 to TArch6 only
XVector3D TDbSlab::_GetNormal() const
{
int nFlag=0;
resbuf *xd=xData(TCHXD);
BOOL bRet=FALSE;
XVector3D vt(0,0,1);
if(xd) {
resbuf *rb=xd->rbnext;
if(rb->restype==1010) {
vt = rb->resval.rpoint;
vt /= vt.Length(); // normalize
}
ads_relrb(xd);
}
return vt;
}
void TDbSlab::_SetNormal(XVector3D vt)
{
assertWriteEnabled();
if(!XSymbolTable(_T("APPID"), TCHXD) && database()==acdbCurDwg())
ads_regapp(TCHXD);
vt /= vt.Length();
int nFlag=0;
resbuf *xd=ads_buildlist(1001, TCHXD, 1010, &vt, NULL);
setXData(xd);
ads_relrb(xd);
}
void TDbSlab::SetNormal(XVector3D vt)
{
assertWriteEnabled();
vt.Normalize();
m_vtNormal=vt;
}
// 扣除洞口
double TDbSlab::GetPerimeter() const
{
double nHoleVal=0.0;
for(int i=0; i<m_lstHoles.Length(); i++)
nHoleVal += m_lstHoles[i].Distance2d();
return (GetPerimeter0()+nHoleVal);
}
double TDbSlab::GetBottomArea() const
{
double nHoleVal=0.0;
for(int i=0; i<m_lstHoles.Length(); i++)
nHoleVal += m_lstHoles[i].Area();
return (GetBottomArea0()-nHoleVal);
}
double TDbSlab::GetSideArea() const
{
double nHoleVal=0.0;
for(int i=0; i<m_lstHoles.Length(); i++)
nHoleVal += m_lstHoles[i].Distance2d()*m_nThickness;
return (GetSideArea0()+nHoleVal);
}
double TDbSlab::GetVolume() const
{
double nHoleVal=0.0;
for(int i=0; i<m_lstHoles.Length(); i++)
nHoleVal += m_lstHoles[i].Area()*m_nThickness;
return (GetVolume0()-nHoleVal);
}
const DList<XPoly2D> &
TDbSlab::GetHoles() const
{
return m_lstHoles;
}
// 高16--洞序号, 低16--边号
BOOL TDbSlab::HitTestOnHole(const XPoint &ptTest,Adesk::UInt32 *bHitFlag) const
{
XPoint pt=ptTest;
pt.z = GetElevation();
for(int i=0; i<m_lstHoles.Length(); i++) {
const XPoly2D &rHole=m_lstHoles[i];
for(int j=0; j<rHole.TotalSegments(); j++) {
XCurveSegment seg;
rHole.Nth(j, seg);
seg.SetElevation(pt.z);
int nFlag=(pt&seg);
if(nFlag==PR_ONPT1 || nFlag==PR_ONPT2 || nFlag==PR_INSIDE) {
Adesk::UInt32 nRet=i;
nRet <<= 16;
nRet += j;
if(bHitFlag) *bHitFlag=nRet;
return TRUE;
}
}
}
return FALSE;
}
int
TDbSlab::HitTestOnOutline(const XPoint &ptTest) const
{
XPoint pt=ptTest;
pt.z = GetElevation();
const XPoly2D &rHole=m_polyOutline;
for(int j=0; j<rHole.TotalSegments(); j++) {
XCurveSegment seg;
rHole.Nth(j, seg);
seg.SetElevation(pt.z);
int nFlag=(pt&seg);
if(nFlag==PR_ONPT1 || nFlag==PR_ONPT2 || nFlag==PR_INSIDE) {
return j;
}
}
return 0;
}
// 0--没有命中; 1--任意穿越; 2--任意包含; 3--重边穿越; 4--重边包含
// segHit--重边穿越或包含时的纠正位置
int
TDbSlab::HitTest(const XCurveSegment &seg, double nTol, XCurveSegment &segHit) const
{
XPoly2D polyMe(m_polyOutline);
polyMe.SetElevation(0.0);
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<GetEdgeNum(); n++) {
if(!GetVisibilityAt(n))
continue;
XCurveSegment seg1;
polyMe.Nth(n, seg1);
if(!seg1)
continue;
if(seg0.Is(CURVE_LINE)!=seg1.Is(CURVE_LINE))
continue;
if(seg0.Is(CURVE_LINE)) {
if(CT_IsSameDrt(seg0.IDirection(0), seg1.IDirection(0), _angSnap)) {
if(seg0.StartPoint().Distance(&seg1)<nTol) { //重合
XLine lnRail=seg1.GetLine().Offset(-nTol/2.0);
lnRail.SetLineFlag(LS_INFINITE);
XPoint(seg0.StartPoint()).Project(&lnRail, seg0.StartPoint());
XPoint(seg0.EndPoint()).Project(&lnRail, seg0.EndPoint());
segHit=seg0;
return (nIntNum? 3:4);
}
}
} else {
ASSERT(seg0.Is(CURVE_ARC) && 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) {
double nOffDist=polyMe.GetBulge(n)>0? -nTol/2.0 : nTol/2.0;
XCurveSegment segRail=seg1.Offset(OFFSET_RIGHT, nOffDist, LS_INFINITE);
XPoint pt1, pt2, ptMid;
seg0.StartPoint().Project(&ar1, pt1);
seg0.EndPoint().Project(&ar1, pt2);
seg0.MidPoint().Project(&ar1, ptMid);
segHit=XArc(pt1, ptMid, pt2);
segHit.SetLineFlag(LS_FINITE);
return (nIntNum? 3:4);
}
}
}
return (nIntNum? 1 : 2);
}
// cet 2012.11.12 add支持导出XML
CString TDbSlab::GetXml(const AcGeMatrix3d& mat) const
{
TXmlTree xmlTree;
POSITION posRoot = xmlTree.Insert(_T("ATS_SLAB"), NULL, NULL);
{
xmlTree.SetAttribute(posRoot, _T("name"), _T("平板"));
xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称"));
}
CString strText;
POSITION posItemThick = xmlTree.Insert(_T("Flr_thick"), posRoot, NULL);
{
xmlTree.SetAttribute(posItemThick, _T("name"), _T("板厚"));
xmlTree.SetAttribute(posItemThick, _T("comment"), _T("板厚"));
strText.Format(_T("%f"), m_nThickness);
xmlTree.SetItemText(posItemThick, strText);
}
POSITION posItemNormal = xmlTree.Insert(_T("VtNormal"), posRoot, posItemThick);
{
xmlTree.SetAttribute(posItemNormal, _T("name"), _T("方向"));
XVector3D vtNormal=GetNormal();
vtNormal.TransformBy(mat);
strText.Format(_T("%f,%f,%f"), vtNormal.x, vtNormal.y, vtNormal.z);
xmlTree.SetItemText(posItemNormal, strText);
}
POSITION posItemOutLine = xmlTree.Insert(_T("Baseline"), posRoot, posItemNormal);
{
xmlTree.SetAttribute(posItemOutLine, _T("name"), _T("截面参数"));
POSITION posItem = NULL;
TADSGePoint3d ptNode;
int iLen = m_polyOutline.Length();
for (int i = 0; i < iLen; i++)
{
ptNode = m_polyOutline[i];
// 对点进行坐标变换
ptNode.TransformBy(mat);
strText.Format(_T("Point_%d"), i + 1);
posItem = xmlTree.Insert(strText, posItemOutLine, 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, posItemOutLine, 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);
}
int nSign = -1;
if (GetVisibilityAt(i))
nSign = 1;
else
nSign = 0;
strText.Format(_T("Show_%d"), i + 1);
posItem = xmlTree.Insert(strText, posItemOutLine, posItem);
{
strText.Format(_T("点%d是否显示"), i + 1);
xmlTree.SetAttribute(posItem, _T("name"), strText);
strText.Format(_T("%d"), nSign);
xmlTree.SetItemText(posItem, strText);
}
}
}
POSITION posItemHole = posItemOutLine;
int nHoles = m_lstHoles.Length();
if(nHoles > 0)
{
posItemHole = xmlTree.Insert(_T("Holes"), posRoot, posItemOutLine);
xmlTree.SetAttribute(posItemHole, _T("name"), _T("板洞参数"));
XPoly2D poly;
CString sHoleNum;
POSITION posItemHoleNum = NULL;
for(int i = 0; i < nHoles; i++)
{
sHoleNum.Format(_T("第%d个洞"), i + 1);
posItemHoleNum = xmlTree.Insert(sHoleNum, posItemHole, posItemHoleNum);
poly = m_lstHoles[i];
int nTotal = poly.Length();
POSITION posItem = NULL;
TADSGePoint3d ptNode;
for (int i = 0; i < nTotal; i++)
{
ptNode = *poly[i];
// 对点进行坐标变换
ptNode.TransformBy(mat);
strText.Format(_T("Point_%d"), i + 1);
posItem = xmlTree.Insert(strText, posItemHoleNum, 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, posItemHoleNum, 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);
}
}
}
}
POSITION posItemId = xmlTree.Insert(_T("Object_ID"), posRoot, posItemHole);
{
xmlTree.SetAttribute(posItemId, _T("name"), _T("ID"));
xmlTree.SetAttribute(posItemId, _T("comment"), _T("平板ID"));
strText.Format(_T("%ld"), objectId().asOldId());
xmlTree.SetItemText(posItemId, strText);
}
CString strBase = TDbEntity::GetXml(mat);
CString strXml = xmlTree.GetXml();
int nIndex = strXml.Find(_T("<Object_ID"));
if (nIndex != -1)
{
strXml.Insert(nIndex, strBase);
}
return strXml;
}
//填充图层id存到xdata中,必须在deep时写出,注意id必须是hard类型
Acad::ErrorStatus TDbSlab::subDeepClone(AcDbObject* pOwnerObject,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbEntity::subDeepClone(pOwnerObject, pClonedObject, idMap, isPrimary);
if (pClonedObject != NULL)
{
TDbEntity* pBase = TDbEntity::cast(pClonedObject);
if (pBase != NULL)
{
TDbXDataMap* pMapClone = pBase->GetSpecialtyData();
if ( pMapClone != NULL)
{
m_XDataMap.BeginCloneXlation(pMapClone,idMap);
}
}
}
return es;
}
Acad::ErrorStatus TDbSlab::subWblockClone( AcRxObject* pOwnerObject,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbEntity::subWblockClone(pOwnerObject, pClonedObject, idMap, isPrimary);
if (pClonedObject != NULL)
{
TDbEntity* pBase = TDbEntity::cast(pClonedObject);
if (pBase != NULL)
{
TDbXDataMap* pMapClone = pBase->GetSpecialtyData();
if ( pMapClone != NULL)
{
m_XDataMap.BeginCloneXlation(pMapClone,idMap);
}
}
}
return es;
}
int EditSlab0(AcDbObjectId id);
void InitDbSlab(BOOL bTrue)
{
AecObjectEditMethod pOldEdit=NULL;
if(bTrue) {
TDbSlab::rxInit();
pOldEdit=TDbSlab::SetEditMethod(EditSlab0);
acrxBuildClassHierarchy();
TDbSlab::InitMatchProtocol(TRUE);
} else {
TDbSlab::InitMatchProtocol(FALSE);
TDbSlab::SetEditMethod(pOldEdit);
deleteAcRxClass(TDbSlab::desc());
}
}
// Command:编辑平板
int EditSlab0(AcDbObjectId id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbSlab, pStep);
if(!pStep)
return RTERROR;
//判断是不是上海城建叠合板实体
CString strCmdName(_T(""));
TDbXDataMap map;
map.Read(pStep, _T("TGZZCL"));
map.GetAt(_T("cmdName"), strCmdName);
if (strCmdName == _T("TGZZCLBD"))
{
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) {
const TCHAR *szPrompt1=_T("\n选择 [加洞(A)/减洞(D)/加边界(P)/减边界(M)/边可见性(E)/板厚(H)/标高(T)/参数列表(L)]<退出>:");
XString sKeyword;
int nRet=0;
INITGET_BEG(0, _T("A D P M E H T L"));
nRet=ads_getkword(szPrompt1, sKeyword);
INITGET_END();
if(nRet!=RTNORM)
break;
if(sKeyword[0]==_T('H')) {
double nRailHeight=pStep->GetThickness();
nRet=GetReal(_T("\n板厚"), nRailHeight);
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('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();
} else if(sKeyword[0]==_T('A')) {
RBList mask=GetClosedCurveMask();
PickSet ss(SS_FREE);
const TCHAR *szPrompt[2]={_T("选择封闭的多段线或圆:"), _T("移除已选的多段线或圆")};
int nRet=ss.Get(_T(":$"), szPrompt, NULL,mask);
if(nRet==RTCAN)
return nRet;
else if(nRet==RTNORM) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
XVector3D vtNorm=pStep->GetNormal();
long len=ss.Length();
for(long i=0L; i<len; i++) {
Entity ent=ss[i];
XVector3D vt(0,0,1);
ent.GetData(210,&vt);
if(vt.AsAcGeVector3d()!=vtNorm.AsAcGeVector3d())
continue;
XPoly2D polyHole(ent);
if(!polyHole) {
continue;
}
pStep->AddHole(polyHole);
}
pStep->downgradeOpen();
int bDelObj;
VERIFY(xg_getvar(_T("DELOBJ"), &bDelObj)==RTNORM);
if(bDelObj) {
ss.Delete();
}
}
} else if(sKeyword[0]==_T('D')) {
XPushVar<int> tVar(_T("OSMODE"), OS_NEA);
XPoint ptEdge;
int nRet=ads_getpoint(NULL, _T("\n请要移除的洞:"), ptEdge);
if(nRet==RTCAN)
return nRet;
else if(nRet==RTNORM) {
Adesk::UInt32 nTestCode=0;
if(!pStep->HitTestOnHole(Ucs2Ecs(ptEdge, pStep->GetNormal()), &nTestCode)) {
adsout << _T("\n请正确点取!");
} else {
nTestCode >>= 16;
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->RemoveHole(nTestCode);
pStep->downgradeOpen();
}
}
} else if(sKeyword[0]==_T('E')) {
XPushVar<int> tVar(_T("OSMODE"), OS_NEA);
XPoint ptEdge;
int nRet=RTNORM;
INITGET_BEG(0, _T("Y N"));
nRet=ads_getpoint(NULL, _T("\n点取不可见的边或 [全可见(Y)/全不可见(N)]<退出>:"), ptEdge);
INITGET_END();
if(nRet==RTCAN)
return nRet;
else if(nRet==RTNORM) {
Adesk::UInt16 nTestCode=pStep->HitTestOnOutline(ptEdge);
if(nTestCode<0) {
adsout << _T("\n请正确点取!");
} else {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
BOOL bVis=pStep->GetVisibilityAt(nTestCode);
pStep->SetVisibilityAt(nTestCode, !bVis);
pStep->downgradeOpen();
}
} else if(nRet==RTKWORD) {
XString sInput;
ads_getinput(sInput);
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
int nEdgeNum=pStep->GetEdgeNum();
for(int n=0; n<nEdgeNum; n++)
pStep->SetVisibilityAt(n, sInput[0]==_T('Y'));
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('P') || sKeyword[0]==_T('M')) {
const TCHAR *szPrompts[2]={
_T("\n选择一封闭的多段线(或圆)并入当前的边界:"),
_T("\n选择一封闭的多段线(或圆)以便从当前边界中减去:")
};
int nSel=(sKeyword[0]==_T('P')? 0 : 1);
Entity ent;
RBList mask=GetClosedCurveMask();
if(SelectEntity(szPrompts[nSel], ent, mask)==RTNORM) {
XVector3D vtNorm=pStep->GetNormal();
XVector3D vt(0,0,1);
ent.GetData(210,&vt);
XPoly2D poly2d(ent);
if(vt.AsAcGeVector3d()==vtNorm.AsAcGeVector3d() && !!poly2d) {
XPoly2D polySrc(1);
DList<XPoly2D> lstDest;
polySrc=pStep->GetOutline();
polySrc.SetElevation(0.0);
poly2d.SetElevation(0.0);
if(PolyBoolOper(polySrc, poly2d, lstDest, nSel? AcDb::kBoolSubtract: AcDb::kBoolUnite) && lstDest.Length()==1) {
if(pStep->upgradeOpen()==Acad::eOk) {
lstDest[0]->Compress();
if(lstDest[0]->PathArea()>0.0)
lstDest[0]->Reverse();
double nElev=pStep->GetElevation();
pStep->SetOutline(*lstDest[0]);
pStep->SetElevation(nElev);
pStep->SetVisibilityAll(TRUE);
pStep->downgradeOpen();
ent.Delete();
}
}
}
}
}
}
}
OPENOBJ_END();
return RTNORM;
}