Files
envi-code/SourceCode/Code2026/AdsXRx/DbSlopeRoof.cpp
T
2026-09-28 15:28:50 +08:00

3786 lines
95 KiB
C++

#include "stdafx.h"
#include "DbSlopeRoof.h"
//AEC7:0,AEC8:1
Adesk::UInt8 TRoofBase::g_nVersion=1;
TRoofBase::TRoofBase():m_nSlabThick(_AS_SYS_UNIT(200))
{
}
Acad::ErrorStatus TRoofBase::Read(AcDbDwgFiler* pFiler)
{
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
if(nVer>g_nVersion)
return Acad::eMakeMeProxy;
pFiler->readItem(&m_idTopFaceLayer);
pFiler->readItem(&m_idBotFaceLayer);
pFiler->readItem(&m_idSlabLayer);
pFiler->readItem(&m_idRidgeLayer);
pFiler->readItem(&m_nSlabThick);
pFiler->readItem(&m_nRidgeWidth);
pFiler->readItem(&m_nRidgeHeight);
Adesk::UInt8 nStyle;
pFiler->readItem(&nStyle);
m_nRidgeStyle=(RidgeStyle)nStyle;
int temp;
pFiler->readItem(&temp);//无用数据
pFiler->readItem(&temp);//无用数据
if(nVer>0)//AEC8
{
Adesk::Int32 num;
m_lstHole.Reset();
pFiler->readItem(&num);
for(long i=0;i<num;i++)
{
XPoly2D *pPoly=new XPoly2D;
ReadPoly2D(pFiler,*pPoly);
m_lstHole.Append(pPoly);
}
m_lstIdOpening.Reset();
pFiler->readItem(&num);
for(i=0;i<num;i++)
{
AcDbSoftPointerId id;
pFiler->readItem(&id);
m_lstIdOpening.Append(new AcDbSoftPointerId(id));
}
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TRoofBase::Write(AcDbDwgFiler* pFiler)const
{
if(g_nSaveTArchVer<8)
pFiler->writeItem((Adesk::UInt8)0);
else
pFiler->writeItem(g_nVersion);
pFiler->writeItem(m_idTopFaceLayer);
pFiler->writeItem(m_idBotFaceLayer);
pFiler->writeItem(m_idSlabLayer);
pFiler->writeItem(m_idRidgeLayer);
pFiler->writeItem(m_nSlabThick);
pFiler->writeItem(m_nRidgeWidth);
pFiler->writeItem(m_nRidgeHeight);
pFiler->writeItem((Adesk::UInt8)m_nRidgeStyle);
int temp=0;
pFiler->writeItem(temp);//无用数据
pFiler->writeItem(temp);//无用数据
if(g_nSaveTArchVer>7)
{
Adesk::Int32 num;
num=m_lstHole.Length();
pFiler->writeItem(num);
for(long i=0;i<num;i++)
WritePoly2D(pFiler,m_lstHole[i]);
num=m_lstIdOpening.Length();
pFiler->writeItem(num);
for(i=0;i<num;i++)
{
const AcDbSoftPointerId &id=m_lstIdOpening[i];
pFiler->writeItem(id);
}
}
return pFiler->filerStatus();
}
TSlopeRoof::TSlopeRoof(const TSlopeRoof &src)
:m_polyOutline(1)
{
*this = src;
}
TSlopeRoof &
TSlopeRoof::operator = (const TSlopeRoof &src)
{
Reset();
m_polyOutline=src.m_polyOutline;
for(int i=0; i<src.m_slope.Length(); i++)
m_slope.Append(new double(src.m_slope[i]));
return *this;
}
void
TSlopeRoof::Reset()
{
m_polyOutline.Reset();
m_slope.Reset();
}
void
TSlopeRoof::AppendEdge(const XPoint &ptFrom, double nSlope)
{
m_polyOutline.AppendNode(ptFrom);
m_slope.Append(new double(nSlope));
}
void
TSlopeRoof::InitEqualSlope(const XPoly2D &poly, double nSlope)
{
ASSERT(poly.IsClosed());
m_polyOutline=poly;
int nEdge=poly.TotalSegments();
m_slope.Reset();
for(int i=0; i<nEdge; i++)
m_slope.Append(new double(nSlope));
}
double
TSlopeRoof::GetSlopeAngle(int idx) const
{
ASSERT(idx<GetEdgeNum());
return m_slope[idx];
}
void
TSlopeRoof::SetSlopeAngle(int idx, double nAngle)
{
ASSERT(idx<GetEdgeNum());
*m_slope[idx]=nAngle;
}
XLine
TSlopeRoof::GetSlopeEdge(int idx) const
{
ASSERT(idx<GetEdgeNum());
XLine ln;
m_polyOutline.Nth(idx, ln, XArc());
return ln;
}
// 求第i边到前一边的角度
double
TSlopeRoof::GetAngleToPrev(int idx) const
{
int nEdge=m_slope.Length();
ASSERT(idx<nEdge && nEdge==m_polyOutline.TotalSegments());
XLine seg;
m_polyOutline.Nth(idx, seg, XArc());
int idPrev=LimitCycle(idx-1, nEdge);
int idNext=LimitCycle(idx+1, nEdge);
double nPrevAng=CT_std_angle(ads_angle(m_polyOutline[idx], m_polyOutline[idPrev]) -
ads_angle(m_polyOutline[idx], m_polyOutline[idNext]));
return nPrevAng;
}
BOOL
TSlopeRoof::OffsetIn(double *pDistArray, TSlopeRoof &result) const
{
int nEdgeNum=GetEdgeNum();
TSlopeRoof tmp;
XLine lnPrev(LS_INFINITE), ln0(LS_INFINITE);
m_polyOutline.Nth(nEdgeNum-1, ln0, XArc());
if(ln0.GetLength()<_DIST_SNAP)
return FALSE;
lnPrev=ln0.Offset(-pDistArray[nEdgeNum-1]);
// lnPrev.flag=LS_INFINITE;
lnPrev.SetLineFlag(LS_INFINITE);
for(int i=0; i<nEdgeNum; i++) {
XLine lnCur(LS_INFINITE), ln1(LS_INFINITE);
m_polyOutline.Nth(i, ln1, XArc());
if(ln1.GetLength()<_DIST_SNAP)
return FALSE;
lnCur=ln1.Offset(-pDistArray[i]);
XPoint ptInt;
if(!lnCur.Intersection(&lnPrev, ptInt))
return FALSE;
tmp.AppendEdge(ptInt, m_slope[i]);
lnPrev=lnCur;
}
result=tmp;
if(tmp.m_polyOutline.PathArea()>_DIST_SNAP*_DIST_SNAP ) {
//需要另外的求解方法, 目前还没有做
return FALSE;
}
return TRUE;
}
// Merge segment
// 有时不能一次性压缩成功
void
TSlopeRoof::Compress()
{
// private AOL API
extern BOOL MergeCurve(XCurveSegment &curve, XCurveSegment &seg, int bMinusCurve, int bMinusSeg);
TSlopeRoof dest;
int nTotalSeg=GetEdgeNum();
BOOL bFirst=TRUE;;
XCurveSegment curve;
double nSlope=0;
for(int n=0; n<nTotalSeg; n++) {
XCurveSegment seg;
m_polyOutline.Nth(n, seg);
if(!seg)
continue;
if(bFirst) {
curve=seg;
nSlope = *m_slope[n];
bFirst=FALSE;
continue;
} else {
if(!curve) { //由于合并产生0线段
curve=seg;
nSlope = *m_slope[n];
} else {
double nLenCurve=curve.GetLength();
double nLenSeg=seg.GetLength();
BOOL bMerged=MergeCurve(curve, seg, FALSE, FALSE);
if(!bMerged) { //当前段没有合并进curve, 更新curve
dest.AppendEdge(curve.StartPoint(), nSlope);
curve=seg;
nSlope = *m_slope[n];
} else { //合并时取较大角度者
if(nLenCurve<nLenSeg)
nSlope=*m_slope[n];
//nSlope = max(nSlope, *m_slope[n]);
}
}
}
}
if(!bFirst)
dest.AppendEdge(curve.StartPoint(), nSlope);
if(dest.GetEdgeNum()>=3) {
int nTotalDest=dest.GetEdgeNum();
XCurveSegment curveFirst, curveFinal;
dest.m_polyOutline.Nth(0, curveFirst),
dest.m_polyOutline.Nth(nTotalDest-1, curveFinal);
double nLenFinal=curveFinal.GetLength();
double nLenFirst=curveFirst.GetLength();
if(MergeCurve(curveFinal, curveFirst, FALSE, FALSE)) {
*dest.m_polyOutline[0]=curveFinal.StartPoint();
// dest.m_polyOutline.bulges.Remove(nTotalDest-1);
dest.m_polyOutline.RemoveBugle(nTotalDest-1);
dest.m_polyOutline.Remove(nTotalDest-1);
double nSlopeFinal=*dest.m_slope[nTotalDest-1];
dest.m_slope.Remove(nTotalDest-1);
if(nLenFinal>nLenFirst)
*dest.m_slope[0] = nSlopeFinal;
if(!curveFinal) {
dest.m_polyOutline.Remove(0);
// dest.m_polyOutline.bulges.Remove(0);
dest.m_polyOutline.RemoveBugle(0);
dest.m_slope.Remove(0);
}
}
*this = dest;
} else {
// Clear me
Reset();
}
}
BOOL
TSlopeRoof::IsInOtherEdge(int idx) const
{
int nEdgeNum=GetEdgeNum();
ASSERT(idx<nEdgeNum);
XLine ln;
m_polyOutline.Nth(idx, ln, XArc());
for(int i=0; i<nEdgeNum; i++) {
XLine ln0;
if(i==idx)
continue;
m_polyOutline.Nth(i, ln0, XArc());
if(!ln0)
continue;
int nPrFlag1=ln.StartPoint()&ln0;
int nPrFlag2=ln.EndPoint()&ln0;
if((nPrFlag1==PR_INSIDE || nPrFlag1==PR_ONPT1 || nPrFlag1==PR_ONPT2) &&
(nPrFlag2==PR_INSIDE || nPrFlag2==PR_ONPT1 || nPrFlag2==PR_ONPT2)) {
return TRUE;
}
}
return FALSE;
}
BOOL
TSlopeRoof::GetGeometry1(XExplodeDraw &dc, BOOL bBotVis) const
{
XAecRoof roof(bBotVis);
roof.InitRoof(m_polyOutline, PI/6.0);
int nEdgeNum=GetEdgeNum();
for(int iEdge=0; iEdge<nEdgeNum; iEdge++) {
XRoofEdgeCompact *pEdge = roof.m_lstEdges[iEdge];
pEdge->m_nSlope = GetSlopeAngle(iEdge);
}
BOOL bRet=FALSE;
if(roof.Calculate()==RTNORM) {
int nVerticeNum=0, nFaceListLen=0;
Adesk::Int32 *pFaceList=NULL;
XPoint *pVerticeList=NULL;
Adesk::UInt8 *pEdgeVisArray=NULL;
if(roof.GetSurfaceData(&nVerticeNum, pVerticeList, &nFaceListLen, pFaceList,
pEdgeVisArray)==RTNORM) {
AcGiEdgeData edge;
edge.setVisibility(pEdgeVisArray);
dc.DrawShell(nVerticeNum,
(const AcGePoint3d *)pVerticeList,
nFaceListLen,
pFaceList,
&edge);
bRet=TRUE;
}
if(pFaceList) delete []pFaceList;
if(pVerticeList) delete []pVerticeList;
if(pEdgeVisArray) delete [] pEdgeVisArray;
}
return bRet;
}
// 求二维几何
BOOL
TSlopeRoof::GetGeometry2d1(XExplodeDraw &dc, BOOL bBotVis) const
{
XAecRoof roof(bBotVis);
roof.InitRoof(m_polyOutline, PI/6.0);
int nEdgeNum=GetEdgeNum();
for(int iEdge=0; iEdge<nEdgeNum; iEdge++) {
XRoofEdgeCompact *pEdge = roof.m_lstEdges[iEdge];
pEdge->m_nSlope = GetSlopeAngle(iEdge);
}
BOOL bRet=FALSE;
if(roof.Calculate()==RTNORM) {
AcDbVoidPtrArray entSet;
XExplodeStream dcTemp(entSet);
int nVerticeNum=0, nFaceListLen=0;
Adesk::Int32 *pFaceList=NULL;
XPoint *pVerticeList=NULL;
Adesk::UInt8 *pEdgeVisArray=NULL;
if(roof.GetSurfaceData(&nVerticeNum, pVerticeList, &nFaceListLen, pFaceList,
pEdgeVisArray)==RTNORM) {
AcGiEdgeData edge;
edge.setVisibility(pEdgeVisArray);
dcTemp.DrawShell(nVerticeNum,
(const AcGePoint3d *)pVerticeList,
nFaceListLen,
pFaceList,
&edge);
bRet=TRUE;
}
if(pFaceList) delete []pFaceList;
if(pVerticeList) delete []pVerticeList;
if(pEdgeVisArray) delete [] pEdgeVisArray;
int nLen=entSet.length();
for(int i=0; i<nLen; i++) {
AcDbEntity *pEnt=(AcDbEntity *)entSet[i];
if(pEnt->isA()==AcDbFace::desc()) {
AcDbFace *pFace=(AcDbFace *)pEnt;
for(int m=0; m<4; m++) {
int mNext=m+1;
if(mNext==4)
mNext=0;
Adesk::Boolean bVis=Adesk::kTrue;
if(pFace->isEdgeVisibleAt(m, bVis)==Acad::eOk && bVis) {
XPoint pt1, pt2;
pFace->getVertexAt(m, pt1);
pFace->getVertexAt(mNext, pt2);
pt1.z=pt2.z=0;
if(pt1.Distance(pt2)>_DIST_SNAP) {
dc << XLine(pt1, pt2);
}
}
}
}
}
ReleaseEntSet(entSet);
}
return bRet;
}
// i--顶点号, n--边号
double TSlopeRoof::GetHMin(int i, int n) const
{
int nEdgeNum=GetEdgeNum();
ASSERT(i>=0 && i<nEdgeNum && n>=0 && n<nEdgeNum);
if(nEdgeNum<3 || DePeriod(nEdgeNum, i+1)==n || DePeriod(nEdgeNum, i-1)==n)
return -1.0;
double h= (-C(n)-A(n)*s(i)-B(n)*v(i))/(A(n)*r(i)+B(n)*u(i)+a(n)*Ctan(n));
double xi=r(i)*h + s(i);
double yi=u(i)*h + v(i);
int n1=DePeriod(nEdgeNum, n+1);
double xn=r(n)*h + s(n);
double yn=u(n)*h + v(n);
double xn1=r(n1)*h + s(n1);
double yn1=u(n1)*h + v(n1);
/*
double xn=m_polyOutline[n].x;
double yn=m_polyOutline[n].y;
double xn1=m_polyOutline[n1].x;
double yn1=m_polyOutline[n1].y;
*/
XPoint pti(xi, yi);
XLine ln(XPoint(xn, yn), XPoint(xn1, yn1));
int nPrFlag=pti&ln;
if(nPrFlag!=PR_INSIDE)
h=-1.0;
/*
if(min(xn, xn1)<xi && xi<max(xn, xn1) &&
min(yn, yn1)<yi && yi<max(yn, yn1))
;
else
h=-1.0;
*/
return h;
}
// i--顶点号, n--边号
double TSlopeRoof::GetHMin(int i, int *n) const
{
int nEdgeNum=GetEdgeNum();
int iPrev=DePeriod(nEdgeNum, i-1);
int iNext=i; //DePeriod(nEdgeNum, i+1);
double hMin=-1;
DList<int> lstEdgeN;
for(int k=0; k<nEdgeNum; k++) {
if(k==iPrev || k==iNext)
continue;
double h=GetHMin(i, k);
if(h>0) {
if(hMin<0) {
hMin=h;
lstEdgeN.Append(new int(k));
} else {
if(fabs(h-hMin)<_DIST_SNAP)
lstEdgeN.Append(new int(k));
else if(h<hMin) {
hMin=h;
lstEdgeN.Reset();
lstEdgeN.Append(new int(k));
}
}
}
}
if(lstEdgeN.Length()!=1)
return -1;
*n=*lstEdgeN.Head();
return hMin;
}
// i--顶点号, n--边号
double TSlopeRoof::GetHMin(int *i, int *n) const
{
int nEdgeNum=GetEdgeNum();
double hMin=-1;
DList<CPoint> lstEdgeDot;
for(int k=0; k<nEdgeNum; k++) {
int nEdge;
double h=GetHMin(k, &nEdge);
if(h>0) {
if(hMin<0) {
hMin=h;
lstEdgeDot.Append(new CPoint(k, nEdge));
} else {
if(fabs(h-hMin)<_DIST_SNAP)
lstEdgeDot.Append(new CPoint(k, nEdge));
else if(h<hMin) {
hMin=h;
lstEdgeDot.Reset();
lstEdgeDot.Append(new CPoint(k, nEdge));
}
}
}
}
if(lstEdgeDot.Length()!=1)
return -1;
*i=lstEdgeDot.Head()->x;
*n=lstEdgeDot.Head()->y;
return hMin;
}
BOOL
TSlopeRoof::SplitRoof(int iVert, int nEdge, TSlopeRoof &roof1, TSlopeRoof &roof2) const
{
XLine ln=GetSlopeEdge(nEdge);
XPoint ptVert=m_polyOutline[iVert];
if((ptVert&ln)!=PR_INSIDE)
return FALSE;
int nEdgeNum=GetEdgeNum();
int nFrom1=iVert, nTo1=nEdge;
if(nTo1<nFrom1) nTo1 += nEdgeNum;
roof1.Reset();
for(int n=nFrom1; n<=nTo1; n++) {
int n1=DePeriod(nEdgeNum, n);
roof1.AppendEdge(m_polyOutline[n1], GetSlopeAngle(n1));
}
int nFrom2=nEdge, nTo2=iVert-1;;
if(nTo2<nFrom2) nTo2 += nEdgeNum;
roof2.Reset();
for(n=nFrom2; n<=nTo2; n++) {
int n1=DePeriod(nEdgeNum, n);
roof2.AppendEdge(m_polyOutline[n1==nEdge? iVert:n1], GetSlopeAngle(n1));
}
return TRUE;
}
// 某一边消失时的HMin
double TSlopeRoof::GetHMin() const
{
double hMin=-1;
int nEdgeNum=GetEdgeNum();
for(int i=0; i<nEdgeNum; i++) {
double xEq = r(i)-r(i+1);
double hx=-1;
BOOL bXEq=FALSE;
if(fabs(xEq)<1.0E-6) {
if(fabs(s(i)-s(i+1))>1.0E-6)
continue;
bXEq=TRUE;
} else {
hx=(s(i+1)-s(i))/xEq;
}
double yEq=u(i)-u(i+1);
double hy=-1;
BOOL bYEq=FALSE;
if(fabs(yEq)<1.0E-6) {
if(fabs(v(i)-v(i+1))>1.0E-6)
continue;
bYEq=TRUE;
} else {
hy=(v(i+1)-v(i))/yEq;
}
double h=-1;
if(bXEq && bYEq) //自动满足
continue;
else if(!bXEq && !bYEq) {
if(fabs(hx-hy)>_DIST_SNAP)
continue;
h=hx;
} else if(!bXEq) {
h=hx;
} else {
h=hy;
}
if(h>0) {
if(hMin<0) hMin=h;
else hMin=min(hMin, h);
}
}
return hMin;
}
#if 0
double TSlopeRoof::GetHMin() const
{
int nEdgeNum=GetEdgeNum();
double *h=new double[nEdgeNum];
for(int i=0; i<nEdgeNum; i++) {
double nEdgeLen=GetSlopeEdge(i).Length();
double nAngPrev=GetAngleToPrev(i);
double nAngNext=GetAngleToPrev(LimitCycle(i+1, nEdgeNum));
double nSlope=GetSlopeAngle(i);
double nSlopePrev=GetSlopeAngle(LimitCycle(i-1, nEdgeNum));
double nSlopeNext=GetSlopeAngle(LimitCycle(i+1, nEdgeNum));
//curLoop.GetSlopeAt(i, &nEdgeLen, &nSlope, &nAngPrev, &nAngNext);
//h[i]=nEdgeLen*tan(nSlope)/(1/tan(nAngPrev/2)+1/tan(nAngNext/2));
ASSERT(nAngPrev>_angSnap && nAngNext>_angSnap &&
fabs(nAngPrev-PI)>_angSnap && fabs(nAngNext-PI)>_angSnap);
BOOL bPrevVert=(fabs(PI/2-nSlopePrev)<_angSnap);
BOOL bNextVert=(fabs(PI/2-nSlopeNext)<_angSnap);
BOOL bVert=(fabs(PI/2-nSlope)<_angSnap);
if(bVert) {
if(bPrevVert && bNextVert) {
h[i]=-1000.0; //没有解
} else {
h[i] = nEdgeLen/
( (bPrevVert? 0 : 1/(tan(nSlopePrev)*sin(nAngPrev)))
+
(bNextVert? 0 : 1/(tan(nSlopeNext)*sin(nAngNext)))
);
}
} else {
h[i] = nEdgeLen*tan(nSlope)/
(
(bPrevVert? 1/tan(nAngPrev) : (tan(nSlope)/tan(nSlopePrev)+cos(nAngPrev))/sin(nAngPrev))
+
(bNextVert? 1/tan(nAngNext) : (tan(nSlope)/tan(nSlopeNext)+cos(nAngNext))/sin(nAngNext))
);
}
if(h[i]<0) {
}
}
// 求最小值
double hMin=-1;
for(i=0; i<nEdgeNum; i++) {
if(h[i]<0)
continue;
if(hMin<0)
hMin=h[i];
else
hMin=min(hMin, h[i]);
}
delete [] h;
return hMin;
}
#endif
BOOL
TSlopeRoof::GetGeometry(XExplodeDraw &dc, BOOL bFirstLoop) const
{
TSlopeRoof curLoop;
curLoop=*this;
curLoop.Compress();
curLoop.Compress();
double hCurrent=0.0;
BOOL bRet=TRUE;
while(1) {
int nEdgeNum=curLoop.GetEdgeNum();
//ASSERT(nEdgeNum>2); // bug here
if(nEdgeNum<=2)
break;
double hMin1=curLoop.GetHMin();
int iVert=0, nEdge=0;
double hMin2=curLoop.GetHMin(&iVert, &nEdge);
double hMin;
int nUseMethod=0; // 0-边消失, 1--分解多边形
if(hMin1<0 && hMin2<0) {
bRet=curLoop.GetGeometry1(dc, bFirstLoop);
break;
} else {
if(hMin1<0) {
hMin=hMin2;
nUseMethod=1;
} else if(hMin2<0) {
hMin=hMin1;
nUseMethod=0;
} else {
hMin=min(hMin1, hMin2);
nUseMethod=(hMin1-hMin2>_DIST_SNAP); // || fabs(hMin2-hMin1)<_DIST_SNAP);
}
}
hCurrent += hMin;
double *d=new double[nEdgeNum]; //偏移量
for(int i=0; i<nEdgeNum; i++) {
d[i]=hMin/tan(curLoop.GetSlopeAngle(i));
}
TSlopeRoof nextLoop, nextLoop1;
if(!curLoop.OffsetIn(d, nextLoop)) {
delete []d;
bRet=curLoop.GetGeometry1(dc, bFirstLoop);
break;
}
delete [] d;
nextLoop.SetElevation(GetElevation()+hCurrent);
if(!nUseMethod) {
nextLoop1=nextLoop;
nextLoop1.Compress();
nextLoop1.Compress();
if(nextLoop1.m_polyOutline.IsSelfIntersect()) {
curLoop.GetGeometry1(dc, bFirstLoop);
break;
}
}
double nBotArea=nextLoop.GetBottomArea();
for(i=0; i<nEdgeNum; i++) {
if(fabs(curLoop.GetSlopeAngle(i)-PI/2.0)<_angSnap) // fix bug here on 2002/8/12
continue; //90 度的坡不绘制
double nPrevSlope=curLoop.GetSlopeAngle(DePeriod(nEdgeNum, i-1));
double nNextSlope=curLoop.GetSlopeAngle(DePeriod(nEdgeNum, i+1));
XLine ln=curLoop.GetSlopeEdge(i);
XLine lnOffset=nextLoop.GetSlopeEdge(i);
X3DFace face;
face.SetVertex(0, ln.StartPoint());
face.SetVertex(1, ln.EndPoint());
face.SetVertex(2, lnOffset.EndPoint());
face.SetVertex(3, lnOffset.StartPoint());
face.SetFlag(0); //0x02;
int nFaceFlag = face.GetFlag();
if(!bFirstLoop)
nFaceFlag |= 0x01; //第3边不可见
if(!nextLoop.IsInOtherEdge(i))
nFaceFlag |= 0x04;
face.SetFlag(nFaceFlag);
dc.DrawFace(face);
double nRoofThick=_AS_SYS_UNIT(200.0);
X3DFace face1=face;
for(int k=0; k<4; k++)
face1.GetVertex(k).z -= nRoofThick;
for(k=0; k<4; k++) {
if( k==0 && bFirstLoop ||
k==1 && fabs(nNextSlope-PI/2)<_angSnap ||
k==3 && fabs(nPrevSlope-PI/2)<_angSnap) {
X3DFace face0;
face0.SetFlag(0);
int kNext=k+1;
if(kNext==4) kNext=0;
face0.GetVertex(0)=face1.GetVertex(k);
face0.GetVertex(1)=face1.GetVertex(kNext);
face0.GetVertex(2)=face.GetVertex(kNext);
face0.GetVertex(3)=face.GetVertex(k);
dc.DrawFace(face0);
}
}
face1.Reverse(); //保证正确的法向
dc.DrawFace(face1);
}
bFirstLoop=FALSE;
if(nUseMethod) { //分解多边形
TSlopeRoof roof1, roof2;
bRet=nextLoop.SplitRoof(iVert, nEdge, roof1, roof2);
if(bRet) {
int bRet1=TRUE;
if(roof1.GetBottomArea()>_DIST_SNAP*1.0)
bRet1=roof1.GetGeometry(dc, FALSE);
int bRet2=TRUE;
if(roof2.GetBottomArea()>_DIST_SNAP*1.0)
bRet2=roof2.GetGeometry(dc, FALSE);
bRet=(bRet1&&bRet2);
}
break;
}
curLoop=nextLoop1;
if(nBotArea<_DIST_SNAP*1.0)
break;
}
return bRet;
}
// 求二维几何
BOOL TSlopeRoof::GetGeometry2d(XExplodeDraw &dc, BOOL bFirstLoop) const
{
TSlopeRoof curLoop;
curLoop=*this;
curLoop.Compress();
curLoop.Compress();
double hCurrent=0.0;
BOOL bRet=TRUE;
while(1) {
int nEdgeNum=curLoop.GetEdgeNum();
if(nEdgeNum<=2)
break;
double hMin1=curLoop.GetHMin();
int iVert=0, nEdge=0;
double hMin2=curLoop.GetHMin(&iVert, &nEdge);
double hMin;
int nUseMethod=0; // 0-边消失, 1--分解多边形
if(hMin1<0 && hMin2<0) {
bRet=curLoop.GetGeometry2d1(dc, bFirstLoop);
break;
} else {
if(hMin1<0) {
hMin=hMin2;
nUseMethod=1;
} else if(hMin2<0) {
hMin=hMin1;
nUseMethod=0;
} else {
hMin=min(hMin1, hMin2);
nUseMethod=(hMin1-hMin2>_DIST_SNAP); // || fabs(hMin2-hMin1)<_DIST_SNAP);
}
}
hCurrent += hMin;
double *d=new double[nEdgeNum]; //偏移量
for(int i=0; i<nEdgeNum; i++) {
d[i]=hMin/tan(curLoop.GetSlopeAngle(i));
}
TSlopeRoof nextLoop, nextLoop1;
if(!curLoop.OffsetIn(d, nextLoop)) {
delete []d;
bRet=curLoop.GetGeometry2d1(dc, bFirstLoop);
break;
}
delete [] d;
nextLoop.SetElevation(GetElevation()+hCurrent);
if(!nUseMethod) {
nextLoop1=nextLoop;
nextLoop1.Compress();
nextLoop1.Compress();
if(nextLoop1.m_polyOutline.IsSelfIntersect()) {
curLoop.GetGeometry2d1(dc, bFirstLoop);
break;
}
}
double nBotArea=nextLoop.GetBottomArea();
for(i=0; i<nEdgeNum; i++) {
//if(fabs(GetSlopeAngle(i)-PI/2.0)<_angSnap)
// continue; //90 度的坡不绘制
XLine ln=curLoop.GetSlopeEdge(i);
XLine lnOffset=nextLoop.GetSlopeEdge(i);
X3DFace face;
face.GetVertex(0)=lnOffset.StartPoint();
face.GetVertex(1)=lnOffset.EndPoint();
face.GetVertex(2)=ln.EndPoint();
face.GetVertex(3)=ln.StartPoint();
//face.flag = 0; //0x02;
face.SetFlag(0x02);
int nFaceFlag = face.GetFlag();
if(!bFirstLoop)
nFaceFlag |= 0x04; //第3边不可见
if(!nextLoop.IsInOtherEdge(i))
nFaceFlag |= 0x01;
face.SetFlag(nFaceFlag);
for(int m=0; m<4; m++)
{
int nBitFlag=(1<<m);
nFaceFlag = face.GetFlag();
if(!(nFaceFlag&nBitFlag))
{
int mNext=m+1;
if(mNext==4)
mNext=0;
XLine lnTemp(face.GetVertex(m), face.GetVertex(mNext));
lnTemp.StartPoint().z=lnTemp.EndPoint().z=0;
if(lnTemp.GetLength()>_DIST_SNAP)
dc << lnTemp;
}
}
}
bFirstLoop=FALSE;
if(nUseMethod) { //分解多边形
TSlopeRoof roof1, roof2;
bRet=nextLoop.SplitRoof(iVert, nEdge, roof1, roof2);
if(bRet) {
int bRet1=TRUE;
if(roof1.GetBottomArea()>_DIST_SNAP*1.0)
bRet1=roof1.GetGeometry2d(dc, FALSE);
int bRet2=TRUE;
if(roof2.GetBottomArea()>_DIST_SNAP*1.0)
bRet2=roof2.GetGeometry2d(dc, FALSE);
bRet=(bRet1&&bRet2);
}
break;
}
curLoop=nextLoop1;
if(nBotArea<_DIST_SNAP*1.0)
break;
}
return bRet;
}
// 表面积
double
TSlopeRoof::GetSurfArea() const
{
AcDbVoidPtrArray entSet;
XExplodeStream dc(entSet);
double nArea=0.0;
if(GetGeometry(dc, TRUE)) {
int len=entSet.length();
for(int i=0; i<len; i++) {
AcDbEntity *pEnt=(AcDbEntity *)entSet[i];
AcDbFace *pFace=AcDbFace::cast(pEnt);
if(pFace) {
XPoint ptArray[4];
for(int n=0; n<4; n++)
pFace->getVertexAt(n, ptArray[n]);
XLine lnBot(ptArray[2], ptArray[3]), lnTop(ptArray[0], ptArray[1]);
double nHeight=ptArray[0].Distance(&lnBot);
double nFaceArea=(lnBot.GetLength()+lnTop.GetLength())*nHeight/2.0;
nArea += nFaceArea;
}
}
}
ReleaseEntSet(entSet);
return nArea;
}
/////////////////////////////////////////////////////////////
// 屋顶对象类
/////////////////////////////////////////////////////////////
//AEC6,1,AEC7=2
const Adesk::UInt8 TDbSlopeRoof::g_nVersion = 2;
ACRX_DXF_DEFINE_MEMBERS(TDbSlopeRoof,TDbPolyPathEnt, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, AEC_SLOPEROOF,"AEC_KERNAL|缺乏图形解释器, 请下载插件");
IMPLEMENT_TENTBASE(TDbSlopeRoof);
TDbSlopeRoof::TDbSlopeRoof()
:TSlopeRoof()
{
}
TDbSlopeRoof::~TDbSlopeRoof()
{
}
BOOL
TDbSlopeRoof::IsValid() const
{
BOOL bRet=TDbPolyPathEnt::IsValid();
if(!bRet)
return bRet;
bRet=(m_slope.Length()==m_polyOutline.TotalSegments()); //倾角
return bRet;
}
// 提供对格式刷的支持
void TDbSlopeRoof::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbPolyPathEnt::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbSlopeRoof *pSrc=TDbSlopeRoof::cast(pSrcEntity);
if(pSrc) {
}
}
Acad::ErrorStatus
TDbSlopeRoof::subGetClassID(CLSID* pClsid) const
{
*pClsid = CLSID_ComSlopeRoof;
return Acad::eOk;
return AcDbEntity::subGetClassID(pClsid);
}
// 从DWG读入数据:
Acad::ErrorStatus TDbSlopeRoof::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Reset();
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;
}
double nElev=0.0;
pFiler->readItem(&nElev);
Adesk::UInt16 nEdgeNum=0;
pFiler->readItem(&nEdgeNum);
for(Adesk::UInt16 i=0; i<nEdgeNum; i++) {
AcGePoint3d ptVertex;
double nSlope;
pFiler->readItem(&ptVertex);
pFiler->readItem(&nSlope);
ptVertex[2]=nElev;
AppendEdge(XPoint(ptVertex), nSlope);
}
if(nVer>1)
{
es=TRoofBase::Read(pFiler);
if(es!=Acad::eOk)return es;
pFiler->readItem(&m_fMaxHeight);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSlopeRoof::dwgOutFields (AcDbDwgFiler* pFiler)const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbPolyPathEnt::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
if(g_nSaveTArchVer<7)
pFiler->writeItem((Adesk::UInt8)1);
else
pFiler->writeItem(g_nVersion);
double nElev=0.0;
if(!!m_polyOutline)
nElev=m_polyOutline[0].z;
pFiler->writeItem(nElev);
Adesk::UInt16 nTotalEdge=GetEdgeNum();
pFiler->writeItem(nTotalEdge);
for(Adesk::UInt16 i=0; i<nTotalEdge; i++) {
pFiler->writeItem(m_polyOutline[i].AsAcGePoint3d());
pFiler->writeItem(m_slope[i]);
}
if(g_nSaveTArchVer>6)
{
es=TRoofBase::Write(pFiler);
if(es!=Acad::eOk)return es;
pFiler->writeItem(m_fMaxHeight);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSlopeRoof::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbPolyPathEnt::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbSlopeRoof"))) {
return Acad::eBadDxfSequence;
}
DList<XPoint> pts;
DList<double> bulges;
DList<double> slopes;
XPoint pt;
double nElev=0.0;
resbuf rb;
int fieldsFlags=0;
while ((es == Acad::eOk)
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
switch (rb.restype) {
case 148:
nElev=rb.resval.rreal;
fieldsFlags |= 0x01;
break;
case AcDb::kDxfAngle:
bulges.Append(new double(rb.resval.rreal));
break;
case AcDb::kDxfAngle+1:
slopes.Append(new double(rb.resval.rreal));
break;
case AcDb::kDxfXCoord:
pt=rb.resval.rpoint;
pts.Append(new XPoint(pt));
break;
//fall through intentional
default:
// An unrecognized group. Push it back so that
// the subclass can read it again.
pFiler->pushBackItem();
es = Acad::eEndOfFile;
break;
}
}
// At this point the es variable must contain eEndOfFile
// - either from readResBuf() or from pushback. If not,
// it indicates that an error happened and we should
// return immediately.
//
if (es != Acad::eEndOfFile)
return Acad::eInvalidResBuf;
if (pts.Length()<2 || pts.Length()!=slopes.Length()) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nError DXF group code: 10, 51"));
return Acad::eMissingDxfField;
}
m_polyOutline.Reset();
m_slope.Reset();
for(int i=0; i<pts.Length(); i++) {
m_polyOutline.AppendNode(*pts[i]);
m_slope.Append(new double(*slopes[i]));
}
m_polyOutline.SetElevation(nElev);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbSlopeRoof::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es;
es = TDbPolyPathEnt::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbSlopeRoof"));
assert(es == Acad::eOk);
pFiler->writeDouble(148, GetElevation());
double nEdgeNum=GetEdgeNum();
for(int i=0; i<nEdgeNum; i++) {
pFiler->writePoint2d(AcDb::kDxfXCoord, m_polyOutline[i].AsAcGePoint2d());
//pFiler->writeDouble(AcDb::kDxfAngle, m_polyOutline.bulges[i]);
pFiler->writeDouble(AcDb::kDxfAngle+1, GetSlopeAngle(i));
}
return es;
}
// Active when being rotated, scaled, moved, etc.
Acad::ErrorStatus TDbSlopeRoof::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
AecEntity::subTransformBy(xform);
ads_matrix mat;
memcpy(mat, &xform, sizeof(ads_matrix));
double nElev=0.0;
for(int i=0; i<m_polyOutline.Length(); i++) {
XPoint *pt=m_polyOutline[i];
pt->TransformBy(mat);
//以第一个顶点的z坐标为基准
if(i==0) {
nElev = pt->z;
} else {
pt->z = nElev;
}
}
if(IsMirrorMatrix(mat) && m_polyOutline.PathArea()>0) {
m_polyOutline.Reverse();
m_slope.Reverse();
}
return Acad::eOk;
}
void TDbSlopeRoof::UnionScale(double nScale)
{
assertWriteEnabled();
double nOldElev=GetElevation();
TDbPolyPathEnt::UnionScale(nScale);
SetElevation(nOldElev*nScale);
m_nSlabThick*=nScale;//板厚
m_nRidgeWidth*=nScale;
m_nRidgeHeight*=nScale;//屋脊大小
m_fMaxHeight*=nScale;
}
Acad::ErrorStatus
TDbSlopeRoof::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
assertReadEnabled();
GetGeometry(dc, TRUE);
return Acad::eOk;
}
bool TDbSlopeRoof::IsClipMe(const AEntityBase* pEnt)const
{
return false;
}
Acad::ErrorStatus
TDbSlopeRoof::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
assertReadEnabled();
GetGeometry2d(dc, TRUE);
return Acad::eOk;
}
const TCHAR *TDbSlopeRoof::GetDefaultLayer() const
{
return LAY_ROOF;
}
/* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */
void TDbSlopeRoof::GetTips(DList<ObjInfoUnit> &lstInfo) const
{
lstInfo.Append(new ObjInfoUnit(_T("对象类型") ,_T("任意坡顶")));
}
Acad::ErrorStatus TDbSlopeRoof::SetPathPoly(const XPoly2D &polyPath,const AcGeVector3d&normal)
{
assertWriteEnabled();
XPoly2D polyPath1=polyPath;
if(polyPath1.PathArea()>0)
polyPath1.Reverse();
InitEqualSlope(polyPath1,PI/6);
return Acad::eOk;
}
Acad::ErrorStatus TDbSlopeRoof::GetPathPoly(XPoly2D &polyPath,AcGeVector3d&normal) const
{
assertReadEnabled();
polyPath=m_polyOutline;
normal=AcGeVector3d::kZAxis;
return Acad::eOk;
}
// aec add 101115,支持统一标高
bool TDbSlopeRoof::UnifyElevation(double dElevation)
{
assertWriteEnabled();
SetElevation(dElevation);
return true;
}
void InitDbRoof(BOOL bTrue)
{
if(bTrue) {
TDbSlopeRoof::rxInit();
acrxBuildClassHierarchy();
TDbSlopeRoof::InitMatchProtocol(TRUE);
} else {
TDbSlopeRoof::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbSlopeRoof::desc());
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//AEC8:2;
const Adesk::UInt8 TDbDualSlopeRoof::g_nVersion=2;
ACRX_DXF_DEFINE_MEMBERS(TDbDualSlopeRoof,TDbPolyPathEnt, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, AEC_DUALROOF,"AEC_KERNAL|缺乏图形解释器, 请下载插件");
IMPLEMENT_TENTBASE(TDbDualSlopeRoof);
Acad::ErrorStatus TDbDualSlopeRoof::SetPathPoly(const XPoly2D &polyPath,const AcGeVector3d&normal)
{
assertWriteEnabled();
SetPolyPath(polyPath);
return Acad::eOk;
}
Acad::ErrorStatus TDbDualSlopeRoof::GetPathPoly(XPoly2D &polyPath,AcGeVector3d&normal) const
{
assertReadEnabled();
polyPath=m_polyOutline;
normal=AcGeVector3d::kZAxis;
return Acad::eOk;
}
BOOL TDbDualSlopeRoof::IsValid()const
{
if(!TDbPolyPathEnt::IsValid())
return FALSE;
return !!m_polyOutline&&m_polyOutline.IsClosed()&&!m_polyOutline.IsSelfIntersect()&&m_ptRidge2!=m_ptRidge1&&
m_nAngleLeft<PI/2-1E-3&&m_nAngleRight<PI/2-1E-3;
}
bool TDbDualSlopeRoof::IsClipMe(const AEntityBase* pEnt)const
{
return false;
}
void TDbDualSlopeRoof::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbPolyPathEnt::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbDualSlopeRoof *pSrc=TDbDualSlopeRoof::cast(pSrcEntity);
if(pSrc) {
}
}
Acad::ErrorStatus TDbDualSlopeRoof::subGetClassID(CLSID* pClsid) const
{
*pClsid=CLSID_ComDualSlopeRoof;
return Acad::eOk;
return AcDbEntity::subGetClassID(pClsid);
}
// 从DWG读入数据:
Acad::ErrorStatus TDbDualSlopeRoof::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)
return Acad::eMakeMeProxy;
es=TRoofBase::Read(pFiler);
if(es!=Acad::eOk)return es;
double nElev;
pFiler->readItem(&nElev);
ReadPoly2D(pFiler,m_polyOutline);
m_polyOutline.SetElevation(nElev);
AcGePoint2d pt;
pFiler->readItem(&pt);
m_ptRidge1=pt;
pFiler->readItem(&pt);
m_ptRidge2=pt;
pFiler->readItem(&m_nAngleLeft);
pFiler->readItem(&m_nAngleRight);
pFiler->readItem(&m_bEqualAngle);
//add by aec on 081223
//AEC8 member
if(nVer>1)
{
pFiler->readItem(&m_bHeightLim);
pFiler->readItem(&m_dHeight);
}
else
{
m_bHeightLim = FALSE;
m_dHeight = _AS_SYS_UNIT(3000);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbDualSlopeRoof::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbPolyPathEnt::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
//modify by aec on 081223
if(g_nSaveTArchVer<8)
pFiler->writeItem((Adesk::UInt8)1);
else
pFiler->writeItem(g_nVersion);
es=TRoofBase::Write(pFiler);
if(es!=Acad::eOk)return es;
double nElev=0;
if(m_polyOutline.Length()>0)
nElev=m_polyOutline[0].z;
pFiler->writeItem(nElev);
WritePoly2D(pFiler,m_polyOutline);
pFiler->writeItem(m_ptRidge1.AsAcGePoint2d());
pFiler->writeItem(m_ptRidge2.AsAcGePoint2d());
pFiler->writeItem(m_nAngleLeft);
pFiler->writeItem(m_nAngleRight);
pFiler->writeItem(m_bEqualAngle);
//add by aec on 081223
//AEC8 member
if(g_nSaveTArchVer>=8)
{
pFiler->writeItem(m_bHeightLim);
pFiler->writeItem(m_dHeight);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbDualSlopeRoof::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbPolyPathEnt::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbDualSlopeRoof"))) {
return Acad::eBadDxfSequence;
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbDualSlopeRoof::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es;
es = TDbPolyPathEnt::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbDualSlopeRoof"));
assert(es == Acad::eOk);
return es;
}
Acad::ErrorStatus TDbDualSlopeRoof::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
AecEntity::subTransformBy(xform);
m_polyOutline.TransformBy(xform);
m_ptRidge1.TransformBy(xform);
m_ptRidge2.TransformBy(xform);
return Acad::eOk;
}
void TDbDualSlopeRoof::UnionScale(double nScale)
{
assertWriteEnabled();
double nOldElev=GetElevation();
AecEntity::UnionScale(nScale);
SetElevation(nOldElev*nScale);
m_nSlabThick*=nScale;//板厚
m_nRidgeWidth*=nScale;
m_nRidgeHeight*=nScale;//屋脊大小
m_dHeight*=nScale;//高度 add by fxj 090916
}
Acad::ErrorStatus TDbDualSlopeRoof::GetGripText(int i, CString &cs) const
{
if(i<m_polyOutline.Length()*2)
return TDbPolyPathEnt::GetGripText(i,cs);
else if(i==m_polyOutline.Length()*2)
cs=_T("移动屋脊线的起点");
else if(i==m_polyOutline.Length()*2+1)
cs=_T("移动屋脊线的终点");
else
cs=_T("平移屋脊线");
return Acad::eOk;
}
Acad::ErrorStatus TDbDualSlopeRoof::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
TDbPolyPathEnt::subGetGripPoints(gripPoints,osnapModes,geomIds);
for(long i=0;i<gripPoints.length();i++)
{
AcGePoint3d pt=gripPoints[i];
pt.z=0;
gripPoints.setAt(i,pt);
}
gripPoints.append(m_ptRidge1.AsAcGePoint3d());
gripPoints.append(m_ptRidge2.AsAcGePoint3d());
gripPoints.append(XCurveSegment(m_ptRidge1,m_ptRidge2,0).MidPoint().AsAcGePoint3d());
return Acad::eOk;
}
Acad::ErrorStatus TDbDualSlopeRoof::subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
AcDbIntArray indices2;
for(long i=0;i<indices.length();i++)
{
int iGrip=indices[i]-m_polyOutline.Length()*2;
if(iGrip>=0)
{
if(iGrip==0)
m_ptRidge1+=offset;
else if(iGrip==1)
m_ptRidge2+=offset;
else
{
m_ptRidge1+=offset;
m_ptRidge2+=offset;
}
}
else
indices2.append(indices[i]);
}
AcGeVector3d offset1=offset;
offset1.z=0;
//modify by aec on 090310
// return TDbPolyPathEnt::moveGripPointsAt(indices2,offset1);
Acad::ErrorStatus es=TDbPolyPathEnt::subMoveGripPointsAt(indices2,offset1);
if(es==Acad::eOk
&&IsHeightLim()
&&GetRoofHeight()>_DIST_SNAP)
{
double angLeft(0),angRight(0);
if(CalAngle(angLeft,angRight))
{
m_nAngleLeft=angLeft;
m_nAngleRight=angRight;
}
}
return es;
}
BOOL TDbDualSlopeRoof::CalAngle(double &angLeft, //[out]左坡角(弧度)
double &angRight //[out]右坡角(弧度)
)
{
BOOL bRet=FALSE;
XLine xLine(GetRidgeStart(),GetRidgeEnd());
xLine.SetElevation(0);
XPoly2D poly;
GetPolyPath(poly);
poly.SetElevation(0);
XPoint pt;
double dLowLeft = 0.0,dLowRight = 0.0; //到屋脊线的水平距离
for (long i = 0;i < poly.Length();i++) //距脊线的最远点
{
pt = *poly[i];
int nSide=xLine.OnWhichSide(pt);
double dTemp;
if (nSide==0) //左侧
{
dTemp = pt.Distance(&xLine);
if (dLowLeft < dTemp)
{
dLowLeft = dTemp;
}
}
else if(nSide==1) //右侧
{
dTemp = pt.Distance(&xLine);
if (dLowRight < dTemp)
{
dLowRight = dTemp;
}
}
}
if (fabs(dLowLeft-0.0) <= 1E-6
&&fabs(dLowRight-0.0) <= 1E-6) //没有左右坡
{
return bRet;
}
if (fabs(dLowLeft-0.0) <= 1E-6) //没有左坡
{
double dTempLow = 0.0;
for (long i = 0;i < poly.Length();i++)
{
pt = *poly[i];
double dTemp = pt.Distance(&xLine);
if (fabs(dTempLow-0.0) <= 1E-6)
{
dTempLow = dTemp;
}
else if (dTempLow > dTemp)
{
dTempLow = dTemp;
}
}
dLowRight = dLowRight - dTempLow;
if(dLowRight>_DIST_SNAP)
{
angLeft=angRight=atan(GetRoofHeight() / dLowRight);
bRet = TRUE;
}
}
else if(fabs(dLowRight-0.0) <= 1E-6) //没有右坡
{
double dTempLow = 0.0;
for (long i = 0;i < poly.Length();i++)
{
pt = *poly[i];
double dTemp = pt.Distance(&xLine);
if (fabs(dTempLow-0.0) <= 1E-6)
{
dTempLow = dTemp;
}
else if (dTempLow > dTemp)
{
dTempLow = dTemp;
}
}
dLowLeft = dLowLeft - dTempLow;
if(dLowLeft>_DIST_SNAP)
{
angLeft=angRight=atan(GetRoofHeight() / dLowLeft);
bRet = TRUE;
}
}
else //左右坡都有
{
angLeft=atan(GetRoofHeight() / dLowLeft);
angRight=atan(GetRoofHeight() / dLowRight);
bRet = TRUE;
}
return bRet;
}
Acad::ErrorStatus TDbDualSlopeRoof::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
Acad::ErrorStatus es=Acad::eOk;
XPoly2D poly=m_polyOutline;
poly.SetElevation(0);
dc<<poly;
dc.PushClip(poly,XDcClip::kClipOut&&XDcClip::kNoClipEdge);
XLine line(m_ptRidge1,m_ptRidge2);
line.SetElevation(0);
AcDbLine acLine(line.StartPoint(),line.EndPoint());
AcDbCurve* pCurveOutline=poly.AsAcDbCurve();
AcGePoint3dArray pts;
pCurveOutline->intersectWith(&acLine,AcDb::kExtendArg,pts);
delete pCurveOutline;
if(pts.length()>1)
{
XPoint ptR1=m_ptRidge1;
XPoint ptR2=m_ptRidge2;
ptR1.z=ptR2.z=0;
XPoint vt=ptR2-ptR1;
vt.Normalize();
vt.Scale(_AS_SYS_UNIT(1E7));
PointList ptList(ptR1-vt,ptR2+vt);
for(long i=0;i<pts.length();i++)
ptList.Insert(pts[i]);
if(ptList.Length()>3)
{
line.StartPoint()=*ptList[1];
line.EndPoint()=*ptList[ptList.Length()-2];
line.SetElevation(0);
dc<<line;
}
}
dc.PopClip();
return es;
}
void TDbDualSlopeRoof::Split(DList<XPoly2D>&lstLeft,DList<XPoly2D>&lstRight)const
{
DList<XCurveSegment> lstCurve;
XPoint vt=m_ptRidge2-m_ptRidge1;
vt.Normalize();
vt.Scale(_AS_SYS_UNIT(5E6));
XCurveSegment line(m_ptRidge1-vt,m_ptRidge2+vt,0);
XCurveSegment line1=line.Offset(_AS_SYS_UNIT(-1E6),0),line2=line.Offset(_AS_SYS_UNIT(1E6),0);
XPoly2D polyLeft(1),polyRight(1);
polyLeft.AppendNode(line.StartPoint());
polyLeft.AppendNode(line.EndPoint());
polyLeft.AppendNode(line1.EndPoint());
polyLeft.AppendNode(line1.StartPoint());
polyRight.AppendNode(line.StartPoint());
polyRight.AppendNode(line.EndPoint());
polyRight.AppendNode(line2.EndPoint());
polyRight.AppendNode(line2.StartPoint());
XPoly2D poly(m_polyOutline);
poly.SetElevation(0);
polyLeft.SetElevation(0);
polyRight.SetElevation(0);
XSubExport::Intersect(polyLeft,poly,lstLeft);
XSubExport::Intersect(polyRight,poly,lstRight);
for(long i=0;i<lstLeft.Length();i++)
{
XPoly2D* pPoly=lstLeft[i];
if(pPoly->PathArea()>0)
pPoly->Reverse();
}
for(i=0;i<lstRight.Length();i++)
{
XPoly2D* pPoly=lstRight[i];
if(pPoly->PathArea()>0)
pPoly->Reverse();
}
}
void TDbDualSlopeRoof::GetPlane(XPlane&leftPlane,XPlane&rightPlane)const
{
XPoint vt=m_ptRidge2-m_ptRidge1;
vt.Normalize();
vt.Scale(_AS_SYS_UNIT(5E6));
XCurveSegment line(m_ptRidge1-vt,m_ptRidge2+vt,0);
line.SetElevation(0);
AcGeVector3d vtAxis=(m_ptRidge2-m_ptRidge1).AsAcGeVector3d();
{
AcGeVector3d vt(AcGeVector3d::kZAxis);
vt.rotateBy(-m_nAngleLeft,vtAxis);
leftPlane=XPlane(XPoint(m_ptRidge1.x,m_ptRidge1.y,GetElevation()),vt);
}
{
AcGeVector3d vt(AcGeVector3d::kZAxis);
vt.rotateBy(m_nAngleRight,vtAxis);
rightPlane=XPlane(XPoint(m_ptRidge1.x,m_ptRidge1.y,GetElevation()),vt);
}
}
Acad::ErrorStatus TDbDualSlopeRoof::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
Acad::ErrorStatus es=Acad::eOk;
XPoint vt=m_ptRidge2-m_ptRidge1;
vt.Normalize();
vt.Scale(_AS_SYS_UNIT(5E6));
XCurveSegment line(m_ptRidge1-vt,m_ptRidge2+vt,0);
line.SetElevation(0);
DList<XPoly2D> lstLeft,lstRight;
Split(lstLeft,lstRight);
AcGeVector3d vtAxis=(m_ptRidge2-m_ptRidge1).AsAcGeVector3d();
{
AcGeVector3d vt(AcGeVector3d::kZAxis);
vt.rotateBy(-m_nAngleLeft,vtAxis);
XPlane planeLeft(XPoint(m_ptRidge1.x,m_ptRidge1.y,GetElevation()),vt);
for(long i=0;i<lstLeft.Length();i++)
{
XPoly2D* pPoly=lstLeft[i];
XPoly2D poly1=*pPoly;
for(long j=0;j<pPoly->Length();j++)
{
XPoint *pPt=(*pPoly)[j];
pPt->z=-1*(planeLeft.GetParaA()*pPt->x+planeLeft.GetParaB()*pPt->y+planeLeft.GetParaD())/planeLeft.GetParaC();
poly1[j]->z=pPt->z-m_nSlabThick;
}
dc.DrawShell(*pPoly);
for(long k=0;k<poly1.TotalSegments();k++)
{
XCurveSegment e0,e1;
pPoly->Nth(k,e0);
poly1.Nth(k,e1);
X3DFace face;
face.SetFlag(0);
face.GetVertex(0)=e1.StartPoint();
face.GetVertex(1)=e1.EndPoint();
face.GetVertex(2)=e0.EndPoint();
face.GetVertex(3)=e0.StartPoint();
e0.SetElevation(0);
int nRet0=line.HitTest2d(e0.StartPoint());
int nRet1=line.HitTest2d(e0.EndPoint());
if(nRet0==1||nRet0==2||nRet1==1||nRet1==2||lstRight.Length()==0)
dc.DrawFace(face);
}
poly1.Reverse();
dc.DrawShell(poly1);
}
}
{
AcGeVector3d vt(AcGeVector3d::kZAxis);
vt.rotateBy(m_nAngleRight,vtAxis);
XPlane planeRight(XPoint(m_ptRidge1.x,m_ptRidge1.y,GetElevation()),vt);
for(long i=0;i<lstRight.Length();i++)
{
XPoly2D* pPoly=lstRight[i];
XPoly2D poly1=*pPoly;
for(long j=0;j<pPoly->Length();j++)
{
XPoint *pPt=(*pPoly)[j];
pPt->z=-1*(planeRight.GetParaA()*pPt->x+planeRight.GetParaB()*pPt->y+planeRight.GetParaD())/planeRight.GetParaC();
poly1[j]->z=pPt->z-m_nSlabThick;
}
dc.DrawShell(*pPoly);
for(long k=0;k<poly1.TotalSegments();k++)
{
XCurveSegment e0,e1;
pPoly->Nth(k,e0);
poly1.Nth(k,e1);
X3DFace face;
face.SetFlag(0);
face.GetVertex(0)=e1.StartPoint();
face.GetVertex(1)=e1.EndPoint();
face.GetVertex(2)=e0.EndPoint();
face.GetVertex(3)=e0.StartPoint();
e0.SetElevation(0);
int nRet0=line.HitTest2d(e0.StartPoint());
int nRet1=line.HitTest2d(e0.EndPoint());
if(nRet0==1||nRet0==2||nRet1==1||nRet1==2||lstLeft.Length()==0)
dc.DrawFace(face);
}
poly1.Reverse();
dc.DrawShell(poly1);
}
}
return es;
}
void TDbDualSlopeRoof::GetTips(DList<ObjInfoUnit> &lstInfo) const
{
lstInfo.Append(new ObjInfoUnit(_T("对象类型") ,_T("人字坡顶")));
}
const TCHAR * TDbDualSlopeRoof::GetDefaultLayer() const
{
return LAY_ROOF;
}
//add by aec on 081223
void TDbDualSlopeRoof::SetHeightLim(Adesk::Boolean bTrue)
{
assertWriteEnabled();
m_bHeightLim=bTrue;
}
Adesk::Boolean TDbDualSlopeRoof::IsHeightLim()const
{
return m_bHeightLim;
}
//add by aec on 090223
void TDbDualSlopeRoof::SetRoofHeight(double h)
{
assertWriteEnabled();
m_dHeight=h;
}
double TDbDualSlopeRoof::GetRoofHeight()const
{
return m_dHeight;
}
// aec add 101119,支持导出XML
CString TDbDualSlopeRoof::GetXml() const
{
XmlTree xmlTree;
POSITION posRoot = xmlTree.Insert(_T("AEC_DUALROOF"), NULL, NULL);
{
xmlTree.SetAttribute(posRoot, _T("name"), _T("人字屋顶"));
xmlTree.SetAttribute(posRoot, _T("comment"), _T("对象名称"));
}
CString strText;
POSITION posItem1 = xmlTree.Insert(_T("Object_ID"), posRoot, NULL);
{
xmlTree.SetAttribute(posItem1, _T("name"), _T("对象编号"));
xmlTree.SetAttribute(posItem1, _T("comment"), _T("当前对象的句柄"));
strText.Format(_T("%ld"), objectId());
xmlTree.SetItemText(posItem1, strText);
}
POSITION posItem2 = xmlTree.Insert(_T("Section"), posRoot, posItem1);
{
xmlTree.SetAttribute(posItem2, _T("name"), _T("屋面参数"));
POSITION posItemAng1 = xmlTree.Insert(_T("Ang_1"), posItem2, NULL);
{
xmlTree.SetAttribute(posItemAng1, _T("name"), _T("坡角1"));
strText.Format(_T("%f"), m_nAngleLeft);
xmlTree.SetItemText(posItemAng1, strText);
}
POSITION posItemAng2 = xmlTree.Insert(_T("Ang_2"), posItem2, posItemAng1);
{
xmlTree.SetAttribute(posItemAng2, _T("name"), _T("坡角2"));
strText.Format(_T("%f"), m_nAngleRight);
xmlTree.SetItemText(posItemAng2, strText);
}
POSITION posItemThick = xmlTree.Insert(_T("Thick"), posItem2, posItemAng2);
{
xmlTree.SetAttribute(posItemThick, _T("name"), _T("檐板厚"));
strText.Format(_T("%f"), m_nSlabThick);
xmlTree.SetItemText(posItemThick, strText);
}
}
POSITION posItem3 = xmlTree.Insert(_T("Ridge_line"), posRoot, posItem2);
{
xmlTree.SetAttribute(posItem3, _T("name"), _T("屋脊线"));
POSITION posItemStartPt = xmlTree.Insert(_T("Start_point"), posItem3, NULL);
{
xmlTree.SetAttribute(posItemStartPt, _T("name"), _T("起始点"));
strText.Format(_T("%f,%f,%f"), m_ptRidge1.x, m_ptRidge1.y, m_ptRidge1.z);
xmlTree.SetItemText(posItemStartPt, strText);
}
POSITION posItemEndPt = xmlTree.Insert(_T("End_point"), posItem3, posItemStartPt);
{
xmlTree.SetAttribute(posItemEndPt, _T("name"), _T("结束点"));
strText.Format(_T("%f,%f,%f"), m_ptRidge2.x, m_ptRidge2.y, m_ptRidge2.z);
xmlTree.SetItemText(posItemEndPt, strText);
}
}
POSITION posItem4 = xmlTree.Insert(_T("Baseline"), posRoot, posItem3);
{
xmlTree.SetAttribute(posItem4, _T("name"), _T("屋顶线参数"));
xmlTree.SetAttribute(posItem4, _T("comment"), _T("用于屋顶线角点"));
POSITION posItemPoint = NULL;
XPoint ptNode;
for (int i = 0; i < m_polyOutline.Length(); i++)
{
ptNode = m_polyOutline[i];
strText.Format(_T("Point_%d"), i + 1);
posItemPoint = xmlTree.Insert(strText, posItem4, posItemPoint);
{
strText.Format(_T("第%d点"), i + 1);
xmlTree.SetAttribute(posItemPoint, _T("name"), strText);
strText.Format(_T("%f,%f,%f"), ptNode.x, ptNode.y, ptNode.z);
xmlTree.SetItemText(posItemPoint, strText);
}
}
}
CString strBase = AEntityBase::GetXml();
CString strXml = xmlTree.GetXml();
int nIndex = strXml.Find(_T("<Object_ID"));
strXml.Insert(nIndex, strBase);
return strXml;
}
void InitDbDualSlopeRoof(BOOL bTrue)
{
if(bTrue) {
TDbDualSlopeRoof::rxInit();
acrxBuildClassHierarchy();
TDbDualSlopeRoof::InitMatchProtocol(TRUE);
} else {
TDbDualSlopeRoof::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbDualSlopeRoof::desc());
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
const Adesk::UInt8 TDbMountRoof::g_nVersion=1;
ACRX_DXF_DEFINE_MEMBERS(TDbMountRoof,TDbPolyPathEnt, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, AEC_MOUNTROOF,"AEC_KERNAL|缺乏图形解释器, 请下载插件");
IMPLEMENT_TENTBASE(TDbMountRoof);
// 从DWG读入数据:
Acad::ErrorStatus TDbMountRoof::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)
return Acad::eMakeMeProxy;
es=TRoofBase::Read(pFiler);
if(es!=Acad::eOk)return es;
AcGePoint3d pt;
pFiler->readItem(&pt);
m_ptLocation=pt;
pFiler->readItem(&m_nRotation);
pFiler->readItem(&m_nLength);
pFiler->readItem(&m_nWidth);
pFiler->readItem(&m_nSlopeAngle2);
pFiler->readItem(&m_dEavesLen);
pFiler->readItem(&m_dMountLen);
pFiler->readItem(&m_dRoofHeight);
pFiler->readItem(&m_dMountHeight);
pFiler->readItem(&m_bShowSide);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbMountRoof::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbPolyPathEnt::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
pFiler->writeItem(g_nVersion);
es=TRoofBase::Write(pFiler);
if(es!=Acad::eOk)return es;
pFiler->writeItem(m_ptLocation.AsAcGePoint3d());
pFiler->writeItem(m_nRotation);
pFiler->writeItem(m_nLength);
pFiler->writeItem(m_nWidth);
pFiler->writeItem(m_nSlopeAngle2);
pFiler->writeItem(m_dEavesLen);
pFiler->writeItem(m_dMountLen);
pFiler->writeItem(m_dRoofHeight);
pFiler->writeItem(m_dMountHeight);
pFiler->writeItem(m_bShowSide);
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbMountRoof::subGetClassID(CLSID* pClsid) const
{
*pClsid=CLSID_ComMountRoof;
return Acad::eOk;
return AcDbEntity::subGetClassID(pClsid);
}
Acad::ErrorStatus TDbMountRoof::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
AecEntity::subTransformBy(xform);
XPoint ptX,ptY;
ads_polar(m_ptLocation, m_nRotation, GetLength(), ptX);
ads_polar(m_ptLocation, m_nRotation+PI/2.0, GetWidth(), ptY);
((AcGePoint3d &)ptX).transformBy(xform);
((AcGePoint3d &)ptY).transformBy(xform);
((AcGePoint3d &)m_ptLocation).transformBy(xform);
double nAng = CT_std_angle(ads_angle(m_ptLocation, ptY)-
ads_angle(m_ptLocation, ptX));
if(fabs(nAng-PI*1.5)<_angSnap)
{
XPrivate::Exchange(m_ptLocation, ptX);
}
m_nRotation = ads_angle(m_ptLocation, ptX);
return Acad::eOk;
}
Acad::ErrorStatus TDbMountRoof::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
XPoint ptLoc=GetLocation();
// ptLoc.z=0;
XPoint ptCenter;
ads_polar(ptLoc,m_nRotation,0.5*GetLength(),ptCenter);
ads_polar(ptCenter,m_nRotation+PI*0.5,0.5*GetWidth(),ptCenter);
gripPoints.append(ptCenter);
gripPoints.append(ptLoc);
XPoint ptFirst;
ads_polar(ptLoc,m_nRotation,GetLength(),ptFirst);
gripPoints.append(ptFirst);
ads_polar(ptFirst,m_nRotation+PI*0.5,GetWidth(),ptFirst);
gripPoints.append(ptFirst);
ads_polar(ptLoc,m_nRotation+PI*0.5,GetWidth(),ptFirst);
gripPoints.append(ptFirst);
ads_polar(ptLoc,m_nRotation,GetLength()*0.5,ptFirst);
ads_polar(ptFirst,m_nRotation-PI*0.5,GetEavesLen(),ptFirst);
gripPoints.append(ptFirst); //出檐长
ads_polar(ptFirst,m_nRotation+PI*0.5,GetWidth()+GetEavesLen()*2,ptFirst);
gripPoints.append(ptFirst); //出檐长
ads_polar(ptLoc,m_nRotation+PI*0.5,GetWidth()*0.5,ptFirst);
ads_polar(ptFirst,m_nRotation+PI,GetMountLen(),ptFirst);
gripPoints.append(ptFirst); //出山长
ads_polar(ptFirst,m_nRotation,GetLength()+GetMountLen()*2,ptFirst);
gripPoints.append(ptFirst); //出山长
XLine leftLine, rightLine, midLine;
GetMountLine(leftLine,rightLine,midLine);
midLine.SetElevation(ptLoc.z);
if (!(GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3)) //四坡,歇山,攒尖
{
if (midLine.GetLength()>_DIST_SNAP) //四坡,歇山
{
gripPoints.append(midLine.StartPoint()); //脊线长
gripPoints.append(midLine.EndPoint()); //脊线长
}
}
return Acad::eOk;
}
Acad::ErrorStatus TDbMountRoof::subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
XPoint vtOffset=*(XPoint *)&offset;
vtOffset.z = 0;
double nVtRot=CT_std_angle(ads_angle(XPoint(), vtOffset)-m_nRotation);
double nIncWidth=ads_distance(XPoint(), vtOffset) * cos(nVtRot);
double nIncLen=ads_distance(XPoint(), vtOffset) * sin(nVtRot);
int nLen=indices.length();
for (int i = 0; i < nLen; i++)
{
int idx = indices[i];
switch(idx) {
case 0:
if(GetCtrlToggle()) //移动
{
m_ptLocation += vtOffset;
}
else //旋转
{
XPoint ptCenter=GetLocation();
ptCenter.z=0;
ads_polar(ptCenter,m_nRotation,0.5*GetLength(),ptCenter);
ads_polar(ptCenter,m_nRotation+PI*0.5,0.5*GetWidth(),ptCenter);
ads_matrix mat;
ptCenter.GetRotationMatrix(AcGeVector2d(offset.x,offset.y).angle(),mat);
subTransformBy(AsAcGeMatrix3d(mat));
}
break;
case 1: //拉伸
{
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3) //人字坡
{
if(((m_nLength-nIncWidth)>_DIST_SNAP) //脊线长度>0
&&(m_nWidth-nIncLen)>_DIST_SNAP)
{
m_ptLocation += vtOffset;
m_nLength -= nIncWidth;
m_nWidth -= nIncLen;
}
}
else //四坡,歇山,攒尖
{
if (GetTopLength()<_DIST_SNAP //攒尖
&&m_nLength-nIncWidth>_DIST_SNAP
&&m_nWidth-nIncLen>_DIST_SNAP
)
{
m_ptLocation += vtOffset;
m_nLength -= nIncWidth;
m_nWidth -= nIncLen;
m_nSlopeAngle2=atan(GetRoofHeight()*2/GetLength());
}
else if((((m_nLength-nIncWidth)*0.5)>(m_dRoofHeight-m_dMountHeight)/tan(GetSlopeAngle2())) //脊线长度>0
&&(m_nWidth-nIncLen)>_DIST_SNAP)
{
m_ptLocation += vtOffset;
m_nLength -= nIncWidth;
m_nWidth -= nIncLen;
}
}
}
break;
case 2: //拉伸
{
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3) //人字坡
{
if(((m_nLength+nIncWidth)>_DIST_SNAP) //脊线长度>0
&&(m_nWidth-nIncLen)>_DIST_SNAP)
{
ads_polar(m_ptLocation,m_nRotation+PI*0.5,nIncLen,m_ptLocation);
m_nLength += nIncWidth;
m_nWidth -= nIncLen;
}
}
else //四坡,歇山,攒尖
{
if (GetTopLength()<_DIST_SNAP //攒尖
&&m_nLength+nIncWidth>_DIST_SNAP
&&m_nWidth-nIncLen>_DIST_SNAP
)
{
ads_polar(m_ptLocation,m_nRotation+PI*0.5,nIncLen,m_ptLocation);
m_nLength += nIncWidth;
m_nWidth -= nIncLen;
m_nSlopeAngle2=atan(GetRoofHeight()*2/GetLength());
}
else if((((m_nLength+nIncWidth)*0.5)>(m_dRoofHeight-m_dMountHeight)/tan(GetSlopeAngle2())) //脊线长度>0
&&(m_nWidth-nIncLen)>_DIST_SNAP)
{
ads_polar(m_ptLocation,m_nRotation+PI*0.5,nIncLen,m_ptLocation);
m_nLength += nIncWidth;
m_nWidth -= nIncLen;
}
}
}
break;
case 3: //拉伸
{
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3) //人字坡
{
if(((m_nLength+nIncWidth)>_DIST_SNAP) //脊线长度>0
&&(m_nWidth+nIncLen)>_DIST_SNAP)
{
m_nLength += nIncWidth;
m_nWidth += nIncLen;
}
}
else //四坡,歇山,攒尖
{
if (GetTopLength()<_DIST_SNAP //攒尖
&&m_nLength+nIncWidth>_DIST_SNAP
&&m_nWidth+nIncLen>_DIST_SNAP
)
{
m_nLength += nIncWidth;
m_nWidth += nIncLen;
m_nSlopeAngle2=atan(GetRoofHeight()*2/GetLength());
}
else if((((m_nLength+nIncWidth)*0.5)>(m_dRoofHeight-m_dMountHeight)/tan(GetSlopeAngle2())) //脊线长度>0
&&(m_nWidth+nIncLen)>_DIST_SNAP)
{
m_nLength += nIncWidth;
m_nWidth += nIncLen;
}
}
}
break;
case 4: //拉伸
{
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3) //人字坡
{
if(((m_nLength-nIncWidth)>_DIST_SNAP) //脊线长度>0
&&(m_nWidth+nIncLen)>_DIST_SNAP)
{
ads_polar(m_ptLocation,m_nRotation,nIncWidth,m_ptLocation);
m_nLength -= nIncWidth;
m_nWidth += nIncLen;
}
}
else //四坡,歇山,攒尖
{
if (GetTopLength()<_DIST_SNAP //攒尖
&&m_nLength-nIncWidth>_DIST_SNAP
&&m_nWidth+nIncLen>_DIST_SNAP
)
{
ads_polar(m_ptLocation,m_nRotation,nIncWidth,m_ptLocation);
m_nLength -= nIncWidth;
m_nWidth += nIncLen;
m_nSlopeAngle2=atan(GetRoofHeight()*2/GetLength());
}
else if((((m_nLength-nIncWidth)*0.5)>(m_dRoofHeight-m_dMountHeight)/tan(GetSlopeAngle2())) //脊线长度>0
&&(m_nWidth+nIncLen)>_DIST_SNAP)
{
ads_polar(m_ptLocation,m_nRotation,nIncWidth,m_ptLocation);
m_nLength -= nIncWidth;
m_nWidth += nIncLen;
}
}
}
break;
case 5: //调整出檐长
case 6:
{
double dIncLen=nIncLen;
if(idx==6)
dIncLen=-nIncLen;
if(m_dEavesLen-dIncLen>_DIST_SNAP)
{
m_dEavesLen -= dIncLen;
}
else
{
m_dEavesLen = 0;
}
}
break;
case 7: //调整出山长
case 8:
{
double dIncWidth=nIncWidth;
if(idx==8)
dIncWidth=-nIncWidth;
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3) //人字坡
{
if(m_dMountLen-dIncWidth>_DIST_SNAP)
{
m_dMountLen -= dIncWidth;
}
else if(m_dMountLen-dIncWidth<-_DIST_SNAP&&m_dMountLen-dIncWidth>-GetLength()*0.5-_DIST_SNAP)//可能改变为歇山或四坡或攒尖屋顶
{
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP)//仍为人字坡
{
m_dMountLen = 0;
}
else if (fabs(cos(GetSlopeAngle2()))<1E-3)
{
if ((fabs(m_dMountLen-dIncWidth)<_DIST_SNAP&&GetMountHeight()<_DIST_SNAP) //变为攒尖屋顶
||(fabs(m_dMountLen-dIncWidth)>_DIST_SNAP) //变为四坡或歇山屋顶
)
{
m_nSlopeAngle2=atan((GetRoofHeight()-GetMountHeight())*2/fabs(m_dMountLen-dIncWidth));
}
}
}
else
{
m_dMountLen = 0;
}
}
else
{
double dLen=dIncWidth*tan(GetSlopeAngle2())/tan(GetSlopeAngle1());
if(m_dEavesLen-dLen>_DIST_SNAP)
{
m_dEavesLen -= dLen;
}
else
{
m_dEavesLen = 0;
}
}
}
break;
case 9:
case 10:
{
double dIncWidth=nIncWidth;
if (idx==10)
{
dIncWidth=-nIncWidth;
}
if (!(GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3)) //四坡,歇山,攒尖
{
XLine leftLine, rightLine, midLine;
GetMountLine(leftLine,rightLine,midLine);
midLine.SetElevation(0);
if (GetMountHeight()<_DIST_SNAP) //四坡
{
if (midLine.GetLength()-dIncWidth*2<_DIST_SNAP)//变为攒尖屋顶
{
m_nSlopeAngle2=atan(GetRoofHeight()*2/GetLength());
}
else if(midLine.GetLength()-dIncWidth*2>GetLength()-_DIST_SNAP)//变为人字屋顶
{
m_nSlopeAngle2=PI*0.5;
m_dMountLen=0;
}
else
{
m_nSlopeAngle2=atan(GetRoofHeight()/(0.5*GetLength()-midLine.GetLength()*0.5+dIncWidth));
}
}
else //歇山
{
if (midLine.GetLength()-dIncWidth*2<_DIST_SNAP)//歇山屋顶脊线长为0时不能直接变为攒尖屋顶
{
//m_nSlopeAngle2=atan(GetRoofHeight()*2/GetLength());
}
else if(midLine.GetLength()-dIncWidth*2>GetLength()-_DIST_SNAP)//变为人字屋顶
{
m_nSlopeAngle2=PI*0.5;
m_dMountLen=0;
}
else
{
m_nSlopeAngle2=atan((GetRoofHeight()-GetMountHeight())/(0.5*GetLength()-midLine.GetLength()*0.5+dIncWidth));
}
}
}
}
break;
default:
break;
}
}
return Acad::eOk;
}
Acad::ErrorStatus TDbMountRoof::subGetStretchPoints(AcGePoint3dArray& stretchPoints) const
{
assertReadEnabled();
XPoint ptLoc=GetLocation();
ptLoc.z=0;
XPoint ptCenter;
ads_polar(ptLoc,m_nRotation,0.5*GetLength(),ptCenter);
ads_polar(ptCenter,m_nRotation+PI*0.5,0.5*GetWidth(),ptCenter);
stretchPoints.append(ptCenter);
XPoint ptFirst;
ads_polar(ptLoc,m_nRotation,GetLength()*0.5,ptFirst);
ads_polar(ptFirst,m_nRotation-PI*0.5,GetEavesLen(),ptFirst);
stretchPoints.append(ptFirst); //出檐长
ads_polar(ptFirst,m_nRotation+PI*0.5,GetWidth()+GetEavesLen()*2,ptFirst);
stretchPoints.append(ptFirst); //出檐长
ads_polar(ptLoc,m_nRotation+PI*0.5,GetWidth()*0.5,ptFirst);
ads_polar(ptFirst,m_nRotation+PI,GetMountLen(),ptFirst);
stretchPoints.append(ptFirst); //出山长
ads_polar(ptFirst,m_nRotation,GetLength()+GetMountLen()*2,ptFirst);
stretchPoints.append(ptFirst); //出山长
return Acad::eOk;
}
Acad::ErrorStatus TDbMountRoof::subMoveStretchPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
XPoint vtOffset=*(XPoint *)&offset;
vtOffset.z = 0;
double nVtRot=CT_std_angle(ads_angle(XPoint(), vtOffset)-m_nRotation);
double nIncWidth=ads_distance(XPoint(), vtOffset) * cos(nVtRot);
double nIncLen=ads_distance(XPoint(), vtOffset) * sin(nVtRot);
int nLen=indices.length();
if(nLen>1)
{
m_ptLocation += vtOffset;
}
else if(nLen==1)
{
int idx=indices[0];
switch(idx)
{
case 1:
{
if(m_nWidth-nIncLen>_DIST_SNAP)
{
m_nWidth -= nIncLen;
ads_polar(m_ptLocation,m_nRotation+PI*0.5,nIncLen,m_ptLocation);
}
}
break;
case 2:
{
if(m_nWidth+nIncLen>_DIST_SNAP)
{
m_nWidth += nIncLen;
}
}
break;
case 3:
{
if(m_nLength-nIncWidth>_DIST_SNAP)
{
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3) //人字坡
{
m_nLength -= nIncWidth;
ads_polar(m_ptLocation,m_nRotation,nIncWidth,m_ptLocation);
}
else //四坡,歇山,攒尖
{
if (GetTopLength()<_DIST_SNAP //攒尖
)
{
m_nLength -= nIncWidth;
m_nSlopeAngle2=atan(GetRoofHeight()*2/GetLength());
ads_polar(m_ptLocation,m_nRotation,nIncWidth,m_ptLocation);
}
else if((((m_nLength-nIncWidth)*0.5)>(m_dRoofHeight-m_dMountHeight)/tan(GetSlopeAngle2())) //脊线长度>0
)
{
m_nLength -= nIncWidth;
ads_polar(m_ptLocation,m_nRotation,nIncWidth,m_ptLocation);
}
}
}
}
break;
case 4:
if(m_nLength+nIncWidth>_DIST_SNAP)
{
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3) //人字坡
{
m_nLength += nIncWidth;
}
else //四坡,歇山,攒尖
{
if (GetTopLength()<_DIST_SNAP //攒尖
)
{
m_nLength += nIncWidth;
m_nSlopeAngle2=atan(GetRoofHeight()*2/GetLength());
}
else if((((m_nLength+nIncWidth)*0.5)>(m_dRoofHeight-m_dMountHeight)/tan(GetSlopeAngle2())) //脊线长度>0
)
{
m_nLength += nIncWidth;
}
}
}
break;
default:
m_ptLocation += vtOffset;
}
}
return Acad::eOk;
}
//////////////////////////////////////////////////////////////////////
//动态输入
#if ADS>15
Acad::ErrorStatus TDbMountRoof::EntityToDim(long iGrip, long iDim, const AcDbEntity *pEnt)
{
AecDbGripDim *pDim = GetGripDim(iGrip, iDim);
if (pDim == NULL)
{
return Acad::eInvalidInput;
}
TDbMountRoof *pRoof = TDbMountRoof::cast(pEnt);
if (pRoof == NULL)
{
pRoof = this; //动态输入打开,查看夹点时,也显示标注
}
if (iGrip>8||iGrip<5) // 与基类处理相同
{
return Acad::eNotImplementedYet;
}
XPoly2D poly;
pRoof->GetPolyPath(poly);
poly.SetElevation(0);
XPoly2D polyIn(1);
XPoint pt=GetLocation();
polyIn.AppendNode(pt); //墙皮左下角点
ads_polar(pt,m_nRotation,GetLength(),pt);
polyIn.AppendNode(pt); //墙皮右下角点
ads_polar(pt,m_nRotation+PI*0.5,GetWidth(),pt);
polyIn.AppendNode(pt); //墙皮右上角点
ads_polar(pt,m_nRotation+PI,GetLength(),pt);
polyIn.AppendNode(pt); //墙皮左上角点
XPoint ptMidOut,ptNew, ptMidIn;
int nNum=iGrip-5;
if(iGrip==6)
{
nNum=2;
}
else if(iGrip==7)
{
nNum=3;
}
else if(iGrip==8)
{
nNum=1;
}
XDirectionCurve cvOut,cvIn;
poly.Nth(nNum,cvOut);
ptMidOut=cvOut.MidPoint();
polyIn.Nth(nNum,cvIn);
ptMidIn=cvIn.MidPoint();
double dAngle = 0,dDist=0;
dAngle = ads_angle(XPoint(), XVector3D(ptMidOut-ptMidIn));
dDist = ptMidOut.Distance(ptMidIn);
ads_polar(ptMidIn, dAngle, dDist, ptNew);
switch(iDim)
{
case 0: // 宽度
{
AecDbGripDistDim *pDistDim = (AecDbGripDistDim*)pDim;
pDistDim->SetData(ptMidIn, ptNew, _AS_SYS_UNIT(800));
}
return Acad::eNotImplementedYet;
break;
default:
return Acad::eNotImplementedYet;
}
return Acad::eOk;
}
Acad::ErrorStatus TDbMountRoof::DimToEntity(long iGrip, long iDim, double newValue, const AcGeVector3d& offset)
{
assertWriteEnabled();
if (iGrip>8||iGrip<5) // 与基类处理相同
{
return Acad::eNotImplementedYet;
}
double dNewDist(newValue);
switch(iDim)
{
case 0: // 宽度
if(dNewDist < 0)
break;
if(iGrip==5||iGrip==7)
{
m_dEavesLen = dNewDist;
}
else
{
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3) //人字坡
{
m_dMountLen = dNewDist;
}
else
{
m_dEavesLen = dNewDist*tan(GetSlopeAngle2())/tan(GetSlopeAngle1());
}
}
break;
default:
return Acad::eNotImplementedYet;
}
return Acad::eOk;
}
#endif
void TDbMountRoof::UnionScale(double nScale)
{
assertWriteEnabled();
double nOldElev=GetElevation();
AecEntity::UnionScale(nScale);
SetElevation(nOldElev*nScale);
m_nSlabThick*=nScale; //板厚
m_nWidth*=nScale; //屋顶宽
m_nLength*=nScale; //屋顶长
m_dRoofHeight*=nScale; //高度
m_dEavesLen*=nScale; //出檐长
m_dMountLen*=nScale; //出山长
m_dMountHeight*=nScale; //歇山高
}
BOOL TDbMountRoof::IsValid() const
{
BOOL bRet=AecEntity::IsValid();
if(!bRet)
return bRet;
bRet=(m_nLength>_DIST_SNAP
&&m_nWidth>_DIST_SNAP
&&m_nSlopeAngle2>0
&&m_nSlopeAngle2<PI*0.5+1E-5
&&m_dEavesLen>=0
&&m_dRoofHeight>=m_dMountHeight
&&m_dMountHeight>=0
);
if(!bRet)
return bRet;
if (m_dRoofHeight-m_dMountHeight<_DIST_SNAP //高度设置的人字坡
||fabs(cos(m_nSlopeAngle2))<1E-3 //转化的人字坡
)
{
return m_dMountLen>=0; //出山长不为负
}
else if (m_dMountHeight<_DIST_SNAP) //四坡或攒尖屋顶
{
return (m_nLength*0.5) - m_dRoofHeight/tan(m_nSlopeAngle2) > -_DIST_SNAP;
}
else //歇山屋顶
{
return (m_nLength*0.5)>(m_dRoofHeight-m_dMountHeight)/tan(m_nSlopeAngle2);
}
return bRet;
}
bool TDbMountRoof::IsClipMe(const AEntityBase* pEnt)const
{
return false;
}
void TDbMountRoof::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbPolyPathEnt::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbMountRoof *pSrc=TDbMountRoof::cast(pSrcEntity);
if(pSrc)
{
m_nLength = pSrc->m_nLength;
m_nWidth = pSrc->m_nWidth;
m_dRoofHeight = pSrc->m_dRoofHeight;
m_dMountHeight = pSrc->m_dMountHeight;
m_dEavesLen = pSrc->m_dEavesLen;
m_nSlopeAngle2 = pSrc->m_nSlopeAngle2;
m_bShowSide = pSrc->m_bShowSide;
m_dMountLen = pSrc->m_dMountLen;
}
}
void TDbMountRoof::GetTips(DList<ObjInfoUnit> &lstInfo) const
{
lstInfo.Append(new ObjInfoUnit(_T("对象类型") ,_T("矩形屋顶")));
if (!(GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3
||GetMountHeight()<_DIST_SNAP)) //歇山
{
lstInfo.Append(new ObjInfoUnit(_T("歇山高"), Dist2Str(GetMountHeight())));
}
lstInfo.Append(new ObjInfoUnit(_T("屋顶高"), Dist2Str(GetRoofHeight())));
lstInfo.Append(new ObjInfoUnit(_T("出檐长"), Dist2Str(GetEavesLen())));
lstInfo.Append(new ObjInfoUnit(_T("出山长"), Dist2Str(GetMountLen())));
}
Acad::ErrorStatus TDbMountRoof::GetGripText(int i, CString &cs) const
{
if(i==0)
cs=GetCtrlToggle()? _T("移动屋顶0(Ctrl-中心旋转)") : _T("中心旋转0(Ctrl-移动屋顶)");
else if(i==1||i==2||i==3||i==4)
{
cs=_T("调整屋顶大小");
}
else if(i==5||i==6||i==7||i==8)
{
cs=_T("调整出檐长和出山长");
}
else
{
cs=_T("调整脊线长");
}
return Acad::eOk;
}
const TCHAR *TDbMountRoof::GetDefaultLayer() const
{
return LAY_ROOF;
}
Acad::ErrorStatus TDbMountRoof::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
if(GetLength()<_DIST_SNAP
||GetWidth()<_DIST_SNAP
)
return Acad::eOk;
XPoly2D poly;
GetPolyPath(poly);
XLine leftLine, rightLine, midLine;
GetMountLine(leftLine,rightLine,midLine);
XLine midLine0;
midLine0=midLine;
midLine0.StartPoint().z+=m_nSlabThick;
midLine0.EndPoint().z+=m_nSlabThick;
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3
||GetMountHeight()<_DIST_SNAP) //人字屋顶,四坡屋顶,攒尖屋顶
{
if (poly.Length()!=4)
return Acad::eOk;
XCurveSegment e0,e1;
poly.Nth(0,e0);
e1=e0;
e1.StartPoint().z+=m_nSlabThick;
e1.EndPoint().z+=m_nSlabThick;
//前后檐屋顶面
X3DFace face;
face.SetFlag(0);
face.GetVertex(0)=midLine.EndPoint();
face.GetVertex(1)=e0.EndPoint();
face.GetVertex(2)=e0.StartPoint();
face.GetVertex(3)=midLine.StartPoint();
dc.DrawFace(face); //主坡内面
face.GetVertex(0)=midLine0.StartPoint();
face.GetVertex(1)=e1.StartPoint();
face.GetVertex(2)=e1.EndPoint();
face.GetVertex(3)=midLine0.EndPoint();
dc.DrawFace(face); //主坡外面
face.GetVertex(0)=e0.StartPoint();
face.GetVertex(1)=e0.EndPoint();
face.GetVertex(2)=e1.EndPoint();
face.GetVertex(3)=e1.StartPoint();
dc.DrawFace(face); //主坡立面
poly.Nth(2,e0);
e1=e0;
e1.StartPoint().z+=m_nSlabThick;
e1.EndPoint().z+=m_nSlabThick;
face.GetVertex(0)=midLine.StartPoint();
face.GetVertex(1)=e0.EndPoint();
face.GetVertex(2)=e0.StartPoint();
face.GetVertex(3)=midLine.EndPoint();
dc.DrawFace(face); //主坡内面
face.GetVertex(0)=midLine0.EndPoint();
face.GetVertex(1)=e1.StartPoint();
face.GetVertex(2)=e1.EndPoint();
face.GetVertex(3)=midLine0.StartPoint();
dc.DrawFace(face); //主坡外面
face.GetVertex(0)=e0.StartPoint();
face.GetVertex(1)=e0.EndPoint();
face.GetVertex(2)=e1.EndPoint();
face.GetVertex(3)=e1.StartPoint();
dc.DrawFace(face); //主坡立面
//山墙屋顶面
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3) //人字屋顶
{
if (IsShowSide()) //显示侧坡
{
poly.Nth(1,e0);
e1=e0;
e1.StartPoint().z+=m_nSlabThick;
e1.EndPoint().z+=m_nSlabThick;
X3DFace face1;
face1.SetFlag(0);
face1.GetVertex(0)=midLine0.EndPoint();
face1.GetVertex(1)=e1.StartPoint();
face1.GetVertex(2)=e1.EndPoint();
face1.GetVertex(3)=midLine0.EndPoint();
dc.DrawFace(face1); //侧坡面
face1.GetVertex(0)=e1.StartPoint();
face1.GetVertex(1)=e0.StartPoint();
face1.GetVertex(2)=e0.EndPoint();
face1.GetVertex(3)=e1.EndPoint();
dc.DrawFace(face1); //侧坡立面
poly.Nth(3,e0);
e1=e0;
e1.StartPoint().z+=m_nSlabThick;
e1.EndPoint().z+=m_nSlabThick;
face1.GetVertex(0)=midLine0.StartPoint();
face1.GetVertex(1)=e1.StartPoint();
face1.GetVertex(2)=e1.EndPoint();
face1.GetVertex(3)=midLine0.StartPoint();
dc.DrawFace(face1); //侧坡面
face1.GetVertex(0)=e1.StartPoint();
face1.GetVertex(1)=e0.StartPoint();
face1.GetVertex(2)=e0.EndPoint();
face1.GetVertex(3)=e1.EndPoint();
dc.DrawFace(face1); //侧坡立面
}
}
else //四坡屋顶,攒尖屋顶
{
poly.Nth(1,e0);
e1=e0;
e1.StartPoint().z+=m_nSlabThick;
e1.EndPoint().z+=m_nSlabThick;
X3DFace face1;
face1.SetFlag(0);
face1.GetVertex(0)=midLine0.EndPoint();
face1.GetVertex(1)=e1.StartPoint();
face1.GetVertex(2)=e1.EndPoint();
face1.GetVertex(3)=midLine0.EndPoint();
dc.DrawFace(face1); //侧坡外面
face1.GetVertex(0)=midLine.EndPoint();
face1.GetVertex(1)=e0.EndPoint();
face1.GetVertex(2)=e0.StartPoint();
face1.GetVertex(3)=midLine.EndPoint();
dc.DrawFace(face1); //侧坡内面
face1.GetVertex(0)=e1.StartPoint();
face1.GetVertex(1)=e0.StartPoint();
face1.GetVertex(2)=e0.EndPoint();
face1.GetVertex(3)=e1.EndPoint();
dc.DrawFace(face1); //侧坡立面
poly.Nth(3,e0);
e1=e0;
e1.StartPoint().z+=m_nSlabThick;
e1.EndPoint().z+=m_nSlabThick;
face1.GetVertex(0)=midLine0.StartPoint();
face1.GetVertex(1)=e1.StartPoint();
face1.GetVertex(2)=e1.EndPoint();
face1.GetVertex(3)=midLine0.StartPoint();
dc.DrawFace(face1); //侧坡外面
face1.GetVertex(0)=midLine.StartPoint();
face1.GetVertex(1)=e0.EndPoint();
face1.GetVertex(2)=e0.StartPoint();
face1.GetVertex(3)=midLine.StartPoint();
dc.DrawFace(face1); //侧坡内面
face1.GetVertex(0)=e1.StartPoint();
face1.GetVertex(1)=e0.StartPoint();
face1.GetVertex(2)=e0.EndPoint();
face1.GetVertex(3)=e1.EndPoint();
dc.DrawFace(face1); //侧坡立面
}
}
else //歇山屋顶
{
XPoly2D poly0(1);
poly0.AppendNode(leftLine.StartPoint());
poly0.AppendNode(rightLine.StartPoint());
poly0.AppendNode(rightLine.EndPoint());
poly0.AppendNode(leftLine.EndPoint());
for(int i=0;i<poly.TotalSegments();i++)
{
XCurveSegment e0,e1,e2,e3;
poly.Nth(i,e0);
e1=e0;
e1.StartPoint().z+=m_nSlabThick;
e1.EndPoint().z+=m_nSlabThick;
poly0.Nth(i,e2);
e3=e2;
e3.StartPoint().z+=m_nSlabThick;
e3.EndPoint().z+=m_nSlabThick;
X3DFace face;
face.SetFlag(0);
face.GetVertex(0)=e0.StartPoint();
face.GetVertex(1)=e0.EndPoint();
face.GetVertex(2)=e1.EndPoint();
face.GetVertex(3)=e1.StartPoint();
dc.DrawFace(face); //立面
face.GetVertex(0)=e2.EndPoint();
face.GetVertex(1)=e0.EndPoint();
face.GetVertex(2)=e0.StartPoint();
face.GetVertex(3)=e2.StartPoint();
if(i%2==0)
face.SetVisible(3,FALSE);
dc.DrawFace(face); //坡内面
face.GetVertex(0)=e3.StartPoint();
face.GetVertex(1)=e1.StartPoint();
face.GetVertex(2)=e1.EndPoint();
face.GetVertex(3)=e3.EndPoint();
if(i%2==0)
face.SetVisible(3,FALSE);
dc.DrawFace(face); //坡外面
}
if(midLine.GetLength()>_DIST_SNAP&&poly0.TotalSegments()==4)
{
XCurveSegment e0,e1;
poly0.Nth(0,e0);
e1=e0;
e1.StartPoint().z+=m_nSlabThick;
e1.EndPoint().z+=m_nSlabThick;
X3DFace face;
face.SetFlag(0);
face.GetVertex(0)=e0.StartPoint();
face.GetVertex(1)=midLine.StartPoint();
face.GetVertex(2)=midLine.EndPoint();
face.GetVertex(3)=e0.EndPoint();
face.SetVisible(3,FALSE);
dc.DrawFace(face); //坡内面
X3DFace face1;
face1.SetFlag(0);
face1.GetVertex(0)=e1.StartPoint();
face1.GetVertex(1)=e1.EndPoint();
face1.GetVertex(2)=midLine0.EndPoint();
face1.GetVertex(3)=midLine0.StartPoint();
face1.SetVisible(0,FALSE);
dc.DrawFace(face1); //坡外面
poly0.Nth(2,e0);
e1=e0;
e1.StartPoint().z+=m_nSlabThick;
e1.EndPoint().z+=m_nSlabThick;
X3DFace face2;
face2.SetFlag(0);
face2.GetVertex(0)=e0.StartPoint();
face2.GetVertex(1)=midLine.EndPoint();
face2.GetVertex(2)=midLine.StartPoint();
face2.GetVertex(3)=e0.EndPoint();
face2.SetVisible(3,FALSE);
dc.DrawFace(face2); //坡内面
X3DFace face3;
face3.SetFlag(0);
face3.GetVertex(0)=e1.StartPoint();
face3.GetVertex(1)=e1.EndPoint();
face3.GetVertex(2)=midLine0.StartPoint();
face3.GetVertex(3)=midLine0.EndPoint();
face3.SetVisible(0,FALSE);
dc.DrawFace(face3); //坡外面
poly0.Nth(1,e0);
e1=e0;
e1.StartPoint().z+=m_nSlabThick;
e1.EndPoint().z+=m_nSlabThick;
X3DFace face4;
face4.SetFlag(0);
face4.GetVertex(0)=midLine0.EndPoint();
face4.GetVertex(1)=e1.StartPoint();
face4.GetVertex(2)=e1.EndPoint();
face4.GetVertex(3)=midLine0.EndPoint();
dc.DrawFace(face4); //山头面
poly0.Nth(3,e0);
e1=e0;
e1.StartPoint().z+=m_nSlabThick;
e1.EndPoint().z+=m_nSlabThick;
face4.GetVertex(0)=midLine0.StartPoint();
face4.GetVertex(1)=e1.StartPoint();
face4.GetVertex(2)=e1.EndPoint();
face4.GetVertex(3)=midLine0.StartPoint();
dc.DrawFace(face4); //山头面
}
}
return Acad::eOk;
}
Acad::ErrorStatus TDbMountRoof::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
if(GetLength()<_DIST_SNAP
||GetWidth()<_DIST_SNAP
)
return Acad::eOk;
XPoly2D poly;
GetPolyPath(poly);
poly.SetElevation(0);
dc<<poly;
XLine leftLine, rightLine, midLine;
GetMountLine(leftLine,rightLine,midLine);
midLine.SetElevation(0);
if(midLine.GetLength()>_DIST_SNAP)
dc<<midLine;
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP
||fabs(cos(GetSlopeAngle2()))<1E-3) //人字屋顶
{
return Acad::eOk;
}
else if (GetMountHeight()<_DIST_SNAP) //四坡屋顶或攒尖屋顶
{
if(poly.Length()==4)
{
dc<<XLine(midLine.StartPoint(),*poly[0]);
dc<<XLine(midLine.EndPoint(),*poly[1]);
dc<<XLine(midLine.EndPoint(),*poly[2]);
dc<<XLine(midLine.StartPoint(),*poly[3]);
}
return Acad::eOk;
}
else //歇山屋顶
{
leftLine.SetElevation(0);
if(leftLine.GetLength()>_DIST_SNAP)
dc<<XLine(leftLine.StartPoint(),leftLine.EndPoint());
rightLine.SetElevation(0);
if(rightLine.GetLength()>_DIST_SNAP)
dc<<rightLine;
if(poly.Length()==4)
{
dc<<XLine(leftLine.StartPoint(),*poly[0]);
dc<<XLine(leftLine.EndPoint(),*poly[3]);
dc<<XLine(rightLine.StartPoint(),*poly[1]);
dc<<XLine(rightLine.EndPoint(),*poly[2]);
}
}
return Acad::eOk;
}
void TDbMountRoof::GetMountLine(XLine &leftLine,XLine &rightLine,XLine &midLine)const
{
XPoint pt=GetLocation();
//modify by aec on 090713 调整基点标高
//pt.z+=GetRoofHeight();
pt.z+=(GetRoofHeight()-m_nSlabThick);
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP||fabs(cos(GetSlopeAngle2()))<1E-3)//人字屋顶
{
ads_polar(pt,m_nRotation+PI*0.5,GetWidth()*0.5,pt);
ads_polar(pt,m_nRotation+PI,GetMountLen(),pt);
midLine.StartPoint() = pt; //屋脊线起点
ads_polar(pt,m_nRotation,GetTopLength(),pt);
midLine.EndPoint() = pt; //屋脊线终点
}
else if (GetMountHeight()<_DIST_SNAP) //四坡屋顶或攒尖屋顶
{
double dDist=GetRoofHeight()/tan(GetSlopeAngle2());//侧坡在平面上的间距
ads_polar(pt,m_nRotation+PI*0.5,GetWidth()*0.5,pt);
ads_polar(pt,m_nRotation,dDist,pt);
midLine.StartPoint() = pt; //屋脊线起点
ads_polar(pt,m_nRotation,GetTopLength(),pt);
midLine.EndPoint() = pt; //屋脊线终点
}
else //歇山屋顶
{
double dWidth=GetMountHeight()/tan(GetSlopeAngle1());//歇山半宽
double dDist=(GetRoofHeight()-GetMountHeight())/tan(GetSlopeAngle2());//侧坡在平面上的间距
pt.z-=GetMountHeight();
ads_polar(pt,m_nRotation,dDist,pt);
ads_polar(pt,m_nRotation+PI*0.5,GetWidth()*0.5-dWidth,pt);
leftLine.StartPoint() = pt; //歇山左下角点
ads_polar(pt,m_nRotation+PI*0.5,dWidth*2,pt);
leftLine.EndPoint() = pt; //歇山左上角点
ads_polar(leftLine.StartPoint(),m_nRotation,GetLength()-dDist*2,pt);
rightLine.StartPoint() = pt; //歇山右下角点
ads_polar(leftLine.EndPoint(),m_nRotation,GetLength()-dDist*2,pt);
rightLine.EndPoint() = pt; //歇山右上角点
Midpoint(leftLine.StartPoint(),leftLine.EndPoint(),pt);
pt.z=GetLocation().z+GetRoofHeight()-m_nSlabThick;
midLine.StartPoint() = pt; //屋脊线起点
ads_polar(pt,m_nRotation,GetLength()-dDist*2,pt);
midLine.EndPoint() = pt; //屋脊线终点
}
}
void TDbMountRoof::GetPolyPath(XPoly2D& poly)const
{
poly.SetFlag(1);
poly.Reset();
double dHeight=0;//屋檐产生的高差
dHeight=GetEavesLen()*tan(GetSlopeAngle1());
XPoint pt=GetLocation();
//modify by aec on 090713 调整基点标高
//pt.z -= dHeight;
pt.z -= (dHeight+m_nSlabThick);
ads_polar(pt,m_nRotation+PI,GetMountLen(),pt);
ads_polar(pt,m_nRotation-PI*0.5,GetEavesLen(),pt);
poly.AppendNode(pt); //屋顶左下角点
ads_polar(pt,m_nRotation,GetMountLen()*2+GetLength(),pt);
poly.AppendNode(pt); //屋顶右下角点
ads_polar(pt,m_nRotation+PI*0.5,GetEavesLen()*2+GetWidth(),pt);
poly.AppendNode(pt); //屋顶右上角点
ads_polar(pt,m_nRotation+PI,GetMountLen()*2+GetLength(),pt);
poly.AppendNode(pt); //屋顶左上角点
}
Acad::ErrorStatus TDbMountRoof::GetPathPoly(XPoly2D &polyPath,AcGeVector3d&normal) const
{
assertReadEnabled();
normal=AcGeVector3d::kZAxis;
GetPolyPath(polyPath);
return Acad::eOk;
}
XPoint TDbMountRoof::GetLocation()const
{
assertReadEnabled();
return m_ptLocation;
}
void TDbMountRoof::SetLocation(const XPoint &pt)
{
assertWriteEnabled();
m_ptLocation=pt;
}
double TDbMountRoof::GetRotation()const
{
assertReadEnabled();
return m_nRotation;
}
void TDbMountRoof::SetRotation(double d)
{
assertWriteEnabled();
m_nRotation=d;
}
double TDbMountRoof::GetEavesLen()const
{
assertReadEnabled();
return m_dEavesLen;
}
void TDbMountRoof::SetEavesLen(double d)
{
assertWriteEnabled();
m_dEavesLen=d;
}
double TDbMountRoof::GetMountLen()const
{
assertReadEnabled();
double dMountLen=0;
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP||fabs(cos(GetSlopeAngle2()))<1E-3)//人字坡
{
return m_dMountLen;
}
else
{
dMountLen=GetEavesLen()*tan(GetSlopeAngle1())/tan(GetSlopeAngle2());
}
return dMountLen;
}
void TDbMountRoof::SetMountLen(double d)//出山长
{
assertWriteEnabled();
m_dMountLen=d;
}
double TDbMountRoof::GetLength()const
{
assertReadEnabled();
return m_nLength;
}
void TDbMountRoof::SetLength(double d)
{
assertWriteEnabled();
if(d>_DIST_SNAP)
m_nLength=d;
}
double TDbMountRoof::GetWidth()const
{
assertReadEnabled();
return m_nWidth;
}
void TDbMountRoof::SetWidth(double d)
{
assertWriteEnabled();
if(d>_DIST_SNAP)
m_nWidth=d;
}
double TDbMountRoof::GetSlopeAngle1()const
{
assertReadEnabled();
double nSlopeAngle1=PI/6.0;
if(GetWidth()>_DIST_SNAP)
{
nSlopeAngle1=atan(GetRoofHeight()*2/GetWidth());
}
return nSlopeAngle1;
}
void TDbMountRoof::SetSlopeAngle1(double d)
{
assertWriteEnabled();
if(d>0)
m_nSlopeAngle1=d;
}
double TDbMountRoof::GetSlopeAngle2()const
{
assertReadEnabled();
return m_nSlopeAngle2;
}
void TDbMountRoof::SetSlopeAngle2(double d)
{
assertWriteEnabled();
if(d>0)
m_nSlopeAngle2=d;
}
double TDbMountRoof::GetMountHeight()const
{
assertReadEnabled();
return m_dMountHeight;
}
void TDbMountRoof::SetMountHeight(double d)
{
assertWriteEnabled();
m_dMountHeight=d;
}
double TDbMountRoof::GetRoofHeight()const
{
assertReadEnabled();
return m_dRoofHeight;
}
void TDbMountRoof::SetRoofHeight(double d)
{
assertWriteEnabled();
m_dRoofHeight=d;
}
double TDbMountRoof::GetTopLength()const
{
assertReadEnabled();
double dTopLength=0;
if (GetRoofHeight()-GetMountHeight()<_DIST_SNAP||fabs(cos(GetSlopeAngle2()))<1E-3)//人字坡
{
dTopLength=GetMountLen()*2+GetLength();
}
else
{
double dDist=(GetRoofHeight()-GetMountHeight())/tan(GetSlopeAngle2());//侧坡在平面上的间距
if (GetLength()-dDist*2>_DIST_SNAP) //歇山屋顶,四坡屋顶
{
dTopLength=GetLength()-dDist*2;
}
}
return dTopLength;
}
void TDbMountRoof::SetShowSide(Adesk::Boolean bTrue)
{
assertWriteEnabled();
m_bShowSide=bTrue;
}
Adesk::Boolean TDbMountRoof::IsShowSide()const
{
return m_bShowSide;
}
// aec add 100722,支持统一标高
bool TDbMountRoof::UnifyElevation(double dElevation)
{
SetElevation(dElevation);
return true;
}
void InitDbMountRoof(BOOL bTrue)
{
if(bTrue) {
TDbMountRoof::rxInit();
acrxBuildClassHierarchy();
TDbMountRoof::InitMatchProtocol(TRUE);
} else {
TDbMountRoof::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbMountRoof::desc());
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//1:AEC7;2:AEC8
const Adesk::UInt8 TDbCuspRoof::g_nVersion=2;
ACRX_DXF_DEFINE_MEMBERS(TDbCuspRoof,TDbPolyPathEnt, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, AEC_CUSPROOF,"AEC_KERNAL|缺乏图形解释器, 请下载插件");
IMPLEMENT_TENTBASE(TDbCuspRoof);
void TDbCuspRoof::GetPolyPath(XPoly2D& poly)const
{
poly.SetFlag(1);
poly.Reset();
double nAngle=PI*2.0/m_nSideNum;
//add by aec on 090225
if(GetRadius()<_DIST_SNAP || m_nSideNum < 2)
return;
//add by aec on 081223
double dEaves=GetEavesLen()/cos(PI/GetSideNum());
XPoint ptCenter=m_ptCenter;
ptCenter.z-=((GetHeight()-m_nSlabThick)*GetEavesLen()/(GetRadius()*cos(PI/GetSideNum()))+m_nSlabThick);
for(long i=0;i<m_nSideNum;i++)
{
XPoint pt;
ads_polar(ptCenter,m_nRotation+i*nAngle,m_nRadius+dEaves,pt);
poly.AppendNode(pt);
}
}
Acad::ErrorStatus TDbCuspRoof::GetPathPoly(XPoly2D &polyPath,AcGeVector3d&normal) const
{
assertReadEnabled();
normal=AcGeVector3d::kZAxis;
GetPolyPath(polyPath);
return Acad::eOk;
}
BOOL TDbCuspRoof::IsValid()const
{
if(!TDbPolyPathEnt::IsValid())
return FALSE;
return m_nSideNum>2&&m_nRadius>1E-6;
}
bool TDbCuspRoof::IsClipMe(const AEntityBase* pEnt)const
{
return false;
}
void TDbCuspRoof::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbPolyPathEnt::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbCuspRoof *pSrc=TDbCuspRoof::cast(pSrcEntity);
if(pSrc) {
}
}
Acad::ErrorStatus TDbCuspRoof::subGetClassID(CLSID* pClsid) const
{
*pClsid=CLSID_ComCuspRoof;
return Acad::eOk;
return AcDbEntity::subGetClassID(pClsid);
}
// 从DWG读入数据:
Acad::ErrorStatus TDbCuspRoof::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)
return Acad::eMakeMeProxy;
es=TRoofBase::Read(pFiler);
if(es!=Acad::eOk)return es;
AcGePoint3d pt;
pFiler->readItem(&pt);
m_ptCenter=pt;
pFiler->readItem(&m_nRotation);
pFiler->readItem(&m_nHeight);
pFiler->readItem(&m_nRadius);
pFiler->readItem(&m_nSideNum);
//add by aec on 081223
if(nVer>1)
{
pFiler->readItem(&m_dEavesLen);
}
else
{
//modify by aec on 090721 屋顶高为到基点的高度
//m_nHeight += m_nSlabThick;
//del by aec on 090713调整标高,与日照0出檐长时一致
//m_ptCenter.z -= m_nSlabThick;
m_dEavesLen = 0;
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbCuspRoof::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbPolyPathEnt::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
if(g_nSaveTArchVer<8)
pFiler->writeItem((Adesk::UInt8)1);
else
pFiler->writeItem(g_nVersion);
es=TRoofBase::Write(pFiler);
if(es!=Acad::eOk)return es;
if(g_nSaveTArchVer<8)
{
//modify by aec on 090721 屋顶高为到基点的高度
//double dHeight = m_nHeight-m_nSlabThick;//出檐长产生的高差
double dHeight = m_nHeight;//出檐长产生的高差
dHeight=dHeight*m_dEavesLen/(m_nRadius*cos(PI/m_nSideNum));
double nRadius = m_nRadius+(m_dEavesLen/cos(PI/m_nSideNum));
double nHeight=m_nHeight +dHeight/*-m_nSlabThick*/;
XPoint ptCenter=m_ptCenter;
ptCenter.z-=(dHeight/*-m_nSlabThick*/);
pFiler->writeItem(ptCenter.AsAcGePoint3d());
pFiler->writeItem(m_nRotation);
pFiler->writeItem(nHeight);
pFiler->writeItem(nRadius);
pFiler->writeItem(m_nSideNum);
}
else
{
pFiler->writeItem(m_ptCenter.AsAcGePoint3d());
pFiler->writeItem(m_nRotation);
pFiler->writeItem(m_nHeight);
pFiler->writeItem(m_nRadius);
pFiler->writeItem(m_nSideNum);
pFiler->writeItem(m_dEavesLen);
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbCuspRoof::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbPolyPathEnt::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbCuspRoof"))) {
return Acad::eBadDxfSequence;
}
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbCuspRoof::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es;
es = TDbPolyPathEnt::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbCuspRoof"));
assert(es == Acad::eOk);
return es;
}
Acad::ErrorStatus TDbCuspRoof::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
AecEntity::subTransformBy(xform);
m_ptCenter.TransformBy(xform);
AcGeVector3d vt(cos(m_nRotation),sin(m_nRotation),0);
vt.transformBy(xform);
AcGeVector2d vt2d(vt.x,vt.y);
m_nRotation=vt2d.angle();
return Acad::eOk;
}
void TDbCuspRoof::UnionScale(double nScale)
{
assertWriteEnabled();
double nOldElev=GetElevation();
AecEntity::UnionScale(nScale);
SetElevation(nOldElev*nScale);
m_nSlabThick*=nScale;//板厚
m_nRidgeWidth*=nScale;
m_nRidgeHeight*=nScale;//屋脊大小
m_nHeight*=nScale;//高度
m_nRadius*=nScale;//半径
m_dEavesLen*=nScale;//出檐长 add by fxj 090916
}
Acad::ErrorStatus TDbCuspRoof::GetGripText(int i, CString &cs) const
{
if(i==0)
cs=_T("移动");
else if(i==1)
cs=_T("调整半径和角度");
else
cs=_T("调整出檐长");
return Acad::eOk;
}
Acad::ErrorStatus TDbCuspRoof::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
gripPoints.append(m_ptCenter);
XPoint ptFirst;
ads_polar(m_ptCenter,m_nRotation,m_nRadius,ptFirst);
gripPoints.append(ptFirst);
//add by aec on 081224
ads_polar(m_ptCenter,m_nRotation+PI/m_nSideNum,m_nRadius*cos(PI/m_nSideNum)+m_dEavesLen,ptFirst);
gripPoints.append(ptFirst); //出檐长
return Acad::eOk;
}
Acad::ErrorStatus TDbCuspRoof::subMoveGripPointsAt(const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
for(long i=0;i<indices.length();i++)
{
int iGrip=indices[i];
if(iGrip==0)
m_ptCenter+=offset;
else if(iGrip==1)
{
AcGeVector2d vt0(m_nRadius*cos(m_nRotation),m_nRadius*sin(m_nRotation));
AcGeVector2d vt=vt0+AcGeVector2d(offset.x,offset.y);
m_nRadius=vt.length();
m_nRotation=vt.angle();
}
//add by aec on 081224
else
{
XPoint vtOffset=*(XPoint *)&offset;
vtOffset.z = 0;
double nVtRot=CT_std_angle(ads_angle(XPoint(), vtOffset)-(m_nRotation+PI/m_nSideNum));
double nIncWidth=ads_distance(XPoint(), vtOffset) * cos(nVtRot);
if(m_dEavesLen+nIncWidth>_DIST_SNAP)
{
m_dEavesLen+=nIncWidth;
}
else if(fabs(m_dEavesLen+nIncWidth)<_DIST_SNAP)
{
m_dEavesLen = 0;
}
}
}
return Acad::eOk;
}
Acad::ErrorStatus TDbCuspRoof::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
Acad::ErrorStatus es=Acad::eOk;
XPoly2D poly;
GetPolyPath(poly);
poly.SetElevation(0);
dc<<poly;
for(long i=0;i<poly.Length();i++)
{
XPoint ptCenter=m_ptCenter;
ptCenter.z=0;
dc<<XLine(ptCenter,*poly[i]);
}
return es;
}
Acad::ErrorStatus TDbCuspRoof::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
Acad::ErrorStatus es=Acad::eOk;
XPoly2D poly;
GetPolyPath(poly);
// for(long i=0;i<poly.Length();i++)
// poly[i]->z-=m_nSlabThick;
XPoint ptTop=m_ptCenter,ptTop1=m_ptCenter;
ptTop.z+=m_nHeight-m_nSlabThick; //下
ptTop1.z+=m_nHeight/*-m_nSlabThick*/; //上
for(long i=0;i<poly.TotalSegments();i++)
{
XCurveSegment e0,e1;
poly.Nth(i,e0);
e1=e0;
e1.StartPoint().z+=m_nSlabThick;
e1.EndPoint().z+=m_nSlabThick;
X3DFace face;
face.SetFlag(0);
face.GetVertex(0)=e0.StartPoint();
face.GetVertex(1)=e0.EndPoint();
face.GetVertex(2)=e1.EndPoint();
face.GetVertex(3)=e1.StartPoint();
dc.DrawFace(face);
face.GetVertex(0)=ptTop;
face.GetVertex(1)=e0.EndPoint();
face.GetVertex(2)=e0.StartPoint();
face.GetVertex(3)=ptTop;
dc.DrawFace(face);
face.GetVertex(0)=ptTop1;
face.GetVertex(1)=e1.StartPoint();
face.GetVertex(2)=e1.EndPoint();
face.GetVertex(3)=ptTop1;
dc.DrawFace(face);
}
return es;
}
void TDbCuspRoof::GetTips(DList<ObjInfoUnit> &lstInfo) const
{
lstInfo.Append(new ObjInfoUnit(_T("对象类型") ,_T("攒尖屋顶")));
}
const TCHAR * TDbCuspRoof::GetDefaultLayer() const
{
return LAY_ROOF;
}
//add by aec on 081223
double TDbCuspRoof::GetEavesLen()const
{
assertReadEnabled();
return m_dEavesLen;
}
void TDbCuspRoof::SetEavesLen(double d)
{
assertWriteEnabled();
m_dEavesLen=d;
}
//动态输入
#if ADS>15
Acad::ErrorStatus TDbCuspRoof::EntityToDim(long iGrip, long iDim, const AcDbEntity *pEnt)
{
AecDbGripDim *pDim = GetGripDim(iGrip, iDim);
if (pDim == NULL)
{
return Acad::eInvalidInput;
}
TDbCuspRoof *pRoof = TDbCuspRoof::cast(pEnt);
if (pRoof == NULL)
{
pRoof = this; //动态输入打开,查看夹点时,也显示标注
}
if (iGrip!=2) // 与基类处理相同
{
return Acad::eNotImplementedYet;
}
XPoly2D poly;
pRoof->GetPolyPath(poly);
poly.SetElevation(0);
XPoly2D polyIn(1);
XPoint ptCenter=m_ptCenter;
double nAngle=PI*2.0/m_nSideNum;
for(long i=0;i<m_nSideNum;i++)
{
XPoint pt;
ads_polar(ptCenter,m_nRotation+i*nAngle,m_nRadius,pt);
polyIn.AppendNode(pt);
}
XPoint ptMidOut,ptNew, ptMidIn;
int nNum=iGrip-2;
XDirectionCurve cvOut,cvIn;
poly.Nth(nNum,cvOut);
ptMidOut=cvOut.MidPoint();
polyIn.Nth(nNum,cvIn);
ptMidIn=cvIn.MidPoint();
double dAngle = 0,dDist=0;
dAngle = ads_angle(XPoint(), XVector3D(ptMidOut-ptMidIn));
dDist = ptMidOut.Distance(ptMidIn);
ads_polar(ptMidIn, dAngle, dDist, ptNew);
switch(iDim)
{
case 0: // 宽度
{
AecDbGripDistDim *pDistDim = (AecDbGripDistDim*)pDim;
pDistDim->SetData(ptMidIn, ptNew, _AS_SYS_UNIT(800));
}
return Acad::eNotImplementedYet;
break;
default:
return Acad::eNotImplementedYet;
}
return Acad::eOk;
}
Acad::ErrorStatus TDbCuspRoof::DimToEntity(long iGrip, long iDim, double newValue, const AcGeVector3d& offset)
{
assertWriteEnabled();
if (iGrip!=2) // 与基类处理相同
{
return Acad::eNotImplementedYet;
}
double dNewDist(newValue);
switch(iDim)
{
case 0: // 宽度
if(dNewDist < 0)
break;
m_dEavesLen = dNewDist;
break;
default:
return Acad::eNotImplementedYet;
}
return Acad::eOk;
}
#endif
// aec add 101115,支持统一标高
bool TDbCuspRoof::UnifyElevation(double dElevation)
{
assertWriteEnabled();
SetElevation(dElevation);
return true;
}
void InitDbCuspRoof(BOOL bTrue)
{
if(bTrue) {
TDbCuspRoof::rxInit();
acrxBuildClassHierarchy();
TDbCuspRoof::InitMatchProtocol(TRUE);
} else {
TDbCuspRoof::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbCuspRoof::desc());
}
}