3786 lines
95 KiB
C++
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());
|
|
}
|
|
}
|