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

1786 lines
52 KiB
C++

#include "stdafx.h"
#include "wall_xdata_key.h"
ACRX_DXF_DEFINE_MEMBERS(ATSCurtainWall, ATSWall, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_CURTAIN_WALL, "ATS_CURTAIN_WALL图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbCurtainWall);
//TArch6:1;TArch7:2
const Adesk::UInt8 TDbCurtainWall::g_nVersion=2;
TDbCurtainWall::TDbCurtainWall()
:m_colAlign(kCenter), //挺的对齐位置
m_uCol(_AS_SYS_UNIT(100.0)), m_vCol(_AS_SYS_UNIT(100.0)), //挺的截面参数,u为沿着墙的方向尺寸
m_uRow(_AS_SYS_UNIT(100.0)), m_vRow(_AS_SYS_UNIT(100.0)), //框的截面参数, u为竖直方向的尺寸
m_nGlazDist(0.0), //玻璃距离基线
m_nRowDist(0.0), //横框中心距离基线
m_nRowNum(1), m_nColNum(1) //横竖均分数目
{
m_nWallFlag = WF_TOP_ROW|WF_BOT_ROW|WF_COL_AVERAGE|WF_ROW_AVERAGE;
m_style=kCurtain;
SetSimple2D(TRUE);
UpdateWallWidth();
}
void TDbCurtainWall::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbWall::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbCurtainWall *pSrc=TDbCurtainWall::cast(pSrcEntity);
if(pSrc)
{
m_idLayerCol3d=pSrc->m_idLayerCol3d;
m_idLayerRow3d=pSrc->m_idLayerRow3d;
m_idLayerGlass3d=pSrc->m_idLayerGlass3d;
m_colAlign=pSrc->m_colAlign;
m_uCol=pSrc->m_uCol;
m_vCol=pSrc->m_vCol;
m_uRow=pSrc->m_uRow;
m_vRow=pSrc->m_vRow;
m_nGlazDist=pSrc->m_nGlazDist;
m_nRowDist=pSrc->m_nRowDist;
//wlw add 131125 非均分幕墙处理墙角崩溃
int nColCount = m_colSpaces.Length();
if (m_nColNum != nColCount)
{
SetColAverage(TRUE);
}
}
}
// Override from AcDbEntity
// 从DWG读入数据:
Acad::ErrorStatus
TDbCurtainWall::dwgInFields(AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbWall::dwgInFields(pFiler);
if(es != Acad::eOk) return es;
Adesk::UInt8 nVer=0;
pFiler->readItem(&nVer);
if(nVer>g_nVersion) {// Version is too new
return Acad::eMakeMeProxy;
}
if(nVer==1)//TArch6图
{
//WF_COL_AVERAGE0->WM_COL_AVERAGE
if((m_nWallFlag&WF_COL_AVERAGE0)!=0)
{
m_nWallFlag&=~WF_COL_AVERAGE0;
m_nWallFlag|=WF_COL_AVERAGE;
}
}
Adesk::UInt8 align;
pFiler->readItem(&align);
m_colAlign=(ColAlignment)align; //挺的对齐位置
pFiler->readItem(&m_uCol);
pFiler->readItem(&m_vCol); //挺的截面参数,u为沿着墙的方向尺寸
pFiler->readItem(&m_uRow);
pFiler->readItem(&m_vRow); //框的截面参数, u为竖直方向的尺寸
pFiler->readItem(&m_nGlazDist); //玻璃距离基线
pFiler->readItem(&m_nRowDist); //横框中心距离基线
pFiler->readItem(&m_nRowNum);
pFiler->readItem(&m_nColNum); //横竖均分数目
m_rowSpaces.Reset();
m_colSpaces.Reset();
if(!IsRowAverage()) {
for(Adesk::UInt8 i=0; i<m_nRowNum; i++) {
double val=0.0;
pFiler->readItem(&val);
m_rowSpaces.Append(new double(val));
}
}
if(!IsColAverage()) {
for(Adesk::UInt8 i=0; i<m_nColNum; i++) {
double val=0.0;
pFiler->readItem(&val);
m_colSpaces.Append(new double(val));
}
}
pFiler->readItem(&m_idLayerGlass3d);
pFiler->readItem(&m_idLayerCol3d);
pFiler->readItem(&m_idLayerRow3d);
es = pFiler->filerStatus();
return es;
}
// 写出数据到dwg:
Acad::ErrorStatus
TDbCurtainWall::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
int nFlag0=GetWallFlag();
if(g_nSaveTArchVer==6)
{
int flag=nFlag0;
//~WF_SECT_TERM
flag&=~WF_SECTTERM;
//WF_COL_AVERAGE
if(flag&WF_COL_AVERAGE)
{
flag&=~WF_COL_AVERAGE;
flag|=WF_COL_AVERAGE0;
}
TDbCurtainWall*pThis=(TDbCurtainWall*)this;
pThis->SetFlagData(flag);
}
Acad::ErrorStatus es = TDbWall::dwgOutFields(pFiler);
if(GetWallFlag()!=nFlag0)
{
TDbCurtainWall*pThis=(TDbCurtainWall*)this;
pThis->SetFlagData(nFlag0);//复原
}
if(es != Acad::eOk) return es;
if(g_nSaveTArchVer==6)
pFiler->writeItem((Adesk::UInt8)1);
else
pFiler->writeItem(g_nVersion);
pFiler->writeItem((Adesk::UInt8)m_colAlign);
pFiler->writeItem(m_uCol);
pFiler->writeItem(m_vCol); //挺的截面参数,u为沿着墙的方向尺寸
pFiler->writeItem(m_uRow);
pFiler->writeItem(m_vRow); //框的截面参数, u为竖直方向的尺寸
pFiler->writeItem(m_nGlazDist); //玻璃距离基线
pFiler->writeItem(m_nRowDist); //横框中心距离基线
pFiler->writeItem(m_nRowNum);
pFiler->writeItem(m_nColNum); //横竖均分数目
Adesk::UInt8 i;
if(!IsRowAverage())
{
ASSERT(m_nRowNum==m_rowSpaces.Length());
for(i=0; i<m_nRowNum; i++)
pFiler->writeItem(m_rowSpaces[i]);
}
if(!IsColAverage())
{
//wlw add 131125 非均分幕墙处理墙角崩溃
int nColCount = m_colSpaces.Length();
if (m_nColNum != nColCount)
{
for(i=0; i< m_nColNum; i++)
pFiler->writeItem(500.0);
}
else
{
for(i=0; i< m_nColNum; i++)
pFiler->writeItem(m_colSpaces[i]);
}
}
pFiler->writeItem(m_idLayerGlass3d);
pFiler->writeItem(m_idLayerCol3d);
pFiler->writeItem(m_idLayerRow3d);
es=pFiler->filerStatus();
return es;
}
Acad::ErrorStatus
TDbCurtainWall::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbWall::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbCurtainWall"))) {
return Acad::eBadDxfSequence;
}
int n1=1, n2=1;
DList<double> lstRows, lstCols;
resbuf rb;
int fieldsFlags=0;
while ((es == Acad::eOk)
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
switch (rb.restype) {
case 77:
m_colAlign=(ColAlignment)rb.resval.rint;
break;
case 78:
n1=rb.resval.rint;
fieldsFlags |= 0x01;
break;
case 79:
n2=rb.resval.rint;
fieldsFlags |= 0x02;
break;
case 140:
m_uRow=rb.resval.rreal;
break;
case 141:
m_vRow=rb.resval.rreal;
break;
case 142:
m_uCol=rb.resval.rreal;
break;
case 143:
m_vCol=rb.resval.rreal;
break;
case 144:
m_nGlazDist=rb.resval.rreal;
break;
case 145:
m_nRowDist=rb.resval.rreal;
break;
case 148:
fieldsFlags |= 0x04;
lstRows.Append(new double(rb.resval.rreal));
break;
case 149:
fieldsFlags |= 0x08;
lstCols.Append(new double(rb.resval.rreal));
break;
case 415:
m_idLayerGlass3d=LayerString2Id(rb.resval.rstring, database());
free(rb.resval.rstring);
break;
case 416:
m_idLayerRow3d=LayerString2Id(rb.resval.rstring, database());
free(rb.resval.rstring);
break;
case 417:
m_idLayerCol3d=LayerString2Id(rb.resval.rstring, database());
free(rb.resval.rstring);
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;
}
}
if (es != Acad::eEndOfFile)
return Acad::eInvalidResBuf;
if((fieldsFlags&0x01)) {
m_nRowNum=n1;
} else {
m_nRowNum=1;
}
if((fieldsFlags&0x02)) {
m_nColNum=n1;
} else {
m_nColNum=1;
}
m_rowSpaces.Reset();
m_colSpaces.Reset();
if(!IsRowAverage()) {
if(lstRows.Length()!=m_nRowNum)
SetRowAverage(TRUE);
else {
for(int n=0; n<lstRows.Length(); n++)
m_rowSpaces.Append(new double (*lstRows[n]));
}
}
if(!IsColAverage()) {
if(lstCols.Length()!=m_nColNum)
SetColAverage(TRUE);
else {
for(int n=0; n<lstCols.Length(); n++)
m_colSpaces.Append(new double (*lstCols[n]));
}
}
return pFiler->filerStatus();
}
Acad::ErrorStatus
TDbCurtainWall::dxfOutFields(AcDbDxfFiler* pFiler) const
{
Acad::ErrorStatus es;
es = TDbWall::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbCurtainWall"));
assert(es == Acad::eOk);
pFiler->writeInt16(77, (Adesk::UInt16)m_colAlign);
pFiler->writeInt16(78, (Adesk::UInt16)m_nRowNum);
pFiler->writeInt16(79, (Adesk::UInt16)m_nColNum);
pFiler->writeDouble(140, m_uRow);
pFiler->writeDouble(141, m_vRow);
pFiler->writeDouble(142, m_uCol);
pFiler->writeDouble(143, m_vCol);
pFiler->writeDouble(144, m_nGlazDist);
pFiler->writeDouble(145, m_nRowDist);
if(!IsRowAverage()) {
for(int i=0; i<m_rowSpaces.Length(); i++) {
pFiler->writeDouble(146, m_rowSpaces[i]);
}
}
if(!IsColAverage()) {
for(int i=0; i<m_colSpaces.Length(); i++) {
pFiler->writeDouble(146, m_colSpaces[i]);
}
}
pFiler->writeString(415, (const TCHAR *)LayerId2String(m_idLayerGlass3d));
pFiler->writeString(416, (const TCHAR *)LayerId2String(m_idLayerRow3d));
pFiler->writeString(417, (const TCHAR *)LayerId2String(m_idLayerCol3d));
return es;
}
Acad::ErrorStatus
TDbCurtainWall::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
Acad::ErrorStatus
TDbCurtainWall::subTransformBy(const AcGeMatrix3d& xform)
{
BOOL bRowHide=IsRowHide();
BOOL bColHide=IsColHide();
Acad::ErrorStatus es=TDbWall::subTransformBy(xform);
SetRowHide(bRowHide);
SetColHide(bColHide);
return es;
}
// 绘制二维
// 尚未考虑门洞
Acad::ErrorStatus
TDbCurtainWall::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
if(IsSimple2D())
return TDbWall::ExplodeOrDraw2d(dc);
double nGlazDist=20.0; //玻璃厚度扩大表示
XPoint ptCen;
BOOL bLinear=TRUE;
if(!Is(CURVE_LINE)) {
ptCen=GetArc().GetCenterPt();
bLinear=FALSE;
}
int nExtSide=OFFSET_RIGHT;
if((GetWallFlag()&WF_LEFTEXT)!=0)
nExtSide=OFFSET_LEFT;
DList<XCurveSegment> segBars, segGlazes;
//绘制挺
//XPointDir2d ptCenRect;
double nAverDist=GetLength()/m_nColNum;
double nCurDist=0.0;
XPointDir2d ptLast, ptLastDir2d;;
for(Adesk::UInt8 i=0; i<=m_nColNum; i++) {
double nFactor=nExtSide? 1.0 : -1.0;
XPointDir2d ptDir2d;
Polar(nCurDist, ptDir2d);
ptDir2d.z=0;
XPointDir2d ptCenRect=ptDir2d;
if(m_colAlign==kInside)
ads_polar(ptDir2d, ptDir2d.nDirection-PI/2.0*nFactor, m_vCol/2.0, ptCenRect);
else if(m_colAlign==kOutside)
ads_polar(ptDir2d, ptDir2d.nDirection+PI/2.0*nFactor, m_vCol/2.0, ptCenRect);
ptCenRect.z=0;
XRectAngle box(ptCenRect, m_uCol, m_vCol);
XPoly2D poly2d(1);
box.AsPoly2D(poly2d);
ads_matrix mat;
ptCenRect.GetRotationMatrix(ptCenRect.nDirection, mat);
poly2d.TransUCS(mat);
ExplodePoly2D(poly2d, segBars);
//dc << poly2d; //绘制竖挺
if(i>0) {
XLine lnStartSide, lnEndSide; //竖挺的起始侧和结束侧
XPoint ptTemp1, ptTemp2;
ads_polar(ptCenRect, ptDir2d.nDirection+PI/2.0, m_vCol/2.0, ptTemp1);
ads_polar(ptCenRect, ptDir2d.nDirection-PI/2.0, m_vCol/2.0, ptTemp2);
lnEndSide = XLine(ptTemp1, ptTemp2).Offset(m_uCol/2.0);
ads_polar(ptLast, ptLast.nDirection+PI/2.0, m_vCol/2.0, ptTemp1);
ads_polar(ptLast, ptLast.nDirection-PI/2.0, m_vCol/2.0, ptTemp2);
lnStartSide = XLine(ptTemp1, ptTemp2).Offset(-m_uCol/2.0);
XCurveSegment segExt, segInt; //外侧玻璃和内侧玻璃
double nGlazOffset=min(m_vCol, nGlazDist);
//绘制玻璃
if(IsColHide()) { //隐式
XPoint pt1, pt2;
ads_polar(ptCenRect, ptCenRect.nDirection - PI/2.0*nFactor, m_vCol/2.0, pt2);
ads_polar(ptLast, ptLast.nDirection-PI/2.0*nFactor, m_vCol/2.0, pt1);
if(Is(CURVE_LINE)) {
segExt = XLine(pt1, pt2); //XLine(ptLast, ptDir2d); //外侧玻璃(关键)
} else {
double rad=ads_distance(ptCen, pt1);
segExt = XArc(ptCen, rad, ads_angle(ptCen, pt1), ads_angle(ptCen, pt2));
}
} else { //显框
segExt = Offset(m_nGlazDist/2, LS_INFINITE);
segExt.SetElevation(0.0);
XPoint ptInt[2];
XPoint pt1, pt2;
int iNum=segExt.Intersection(lnStartSide, ptInt[0], ptInt[1]);
ASSERT(iNum);
if(iNum==1) pt1=ptInt[0];
else pt1=XLine(ptInt[0], ptInt[1]).NearPoint(ptLast);
iNum=segExt.Intersection(lnEndSide, ptInt[0], ptInt[1]);
ASSERT(iNum);
if(iNum==1) pt2=ptInt[0];
else pt2=XLine(ptInt[0], ptInt[1]).NearPoint(ptCenRect);
segExt.SetPoints(pt1, pt2);
}
segInt = segExt.Offset(-nGlazOffset*nFactor*(IsColHide()? -1.0 : 1.0), LS_INFINITE);
if(!IsColHide()) { //segIn进行裁剪
XPoint ptInt[2];
XPoint pt1, pt2;
int iNum=segInt.Intersection(lnStartSide, ptInt[0], ptInt[1]);
ASSERT(iNum);
if(iNum==1) pt1=ptInt[0];
else pt1=XLine(ptInt[0], ptInt[1]).NearPoint(ptLast);
iNum=segInt.Intersection(lnEndSide, ptInt[0], ptInt[1]);
ASSERT(iNum);
if(iNum==1) pt2=ptInt[0];
else pt2=XLine(ptInt[0], ptInt[1]).NearPoint(ptCenRect);
segInt.SetPoints(pt1, pt2);
} else { //绘制垂直隐框的玻璃线端头
if(bLinear || nExtSide==OFFSET_RIGHT)
segGlazes.Append(new XCurveSegment(segExt.StartPoint(), segInt.StartPoint(), 0.0));
else
segGlazes.Append(new XCurveSegment(segExt.EndPoint(), segInt.EndPoint(), 0.0));
if(m_nColNum==i) {
if(bLinear || nExtSide==OFFSET_RIGHT)
segGlazes.Append(new XCurveSegment(segExt.EndPoint(), segInt.EndPoint(), 0.0));
else
segGlazes.Append(new XCurveSegment(segExt.StartPoint(), segInt.StartPoint(), 0.0));
}
}
//dc << segExt << segInt;
segGlazes.Append(new XCurveSegment(segExt));
//if(0) //4线表示
segGlazes.Append(new XCurveSegment(segInt));
}
if(i < m_nColNum)
{
double nDist=nAverDist;
if(!IsColAverage())
nDist=m_colSpaces[i];
nCurDist += nDist;
ptLast = ptCenRect;
ptLast.nDirection=ptDir2d.nDirection;
ptLastDir2d = ptDir2d;
}
}
//用门窗洞,扣减
DList<TOpeningData> lstOpenings;
GetSortedOpenings(lstOpenings);
DList<XCurveSegment> segBarOuts, segGlazeOuts;
for(int k=0; k<lstOpenings.Length(); k++) {
TOpeningData *pWin=lstOpenings[k];
XLine lnLeft, lnRight;
int nRetFlag=pWin->GetSideLine2d(lnLeft, lnRight);
for(int nIter=0; nIter<2; nIter++) {
DList<XCurveSegment> &lstSegs=nIter? segGlazes : segBars;
DList<XCurveSegment> &lstSegOuts=nIter? segGlazeOuts : segBarOuts;
for(int m=0; m<lstSegs.Length(); m++) {
XCurveSegment &seg=*lstSegs[m];
seg.SetLineFlag(LS_FINITE);
int nFlag1=OFFSET_RIGHT, nFlag2=OFFSET_RIGHT;
int nTag1=OFFSET_LEFT, nTag2=OFFSET_LEFT;
if(nRetFlag&0x01) { //有左线
nFlag1=lnLeft.OnWhichSide(seg.StartPoint());
nFlag2=lnLeft.OnWhichSide(seg.EndPoint());
}
if(nRetFlag&0x02) { //有右线
nTag1=lnRight.OnWhichSide(seg.StartPoint());
nTag2=lnRight.OnWhichSide(seg.EndPoint());
}
if(nFlag1!=OFFSET_RIGHT && nFlag2!=OFFSET_RIGHT) { //都在左线左边,输出
lstSegOuts.Append(new XCurveSegment(seg));
lstSegs.Remove(m);
m--;
} else if(nFlag1!=OFFSET_LEFT && nFlag2!=OFFSET_LEFT) { //都在左线右边
if(nTag1!=OFFSET_RIGHT && nTag2!=OFFSET_RIGHT) {
//都在右线左边,删除
lstSegs.Remove(m);
m--;
} else if(nTag1!=OFFSET_LEFT && nTag2!=OFFSET_LEFT) {
//都在右线右边,继续
} else { //与右线相交
XPoint ptInt[2];
int nIntNum=seg.Intersection(lnRight, ptInt[0], ptInt[1]);
ASSERT(nIntNum==1);
if(nTag2==OFFSET_RIGHT)
seg.SetPoints(ptInt[0], XPoint(seg.EndPoint()));
else if(nTag1==OFFSET_RIGHT)
seg.SetPoints(seg.StartPoint(), ptInt[0]);
else
ASSERT(0);
}
} else { //有左有右,与左线相交
XPoint ptInt[2];
int nIntNum=seg.Intersection(lnLeft, ptInt[0], ptInt[1]);
ASSERT(nIntNum==1);
XCurveSegment *segOut=new XCurveSegment(seg);
if(nFlag1==OFFSET_LEFT) {
segOut->SetPoints(seg.StartPoint(), ptInt[0]);
seg.SetPoints(ptInt[0], XPoint(seg.EndPoint()));
} else if(nFlag2==OFFSET_LEFT) {
segOut->SetPoints(ptInt[0], seg.EndPoint());
seg.SetPoints(XPoint(seg.StartPoint()), ptInt[0]);
} else
ASSERT(0);
lstSegOuts.Append(segOut);
if(nTag1!=OFFSET_RIGHT && nTag2!=OFFSET_RIGHT) {
//都在右线左边,删除
lstSegs.Remove(m);
m--;
} else if(nTag1!=OFFSET_LEFT && nTag2!=OFFSET_LEFT) {
//都在右线右边,不可能
ASSERT(0);
} else { //与右线相交
XPoint ptInt[2];
int nIntNum=seg.Intersection(lnRight, ptInt[0], ptInt[1]);
ASSERT(nIntNum==1);
if(nTag2==OFFSET_RIGHT)
seg.SetPoints(ptInt[0], XPoint(seg.EndPoint()));
else if(nTag1==OFFSET_RIGHT)
seg.SetPoints(seg.StartPoint(), ptInt[0]);
else
ASSERT(0);
}
}
}
} // end for Iter
} // end for k
// 输出玻璃
for(int j=0; j<segGlazeOuts.Length(); j++)
dc << *segGlazeOuts[j];
for(j=0; j<segGlazes.Length(); j++)
dc << *segGlazes[j];
//输出竖挺
TMasterProperties prop;
dc.BackUpProperties(prop);
dc.SetColorLayer(colorIndex(), m_idLayerCol3d);
for(j=0; j<segBarOuts.Length(); j++)
dc << *segBarOuts[j];
for(j=0; j<segBars.Length(); j++)
dc << *segBars[j];
// 输出基线
int nDrawMethod=g_bShowBase;
if(nDrawMethod&& // 1 或 2
!dc.IsPlotGeneration()&&
!dc.IsExportTch4())
{
dc.SetColor(g_nWallBaseColor);
XCurveSegment seg = *this;
seg.SetElevation(0.0);
dc << seg;
}
dc.RestoreProperties(prop);
return Acad::eOk;
}
// 绘制三维
// 尚未考虑洞口
Acad::ErrorStatus
TDbCurtainWall::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
XCurveSegment segOnZero=*this;
segOnZero.SetElevation(0.0);
if(m_nHeight<_DIST_SNAP)
return Acad::eOk;
TMasterProperties prop;
dc.BackUpProperties(prop);
XPoint ptCen;
if(!Is(CURVE_LINE))
ptCen=GetArc().GetCenterPt();
int nExtSide=OFFSET_RIGHT;
if((GetWallFlag()&WF_LEFTEXT)!=0)
nExtSide=OFFSET_LEFT;
double nFactor=nExtSide? 1.0 : -1.0;
DList<XPointDir2d> lstColPos;
DList<XCurveSegment> lstRow;
//确定竖挺位置和转角
double nAverDist=GetLength()/m_nColNum;
double nCurDist=0.0;
double nElev=GetElevation();
for(Adesk::UInt8 i=0; i<=m_nColNum; i++) {
XPointDir2d ptDir2d;
Polar(nCurDist, ptDir2d);
XPointDir2d ptCenRect=ptDir2d;
if(m_colAlign==kInside)
ads_polar(ptDir2d, ptDir2d.nDirection-PI/2.0*nFactor, m_vCol/2.0, ptCenRect);
else if(m_colAlign==kOutside)
ads_polar(ptDir2d, ptDir2d.nDirection+PI/2.0*nFactor, m_vCol/2.0, ptCenRect);
ptCenRect.z=nElev;
lstColPos.Append(new XPointDir2d(ptCenRect));
if(i<m_nColNum) {
double nDist=nAverDist;
if(!IsColAverage() && i < m_colSpaces.Length())
nDist=m_colSpaces[i];
nCurDist += nDist;
}
}
XCurveSegment segRowBase;
XCurveSegment segColBase, //竖挺中心基线
segGlaz; //玻璃位置
if(m_colAlign==kCenter)
segColBase = *this;
else if(m_colAlign==kInside)
segColBase=Offset(m_vCol/2*nFactor, LS_FINITE);
else
segColBase=Offset(-m_vCol/2*nFactor, LS_FINITE);
if(IsColHide()) { //隐式竖挺
segGlaz = segColBase.Offset(m_vCol/2.0*nFactor, LS_FINITE);
} else { //显式竖挺
segGlaz = Offset(m_nGlazDist, LS_FINITE);
}
if(IsRowHide()) { //隐式横框
segRowBase = segGlaz.Offset(-m_vRow/2.0*nFactor, LS_FINITE);
} else {
segRowBase=Offset(m_nRowDist, LS_FINITE);
}
segRowBase.SetElevation(nElev);
lstRow.Append(new XCurveSegment(segRowBase));
double nElevCur=nElev;
double nAverRowDist=m_nHeight/m_nRowNum;
//确定横框中心线
for(i=0; i<m_nRowNum; i++) {
double nDist=nAverRowDist;
if(!IsRowAverage())
nDist=m_rowSpaces[i];
nElevCur += nDist;
XCurveSegment *segNew=new XCurveSegment(segRowBase);
segNew->SetElevation(nElevCur);
lstRow.Append(segNew);
}
// 构造门窗洞
DList<TOpeningData> lstOpenings;
GetOpenings(lstOpenings, FALSE);
DList<XPoly2D> holes, holeExpands;
for(i=0; i<lstOpenings.Length(); i++) {
TOpeningData &opening=*lstOpenings[i];
XPoly2D *poly=new XPoly2D(1);
opening.GetElevOutline(*poly); //分弧精度的控制未使用
if(!*poly)
delete poly;
else
holes.Append(poly);
XPoly2D *polyExpand=new XPoly2D(1);
segOnZero.Wcs2Ecs(*poly, *polyExpand);
polyExpand->SetElevation(0.0);
holeExpands.Append(polyExpand);
}
dc.SetColorLayer(colorIndex(), m_idLayerCol3d);
double nExtrude=10.0; // 凸出距离以便造成隐框错觉
//绘制竖挺
for(i=0; i<lstColPos.Length(); i++) {
XPointDir2d &pos=*lstColPos[i];
XPoint ptLow=pos;
XPoint ptLowEcs=segOnZero.Wcs2Ecs(ptLow);
ptLowEcs.z=0.0;
XPoint ptUpEcs=ptLowEcs;
ptUpEcs.y += m_nHeight;
XCurveSegment *pSeg=new XCurveSegment(ptLowEcs, ptUpEcs, 0.0, LS_FINITE);
DList<XCurveSegment> srcSegs, inSegs, outSegs, edgeSegs, *pSource, *pDest;;
srcSegs.Append(pSeg);
pSource=&srcSegs;
pDest=&outSegs;
for(int n=0; n<holeExpands.Length(); n++) {
pDest->Reset();
PolyClip(*pSource, *holeExpands[n], inSegs, *pDest, edgeSegs);
TchPrivate::Exchange(pSource, pDest);
}
for(int k=0; k<pSource->Length(); k++) {
XCurveSegment *segOut=(*pSource)[k];
double yMin=min(segOut->StartPoint().y, segOut->EndPoint().y);
double yMax=max(segOut->StartPoint().y, segOut->EndPoint().y);
XPoint ptBoxCen=pos;
ptBoxCen.z = yMin;
XRectAngle box(ptBoxCen, m_uCol, m_vCol);
XPoly2D poly2d(1);
box.AsPoly2D(poly2d);
if(IsColHide()) {
if(nExtSide) {
XPoint ptAdd[4];
ptAdd[0].x=-nExtrude/2; ptAdd[0].y=-m_vCol/2;
ptAdd[1].x=-nExtrude/2; ptAdd[1].y=-m_vCol/2-nExtrude;
ptAdd[2].x=nExtrude/2; ptAdd[2].y=-m_vCol/2-nExtrude;
ptAdd[3].x=nExtrude/2; ptAdd[3].y=-m_vCol/2;
for(int mm=0; mm<4; mm++)
ptAdd[mm] += XVector3D(ptBoxCen.x, ptBoxCen.y);
poly2d.InsertNodeAt(1, ptAdd[0]);
poly2d.InsertNodeAt(2, ptAdd[1]);
poly2d.InsertNodeAt(3, ptAdd[2]);
poly2d.InsertNodeAt(4, ptAdd[3]);
} else {
XPoint ptAdd[4];
ptAdd[0].x=nExtrude/2; ptAdd[0].y=m_vCol/2;
ptAdd[1].x=nExtrude/2; ptAdd[1].y=m_vCol/2+nExtrude;
ptAdd[2].x=-nExtrude/2; ptAdd[2].y=m_vCol/2+nExtrude;
ptAdd[3].x=-nExtrude/2; ptAdd[3].y=m_vCol/2;
for(int mm=0; mm<4; mm++)
ptAdd[mm] += XVector3D(ptBoxCen.x, ptBoxCen.y);
poly2d.InsertNodeAt(3, ptAdd[0]);
poly2d.InsertNodeAt(4, ptAdd[1]);
poly2d.InsertNodeAt(5, ptAdd[2]);
poly2d.InsertNodeAt(6, ptAdd[3]);
}
}
ads_matrix mat;
pos.GetRotationMatrix(pos.nDirection, mat);
poly2d.TransUCS(mat);
poly2d.SetElevation(ptBoxCen.z);
dc.DrawMesh(poly2d, XVector3D(0,0,yMax-yMin));
}
}
dc.RestoreProperties(prop);
dc.SetColorLayer(colorIndex(), m_idLayerRow3d);
XPoly2D polyShape;
XRectAngle(XPoint(), m_vRow, m_uRow).AsPoly2D(polyShape);
if(IsRowHide()) {
if(nExtSide) {
XPoint ptAdd[4];
ptAdd[0].x=m_vRow/2; ptAdd[0].y=-nExtrude/2;
ptAdd[1].x=m_vRow/2+nExtrude; ptAdd[1].y=-nExtrude/2;
ptAdd[2].x=m_vRow/2+nExtrude; ptAdd[2].y=nExtrude/2;
ptAdd[3].x=m_vRow/2; ptAdd[3].y=nExtrude/2;
polyShape.InsertNodeAt(2, ptAdd[0]);
polyShape.InsertNodeAt(3, ptAdd[1]);
polyShape.InsertNodeAt(4, ptAdd[2]);
polyShape.InsertNodeAt(5, ptAdd[3]);
} else {
XPoint ptAdd[4];
ptAdd[0].x=-m_vRow/2; ptAdd[0].y=nExtrude/2;
ptAdd[1].x=-m_vRow/2-nExtrude; ptAdd[1].y=nExtrude/2;
ptAdd[2].x=-m_vRow/2-nExtrude; ptAdd[2].y=-nExtrude/2;
ptAdd[3].x=-m_vRow/2; ptAdd[3].y=-nExtrude/2;
polyShape.AppendNode(ptAdd[0]);
polyShape.AppendNode(ptAdd[1]);
polyShape.AppendNode(ptAdd[2]);
polyShape.AppendNode(ptAdd[3]);
}
}
//绘制横框
for(i=0; i<lstRow.Length(); i++) {
if(!HasBotRow() && i==0)
continue;
if(!HasTopRow() && i==lstRow.Length()-1)
continue;
// 隐框用微小的显框替代
XCurveSegment &segRow=*lstRow[i];
XPoint ptEcs1=segOnZero.Wcs2Ecs(segRow.StartPoint());
XPoint ptEcs2=segOnZero.Wcs2Ecs(segRow.EndPoint());
double z1=ptEcs1.z, z2=ptEcs2.z;
ptEcs1.z=ptEcs2.z=0.0;
ASSERT(fabs(z1-z2)<_DIST_SNAP);
XCurveSegment *pSeg=new XCurveSegment(ptEcs1, ptEcs2, 0.0, LS_FINITE);
DList<XCurveSegment> srcSegs, inSegs, outSegs, edgeSegs, *pSource, *pDest;;
srcSegs.Append(pSeg);
pSource=&srcSegs;
pDest=&outSegs;
for(int n=0; n<holeExpands.Length(); n++) {
pDest->Reset();
PolyClip(*pSource, *holeExpands[n], inSegs, *pDest, edgeSegs);
TchPrivate::Exchange(pSource, pDest);
}
TDbCurveMesh obj;
obj.setPropertiesFrom(this);
obj.setLayer(m_idLayerRow3d);
TPushProperty vProp(&obj, dc);
for(int k=0; k<pSource->Length(); k++) {
XCurveSegment *segBase=(*pSource)[k];
segBase->SetElevation(z1);
XCurveSegment segWcs(segRow);
XPoint pt1=segOnZero.Ecs2Wcs(segBase->StartPoint());
XPoint pt2=segOnZero.Ecs2Wcs(segBase->EndPoint());
segWcs.SetPoints(pt1, pt2);
XPoly2D polyBase;
segWcs.AsPoly2D(polyBase);
obj.setColorIndex(256);
obj.SetBasePoly(polyBase);
obj.SetShapePoly(polyShape);
obj.ExplodeOrDraw3d(dc);
}
}
dc.RestoreProperties(prop);
dc.SetColorLayer(colorIndex(), m_idLayerGlass3d);
XCurveSegment segGlazTemp=segGlaz.Offset(nFactor*nExtrude/2, LS_FINITE);
segGlaz=segGlazTemp;
// 绘制玻璃
//t20 wlw add 14.02.17 幕墙三维颜色
AcCmColor crRef;
Adesk::UInt32 ncolor(0);
m_XDataMap.GetAt(uKEY_CURTAIN_GLASS_COLOUR_INDEX, (int&)ncolor);
if (ncolor > 0)
{
#if ADS > 23
#if defined(ZWCAD) && (ADS == 24 || defined(R24))
crRef.setRGB(GetRValue(ncolor), GetGValue(ncolor), GetBValue(ncolor));
#else
crRef.setRGB(ncolor);
#endif
#else
crRef.setColor(ncolor);
#endif
dc.SetTrueColor(crRef);
}
if(!holes)
dc.DrawCurve(segGlaz, m_nHeight);
else {
if(Is(CURVE_ARC)) {
XArc iAr=segGlaz.GetArc();
DrawArcFace(dc, iAr, m_nHeight, holes);
} else {
XPoly2D polyOut(1);
polyOut.AppendNode(segGlaz.StartPoint());
polyOut.AppendNode(segGlaz.EndPoint());
XCurveSegment segTemp(segGlaz);
segTemp.SetElevation(m_nHeight+segGlaz.StartPoint().z);
polyOut.AppendNode(segTemp.EndPoint());
polyOut.AppendNode(segTemp.StartPoint());
// 要把holes投影到合适的polyOut
XPlane plan;
plan.SetFrom3p(segGlaz.StartPoint(), segGlaz.EndPoint(), segTemp.EndPoint());
for(int n=0; n<holes.Length(); n++) {
XPoly2D &rHole=*holes[n];
for(int m=0; m<rHole.Length(); m++)
*rHole[m]=rHole[m]->Project(&plan);
}
dc.DrawShell(polyOut, holes);
}
}
dc.RestoreProperties(prop);
return Acad::eOk;
}
//取动态属性显示数据
void TDbCurtainWall::GetTips(DList<TObjInfoUnit> &lstInfos) const
{
TDbWall::GetTips(lstInfos);
}
// SetData
void TDbCurtainWall::SetRowNum(Adesk::UInt8 rowNum)
{
assertWriteEnabled();
if(rowNum)
m_nRowNum=rowNum;
/*
if(IsRowAverage() && rowNum) {
m_nRowNum=rowNum;
m_rowSpaces.Reset();
for(Adesk::UInt8 i=0; i<m_nRowNum; i++) {
m_rowSpaces.Append(new double(m_nHeight/rowNum));
}
} else
*/
}
// 设置列数
void TDbCurtainWall::SetColNum(Adesk::UInt8 colNum)
{
assertWriteEnabled();
if(colNum)
m_nColNum=colNum;
/*
if(IsColAverage() && colNum) {
m_nColNum=colNum;
m_colSpaces.Reset();
for(Adesk::UInt8 i=0; i<m_nColNum; i++) {
double nLen=Length();
m_colSpaces.Append(new double(nLen/colNum));
}
}*/
}
void TDbCurtainWall::SetRowAverage(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nWallFlag |= WF_ROW_AVERAGE;
else
m_nWallFlag &= ~WF_ROW_AVERAGE;
};
void TDbCurtainWall::SetColAverage(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nWallFlag |= WF_COL_AVERAGE;
else
m_nWallFlag &= ~WF_COL_AVERAGE;
};
void TDbCurtainWall::SetRowHide(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nWallFlag |= WF_ROW_INVIS;
else
m_nWallFlag &= ~WF_ROW_INVIS;
};
void TDbCurtainWall::SetColHide(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nWallFlag |= WF_COL_INVIS;
else
m_nWallFlag &= ~WF_COL_INVIS;
};
void TDbCurtainWall::SetTopRow(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nWallFlag |= WF_TOP_ROW;
else
m_nWallFlag &= ~WF_TOP_ROW;
};
void TDbCurtainWall::SetBotRow(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nWallFlag |= WF_BOT_ROW;
else
m_nWallFlag &= ~WF_BOT_ROW;
};
void TDbCurtainWall::SetSimple2D(BOOL bTrue)
{
assertWriteEnabled();
if(bTrue)
m_nWallFlag |= WF_SIMPLE2D;
else
m_nWallFlag &= ~WF_SIMPLE2D;
};
void TDbCurtainWall::SetColAlignment(TDbCurtainWall::ColAlignment align)
{
assertWriteEnabled();
m_colAlign=align;
}
void TDbCurtainWall::SetGlazeDist(double nDist)
{
assertWriteEnabled();
m_nGlazDist=nDist;
}
void TDbCurtainWall::SetRowDist(double nDist)
{
assertWriteEnabled();
m_nRowDist=nDist;
}
void TDbCurtainWall::SetColU(double u)
{
assertWriteEnabled();
m_uCol = u;
}
void TDbCurtainWall::SetColV(double v)
{
assertWriteEnabled();
m_vCol = v;
//UpdateWallWidth();
}
void TDbCurtainWall::SetRowU(double u)
{
assertWriteEnabled();
m_uRow = u;
}
void TDbCurtainWall::SetRowV(double v)
{
assertWriteEnabled();
m_vRow = v;
}
// 根据竖挺参数更新墙宽
void TDbCurtainWall::UpdateWallWidth()
{
assertWriteEnabled();
int nExtSide=OFFSET_RIGHT;
if((GetWallFlag()&WF_LEFTEXT)!=0)
nExtSide=OFFSET_LEFT;
if(m_colAlign==kInside) {
if(nExtSide==OFFSET_RIGHT) {
m_rWidth = m_vCol;
m_lWidth = 0.0;
} else {
m_lWidth = m_vCol;
m_rWidth = 0.0;
}
} else if(m_colAlign==kOutside) {
if(nExtSide==OFFSET_LEFT) {
m_rWidth = m_vCol;
m_lWidth = 0.0;
} else {
m_lWidth = m_vCol;
m_rWidth = 0.0;
}
} else {
m_lWidth = m_rWidth = m_vCol/2;
}
}
Acad::ErrorStatus TDbCurtainWall::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet, BOOL *bErase)
{
return TDbCurveEntity::DownGradeSave(nDrawMode,entSet,bErase);
}
const TCHAR *TDbCurtainWall::GetDefaultLayer() const
{
return LAY_CURTWALL;
}
// sg add 101119,支持导出XML
CString TDbCurtainWall::GetXml(const AcGeMatrix3d& mat) const
{
TXmlTree xmlTree;
POSITION posRoot = xmlTree.Insert(_T("ATS_CURTAIN_WALL"), 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("Link_WinDoor"), posRoot, posItem1);
{
xmlTree.SetAttribute(posItem2, _T("name"), _T("墙内门窗"));
xmlTree.SetAttribute(posItem2, _T("comment"), _T("墙内门窗"));
POSITION posItemLinkId = NULL;
for (int i = 0; i < m_lstOpeningId.Length(); i++)
{
posItemLinkId = xmlTree.Insert(_T("Link_ID"), posItem2, posItemLinkId);
{
xmlTree.SetAttribute(posItemLinkId, _T("name"), _T("门窗句柄"));
strText.Format(_T("门窗句柄%d"), i + 1);
xmlTree.SetAttribute(posItemLinkId, _T("comment"), strText);
strText.Format(_T("%ld"), m_lstOpeningId[i]);
xmlTree.SetItemText(posItemLinkId, strText);
}
}
}
POSITION posItem3 = xmlTree.Insert(_T("Link_Col"), posRoot, posItem2);
{
xmlTree.SetAttribute(posItem3, _T("name"), _T("连接柱子"));
xmlTree.SetAttribute(posItem3, _T("name"), _T("两端连接柱子"));
POSITION posItemColStart = xmlTree.Insert(_T("Link_ID"), posItem3, NULL);
{
xmlTree.SetAttribute(posItemColStart, _T("name"), _T("柱子句柄"));
xmlTree.SetAttribute(posItemColStart, _T("comment"), _T("起点端柱子句柄"));
strText.Format(_T("%ld"), m_idColuStart);
xmlTree.SetItemText(posItemColStart, strText);
}
POSITION posItemColEnd = xmlTree.Insert(_T("Link_ID"), posItem3, posItemColStart);
{
xmlTree.SetAttribute(posItemColEnd, _T("name"), _T("柱子句柄"));
xmlTree.SetAttribute(posItemColEnd, _T("comment"), _T("终点端柱子句柄"));
strText.Format(_T("%ld"), m_idColuEnd);
xmlTree.SetItemText(posItemColEnd, strText);
}
}
POSITION posItem4 = xmlTree.Insert(_T("Feature"), posRoot, posItem3);
{
xmlTree.SetAttribute(posItem4, _T("name"), _T("墙体性质"));
xmlTree.SetAttribute(posItem4, _T("comment"), _T("墙是内墙还是外墙"));
strText = IsExternal() ? _T("外墙") : _T("内墙");
xmlTree.SetItemText(posItem4, strText);
}
POSITION posItem5 = xmlTree.Insert(_T("Width"), posRoot, posItem4);
{
xmlTree.SetAttribute(posItem5, _T("name"), _T("墙体宽度"));
POSITION posItemLeftWidth = xmlTree.Insert(_T("Left_Width"), posItem5, NULL);
{
xmlTree.SetAttribute(posItemLeftWidth, _T("name"), _T("墙体左宽"));
strText.Format(_T("%f"), GetWidth(0));
xmlTree.SetItemText(posItemLeftWidth, strText);
}
POSITION posItemRightWidth = xmlTree.Insert(_T("Right_Width"), posItem5, posItemLeftWidth);
{
xmlTree.SetAttribute(posItemRightWidth, _T("name"), _T("墙体右宽"));
strText.Format(_T("%f"), GetWidth(1));
xmlTree.SetItemText(posItemRightWidth, strText);
}
}
POSITION posItem6 = xmlTree.Insert(_T("Height"), posRoot, posItem5);
{
xmlTree.SetAttribute(posItem6, _T("name"), _T("墙体高度参数"));
POSITION posItemNetHeight = xmlTree.Insert(_T("Net_height"), posItem6, NULL);
{
xmlTree.SetAttribute(posItemNetHeight, _T("name"), _T("墙体高"));
xmlTree.SetAttribute(posItemNetHeight, _T("comment"), _T("从墙底起算的墙体净高"));
strText.Format(_T("%f"), GetHeight());
xmlTree.SetItemText(posItemNetHeight, strText);
}
POSITION posItemBottomHeight = xmlTree.Insert(_T("Botton_height"), posItem6, posItemNetHeight);
{
xmlTree.SetAttribute(posItemBottomHeight, _T("name"), _T("墙底高"));
xmlTree.SetAttribute(posItemBottomHeight, _T("comment"), _T("从零标高到墙底的相对高度"));
strText.Format(_T("%f"), GetElevation());
xmlTree.SetItemText(posItemBottomHeight, strText);
}
}
POSITION posItem7 = xmlTree.Insert(_T("Planview_type"), posRoot, posItem6);
{
xmlTree.SetAttribute(posItem7, _T("name"), _T("平面显示样式"));
xmlTree.SetAttribute(posItem7, _T("comment"), _T("示意为1,详图为0"));
strText.Format(_T("%d"), IsSimple2D());
xmlTree.SetItemText(posItem7, strText);
}
POSITION posItem8 = xmlTree.Insert(_T("Baseline"), posRoot, posItem7);
{
xmlTree.SetAttribute(posItem8, _T("name"), _T("基线参数"));
POSITION posItem = NULL;
posItem = xmlTree.Insert(_T("Start_point"), posItem8, posItem);
{
// sg modify 120117,对点进行坐标变换
TADSGePoint3d ptTransformBy = StartPoint();
ptTransformBy.TransformBy(mat);
xmlTree.SetAttribute(posItem, _T("name"), _T("起始点"));
// strText.Format(_T("%f,%f,%f"), StartPoint().x, StartPoint().y, StartPoint().z);
strText.Format(_T("%f,%f,%f"), ptTransformBy.x, ptTransformBy.y, ptTransformBy.z);
xmlTree.SetItemText(posItem, strText);
}
posItem = xmlTree.Insert(_T("End_point"), posItem8, posItem);
{
// sg modify 120117,对点进行坐标变换
TADSGePoint3d ptTransformBy = EndPoint();
ptTransformBy.TransformBy(mat);
xmlTree.SetAttribute(posItem, _T("name"), _T("结束点"));
// strText.Format(_T("%f,%f,%f"), EndPoint().x, EndPoint().y, EndPoint().z);
strText.Format(_T("%f,%f,%f"), ptTransformBy.x, ptTransformBy.y, ptTransformBy.z);
xmlTree.SetItemText(posItem, strText);
}
posItem = xmlTree.Insert(_T("Central_ang"), posItem8, posItem);
{
xmlTree.SetAttribute(posItem, _T("name"), _T("圆心角"));
strText.Format(_T("%f"), GetBulge());
xmlTree.SetItemText(posItem, strText);
}
}
POSITION posItem9 = xmlTree.Insert(_T("Cell_grid"), posRoot, posItem8);
{
xmlTree.SetAttribute(posItem9, _T("name"), _T("幕墙分格参数"));
CString sTemp;
POSITION posItemCellRows = xmlTree.Insert(_T("Cell_rows"), posItem9, NULL);
{
xmlTree.SetAttribute(posItemCellRows, _T("name"), _T("竖向行数"));
strText.Format(_T("%d"), GetRowNum());
xmlTree.SetItemText(posItemCellRows, strText);
POSITION posItem = NULL;
if (IsRowAverage())
{
strText.Format(_T("%f"), GetHeight() / GetRowNum());
for (int i = 0; i < GetRowNum(); i++)
{
sTemp.Format(_T("Cell_height%d"), i + 1);
posItem = xmlTree.Insert(sTemp, posItemCellRows, posItem);
{
xmlTree.SetAttribute(posItem, _T("name"), _T("竖向行高"));
xmlTree.SetItemText(posItem, strText);
}
}
}
else
{
for (int i = 0; i < m_rowSpaces.Length(); i++)
{
sTemp.Format(_T("Cell_height%d"), i + 1);
posItem = xmlTree.Insert(sTemp, posItemCellRows, posItem);
{
xmlTree.SetAttribute(posItem, _T("name"), _T("竖向行高"));
strText.Format(_T("%f"), m_rowSpaces[i]);
xmlTree.SetItemText(posItem, strText);
}
}
}
}
POSITION posItemCellCols = xmlTree.Insert(_T("Cell_columns"), posItem9, posItemCellRows);
{
xmlTree.SetAttribute(posItemCellCols, _T("name"), _T("横向列数"));
strText.Format(_T("%d"), GetColNum());
xmlTree.SetItemText(posItemCellCols, strText);
POSITION posItem = NULL;
if (IsColAverage())
{
strText.Format(_T("%f"), m_startPoint.Distance2d(m_endPoint) / GetColNum());
for (int i = 0; i < GetColNum(); i++)
{
sTemp.Format(_T("Cell_width%d"), i + 1);
posItem = xmlTree.Insert(sTemp, posItemCellCols, posItem);
{
xmlTree.SetAttribute(posItem, _T("name"), _T("横向列宽"));
xmlTree.SetItemText(posItem, strText);
}
}
}
else
{
for (int i = 0; i < m_colSpaces.Length(); i++)
{
sTemp.Format(_T("Cell_width%d"), i + 1);
posItem = xmlTree.Insert(sTemp, posItemCellCols, posItem);
{
xmlTree.SetAttribute(posItem, _T("name"), _T("横向列宽"));
strText.Format(_T("%f"), m_colSpaces[i]);
xmlTree.SetItemText(posItem, strText);
}
}
}
}
POSITION posItemMullionSize = xmlTree.Insert(_T("Mullion_size"), posItem9, posItemCellCols);
{
xmlTree.SetAttribute(posItemMullionSize, _T("name"), _T("竖梃尺寸"));
strText.Format(_T("%f,%f"), GetColV(), GetColU());
xmlTree.SetItemText(posItemMullionSize, strText);
}
POSITION posItemFrameSize = xmlTree.Insert(_T("Frame_size"), posItem9, posItemMullionSize);
{
xmlTree.SetAttribute(posItemFrameSize, _T("name"), _T("横框尺寸"));
strText.Format(_T("%f,%f"), GetRowV(), GetRowU());
xmlTree.SetItemText(posItemFrameSize, strText);
}
POSITION posItemFrameHide = xmlTree.Insert(_T("Frame_hide"), posItem9, posItemFrameSize);
{
xmlTree.SetAttribute(posItemFrameHide, _T("name"), _T("置顶框和底框"));
xmlTree.SetAttribute(posItemFrameHide, _T("comment"), _T("需要顶框和底框为1,1"));
strText.Format(_T("%d,%d"), HasTopRow(), HasBotRow());
xmlTree.SetItemText(posItemFrameHide, strText);
}
}
POSITION posItem10 = xmlTree.Insert(_T("Offset"), posRoot, posItem9);
{
xmlTree.SetAttribute(posItem10, _T("name"), _T("玻璃与框架与基线偏移"));
POSITION posItemMullionOffset = xmlTree.Insert(_T("Mullion_offset"), posItem10, NULL);
{
xmlTree.SetAttribute(posItemMullionOffset, _T("name"), _T("竖梃与基线关系"));
strText.Format(_T("%d"), GetColAlignment());
xmlTree.SetItemText(posItemMullionOffset, strText);
}
POSITION posItemGlassOffset = xmlTree.Insert(_T("Glass_offset"), posItem10, posItemMullionOffset);
{
xmlTree.SetAttribute(posItemGlassOffset, _T("name"), _T("玻璃与基线偏移"));
strText.Format(_T("%f"), GetGlazeDist());
xmlTree.SetItemText(posItemGlassOffset, strText);
}
POSITION posItemFrameOffset = xmlTree.Insert(_T("Frame_offset"), posItem10, posItemGlassOffset);
{
xmlTree.SetAttribute(posItemFrameOffset, _T("name"), _T("横框与基线偏移"));
strText.Format(_T("%f"), GetRowDist());
xmlTree.SetItemText(posItemFrameOffset, strText);
}
}
CString strBase = TEntityBase::GetXml(mat);
CString strXml = xmlTree.GetXml();
int nIndex = strXml.Find(_T("<Object_ID"));
strXml.Insert(nIndex, strBase);
return strXml;
}
void InitDbCurtainWall(BOOL bTrue)
{
if(bTrue) {
TDbCurtainWall::rxInit();
acrxBuildClassHierarchy();
TDbCurtainWall::InitMatchProtocol(TRUE);
} else {
TDbCurtainWall::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbCurtainWall::desc());
}
}
void TDbCurtainWall::RearrangeCol(TDbWall* pNewWall, double dOldLenght)
{
if (!pNewWall->isKindOf(TDbCurtainWall::desc())) return;
TDbCurtainWall* pWall = (TDbCurtainWall*)pNewWall;
double dNewLenght = pWall->GetLength();
if(fabs(dNewLenght - dOldLenght) < 0.01) return;
if(pWall->IsColAverage())
{
int nColNum = pWall->GetColNum();
if(nColNum <= 0)
nColNum = 1;
pWall->SetColAverage(true);
if(dOldLenght < DocGetMinLenWall())
{
pWall->SetColNum(nColNum);
return;
}
double dAveColLen = dOldLenght / nColNum;
nColNum = ((int)dNewLenght) / (int)dAveColLen;
double dTemp = dNewLenght - nColNum * dAveColLen;
if( fabs(dTemp) < 0.01) //墙的长度刚好是pWallData->dFixedGapLen的倍数
{
}
else if(dTemp > 0.0)
{
++nColNum;
}
else
{
--nColNum;
}
if(nColNum <= 0)
nColNum = 1;
pWall->SetColNum(nColNum);
}
else
{
pWall->SetColAverage(false);
int nColNum = pWall->m_colSpaces.Length();
if(nColNum == 0)
{
nColNum = 1;
pWall->SetColNum(1);
pWall->m_colSpaces.Reset();
pWall->m_colSpaces.Append(new double(dNewLenght));
return;
}
double dFirstLen = *(pWall->m_colSpaces.GetAt(0));
double dTempLen;
double dSumColLen = dFirstLen;
bool bIsSame = true;
//判断前nColNum - 1个是否相等
for(int i = 1; i < pWall->m_colSpaces.Length() - 1; ++i)
{
dTempLen = *(pWall->m_colSpaces.GetAt(i));
dSumColLen += dTempLen;
if(bIsSame)
{
if(fabs(dTempLen - dFirstLen) > 0.01)
{
bIsSame = false;
}
}
}
dSumColLen += *(pWall->m_colSpaces.GetAt(pWall->m_colSpaces.Length() - 1));
if(bIsSame)
{
pWall->m_colSpaces.Reset();
nColNum = (int)(dNewLenght / dFirstLen);
for(int i = 0; i < nColNum; ++i)
pWall->m_colSpaces.Append(new double(dFirstLen));
double dOdd = dNewLenght - nColNum * dFirstLen;
if(dOdd > 0.01)
{
pWall->m_colSpaces.Append(new double(dOdd));
++nColNum;
}
pWall->SetColNum(nColNum);
}
else
{
if(dOldLenght < dNewLenght)
{
double dSumLen = dOldLenght;
while(dSumLen + dFirstLen < dNewLenght)
{
pWall->m_colSpaces.Append(new double(dFirstLen));
dSumLen += dFirstLen;
}
if(fabs(dNewLenght - dSumLen) > 0.01)
{
pWall->m_colSpaces.Append(new double(dNewLenght - dSumLen));
}
pWall->SetColNum(pWall->m_colSpaces.Length());
}
else
{
int nColNum = pWall->m_colSpaces.Length();
double dLastLen;
while(1)
{
dLastLen = *(pWall->m_colSpaces.GetAt(nColNum-1));
if(dSumColLen - dLastLen > dNewLenght)
{
pWall->m_colSpaces.Remove(nColNum -1);
dSumColLen -= dLastLen;
--nColNum;
}
else
{
pWall->m_colSpaces.Remove(nColNum -1);
pWall->m_colSpaces.Append(new double(dNewLenght - dSumColLen));
break;
}
}
pWall->SetColNum(nColNum);
}
}
}
}
void TDbCurtainWall::WallSegmentateColumnAdjust(TDbCurtainWall* pWall, const double &lenght, double dSegmentatePos,
BOOL& bFirstAve, UINT& nFirstColumnNum, std::vector<double>& vecFirstColumnGap,
BOOL& bSecondAve, UINT& nSecondColumnNum, std::vector<double>& vecSecondColumnGap)
{
if(!pWall)
return;
double dWallLen = lenght;
//如果分段位置不对 则对其进行容错性处理
if(dSegmentatePos < 0 || dSegmentatePos > dWallLen)
{
bFirstAve = TRUE;
nFirstColumnNum = 1;
bSecondAve = TRUE;
nSecondColumnNum = 1;
return ;
}
vecFirstColumnGap.clear();
vecSecondColumnGap.clear();
double dFirstWallLen = dSegmentatePos;
double dSecondWallLen = dWallLen - dFirstWallLen;
BOOL bAve = pWall->IsColAverage();
if(dWallLen < g_nMinLenWall)
{
bFirstAve = bAve;
bSecondAve = bAve;
if(bAve)
{
nFirstColumnNum = 1;
nSecondColumnNum = 1;
}
else
{
vecFirstColumnGap.push_back(dFirstWallLen);
vecSecondColumnGap.push_back(dSecondWallLen);
}
return;
}
bFirstAve = bAve;
bSecondAve = bAve;
if(bAve)
{
//认为是等分接近值
//那么分段后,两端新墙也将使用相同的等分接近值,但两端墙立柱间平均值不一定相当
UINT nColumnNum = pWall->GetColNum();
if(nColumnNum == 0) nColumnNum = 1;
double dAveLen = dWallLen / nColumnNum;
nFirstColumnNum = (UINT)(dFirstWallLen / dAveLen);
if((dFirstWallLen - dAveLen * nFirstColumnNum) > 0.0)
++nFirstColumnNum;
else if(fabs(dFirstWallLen - dAveLen * nFirstColumnNum) < 0.00001)
nFirstColumnNum = nFirstColumnNum;
else
--nFirstColumnNum;
nSecondColumnNum = (UINT)(dSecondWallLen / dAveLen);
if((dSecondWallLen - dAveLen * nSecondColumnNum) > 0.0)
++nSecondColumnNum;
else if(fabs(dSecondWallLen - dAveLen * nFirstColumnNum) < 0.00001)
nSecondColumnNum = nSecondColumnNum;
else
--nSecondColumnNum;
}
else
{
//不等分, 分为两种情况, 先判断其是不是等间距的, 如果是等间距的,则新墙也将是等间距的
int nOldColNum = pWall->m_colSpaces.Length();
if(nOldColNum == 0)
{
vecFirstColumnGap.push_back(dFirstWallLen);
vecSecondColumnGap.push_back(dSecondWallLen);
return;
}
bool bIsEqualGap = true;
double dFirstGap = *(pWall->m_colSpaces.GetAt(0));
double dNewGap;
for(int i = 1; i < nOldColNum - 1; ++i)
{
dNewGap = *(pWall->m_colSpaces.GetAt(i));
if(fabs(dFirstGap - dNewGap) > 0.001)
{
bIsEqualGap = false;
break;
}
}
if(bIsEqualGap) //说明是等距的
{
double dSum = dFirstGap;
//第一段墙设置立柱间距
while(dSum < dFirstWallLen)
{
vecFirstColumnGap.push_back(dFirstGap);
dSum += dFirstGap;
}
double dVestigialLen = dFirstWallLen - (dSum - dFirstGap);
if(fabs(dVestigialLen) > 0.0)
vecFirstColumnGap.push_back(dVestigialLen);
dSum = dFirstGap;
//第二段墙设置立柱间距
while(dSum < dSecondWallLen)
{
vecSecondColumnGap.push_back(dFirstGap);
dSum += dFirstGap;
}
dVestigialLen = dSecondWallLen - (dSum - dFirstGap);
if(fabs(dVestigialLen) > 0.0)
vecSecondColumnGap.push_back(dVestigialLen);
}
else
{
bool bFirstWallHaveSet = false;
double dFirstWallSumLen = 0.0;
double dSecondWallSumLen = 0.0;
for(int i = 0; i < nOldColNum; ++i)
{
dNewGap = *(pWall->m_colSpaces.GetAt(i));
if(dNewGap <= 0.0) continue;
if(!bFirstWallHaveSet)
{
//先设置第一段墙
dFirstWallSumLen += dNewGap;
if(dFirstWallSumLen < dFirstWallLen)
{
vecFirstColumnGap.push_back(dNewGap);
}
else
{
double dVestigialLen = dFirstWallLen - (dFirstWallSumLen - dNewGap);
if(fabs(dVestigialLen) > 0.001)
{
vecFirstColumnGap.push_back(dVestigialLen);
dFirstWallSumLen = dFirstWallLen;
}
bFirstWallHaveSet = true;
}
}
else
{
dSecondWallSumLen += dNewGap;
if(dSecondWallSumLen < dSecondWallLen)
{
vecSecondColumnGap.push_back(dNewGap);
}
else
{
double dVestigialLen = dSecondWallLen - (dSecondWallSumLen -dNewGap);
if(fabs(dVestigialLen) > 0.001)
{
vecSecondColumnGap.push_back(dVestigialLen);
dSecondWallSumLen = dSecondWallLen;
}
}
}
}
//最后保证立柱的间距之和等于墙的长度
if(dFirstWallLen > dFirstWallSumLen)
vecFirstColumnGap.push_back(dFirstWallLen - dFirstWallSumLen);
if(dSecondWallLen > dSecondWallSumLen)
vecSecondColumnGap.push_back(dSecondWallLen - dSecondWallSumLen);
}
}
}
Acad::ErrorStatus TDbCurtainWall::subMoveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset )
{
assertWriteEnabled();
Acad::ErrorStatus eRet;
BOOL bColAve = IsColAverage();
if((eRet = TDbWall::subMoveGripPointsAt(indices, offset)) != Acad::eOk)
return eRet;
if(bColAve)
return eRet;
bool bWallLenghtChanged = false;
for (int i = 0; i < indices.length(); i++)
{
if(indices[i] == 1 || indices[i] == 0)
{
bWallLenghtChanged = true;
}
}
if(!bWallLenghtChanged) return eRet;
int nColNum = m_colSpaces.Length();
if(nColNum == 0)
return eRet;
double dWallLen = GetLength();
bool bPreColLenSame = true;
double dFirstColLen = *(m_colSpaces.GetAt(0));
double dCurColLen;
double dColSum = dFirstColLen;
if(dColSum >= dWallLen)
{
m_colSpaces.Reset();
m_colSpaces.Append(new double(dWallLen));
SetColNum(1);
SetColAverage(FALSE);
return eRet;
}
for(int i = 1; i < nColNum - 1; ++i) //最后一个列元素暂时不考虑,因为这个会影响判断前几个元素是否相等的判断
{
dCurColLen = *(m_colSpaces.GetAt(i));
//判断前几个元素是否相等
if(bPreColLenSame)
{
if(fabs(dCurColLen - dFirstColLen) > 0.001)
bPreColLenSame = false;
}
dColSum += dCurColLen;
if(dColSum >= dWallLen)
{
//如果立柱长度之和大于墙的长度,说明墙缩短了, 此时删除后面的立柱
dColSum -= dCurColLen;
//删除此位置后面的所有的元素
for(int j = i; j < nColNum; ++j)
m_colSpaces.Remove();
nColNum = i;
if(fabs(dWallLen - dColSum) > 0.001)
{
m_colSpaces.Append(new double(dWallLen - dColSum));
++nColNum;
}
SetColNum(nColNum);
SetColAverage(FALSE);
return eRet;
}
}
//考虑最后一个立柱
dCurColLen = *(m_colSpaces.GetAt(nColNum - 1));
m_colSpaces.Remove(); //上一句GetAt将指针置为最后一个元素位置, 此函数删除当前元素
nColNum = nColNum - 1; //新的立柱数目, 下面将会对此值进行修正
if(!bPreColLenSame)
{
if(dCurColLen > g_nMinLenWall)
dFirstColLen = dCurColLen;
}
dColSum += dFirstColLen;
while(dColSum < dWallLen)
{
m_colSpaces.Append(new double(dFirstColLen));
dColSum += dFirstColLen;
++nColNum;
}
double dLastColLen = dWallLen - (dColSum - dFirstColLen);
if(dLastColLen > 0.001)
{
m_colSpaces.Append(new double(dLastColLen));
++nColNum;
}
SetColNum(nColNum);
SetColAverage(FALSE);
return eRet;
}
#if (ADS == 17)
void TDbCurtainWall::AppendForColSpaces(const double & d)
{
m_colSpaces.Append(new double(d));
}
void TDbCurtainWall::AppendForRowSpaces(const double & d)
{
m_rowSpaces.Append(new double(d));
}
#endif