Files
envi-code/SourceCode/Code2026/tg_shs/shs_kernal/dbHandRail.cpp
T
gjm 164968b62e chore
把非utf8-bom编码的cpp/h文件改为 utf8 bom 编码, msvc识别utf8编码时,如果不是bom格式的,会使用当前cp_oem来解码.
2026-10-04 00:04:20 +08:00

1349 lines
37 KiB
C++

#include "stdafx.h"
#include "TDbColumn.h"
/////////////////////////////////////////////////////////////
// 扶手对象类
/////////////////////////////////////////////////////////////
const Adesk::UInt8 TDbHandRail::g_nVersion = 2;
ACRX_DXF_DEFINE_MEMBERS(ATSHandRail, ATSPolyPathEnt, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_HANDRAIL, "ATS_HANDRAIL图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbHandRail);
TDbHandRail::TDbHandRail()
{
m_nWidth=_AS_SYS_UNIT(60);
m_nThick=_AS_SYS_UNIT(120.0);
m_nHeight=_AS_SYS_UNIT(900);
m_nStyle=RS_RAIL1;
m_nAlignment=AL_CENTER;
m_nDrawMode=DRAW_2D|DRAW_3D;
m_pTempStair=NULL;
}
TDbHandRail::~TDbHandRail()
{
}
BOOL TDbHandRail::IsValid() const
{
BOOL bRet=TDbPolyPathEnt::IsValid();
bRet=(m_nHeight>_DIST_SNAP && m_nThick>_DIST_SNAP &&
m_nWidth>_DIST_SNAP); //扶手高和扶手宽
return bRet;
}
Acad::ErrorStatus
TDbHandRail::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
void TDbHandRail::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbPolyPathEnt::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbHandRail *pSrc=TDbHandRail::cast(pSrcEntity);
if(pSrc) {
m_nStyle=pSrc->m_nStyle; //扶手标志, 0--为自定义
m_nAlignment=pSrc->m_nAlignment; //对齐方式: 0--中间;1-左;2-右
if(database()==NULL||
pSrcEntity->database()==NULL||
database()==pSrcEntity->database())//add by whl on 060317
{
m_idCustStyle=pSrc->m_idCustStyle; //自定义扶手
}
m_nHeight=pSrc->m_nHeight;
m_nWidth=pSrc->m_nWidth;
m_nThick=pSrc->m_nThick; //扶手顶高和扶手宽和扶手厚
m_nDrawMode=pSrc->m_nDrawMode; // DRAW_2D, DRAW_3D, DRAW_2D+DRAW_3D
}
}
// 从DWG读入数据:
Acad::ErrorStatus TDbHandRail::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbPolyPathEnt::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;
}
Adesk::UInt8 nRailFlag;
pFiler->readItem(&nRailFlag);
m_nStyle=(TRailStyle)nRailFlag;
if(m_nStyle==RS_CUSTOM)
pFiler->readItem(&m_idCustStyle);
m_polyBase.Reset();
Adesk::UInt8 nPolyFlag;
pFiler->readItem(&nPolyFlag);
m_polyBase.SetFlag(nPolyFlag);
Adesk::UInt16 m_nCount=0;
pFiler->readItem(&m_nCount);
for(Adesk::UInt16 i=0; i<m_nCount; i++) {
AcGePoint3d pt;
double nBulge=0.0;
pFiler->readItem(&pt);
pFiler->readItem(&nBulge);
m_polyBase.AppendNode(XPoint(pt), nBulge);
}
pFiler->readItem(&m_nWidth);
if(nVer>1)
pFiler->readItem(&m_nThick);
pFiler->readItem(&m_nHeight);
pFiler->readItem(&m_nAlignment);
pFiler->readItem(&m_nDrawMode);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbHandRail::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbPolyPathEnt::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
pFiler->writeItem((Adesk::UInt8)m_nStyle);
if(m_nStyle==RS_CUSTOM)
pFiler->writeItem(m_idCustStyle);
pFiler->writeItem((Adesk::UInt8) m_polyBase.GetFlag());
Adesk::UInt16 nCount=m_polyBase.Length();
pFiler->writeItem(nCount);
for(Adesk::UInt16 i=0; i<nCount; i++) {
pFiler->writeItem((AcGePoint3d &)m_polyBase[i]);
pFiler->writeItem(m_polyBase.GetBulge(i));
}
pFiler->writeItem(m_nWidth);
pFiler->writeItem(m_nThick);
pFiler->writeItem(m_nHeight);
pFiler->writeItem(m_nAlignment);
pFiler->writeItem(m_nDrawMode);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbHandRail::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbPolyPathEnt::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbHandRail"))) {
return Acad::eBadDxfSequence;
}
int fieldsFlags=0;
resbuf rb;
int n1, n2, n3, n4;
double r1, r2, r3;
DList<XPoint> pts;
DList<double> bulges;
while ((es == Acad::eOk)
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
switch (rb.restype) {
case AcDb::kDxfInt16:
n1=rb.resval.rint;
fieldsFlags |= 0x01;
break;
case AcDb::kDxfInt16+1:
n2=rb.resval.rint;
fieldsFlags |= 0x02;
break;
case AcDb::kDxfInt16+2:
n3=rb.resval.rint;
fieldsFlags |= 0x04;
break;
case AcDb::kDxfInt16+3:
n4=rb.resval.rint;
fieldsFlags |= 0x08;
break;
case AcDb::kDxfReal:
r1=rb.resval.rreal;
fieldsFlags |= 0x10;
break;
case AcDb::kDxfReal+1:
r2=rb.resval.rreal;
fieldsFlags |= 0x20;
break;
case AcDb::kDxfReal+2:
r3=rb.resval.rreal;
fieldsFlags |= 0x40;
break;
case AcDb::kDxfXCoord:
pts.Append(new XPoint(rb.resval.rpoint));
break;
case AcDb::kDxfAngle:
bulges.Append(new double(rb.resval.rreal));
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;
}
if (fieldsFlags&0x01)
m_nStyle=(TRailStyle)n1;
if(fieldsFlags&0x02)
m_nAlignment=n2;
if(fieldsFlags&0x04)
m_nDrawMode=n3;
if (fieldsFlags&0x08)
m_polyBase.SetFlag(n4);
if (fieldsFlags&0x10)
m_nHeight=r1;
if(fieldsFlags&0x20)
m_nWidth=r2;
if(fieldsFlags&0x40)
m_nThick=r3;
m_polyBase.Reset();
for(int i=0; i<pts.Length(); i++) {
m_polyBase.AppendNode(*pts[i], *bulges[i]);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbHandRail::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es= TDbPolyPathEnt::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbHandRail"));
assert(es == Acad::eOk);
pFiler->writeInt16(AcDb::kDxfInt16, m_nStyle);
pFiler->writeInt16(AcDb::kDxfInt16+1,m_nAlignment);
pFiler->writeInt16(AcDb::kDxfInt16+2, m_nDrawMode);
pFiler->writeInt16(AcDb::kDxfInt16+3, m_polyBase.GetFlag());
pFiler->writeDouble(AcDb::kDxfReal, m_nHeight);
pFiler->writeDouble(AcDb::kDxfReal+1, m_nWidth);
pFiler->writeDouble(AcDb::kDxfReal+2, m_nThick);
for(int i=0; i<m_polyBase.Length(); i++)
{
pFiler->writePoint3d(AcDb::kDxfXCoord, m_polyBase[i]);
pFiler->writeDouble(AcDb::kDxfAngle, m_polyBase.GetBulge(i));
}
return es;
}
// -----------------------------------------------------------------------
// Overriden functions for edit
// to do:
// 允许通过夹点改变边界
Acad::ErrorStatus TDbHandRail::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
int nEdgeNum=GetEdgeNum();
XPoly2D poly2d;
GetBaseline2d(poly2d);
for(int i=0; i<poly2d.Length(); i++) {
gripPoints.append(*poly2d[i]);
}
//边上的夹点
for(i=0; i<nEdgeNum; i++) {
XCurveSegment edge;
poly2d.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 TDbHandRail::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
assertReadEnabled();
XPoly2D poly2d;
GetBaseline2d(poly2d);
for(int i=0; i<poly2d.Length(); i++) {
stretchPoints.append(*poly2d[i]);
}
return Acad::eOk;
}
// Active when being rotated, scaled, moved, etc.
Acad::ErrorStatus TDbHandRail::subTransformBy(const AcGeMatrix3d& xform)
{
// Modify on 2002/1/30 纠正弧段的镜像问题
Acad::ErrorStatus es = TDbPolyPathEnt::subTransformBy(xform);
if(m_nAlignment==1 || m_nAlignment==2) {
ads_matrix mat;
memcpy(mat, &xform, sizeof(ads_matrix));
if(IsMirrorMatrix(mat)) {
m_nAlignment=3-m_nAlignment;
}
}
return es;
}
// 功能: 夹点操作
Acad::ErrorStatus TDbHandRail::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
XPoly2D poly2d, polyBack(m_polyBase);
GetBaseline2d(poly2d);
m_polyBase=poly2d;
Acad::ErrorStatus es = TDbPolyPathEnt::subMoveGripPointsAt(indices, offset);
if(es!=Acad::eOk) {
m_polyBase=polyBack;
} else {
if(m_polyBase.IsClosed()) {
AS_OPENPOLY(m_polyBase);
}
ASSERT(m_polyBase.Length()==polyBack.Length());
for(int n=0; n<m_polyBase.Length(); n++) {
m_polyBase[n]->z = polyBack[n]->z;
}
}
return es;
}
// 取得夹点说明
Acad::ErrorStatus TDbHandRail::GetGripText(int i, CString &cs) const
{
assertReadEnabled();
Acad::ErrorStatus es=Acad::eOk;
XString sInfo;
XPoly2D poly2d;
GetBaseline2d(poly2d);
if(i<poly2d.Length()) {
sInfo << _T("移动第") << (i+1) << _T("个顶点");
} else {
sInfo << _T("移动第") << (i-poly2d.Length()+1) << _T("条边");
}
cs = sInfo;
return es;
}
// 功能: 夹点操作
Acad::ErrorStatus TDbHandRail::subMoveStretchPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
int nCount=indices.length();
return subMoveGripPointsAt(indices, offset);
}
Acad::ErrorStatus
TDbHandRail::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
assertReadEnabled();
if(!Has3D())
return Acad::eOk;
if(m_nStyle==RS_SLAB || m_nStyle==RS_RAIL1 || m_nStyle==RS_RAIL2) {
XPoly2D polyShape(1);
if(m_nStyle==RS_SLAB || m_nStyle==RS_RAIL1) {
double nShapeHeight;
if(m_nStyle==RS_SLAB) nShapeHeight=m_nHeight;
else nShapeHeight=m_nThick;
polyShape.AppendNode(XPoint(0, m_nHeight-nShapeHeight));
polyShape.AppendNode(XPoint(0, m_nHeight));
polyShape.AppendNode(XPoint(-m_nWidth, m_nHeight));
polyShape.AppendNode(XPoint(-m_nWidth, m_nHeight-nShapeHeight));
} else {
polyShape.AppendNode(XPoint(0, m_nHeight-m_nWidth/2), PI);
polyShape.AppendNode(XPoint(-m_nWidth, m_nHeight-m_nWidth/2), PI);
}
XPoint ptShapeBase;
if(m_nAlignment==AL_LEFT)
ptShapeBase=XPoint(-m_nWidth,0);
else if(m_nAlignment==AL_CENTER)
ptShapeBase=XPoint(-m_nWidth/2, 0);
TDbCurveMesh cvMesh;
cvMesh.setPropertiesFrom(this);
cvMesh.SetBasePoly(m_polyBase);
cvMesh.SetShapePoly(polyShape);
cvMesh.SetShapeBase(ptShapeBase);
TPushProperty vProp(&cvMesh, dc);
if(dc.IsFullExplode())
cvMesh.ExplodeOrDraw3d(dc);
else
dc.DrawEntity(cvMesh);
}
return Acad::eOk;
}
bool TDbHandRail::IsClipMe(const TEntityBase* pEnt)const
{
if(TDbEntity::IsClipMe(pEnt))
return true;
if(pEnt->GetMe()->isKindOf(TDbColumn::desc()))
return true;
return false;
}
Acad::ErrorStatus
TDbHandRail::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
assertReadEnabled();
if(!Has2D())
return Acad::eOk;
XPoly2D lPoly, rPoly;
GetSidePoly2d(lPoly, rPoly);
XCurveStream dcCurve;
(XDcStream &)dcCurve << lPoly << rPoly;
if(!lPoly.IsClosed() && !!lPoly && !!rPoly) {
dcCurve << XLine(*lPoly.Head(), *rPoly.Head())
<< XLine(*lPoly.Tail(), *rPoly.Tail());
}
// 用楼梯剖断线裁剪扶手
if(m_pTempStair)
{
if(m_pTempStair->Get2DFlag()==SF_1SECT||m_pTempStair->Get2DFlag()==SF_UP_SECT)
{
lPoly.SetFlag(0);
rPoly.SetFlag(0);
m_pTempStair->ClipPolyPath(lPoly, rPoly);
dcCurve.m_lstCurves.Reset();
if(lPoly.Length() && rPoly.Length())
(XDcStream &)dcCurve << lPoly << rPoly << XLine(*lPoly.Head(), *rPoly.Head());
}
else
{
m_pTempStair->ClipCurveBySection(dcCurve.m_lstCurves);
}
}
//add by xlc on 080219
else if(m_tempStairArray.physicalLength()>= m_tempStairArray.logicalLength() &&m_tempStairArray.length())
{
int num=m_tempStairArray.length();
for(int n=0; n<num; n++)
{
TDbStair *pStair=(TDbStair*)m_tempStairArray[n];
if(pStair->Get2DFlag()==SF_1SECT||pStair->Get2DFlag()==SF_UP_SECT)
{
lPoly.SetFlag(0);
rPoly.SetFlag(0);
pStair->ClipPolyPath(lPoly, rPoly);
dcCurve.m_lstCurves.Reset();
if(lPoly.Length() && rPoly.Length())
(XDcStream &)dcCurve << lPoly << rPoly << XLine(*lPoly.Head(), *rPoly.Head());
}
else
{
pStair->ClipCurveBySection(dcCurve.m_lstCurves);
}
}
}
else
{
AcDbObjectIdArray idArray;
if(GetHitObjects(idArray)) {
int nLen=idArray.length();
for(int i=0; i<nLen; i++) {
AcDbObjectId id=idArray[i];
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbStair, pEnt);
if(pEnt)
{
if(nLen==1 && (pEnt->Get2DFlag()==SF_1SECT||pEnt->Get2DFlag()==SF_UP_SECT))//上下剖断
{
lPoly.SetFlag(0);
rPoly.SetFlag(0);
pEnt->ClipPolyPath(lPoly, rPoly);
dcCurve.m_lstCurves.Reset();
if(lPoly.Length() && rPoly.Length())
(XDcStream &)dcCurve << lPoly << rPoly << XLine(*lPoly.Head(), *rPoly.Head());
}
else
{
pEnt->ClipCurveBySection(dcCurve.m_lstCurves);
}
}
OPENOBJ_END();
}
}
}
dcCurve.CopyTo(dc);
return Acad::eOk;
}
Acad::ErrorStatus
TDbHandRail::GetExtents2d(XPoint &ptLow, XPoint &ptUp) const
{
assertReadEnabled();
XPoly2D polyCur;
GetBaseline2d(polyCur);
polyCur.GetExtend(ptLow, ptUp);
XPoly2D lPoly, rPoly;
if(polyCur.Offset(-m_nWidth/2.0, lPoly)==RTNORM) {
XPoint pt1, pt2;
lPoly.GetExtend(pt1, pt2);
ptLow=Min(ptLow, pt1);
ptUp=Max(ptUp, pt2);
}
if(polyCur.Offset(m_nWidth/2.0, rPoly)==RTNORM) {
XPoint pt1, pt2;
rPoly.GetExtend(pt1, pt2);
ptLow=Min(ptLow, pt1);
ptUp=Max(ptUp, pt2);
}
ptLow.z=ptUp.z=0.0;
return Acad::eOk;
}
const TCHAR *TDbHandRail::GetDefaultLayer() const
{
return LAY_HANDRAIL;
}
/* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */
void TDbHandRail::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
assertReadEnabled();
lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("扶手")));
lstInfo.Append(new TObjInfoUnit(_T("扶手宽度"), Dist2Str(GetWidth())));
lstInfo.Append(new TObjInfoUnit(_T("扶手高度"), Dist2Str(GetHeight())));
lstInfo.Append(new TObjInfoUnit(_T("扶手长度"), Dist2Str(GetLength())));
lstInfo.Append(new TObjInfoUnit(_T("需要2D"), Has2D()? _T("是") : _T("否")));
lstInfo.Append(new TObjInfoUnit(_T("需要3D"), Has3D()? _T("是") : _T("否")));
const TCHAR *pszShape=_T("未知");
switch(m_nStyle) {
case RS_SLAB: pszShape=_T("栏板"); break;
case RS_RAIL1: pszShape=_T("矩形"); break;
case RS_RAIL2: pszShape=_T("圆形"); break;
}
const TCHAR *pszAlign=_T("中间");
if(m_nAlignment==1)
pszAlign=_T("左");
else if(m_nAlignment==2)
pszAlign=_T("右");
lstInfo.Append(new TObjInfoUnit(_T("扶手形状"), pszShape));
lstInfo.Append(new TObjInfoUnit(_T("对齐方式"), pszAlign));
}
////////////////////////////////////////////////////////////////
BOOL
TDbHandRail::AddVertex(const XPoint &ptAdd)
{
assertWriteEnabled();
XPoint ptOnCurve;
if(GetClosestPoint2d(ptAdd, ptOnCurve)) {
int nPos=HitTestOnRail2d(ptOnCurve);
if(nPos<0) {
nPos = abs(nPos);
nPos--;
XPoly2D poly2d;
GetBaseline2d(poly2d);
XDirectionCurve seg;
poly2d.Nth(nPos, seg);
if(seg.IsMinusArc()) {
XArc ar1=seg.GetArc(), ar2=seg.GetArc();
ar1.SetAngleByPoints(seg.EndPoint(), ptOnCurve);
ar2.SetAngleByPoints(ptOnCurve, seg.StartPoint());
ptOnCurve.z = m_polyBase[nPos]->z;
m_polyBase.SetBulge(nPos, - ar2.Bulge());
m_polyBase.InsertNodeAt(nPos+1, ptOnCurve, ar1.Bulge());
} else {
XCurveSegment seg1=seg, seg2=seg;
seg1.SetPoints(seg.StartPoint(), ptOnCurve);
seg2.SetPoints(ptOnCurve, seg.EndPoint());
ptOnCurve.z = m_polyBase[nPos]->z;
m_polyBase.SetBulge(nPos, seg1.GetBulge());
m_polyBase.InsertNodeAt(nPos+1, ptOnCurve, seg2.GetBulge());
}
return TRUE;
}
}
return FALSE;
}
BOOL
TDbHandRail::RemoveVertexAt(int nPos)
{
assertWriteEnabled();
ASSERT(nPos>=0 && nPos<m_polyBase.Length());
m_polyBase.Remove(nPos);
m_polyBase.RemoveBugle(nPos);
return TRUE;
}
// 取得命中的可能的对象(用矩形快速命中)
int
TDbHandRail::GetHitObjects(AcDbObjectIdArray &idArray) const
{
assertReadEnabled();
AcDbObjectId idOwner=ownerId();
if(!idOwner)
return 0;
XPoint ptMin, ptMax;
GetExtents2d(ptMin, ptMax);
CRect rect0(AS_INT(_AS_MM(ptMin.x)),
AS_INT(_AS_MM(ptMin.y)), AS_INT(_AS_MM(ptMax.x)), AS_INT(_AS_MM(ptMax.y)));
OPENOBJ_BEGIN(idOwner, AcDb::kForRead, AcDbBlockTableRecord, pModel);
if(!pModel)
return 0;
AcDbBlockTableRecordIterator *pIterator=NULL;
VERIFY(pModel->newIterator(pIterator)==Acad::eOk && pIterator);
for (pIterator->start(); !pIterator->done(); pIterator->step()) {
AcDbEntity *pEntity=NULL;
Acad::ErrorStatus es=pIterator->getEntity(pEntity, AcDb::kForRead);
if(es!=Acad::eOk) continue;
ASSERT(pEntity);
XDbObject vTemp(pEntity);
//不处理不可见的实体
if (pEntity->visibility() == AcDb::kInvisible)
continue;
TDbEntity *pEnt=TDbEntity::cast(pEntity);
if(pEnt && (pEnt->isKindOf(TDbStair::desc()) ||
pEnt->isKindOf(TDbSlab::desc()) ||
pEnt->isKindOf(TDbAscent::desc()) ||
pEnt->isKindOf(TDbStep::desc()))) { //Status: 没有进行标准层的过滤
XPoint ptLow, ptUp;
pEnt->GetExtents2d(ptLow, ptUp);
CRect rect(AS_INT(_AS_MM(ptLow.x)),
AS_INT(_AS_MM(ptLow.y)),
AS_INT(_AS_MM(ptUp.x)),
AS_INT(_AS_MM(ptUp.y)));
CRect rectInt;
if(rectInt.IntersectRect(rect, rect0)) {
idArray.append(pEnt->objectId());
}
}
}
delete pIterator;
OPENOBJ_END();
return idArray.length();
}
// 取得用于遮挡其它物体的轨迹(2D)
BOOL
TDbHandRail::GetPolyTrace(XPoly2D &polyTrace) const
{
assertReadEnabled();
XPoly2D polyOut, polyIn;
GetSidePoly2d(polyIn, polyOut);
if(polyIn.IsClosed()) {
AS_OPENPOLY(polyOut);
AS_OPENPOLY(polyIn);
}
polyIn.Reverse();
polyTrace=polyOut;
polyTrace.SetFlag(1);
for(int i=0; i<polyIn.Length(); i++)
polyTrace.AppendNode(*polyIn[i], polyIn.GetBulge(i));
return TRUE;
}
void
TDbHandRail::ClipCurveByTrace(DList<XCurveSegment> &lnSet) const
{
assertReadEnabled();
XPoly2D polyTrace(1);
//modify by xlc on 090402 解决扶手线自相交的问题
//if(GetPolyTrace(polyTrace) && !!polyTrace)
XPoly2D polyOut, polyIn;
GetSidePoly2d(polyIn, polyOut);
if(polyIn.IsClosed()) {
AS_OPENPOLY(polyOut);
AS_OPENPOLY(polyIn);
}
if(polyOut.Length()==polyIn.Length()
&&polyOut.Length()>1)
{
for(int i=0;i<polyOut.Length()-1;i++)
{
polyTrace.Reset();
polyTrace.AppendNode(*polyOut[i],polyOut.GetBulge(i));
polyTrace.AppendNode(*polyOut[i+1],0);
//modify by xlc on 090526 解决了圆弧梯段加扶手时裁剪不正确的问题
// polyTrace.AppendNode(*polyIn[i+1],*polyOut.bulges[i+1]);
// polyTrace.AppendNode(*polyIn[i],0);
XPoly2D poly;
poly.AppendNode(*polyIn[i],polyIn.GetBulge(i));
poly.AppendNode(*polyIn[i+1],polyIn.GetBulge(i + 1));
poly.Reverse ();
polyTrace.AppendNode(*poly[0],poly.GetBulge(0));
polyTrace.AppendNode(*poly[1],poly.GetBulge(1));
DList<XCurveSegment> lstIn, lstOut(0), lstEdge(0);
PolyClip(lnSet, polyTrace, lstIn, lstOut, lstEdge);
lnSet.Reset();
for(int k=0; k<lstOut.Length(); k++)
lnSet.Append(lstOut[k]);
for(k=0; k<lstEdge.Length(); k++)
lnSet.Append(lstEdge[k]);
}
}
}
// static 取得被多段线(CP方式)命中的扶手
int
TDbHandRail::GetRailsByCP(const XPoly2D &poly, AcDbObjectId idOwner, AcDbObjectIdArray &idArray)
{
ASSERT(poly.IsClosed());
if(!idOwner)
return 0;
XPoly2D polyPath=poly;
polyPath.SetElevation(0.0);
XPoint ptMin, ptMax;
polyPath.GetExtend(ptMin, ptMax);
CRect rect0(AS_INT(_AS_MM(ptMin.x)), AS_INT(_AS_MM(ptMin.y)),
AS_INT(_AS_MM(ptMax.x)), AS_INT(_AS_MM(ptMax.y)));
OPENOBJ_BEGIN(idOwner, AcDb::kForRead, AcDbBlockTableRecord, pModel);
if(!pModel)
return 0;
AcDbBlockTableRecordIterator *pIterator=NULL;
VERIFY(pModel->newIterator(pIterator)==Acad::eOk && pIterator);
for (pIterator->start(); !pIterator->done(); pIterator->step()) {
AcDbEntity *pEntity=NULL;
Acad::ErrorStatus es=pIterator->getEntity(pEntity, AcDb::kForRead);
if(es!=Acad::eOk) continue;
ASSERT(pEntity);
XDbObject vTemp(pEntity);
//不处理不可见的实体
if (pEntity->visibility() == AcDb::kInvisible)
continue;
TDbHandRail *pEnt=TDbHandRail::cast(pEntity);
if(pEnt) {
XPoly2D polyTrace(1);
pEnt->GetPolyTrace(polyTrace);
if(!polyTrace) continue;
XPoint ptLow, ptUp;
polyTrace.GetExtend(ptLow, ptUp);
CRect rect(AS_INT(_AS_MM(ptLow.x)), AS_INT(_AS_MM(ptLow.y)),
AS_INT(_AS_MM(ptUp.x)), AS_INT(_AS_MM(ptUp.y)));
CRect rectInt;
if(rectInt.IntersectRect(rect, rect0)) {
idArray.append(pEnt->objectId());
}
}
}
delete pIterator;
OPENOBJ_END();
return idArray.length();
}
// >0 命中顶点; <0 命中边; 0--没有命中
// abs(nRet)-1 为命中目标序号
int
TDbHandRail::HitTestOnRail2d(const XPoint &ptTest, double nTol) const
{
assertReadEnabled();
XPoint pt2d=ptTest;
pt2d.z=0;
for(int i=0; i<m_polyBase.Length(); i++) {
if(pt2d.Distance2d(m_polyBase[i])<nTol)
return (i+1);
}
XPushPrec vTemp(nTol, _angSnap);
int nEdgeNum=GetEdgeNum();
for(i=0; i<nEdgeNum; i++) {
XCurveSegment seg;
m_polyBase.Nth(i, seg);
seg.SetElevation(0.0);
if((pt2d&seg)==PR_INSIDE)
return (-i-1);
}
return 0;
}
Acad::ErrorStatus
TDbHandRail::SetPathPoly(const XPoly2D &polyPath,const AcGeVector3d&normal)
{
assertWriteEnabled();
m_polyBase=polyPath;
SetNormal(normal);
return Acad::eOk;
}
Acad::ErrorStatus
TDbHandRail::GetPathPoly(XPoly2D &polyPath,AcGeVector3d &normal) const
{
assertReadEnabled();
polyPath=m_polyBase;
normal=GetNormal().AsAcGeVector3d();
return Acad::eOk;
}
Acad::ErrorStatus
TDbHandRail::GetBindPath(XPoly2D &polyPath,AcGeVector3d &normal) const
{
assertReadEnabled();
XPoly2D polyCur;
GetBaseline2d(polyCur);
if(m_nAlignment==AL_LEFT) {
polyCur.Offset(m_nWidth/2, polyPath);
} else if(m_nAlignment==AL_RIGHT) {
polyCur.Offset(-m_nWidth/2, polyPath);
} else {
polyPath=polyCur;
}
if(polyCur.IsClosed()) {
AS_OPENPOLY(polyPath);
}
if(polyPath.Length()==m_polyBase.Length()) {
for(int i=0; i<m_polyBase.Length(); i++)
polyPath[i]->z = m_polyBase[i].z;
}
normal=GetNormal().AsAcGeVector3d();
return Acad::eOk;
}
void
TDbHandRail::GetSidePoly2d(XPoly2D &lPoly, XPoly2D &rPoly) const
{
assertReadEnabled();
XPoly2D polyCur;
GetBaseline2d(polyCur);
polyCur.Compress();
if(m_nAlignment==AL_LEFT) {
lPoly=polyCur;
lPoly.Offset(m_nWidth, rPoly);
} else if(m_nAlignment==AL_RIGHT) {
rPoly=polyCur;
rPoly.Offset(-m_nWidth, lPoly);
} else {
polyCur.Offset(-m_nWidth/2.0, lPoly);
polyCur.Offset(m_nWidth/2.0, rPoly);
}
}
BOOL
TDbHandRail::GetClosestPoint2d(const XPoint &ptTest, XPoint &ptOnCurve) const
{
assertReadEnabled();
AcDbPolyline pline;
XPoly2D poly2d;
GetBaseline2d(poly2d);
PolyConvert(poly2d, pline);
XPoint pt2d=ptTest;
pt2d.z=0;
return (pline.getClosestPointTo(pt2d, ptOnCurve)==Acad::eOk);
}
void
TDbHandRail::GetBaseline2d(XPoly2D &poly2d) const
{
assertReadEnabled();
poly2d=m_polyBase;
poly2d.SetElevation(0.0);
if (poly2d.Head() == NULL ||
poly2d.Tail() == NULL)
{
return;
}
if(*poly2d.Head() == *poly2d.Tail())
{
poly2d.SetFlag(1);
int nLast=poly2d.Length()-1;
poly2d.Remove(nLast);
poly2d.RemoveBugle(nLast);
}
}
void
TDbHandRail::UpdateHitObjects() const
{
assertReadEnabled();
AcDbObjectIdArray idArray;
if(GetHitObjects(idArray)) {
int nCount=idArray.length();
for(int n=0; n<nCount; n++) {
AcDbObjectId idEnt=idArray[n];
OPENOBJ_BEGIN(idEnt, AcDb::kForWrite, TDbEntity, pEnt);
if(pEnt)
pEnt->recordGraphicsModified();
OPENOBJ_END();
}
}
}
////////////////////////////////////////////////////////////////
void
TDbHandRail::SetTempStair(const TDbStair *pStair)
{
m_pTempStair=(TDbStair *)pStair;
}
//add by xlc on 080219
void
TDbHandRail::AddTempStair(const TDbStair *pStair)
{
if(pStair)
m_tempStairArray.append((void *)pStair);
}
Adesk::UInt8
TDbHandRail::GetAlignment() const
{
assertReadEnabled();
return m_nAlignment;
}
BOOL
TDbHandRail::Has2D() const
{
assertReadEnabled();
return ((m_nDrawMode&DRAW_2D)!=0);
}
BOOL
TDbHandRail::Has3D() const
{
assertReadEnabled();
return ((m_nDrawMode&DRAW_3D)!=0);
}
double
TDbHandRail::GetElevationAt(int idx) const
{
assertReadEnabled();
if(idx<0)
idx=0;
if(idx>=m_polyBase.Length())
idx = m_polyBase.Length()-1;
return m_polyBase[idx].z;
}
double
TDbHandRail::GetSweepAngleAt(int idx) const
{
assertReadEnabled();
if(idx<0)
idx=0;
if(idx>=m_polyBase.Length())
idx = m_polyBase.Length()-1;
return m_polyBase.GetBulge(idx);
}
int
TDbHandRail::GetEdgeNum() const
{
assertReadEnabled();
return m_polyBase.TotalSegments();
}
AcDbObjectId
TDbHandRail::GetCustStyle() const
{
assertReadEnabled();
return m_idCustStyle;
}
TDbHandRail::TRailStyle
TDbHandRail::GetStyle() const
{
assertReadEnabled();
return m_nStyle;
}
void
TDbHandRail::SetStyle(TRailStyle ns, AcDbObjectId id)
{
assertWriteEnabled();
m_nStyle = ns;
m_idCustStyle=id;
}
double
TDbHandRail::GetHeight() const
{
assertReadEnabled();
return m_nHeight;
}
double
TDbHandRail::GetWidth() const
{
assertReadEnabled();
return m_nWidth;
}
double
TDbHandRail::GetThickness() const
{
assertReadEnabled();
return m_nThick;
}
double
TDbHandRail::GetLength() const
{
assertReadEnabled();
return m_polyBase.Distance3d();
}
const XPoly2D &
TDbHandRail::GetOutline() const
{
assertReadEnabled();
return m_polyBase;
}
void
TDbHandRail::SetHas2D(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nDrawMode |= DRAW_2D;
else
m_nDrawMode &= ~DRAW_2D;
}
void
TDbHandRail::SetHas3D(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nDrawMode |= DRAW_3D;
else
m_nDrawMode &= ~DRAW_3D;
}
void
TDbHandRail::SetHeight(double h)
{
assertWriteEnabled();
m_nHeight=h;
}
void
TDbHandRail::SetWidth(double w)
{
assertWriteEnabled();
m_nWidth = w;
}
void
TDbHandRail::SetThickness(double w)
{
assertWriteEnabled();
m_nThick = w;
}
void
TDbHandRail::SetOutline(const XPoly2D &poly)
{
assertWriteEnabled();
m_polyBase = poly;
}
void
TDbHandRail::SetElevationAt(int idx, double nElev)
{
assertWriteEnabled();
if(idx<0)
idx=0;
if(idx>=m_polyBase.Length())
idx = m_polyBase.Length()-1;
m_polyBase[idx]->z=nElev;
}
void
TDbHandRail::SetSweepAngleAt(int idx, double nAng)
{
assertWriteEnabled();
if(idx<0)
idx=0;
if(idx>=m_polyBase.Length())
idx = m_polyBase.Length()-1;
m_polyBase.SetBulge(idx, nAng);
}
void
TDbHandRail::SetAlignment(Adesk::UInt8 nAlign)
{
assertWriteEnabled();
m_nAlignment = nAlign;
}
int EditHandRail0(AcDbObjectId id);
void InitDbHandRail(BOOL bTrue)
{
AecObjectEditMethod pOldEdit=NULL;
if(bTrue) {
TDbHandRail::rxInit();
pOldEdit=TDbHandRail::SetEditMethod(EditHandRail0);
acrxBuildClassHierarchy();
TDbHandRail::InitMatchProtocol(TRUE);
} else {
TDbHandRail::InitMatchProtocol(FALSE);
TDbHandRail::SetEditMethod(pOldEdit);
deleteAcRxClass(TDbHandRail::desc());
}
}
// 编辑扶手
int EditHandRail0(AcDbObjectId id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbHandRail, pStep);
if(!pStep)
return RTERROR;
while(1) {
const TCHAR *szPrompt1=_T("\n选择 [加点(A)/删点(D)/改点(S)/截面(P)/宽度(W)/厚度(T)/顶高(H)/对齐(E)/二维(2)/三维(3)]<退出>:");
XString sKeyword;
int nRet=0;
INITGET_BEG(0, _T("A D S P W T H E 2 3 L"));
nRet=ads_getkword(szPrompt1, sKeyword);
INITGET_END();
if(nRet!=RTNORM)
break;
if(sKeyword[0]==_T('A')) {
int nOsMode=0;
xg_getvar(_T("OSMODE"), &nOsMode);
nOsMode &= ~0x4000;
nOsMode |= OS_INT;
XPushVar<int> tVar(_T("OSMODE"), nOsMode);
XPoint ptAdd;
if(XGetPoint(NULL, _T("\n点取新的顶点位置"), ptAdd)==RTNORM) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
if(!pStep->AddVertex(ptAdd)) {
adsout << _T("\n请正确点取!");
}
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('D')) {
XPushVar<int> osmode(_T("OSMODE"), OS_NOD);
XPoint ptVert;
while(ads_getpoint(NULL, _T("\n选取顶点: "), ptVert)==RTNORM) {
int nPos=pStep->HitTestOnRail2d(ptVert);
if(nPos>0) {
nPos--;
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->RemoveVertexAt(nPos);
pStep->downgradeOpen();
}
}
} else if(sKeyword[0]==_T('S')) {
XPushVar<int> osmode(_T("OSMODE"), OS_NOD);
XPoint ptVert;
while(ads_getpoint(NULL, _T("\n选取顶点: "), ptVert)==RTNORM) {
int nPos=pStep->HitTestOnRail2d(ptVert);
if(nPos>0) {
nPos--;
if(nPos==0) {
XPoly2D poly2d;
pStep->GetBaseline2d(poly2d);
if(poly2d.IsClosed()) {
int nAns=YesNoQuestion(_T("\n起点和终点的平面投影相同,您指的是起点吗"));
if(nAns==RTCAN)
continue;
else if(nAns==Q_NO)
nPos = poly2d.Length();
}
}
double nElev=pStep->GetElevationAt(nPos);
adsout << _T("\n改夹角[A]/点取[P]/输入顶点标高<")
<< Dist2Str(nElev)
<< _T(">: ");
int nCode;
INITGET_BEG(0, _T("A P"));
nCode=ads_getreal(_T(""), &nElev);
INITGET_END();
if(nCode==RTKWORD) {
TCHAR szKey[80]=_T("");
ads_getinput(szKey);
if(szKey[0]==_T('P')) {
XPushVar<int> osMode(_T("OSMODE"), OS_NEA);
XPoint ptElev;
nCode=ads_getpoint(NULL, _T("\n点取参照物:"), ptElev);
if(nCode==RTNORM) {
nElev=ptElev.z;
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetElevationAt(nPos, nElev);
pStep->downgradeOpen();
}
} else if(szKey[0]==_T('A')) {
double nOldAng=pStep->GetSweepAngleAt(nPos)*180.0/PI;
nCode=GetReal(_T("\n输入夹角"), nOldAng);
if(nCode==RTNORM) {
nOldAng *= PI/180.0;
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetSweepAngleAt(nPos, nOldAng);
pStep->downgradeOpen();
}
}
} else if(nCode==RTNORM) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetElevationAt(nPos, nElev);
pStep->downgradeOpen();
}
} else {
adsout << _T("\n请正确点取!");
}
}
} else if(sKeyword[0]==_T('P')) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
TDbHandRail::TRailStyle ns=pStep->GetStyle();
if(ns==TDbHandRail::RS_SLAB) ns=TDbHandRail::RS_RAIL1;
else if(ns==TDbHandRail::RS_RAIL1) ns=TDbHandRail::RS_RAIL2;
else ns=TDbHandRail::RS_SLAB;
pStep->SetStyle(ns);
pStep->downgradeOpen();
} else if(sKeyword[0]==_T('W')) {
double nWidth=pStep->GetWidth();
nRet=GetReal(_T("\n扶手宽度"), nWidth, RSG_NOZERO|RSG_NONEG);
if(nRet==RTCAN)
break;
if(nRet==RTNORM) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetWidth(nWidth);
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('T')) {
double nThick=pStep->GetThickness();
nRet=GetReal(_T("\n扶手厚度"), nThick, RSG_NOZERO|RSG_NONEG);
if(nRet==RTCAN)
break;
if(nRet==RTNORM) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetThickness(nThick);
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('H')) {
double nHeight=pStep->GetHeight();
nRet=GetReal(_T("\n扶手高度"), nHeight, RSG_NOZERO|RSG_NONEG);
if(nRet==RTCAN)
break;
if(nRet==RTNORM) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->assertWriteEnabled();
pStep->SetHeight(nHeight);
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('E')) {
Adesk::UInt8 nAlign=pStep->GetAlignment();
adsout << _T("\n输入对齐方式[中间对齐(0)/左边对齐(1)/右边对齐(2)]<")
<< int(nAlign) << _T(">:");
XString sKeyword;
int nRetCode;
INITGET_BEG(0, _T("0 1 2"));
nRetCode=ads_getkword(_T(""), sKeyword);
INITGET_END();
if(nRetCode==RTNORM) {
nAlign=_ttoi(sKeyword);
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
pStep->SetAlignment(nAlign);
pStep->downgradeOpen();
}
} else if(sKeyword[0]==_T('2')) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
BOOL bHas2d=!pStep->Has2D();
pStep->SetHas2D(bHas2d);
if(!bHas2d && !pStep->Has3D())
pStep->SetHas3D(TRUE);
pStep->downgradeOpen();
} else if(sKeyword[0]==_T('3')) {
if(pStep->upgradeOpen()!=Acad::eOk)
return RTERROR;
BOOL bHas3d=!pStep->Has3D();
pStep->SetHas2D(bHas3d);
if(!bHas3d && !pStep->Has2D())
pStep->SetHas2D(TRUE);
pStep->downgradeOpen();
} else if(sKeyword[0]==_T('L')) {
pStep->list();
}
}
OPENOBJ_END();
return RTNORM;
}