1589 lines
40 KiB
C++
1589 lines
40 KiB
C++
#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;
|
||
}
|
||
|
||
|