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

5461 lines
160 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "stdafx.h"
#include "TDbColumn.h"
#include "TDbWallPatch.h"
#include "OpeningLabelData.h"
#include <sstream>
//T20 扩展数据定义 wlw add 150415
#define sKEY_OP_PROWIN_LINE _T("T20d1") // 用来标记是否是pc构件增加凸窗
#define OP_QUANTUM_1 _T("周长")
#define OP_QUANTUM_2 _T("面积")
#define OP_QUANTUM_3 _T("宽度")
#define OP_HWINDOW 6
#define OP_HARCWIN 7
#define TDBOPENING_INSULATE _T("TDBOPENING_INSULATE")
extern AcDbObjectId GetValidTextStyle(AcDbDatabase *pDb, const TCHAR *pStyle);
extern void RemoveContainership(class TDbWall *pWall, class TDbOpening *pOpening);
//extern void GemCreateExplodeBlock(AcDbVoidPtrArray& entityArray,AcDbVoidPtrArray& entitySet,AcGePoint3d ip,TCHAR *Layer);
extern int GetViewDrawMode();
//extern int ExplodeBlockRef(AcDbBlockTableRecord &blockRec, ads_matrix matForInsert, DList<AcDbEntity> &entSet);
extern TARCH_IMPEXP void GetWinWidthModel(DList<double> &lstWidth);
extern TARCH_IMPEXP void GetDoorWidthModel(DList<double> &lstWidth);
extern TARCH_IMPEXP double GetModelNumber(DList<double> &lstModel, double nNearNumber);
//extern AcDbObjectId GetPrepickEntity(RBList &rbBaseMask);
//Acad::ErrorStatus ConvertToDouble(const VARIANT *val, double *pRes);
//Acad::ErrorStatus ConvertToInteger(const VARIANT *val, int *pInt);
static AcDbObjectId g_idCurStretchOpening;
//extern BOOL g_bMakeBlock;
//extern double g_nAcadVer;
extern double g_fWinLabelDefaultHeight;
extern BOOL g_bSlotInsulateCap;
extern double g_dSlotInsulateThick;
// 1-TArch5;2-TArch6;3-TArch7;4-TArch8;5-TArch9
// const Adesk::UInt8 TDbOpening::g_nVersion = 4;
const Adesk::UInt8 TDbOpening::g_nVersion = 5;
ACRX_DXF_DEFINE_MEMBERS(ATSOpening, ATSEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
1, ATS_OPENING, "ATS_OPENING图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com");
IMPLEMENT_TENTBASE(TDbOpening);
TDbOpening::TDbOpening()
:m_uFrame(_AS_SYS_UNIT(40.0)), m_vFrame(_AS_SYS_UNIT(40.0)), m_nSlabThickness(_AS_SYS_UNIT(100.0)), m_nTextHeight(g_fWinLabelDefaultHeight)
{
m_colorText=7;
m_iEnFlag=0;
m_dbAbsorption=0;
m_dbShadeCo=0;
m_dbOutShadeCoSum=0;
m_dbOutShadeCoWin=0;
// 修改人 : lfy 2009-11-08 动态举证单位化
m_mat3d.setToIdentity();
// wlw add 门窗保温参数2011-02-15
m_nMaterial = GetSlotMaterial();
m_bSlotInsCap = g_bSlotInsulateCap;
m_dInsWidth = g_dSlotInsulateThick;
}
// 用所在的
TDbOpening::TDbOpening(AcDbObjectId idWall, AcDbObjectId idStyle2d, AcDbObjectId idStyle3d)
:m_uFrame(_AS_SYS_UNIT(40.0)), m_vFrame(_AS_SYS_UNIT(40.0)), m_nSlabThickness(_AS_SYS_UNIT(100.0)), m_nTextHeight(g_fWinLabelDefaultHeight)
{
m_nIdOfWall=idWall;
m_nIdStyle2d=idStyle2d;
m_nIdStyle3d=idStyle3d;
m_colorText=7;
m_iEnFlag=0;
m_dbAbsorption=0;
m_dbShadeCo=0;
m_dbOutShadeCoSum=0;
m_dbOutShadeCoWin=0;
// 修改人 : lfy 2009-11-08 动态举证单位化
m_mat3d.setToIdentity();
// wlw add 门窗保温参数2011-02-15
m_nMaterial = GetSlotMaterial();
m_bSlotInsCap = g_bSlotInsulateCap;
m_dInsWidth = g_dSlotInsulateThick;
}
// sg modify 110224,增加返回标注,告诉用户端是否需要补充数字
// CString TDbOpening::GetAutoLabel()const
CString TDbOpening::GetAutoLabel(bool &bAddNum)const
{
TOpeningData::OpeningKind opKind;
double nWidth, nHeight;
opKind = GetKind();
nWidth = GetWidth();
nHeight = GetHeight();
// 获得门窗类别,以及软件内部固定死的标注前缀
CString csSectionLabel,
csFixupLabel;
if (opKind == TOpeningData::OP_DOOR)
{
csSectionLabel = _T("Door");
csFixupLabel = _T("M");
}
else if (opKind == TOpeningData::OP_WINDOW)
{
csSectionLabel = _T("Window");
csFixupLabel = _T("C");
}
else if (opKind == TOpeningData::OP_HOLE)
{
csSectionLabel = _T("Hole");
csFixupLabel = _T("DK");
}
else if (opKind == TOpeningData::OP_ARCWIN)
{
csSectionLabel = _T("ArcWin");
csFixupLabel = _T("HC");
}
else if (opKind == TOpeningData::OP_PROWIN)
{
csSectionLabel = _T("BayWin");
csFixupLabel = _T("TC");
}
else if (opKind == TOpeningData::OP_CORNWIN)
{
csSectionLabel = _T("CornerWin");
csFixupLabel = _T("JC");
}
else if (opKind == TOpeningData::OP_DOORWIN)
{
csSectionLabel = _T("DoorWin");
csFixupLabel = _T("MC");
}
else if (opKind == TOpeningData::OP_TWODOOR)
{
csSectionLabel = _T("TwoDoor");
csFixupLabel = _T("ZM");
}
else if (opKind == TOpeningData::OP_GROUP)
{
csSectionLabel = _T("GroupOpening");
if (IsDoor())
csFixupLabel = _T("ZM");
else
csFixupLabel = _T("ZC");
}
bool bFlag = false; // 标记是否已经正确从OpeningLabel.ini文件中得到标注前缀
TOpeningLabelData data;
CString csNewName;
if (!csSectionLabel.IsEmpty()) // 类别不为空时
{
// 获得门窗类型
CString csSubKind = GetSubKind();
bFlag = data.GetOpeningLabel(csSectionLabel, csSubKind, csNewName);
}
if (!bFlag) // 如果没有得到正确的数据,输出固定的标注前缀
csNewName = csFixupLabel;
// 获得是否需要添加连字符
CString csHypen = _T("");
if (data.HasHypen())
csHypen = _T("-");
bool bRound = data.IsRound(); // 是否进行四舍五入
// 获得标注方式
TOpeningLabelData::ESerialRule nRule = data.GetNumRule();
if (nRule == TOpeningLabelData::kSize) // 按尺寸标注
{
int nWidth1 = AS_INT(nWidth/100),
nHeight1 = AS_INT(nHeight/100);
if (!bRound) // 不进行四舍五入
{
nWidth1 = AS_INT(nWidth)/100;
nHeight1 = AS_INT(nHeight)/100;
}
if (nWidth1>9&&nHeight1>9)
csNewName.Format(_T("%s%s%d%d"),csNewName, csHypen, nWidth1, nHeight1);
else if (nWidth1<10&&nHeight1>9)
csNewName.Format(_T("%s%s0%d%d"),csNewName, csHypen, nWidth1, nHeight1);//add by whl
else if (nWidth1>9&&nHeight1<10)
csNewName.Format(_T("%s%s%d0%d"),csNewName, csHypen, nWidth1, nHeight1);//add by whl
else // if(nWidth<10&&nHeight<10)
csNewName.Format(_T("%s%s0%d0%d"),csNewName, csHypen, nWidth1, nHeight1);//add by whl
bAddNum = false;
}
else // 按数序排列
{
csNewName.Format(_T("%s%s"), csNewName, csHypen);
bAddNum = true; // 由对话框处进行+1工作
}
return csNewName;
}
BOOL TDbOpening::IsValid() const
{
BOOL bRet = TDbEntity::IsValid();
if (!bRet)
return bRet;
bRet = (m_nWidth>_DIST_SNAP &&
m_nThickness>_DIST_SNAP);
return bRet;
}
TEntityBase::DrawType TDbOpening::GetDrawType() const
{
if (!Has3D())
return k2DOnly;
return k2Dand3D;
}
// 提供对格式刷的支持
void TDbOpening::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
{
assertWriteEnabled();
TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
TDbOpening *pSrc=TDbOpening::cast(pSrcEntity);
if(pSrc)
{
m_nWidth=pSrc->m_nWidth;
m_nThickness=pSrc->m_nThickness;
m_nHeight=pSrc->m_nHeight;
if(pSrc->m_nIdOfWall == m_nIdOfWall)
{
m_nRotation=pSrc->m_nRotation;
m_nQuadrant=pSrc->m_nQuadrant; //象限0,1,2,3代表第1~4象限, m_nRotation为象限的X正方向
}
m_opKind=pSrc->m_opKind; // 门窗类型
// sg add 110908,根据8.5的需求,格式刷要支持子类型
SetSubKind(pSrc->GetSubKind());
m_nBulge=pSrc->m_nBulge; //对于弧形窗不为0
m_sLabel=pSrc->m_sLabel; //标号
if(database()==NULL||
pSrcEntity->database()==NULL||
database()==pSrcEntity->database())//add by whl on 060317
{
m_nIdStyle2d=pSrc->m_nIdStyle2d;
m_nIdStyle3d=pSrc->m_nIdStyle3d; //块表中的ID
}
m_nOpStyle=pSrc->m_nOpStyle; //是否包含门窗套等标记
m_nSlotExt=pSrc->m_nSlotExt;
m_nSlotWidth=pSrc->m_nSlotWidth; //伸出墙的距离,窗套宽度
m_nDoorWidth=pSrc->m_nDoorWidth;
m_nWinHeight=pSrc->m_nWinHeight; //门联窗门宽(或子母大门宽)和窗高
m_ptLocation.z=pSrc->m_ptLocation.z;//add by whl on 060411,窗台高
if(pSrc->m_pBayWin)
{
if(!m_pBayWin)
m_pBayWin=new XBayWindow;
memcpy(m_pBayWin, pSrc->m_pBayWin, sizeof(XBayWindow));
}
else
{
if(m_pBayWin)
{
delete m_pBayWin;
m_pBayWin=NULL;
}
}
// TArch6 data
if(database()==NULL||
pSrcEntity->database()==NULL||
database()==pSrcEntity->database())//add by whl on 060317
{
m_idTextStyle=pSrc->m_idTextStyle;
m_idLayerText=pSrc->m_idLayerText; //文字样式和图层
m_idLayerGlass3d=pSrc->m_idLayerGlass3d;
m_idLayerFrame3d=pSrc->m_idLayerFrame3d;
m_idLayerSlab3d=pSrc->m_idLayerSlab3d; //玻璃、窗框和窗台板的图层
}
m_nTextHeight=pSrc->m_nTextHeight; //文字转角,文字高度
m_uFrame=pSrc->m_uFrame;
m_vFrame=pSrc->m_vFrame; //窗框(竖直)高度和窗框(水平)厚度
m_nSlabThickness=pSrc->m_nSlabThickness; //窗台板厚
m_lstFrameLines.Reset(); //待映射的窗框线,不包括外框
for(int n=0; n<pSrc->m_lstFrameLines.Length(); n++)
{
m_lstFrameLines.Append(new XCurveSegment(*pSrc->m_lstFrameLines[n]));
}
m_colorText=pSrc->m_colorText;
m_nOpStyleEx=pSrc->m_nOpStyleEx;
m_nProWinSlabWidth=pSrc->m_nProWinSlabWidth;
}
}
///////////////////////////////////////////////////////////////////////
// 访问属性的方法
Acad::ErrorStatus
TDbOpening::subGetClassID(CLSID* pClsid) const
{
return Acad::eOk;
}
// 从DWG读入数据:
Acad::ErrorStatus TDbOpening::dwgInFields (AcDbDwgFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbEntity::dwgInFields(pFiler);
if(es != Acad::eOk)
return es;
Adesk::UInt8 nVer;
pFiler->readItem(&nVer);
if(nVer>g_nVersion)
{// Version is too new
return Acad::eMakeMeProxy;
}
pFiler->readItem(&(AcGePoint3d &)m_ptLocation); //含Z坐标,作为窗台高度
pFiler->readItem(&m_nWidth);
pFiler->readItem(&m_nThickness);
pFiler->readItem(&m_nHeight); // nWidth有正负, nHeight>0
pFiler->readItem(&m_nRotation); // 0~2*PI
pFiler->readItem(&m_nQuadrant);
Adesk::UInt8 nKind;
pFiler->readItem(&nKind);
m_opKind = (OpeningKind)nKind;
pFiler->readItem(&m_nBulge); //对于弧形窗不为0
TCHAR *pBuffer=NULL;
pFiler->readString(&pBuffer);
assert(pBuffer);
m_sLabel=pBuffer;
acdbFree(pBuffer);
pFiler->readItem(&m_nIdStyle2d);
pFiler->readItem(&m_nIdStyle3d);
pFiler->readItem(&(AcGePoint3d &)m_ptLabel);
pFiler->readItem(&m_nIdOfWall);
if(nVer>1) // TArch6
pFiler->readItem(&m_nOpStyle);
else
{ // Upgrade
Adesk::UInt8 oldStyle=0;
pFiler->readItem(&oldStyle);
m_nOpStyle=oldStyle;
if(HasSlot())
SetSlot3d(TRUE);
}
if(HasSlot())
{
pFiler->readItem(&m_nSlotExt);
pFiler->readItem(&m_nSlotWidth);
}
if (m_opKind==OP_PROWIN)
{
if(!m_pBayWin)
m_pBayWin = new XBayWindow;
// sg modify 120518,在凸窗中增加了数据,间接需要版本号来增加数据
// VERIFY(m_pBayWin->dwgInFields(pFiler)==Acad::eOk);
VERIFY(m_pBayWin->dwgInFields(pFiler, nVer)==Acad::eOk);
}
else if(m_opKind==OP_DOORWIN || m_opKind==OP_TWODOOR)
{
pFiler->readItem(&m_nDoorWidth);
if(m_opKind==OP_DOORWIN)
pFiler->readItem(&m_nWinHeight);
}
m_lstFrameLines.Reset();
m_idLayerGlass3d=m_idLayerFrame3d=m_idLayerSlab3d=AcDbObjectId::kNull;
if(nVer>1) { // TArch6
pFiler->readItem(&m_idTextStyle);
pFiler->readItem(&m_idLayerText);
pFiler->readItem(&m_idLayerGlass3d);
pFiler->readItem(&m_idLayerFrame3d);
pFiler->readItem(&m_idLayerSlab3d);
pFiler->readItem(&m_nTextHeight);
pFiler->readItem(&m_nSlabThickness);
pFiler->readItem(&m_uFrame);
pFiler->readItem(&m_vFrame);
Adesk::UInt16 nCount=0;
pFiler->readItem(&nCount);
for(Adesk::UInt16 n=0; n<nCount; n++)
{
XPoint pt1, pt2;
double val;
pFiler->readItem(&(AcGePoint2d &)pt1);
pFiler->readItem(&(AcGePoint2d &)pt2);
pFiler->readItem(&val);
m_lstFrameLines.Append(new XCurveSegment(pt1, pt2, val, LS_FINITE));
}
}
else
{
if(database()==acdbCurDwg())
{
m_idTextStyle = InitTextStyle(TS_WINDOW);
m_idLayerText = InitLayer(LAY_OPENING_DIM, FALSE);
m_idLayerGlass3d = InitLayer(LAY_3DGLASS, FALSE);
m_idLayerSlab3d = m_idLayerFrame3d = InitLayer(LAY_3DFRAME, FALSE);
}
else
{
m_idTextStyle = GetValidTextStyle(database(), _T("_TCH_WINDOW"));
m_idLayerText = GetLayerIdFromString(LAY_OPENING_DIM, database());
m_idLayerGlass3d = GetLayerIdFromString(LAY_3DGLASS, database());
m_idLayerSlab3d = m_idLayerFrame3d = GetLayerIdFromString(LAY_3DFRAME, database());
}
}
if(nVer>2)//TArch7
{
pFiler->readItem(&m_nOpStyleEx);
pFiler->readItem(&m_colorText);
pFiler->readItem(&m_iEnFlag);
ReadString(pFiler,m_sCons);
pFiler->readItem(&m_dbAbsorption);
pFiler->readItem(&m_dbShadeCo);
pFiler->readItem(&m_dbOutShadeCoSum);
pFiler->readItem(&m_dbOutShadeCoWin);
}
if(nVer>3)//TArch8
{
pFiler->readItem(&m_nProWinSlabWidth);
}
return pFiler->filerStatus();
}
// 写出数据到dwg:
Acad::ErrorStatus TDbOpening::dwgOutFields(AcDbDwgFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler);
if(es != Acad::eOk) return es;
if(g_nSaveTArchVer==5)
pFiler->writeItem((Adesk::UInt8)1);
else if(g_nSaveTArchVer==6)
pFiler->writeItem((Adesk::UInt8)2);
else if(g_nSaveTArchVer==7)
pFiler->writeItem((Adesk::UInt8)3);
else if(g_nSaveTArchVer==8) // sg modify 1200703,9.0升级版本号
pFiler->writeItem((Adesk::UInt8)4);
else
pFiler->writeItem(g_nVersion);
pFiler->writeItem((AcGePoint3d &)m_ptLocation); //含Z坐标,作为窗台高度
pFiler->writeItem(m_nWidth);
pFiler->writeItem(m_nThickness);
pFiler->writeItem(m_nHeight); // nWidth有正负, nHeight>0
pFiler->writeItem(m_nRotation); // 0~2*PI
pFiler->writeItem(m_nQuadrant);
Adesk::UInt8 nKind=m_opKind;
if(g_nSaveTArchVer<7)
{
if(IsDoorAsWin())
nKind=OP_WINDOW;
}
pFiler->writeItem(nKind);
pFiler->writeItem(m_nBulge); //对于弧形窗不为0
pFiler->writeString(m_sLabel);
pFiler->writeItem(m_nIdStyle2d);
pFiler->writeItem(m_nIdStyle3d);
pFiler->writeItem((AcGePoint3d &)m_ptLabel);
pFiler->writeItem(m_nIdOfWall);
if(g_nSaveTArchVer==5)
pFiler->writeItem((Adesk::UInt8)m_nOpStyle);
else
pFiler->writeItem(m_nOpStyle);
if(HasSlot())
{
pFiler->writeItem(m_nSlotExt);
pFiler->writeItem(m_nSlotWidth);
}
if(m_opKind==OP_PROWIN)
{
ASSERT(m_pBayWin);
VERIFY(m_pBayWin->dwgOutFields(pFiler)==Acad::eOk);
}
else if(m_opKind==OP_DOORWIN || m_opKind==OP_TWODOOR)
{
pFiler->writeItem(m_nDoorWidth);
if(m_opKind==OP_DOORWIN)
pFiler->writeItem(m_nWinHeight);
}
// TArch6
if(g_nSaveTArchVer>5)
{
pFiler->writeItem(m_idTextStyle);
pFiler->writeItem(m_idLayerText);
pFiler->writeItem(m_idLayerGlass3d);
pFiler->writeItem(m_idLayerFrame3d);
pFiler->writeItem(m_idLayerSlab3d);
pFiler->writeItem(m_nTextHeight);
pFiler->writeItem(m_nSlabThickness);
pFiler->writeItem(m_uFrame);
pFiler->writeItem(m_vFrame);
Adesk::UInt16 nCount=m_lstFrameLines.Length();
pFiler->writeItem(nCount);
for(Adesk::UInt16 n=0; n<nCount; n++)
{
const XCurveSegment &rSeg=m_lstFrameLines[(int)n];
pFiler->writeItem((const AcGePoint2d &)rSeg.StartPoint());
pFiler->writeItem((const AcGePoint2d &)rSeg.EndPoint());
pFiler->writeItem(rSeg.GetBulge());
}
}
//TArch7
if(g_nSaveTArchVer>6)
{
pFiler->writeItem(m_nOpStyleEx);
pFiler->writeItem(m_colorText);
pFiler->writeItem(m_iEnFlag);
pFiler->writeString(m_sCons);
pFiler->writeItem(m_dbAbsorption);
pFiler->writeItem(m_dbShadeCo);
pFiler->writeItem(m_dbOutShadeCoSum);
pFiler->writeItem(m_dbOutShadeCoWin);
}
//TArch8
if(g_nSaveTArchVer>7)
{
pFiler->writeItem(m_nProWinSlabWidth);
}
return es;
}
Acad::ErrorStatus TDbOpening::dxfInFields (AcDbDxfFiler* pFiler)
{
assertWriteEnabled();
Acad::ErrorStatus es = TDbEntity::dxfInFields(pFiler);
if(es!=Acad::eOk)
return es;
if (!pFiler->atSubclassData(_T("TDbOpening"))) {
return Acad::eBadDxfSequence;
}
int fieldsFlags=0;
resbuf rb;
XString s1, s2, s3;
Adesk::Int32 bitFlags=0;
int n1, n2, n3, n4;
double r1, r2, r3, r4, r5, r6;
double a1, a2;
XPoint pt1, pt2;
AcDbObjectId idWall;
while ((es == Acad::eOk)
&& ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) {
switch (rb.restype) {
case 1:
s1=rb.resval.rstring;
fieldsFlags |= 0x01;
free(rb.resval.rstring);
break;
case 2:
s2=rb.resval.rstring;
fieldsFlags |= 0x02;
free(rb.resval.rstring);
break;
case 302:
s3=rb.resval.rstring;
fieldsFlags |= 0x04;
free(rb.resval.rstring);
break;
case AcDb::kDxfXCoord:
pt1=rb.resval.rpoint;
fieldsFlags |= 0x08;
break;
case AcDb::kDxfXCoord+1:
pt2=rb.resval.rpoint;
fieldsFlags |= 0x10;
break;
case AcDb::kDxfReal:
r1=rb.resval.rreal;
fieldsFlags |= 0x20;
break;
case AcDb::kDxfReal+1:
r2=rb.resval.rreal;
fieldsFlags |= 0x40;
break;
case AcDb::kDxfReal+3:
r3=rb.resval.rreal;
fieldsFlags |= 0x80;
break;
case AcDb::kDxfReal+4:
r4=rb.resval.rreal;
fieldsFlags |= 0x100;
break;
case AcDb::kDxfReal+5:
r5=rb.resval.rreal;
fieldsFlags |=0x200;
break;
case AcDb::kDxfReal+6:
r6=rb.resval.rreal;
fieldsFlags |= 0x400;
break;
case AcDb::kDxfAngle:
a1=rb.resval.rreal;
fieldsFlags |= 0x800;
break;
case AcDb::kDxfAngle+1:
a2=rb.resval.rreal;
fieldsFlags |= 0x1000;
break;
case AcDb::kDxfInt16:
n1=rb.resval.rint;
fieldsFlags |= 0x2000;
break;
case AcDb::kDxfInt16+1:
n2=rb.resval.rint;
fieldsFlags |= 0x4000;
break;
case AcDb::kDxfInt16+2:
n3=rb.resval.rint;
fieldsFlags |= 0x8000;
break;
case AcDb::kDxfInt16+3:
n4=rb.resval.rint;
fieldsFlags |= 0x10000;
break;
case AcDb::kDxfInt32:
bitFlags=rb.resval.rint;
break;
case AcDb::kDxfSoftPointerId:
acdbGetObjectId(idWall, rb.resval.rlname);
fieldsFlags |= 0x20000;
break;
case 147:
m_nSlabThickness = rb.resval.rreal;
break;
case 148:
m_uFrame = rb.resval.rreal;
break;
case 149:
m_vFrame = rb.resval.rreal;
break;
case 7:
{
XString sName;
sName=rb.resval.rstring;
free(rb.resval.rstring);
m_idTextStyle=TchExport::GetTextStyleId(sName, database());
}
break;
case 140:
m_nTextHeight=rb.resval.rreal;
break;
case 410:
m_idLayerText=LayerString2Id(rb.resval.rstring, database());
free(rb.resval.rstring);
break;
case 411:
m_idLayerGlass3d=LayerString2Id(rb.resval.rstring, database());
free(rb.resval.rstring);
break;
case 412:
m_idLayerFrame3d=LayerString2Id(rb.resval.rstring, database());
free(rb.resval.rstring);
break;
case 413:
m_idLayerSlab3d=LayerString2Id(rb.resval.rstring, database());
free(rb.resval.rstring);
break;
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(!m_idTextStyle) {
XString style;
if(database())
m_idTextStyle=database()->textstyle();
else {
xg_getvar(_T("TEXTSTYLE"), style);
m_idTextStyle = TchExport::GetTextStyleId(style, database());
}
}
if (!(fieldsFlags&0x08)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 10"));
return Acad::eMissingDxfField;
}
if (!(fieldsFlags&0x10)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 11"));
return Acad::eMissingDxfField;
}
if (!(fieldsFlags&0x20)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 40"));
return Acad::eMissingDxfField;
}
if (!(fieldsFlags&0x40)) {
pFiler->setError(Acad::eMissingDxfField,
_T("\nMissing DXF group code: 41"));
return Acad::eMissingDxfField;
}
if(!!s1)
m_nIdStyle2d=GetBlockIdFromString(s1);
if(!!s2)
m_nIdStyle3d=GetBlockIdFromString(s2);
if(fieldsFlags&0x04)
m_sLabel=s3;
m_ptLocation=pt1;
m_ptLabel=pt2;
m_nWidth=r1;
m_nHeight=r2;
if(fieldsFlags&0x80)
m_nSlotExt=r3;
if(fieldsFlags&0x100)
m_nSlotWidth=r4;
if(fieldsFlags&0x200)
m_nDoorWidth=r5;
if(fieldsFlags&0x400)
m_nWinHeight=r6;
if(fieldsFlags&0x800)
m_nRotation=a1;
if(fieldsFlags&0x1000)
m_nBulge=a2;
if(fieldsFlags&0x2000)
m_nQuadrant=n1;
if(fieldsFlags&0x4000)
m_opKind=(OpeningKind)n2;
if(m_opKind==OP_PROWIN) {
if(!m_pBayWin)
m_pBayWin=new XBayWindow;
if(fieldsFlags&0x200)
m_pBayWin->m_nProtrude=r5;
if(fieldsFlags&0x400)
m_pBayWin->m_nTrapezia=r6;
}
if(fieldsFlags&0x8000)
m_nOpStyle=n3;
if(fieldsFlags&0x10000) {
if(m_pBayWin)
m_pBayWin->m_nStyle=(XBayWindow::XBayWinStyle)n4;
}
if(fieldsFlags&0x20000) {
m_nIdOfWall=idWall;
}
//TArch7
m_nOpStyleEx=bitFlags;
return pFiler->filerStatus();
}
Acad::ErrorStatus TDbOpening::dxfOutFields(AcDbDxfFiler* pFiler) const
{
assertReadEnabled();
Acad::ErrorStatus es;
es = TDbEntity::dxfOutFields(pFiler);
assert(es == Acad::eOk);
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbOpening"));
assert(es == Acad::eOk);
/*
es = pFiler->writeItem(AcDb::kDxfInt8,g_nVersion);
assert(es == Acad::eOk);
*/
XString sName2d, sName3d;
if(!m_nIdStyle2d) ;
else
sName2d=GetSymbolName(m_nIdStyle2d);
if(!m_nIdStyle3d) ;
else
sName3d=GetSymbolName(m_nIdStyle3d);
pFiler->writeString(1, sName2d);
pFiler->writeString(2, sName3d);
pFiler->writeString(302, m_sLabel);
pFiler->writePoint3d(10, m_ptLocation);
pFiler->writePoint2d(11, m_ptLabel);
pFiler->writeDouble(AcDb::kDxfReal, m_nWidth);
pFiler->writeDouble(AcDb::kDxfReal+1, m_nHeight);
pFiler->writeDouble(AcDb::kDxfAngle, m_nRotation);
pFiler->writeDouble(AcDb::kDxfAngle+1, m_nBulge);
pFiler->writeDouble(AcDb::kDxfReal+3, m_nSlotExt);
pFiler->writeDouble(AcDb::kDxfReal+4, m_nSlotWidth);
pFiler->writeDouble(AcDb::kDxfReal+5, m_pBayWin? m_pBayWin->m_nProtrude : m_nDoorWidth);
pFiler->writeDouble(AcDb::kDxfReal+6, m_pBayWin? m_pBayWin->m_nTrapezia : m_nWinHeight);
pFiler->writeInt16(AcDb::kDxfInt16, m_nQuadrant);
pFiler->writeInt16(AcDb::kDxfInt16+1, m_opKind);
pFiler->writeInt16(AcDb::kDxfInt16+2, m_nOpStyle);
if(m_pBayWin)
pFiler->writeInt16(AcDb::kDxfInt16+3, m_pBayWin->m_nStyle);
es = pFiler->writeItem(AcDb::kDxfSoftPointerId,m_nIdOfWall);
pFiler->writeDouble(147, m_nSlabThickness);
pFiler->writeDouble(148, m_uFrame);
pFiler->writeDouble(149, m_vFrame);
pFiler->writeString(7, (const TCHAR *)GetSymbolName(m_idTextStyle));
pFiler->writeDouble(140, m_nTextHeight);
pFiler->writeString(410, (const TCHAR *)LayerId2String(m_idLayerText));
pFiler->writeString(411, (const TCHAR *)LayerId2String(m_idLayerGlass3d));
pFiler->writeString(412, (const TCHAR *)LayerId2String(m_idLayerFrame3d));
pFiler->writeString(413, (const TCHAR *)LayerId2String(m_idLayerSlab3d));
//TArch7
pFiler->writeItem(AcDb::kDxfInt32,m_nOpStyleEx);
return es;
}
// 克隆门窗的时候
Acad::ErrorStatus
TDbOpening::subDeepClone(AcDbObject* pOwner,
AcDbObject*& pClonedObject,
AcDbIdMapping& idMap,
Adesk::Boolean isPrimary) const
{
Acad::ErrorStatus es=TDbEntity::subDeepClone(pOwner, pClonedObject, idMap, isPrimary);
return es; // Modify by ZJQ on 2001/11/29
if(es!=Acad::eOk)
return es;
if(!m_nIdOfWall)
return es;
// STEP 8:
// if the wall is not beening cloned then modify pcloned
if (idMap.deepCloneContext()==AcDb::kDcCopy)
{
AcDbIdPair idPairWall(m_nIdOfWall, AcDbObjectId::kNull,
false, isPrimary? true :false);
if(!idMap.compute(idPairWall))
{
TDbOpening *pClonedOpening = TDbOpening::cast(pClonedObject);
assert(pClonedOpening);
pClonedOpening->m_nIdOfWall=AcDbObjectId();
}
}
// Leave pClonedObject open for the caller
//
return Acad::eOk;
}
Acad::ErrorStatus TDbOpening::subGetOsnapPoints(
AcDb::OsnapMode osnapMode,
INT_PTR gsSelectionMark,
const AcGePoint3d& ptPick,
const AcGePoint3d& lastPoint,
const AcGeMatrix3d& viewXform,
AcGePoint3dArray& snapPoints,
AcDbIntArray& geomIds) const
{
assertReadEnabled();
if (osnapMode == AcDb::kOsModeIns)
{ //插入点捕捉
XPoint ptIns=m_ptLocation;
if(!IsExplode3D())
ptIns.z=0;
snapPoints.append(ptIns);
return Acad::eOk;
}
return TDbEntity::subGetOsnapPoints(osnapMode, gsSelectionMark, ptPick, lastPoint, viewXform,
snapPoints, geomIds);
}
// -----------------------------------------------------------------------
// Overriden functions for edit
// 取夹点
// 依次为插入点, 左右侧点, 开启方向控制点,
// 待加标号控制点
Acad::ErrorStatus TDbOpening::subGetGripPoints(AcGePoint3dArray& gripPoints,
AcDbIntArray& osnapModes,
AcDbIntArray& geomIds) const
{
//if(TArchCmdReactor::g_sCurCommand==_T("GRIP_STRETCH")) {
// if(!!objectId())
// g_idCurStretchOpening=objectId();
//}
gripPoints.append(m_ptLocation);
// 左右侧点
XPoint ptSideStart, ptSideEnd;
GetSidePoints(ptSideStart, ptSideEnd);
gripPoints.append(ptSideStart);
gripPoints.append(ptSideEnd);
XPoint ptQuadrant;
ads_polar(m_ptLocation, m_nRotation+m_nQuadrant*PI/2+PI/4, m_nWidth/2.0, ptQuadrant);
gripPoints.append(ptQuadrant);
if(!(!m_sLabel))
{
gripPoints.append(m_ptLabel);
}
return Acad::eOk;
}
#if ADS>15
void TDbOpening::CreateGrip()
{
TDbEntity::CreateGrip();
XCurveSegment curve;
if(GetCenterCurve(curve)&&curve.Is(CURVE_LINE))
{
GetGrip(0)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength));
GetGrip(0)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength,false));
GetGrip(1)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength));
GetGrip(1)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength));
GetGrip(1)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength,false));
GetGrip(2)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength));
GetGrip(2)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength));
GetGrip(2)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength,false));
}
}
Acad::ErrorStatus TDbOpening::EntityToDim(long iGrip,long iDim,const AcDbEntity*pEnt0)
{
XCurveSegment wall;
if(!GetCenterCurve(wall))//中线
return Acad::eInvalidInput;
TDbGripDim*pDim=GetGripDim(iGrip,iDim);
if(pDim==NULL)
return Acad::eInvalidInput;
TDbOpening*pEnt=TDbOpening::cast(pEnt0);
if(pEnt==NULL)
pEnt=this;
XPoint vt(wall.EndPoint()-wall.StartPoint());
switch(iGrip)
{
case 0://位置夹点
switch(iDim)
{
case 0://宽度
{
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
XPoint ptSideStart, ptSideEnd;
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
pDistDim->SetData(ptSideStart.AsAcGePoint3d(),ptSideEnd.AsAcGePoint3d(),1500);
}
break;
case 1://位置偏移
{
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
XPoint pt;
wall.ProjectToMe(pEnt->GetLocation(),pt);
pDistDim->SetData(pt.AsAcGePoint3d(),pDim->GripPoint(),800);
}
break;
default:
return Acad::eNotImplementedYet;
}
break;
case 1://起点
switch(iDim)
{
case 0://从终点到起点的宽度
{
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
XPoint ptSideStart, ptSideEnd;
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
pDistDim->SetData(ptSideStart.AsAcGePoint3d(),ptSideEnd.AsAcGePoint3d(),1500);
}
break;
case 1://前垛距
{
XCurveSegment seg;
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
XPoint pt;
if(GetNeighbourPoint(pt,true))
{
XPoint ptSideStart,ptSideEnd;
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
wall.ProjectToMe(pt,pt);
wall.ProjectToMe(ptSideStart,ptSideStart);
pDistDim->SetData(pt.AsAcGePoint3d(),ptSideStart.AsAcGePoint3d(),1200);
}
}
break;
case 2://总体偏移或起点偏移
{
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
XPoint ptSideStart,ptSideEnd;
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
wall.ProjectToMe(ptSideStart,ptSideStart);
pDistDim->SetData(pDim->GripPoint(),ptSideStart.AsAcGePoint3d(),800);
}
break;
default:
return Acad::eNotImplementedYet;
}
break;
case 2://终点
switch(iDim)
{
case 0://从起点到终点的宽度
{
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
XPoint ptSideStart, ptSideEnd;
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
pDistDim->SetData(ptSideStart.AsAcGePoint3d(),ptSideEnd.AsAcGePoint3d(),1500);
}
break;
case 1://后垛距
{
XCurveSegment seg;
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
XPoint pt;
if(GetNeighbourPoint(pt,false))
{
XPoint ptSideStart,ptSideEnd;
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
wall.ProjectToMe(pt,pt);
wall.ProjectToMe(ptSideEnd,ptSideEnd);
pDistDim->SetData(ptSideEnd.AsAcGePoint3d(),pt.AsAcGePoint3d(),1200);
}
}
break;
case 2://总体偏移或起点偏移
{
TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim;
XPoint ptSideStart,ptSideEnd;
pEnt->GetSidePoints(ptSideStart, ptSideEnd);
wall.ProjectToMe(ptSideEnd,ptSideEnd);
pDistDim->SetData(pDim->GripPoint(),ptSideEnd.AsAcGePoint3d(),800);
}
break;
default:
return Acad::eNotImplementedYet;
}
break;
default:
return Acad::eNotImplementedYet;
}
return Acad::eOk;
}
Acad::ErrorStatus TDbOpening::DimToEntity(long iGrip,long iDim,double newValue,const AcGeVector3d &offset)
{
assertWriteEnabled();
AcGePoint3d ptNew=GetGripPoint(iGrip)+offset;
XCurveSegment wall;
GetCenterCurve(wall);
XPoint vt=wall.EndPoint()-wall.StartPoint();
vt.Normalize();
switch(iGrip)
{
case 0://位置夹点
switch(iDim)
{
case 0://宽度
if(newValue>1E-6)
SetWidth(newValue);
break;
case 1://整体偏移
{
if(vt.AsAcGeVector3d().dotProduct(offset)>0)
vt*=newValue;
else
vt*=-newValue;
m_ptLocation+=vt;
m_ptLabel+=vt;
}
break;
}
break;
case 1://起点
switch(iDim)
{
case 0://单侧改宽
if(newValue>1E-6)
{
vt*=((m_nWidth-newValue)/2);
m_ptLocation+=vt;
m_ptLabel+=vt;
SetWidth(newValue);
}
break;
case 1://前垛距
{
XCurveSegment seg;
XPoint pt;
GetNeighbourPoint(pt,true);
wall.ProjectToMe(pt,pt);
double oldValue=pt.Distance2d(GetGripPoint(iGrip));
// sg modify 110120,根据8.5需求,夹点功能改变,默认为“单侧改宽”
// if(GetCtrlToggle())//单侧改宽
if(!GetCtrlToggle())//单侧改宽
{
newValue=m_nWidth-newValue+oldValue;
if(newValue>1E-6)
{
vt*=((m_nWidth-newValue)/2);
m_ptLocation+=vt;
m_ptLabel+=vt;
SetWidth(newValue);
}
}
else//整体偏移
{
vt*=(newValue-oldValue);
m_ptLocation+=vt;
m_ptLabel+=vt;
}
}
break;
case 2://总体偏移或起点偏移
// sg modify 110120,根据8.5需求,夹点功能改变,默认为“单侧改宽”
//if(GetCtrlToggle())//单侧改宽
if(!GetCtrlToggle())//单侧改宽
{
if(vt.AsAcGeVector3d().dotProduct(offset)>0)
newValue=m_nWidth-newValue;
else
newValue=m_nWidth+newValue;
if(newValue>1E-6)
{
vt*=((m_nWidth-newValue)/2);
m_ptLocation+=vt;
m_ptLabel+=vt;
SetWidth(newValue);
}
}
else//整体偏移
{
if(vt.AsAcGeVector3d().dotProduct(offset)>0)
vt*=newValue;
else
vt*=-newValue;
m_ptLocation+=vt;
m_ptLabel+=vt;
}
break;
}
break;
case 2://终点
switch(iDim)
{
case 0://单侧改宽
{
vt*=((newValue-m_nWidth)/2);
m_ptLocation+=vt;
m_ptLabel+=vt;
SetWidth(newValue);
}
break;
case 1://后垛距
{
XCurveSegment seg;
XPoint pt;
GetNeighbourPoint(pt,false);
wall.ProjectToMe(pt,pt);
double oldValue=pt.Distance2d(GetGripPoint(iGrip));
// sg modify 110120,根据8.5需求,夹点功能改变,默认为“单侧改宽”
//if(GetCtrlToggle())//单侧改宽
if(!GetCtrlToggle())//单侧改宽
{
newValue=m_nWidth-newValue+oldValue;
if(newValue>1E-6)
{
vt*=((newValue-m_nWidth)/2);
m_ptLocation+=vt;
m_ptLabel+=vt;
SetWidth(newValue);
}
}
else//整体偏移
{
vt*=(oldValue-newValue);
m_ptLocation+=vt;
m_ptLabel+=vt;
}
}
break;
case 2://总体偏移或终点偏移
{
// sg modify 110120,根据8.5需求,夹点功能改变,默认为“单侧改宽”
//if(GetCtrlToggle())//单侧改宽
if(!GetCtrlToggle())//单侧改宽
{
if(vt.AsAcGeVector3d().dotProduct(offset)>0)
newValue=m_nWidth+newValue;
else
newValue=m_nWidth-newValue;
if(newValue>1E-6)
{
vt*=((newValue-m_nWidth)/2);
m_ptLocation+=vt;
m_ptLabel+=vt;
SetWidth(newValue);
}
}
else//整体偏移
{
if(vt.AsAcGeVector3d().dotProduct(offset)>0)
vt*=newValue;
else
vt*=-newValue;
m_ptLocation+=vt;
m_ptLabel+=vt;
}
}
break;
}
break;
}
return Acad::eOk;
}
#endif
// Stretch的夹点只有插入点和标号位置
Acad::ErrorStatus TDbOpening::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
{
stretchPoints.append(m_ptLocation);
if (!!m_sLabel)
{
stretchPoints.append(m_ptLabel);
}
return Acad::eOk;
}
// Active when being rotated, scaled, moved, etc.
// 在全局旋转之后,仍然要保持旋转角度同墙体一致
Acad::ErrorStatus TDbOpening::subTransformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
TDbEntity::subTransformBy(xform);
//修改原因 : 增加记录 boundary,hatch 命令涉及到的 动态变换矩阵 m_mat3d
// 当AcDbBlockRef 中引用到门窗时,对于boundary,hatch 这样的边界分析命令,
// 先调用 transformby,然后调用 ExplodeOrDraw2d时,对关联的墙分析有误,此时
// 墙还没有transformby,导致门窗和墙关系不同步错误,boundary,hatch 分析乱线
// 该矩阵不序列化
//修改人 : lfy 2009-11-08
m_mat3d.setToIdentity();
struct resbuf rb;
acedGetVar(_T("CMDNAMES"),&rb);
CString sCmd = rb.resval.rstring;
acutDelString(rb.resval.rstring);
if (sCmd.CompareNoCase(_T("BHATCH") ) == 0 ||
sCmd.CompareNoCase(_T("_BHATCH") ) == 0 ||
sCmd.CompareNoCase(_T("BOUNDARY")) == 0||
sCmd.CompareNoCase(_T("_BOUNDARY")) == 0||
//add by xlc on 110304 解决弧墙上的门窗移动复制时飞线问题
sCmd.CompareNoCase(_T("MOVE")) == 0||
sCmd.CompareNoCase(_T("COPY")) == 0||
sCmd.CompareNoCase(_T("_MOVE")) == 0||
sCmd.CompareNoCase(_T("_COPY")) == 0
)
{
m_mat3d = xform;
}
XPoint ptQuadrant;
ads_polar(m_ptLocation, m_nRotation+m_nQuadrant*PI/2+PI/4, m_nWidth/2.0, ptQuadrant);
AcGePoint3d &pt=m_ptLocation;
pt.transformBy(xform);
((AcGePoint3d &)m_ptLabel).transformBy(xform);
/*
if(!!m_nIdOfWall) {
AcDbObjectIdArray idArray;
if(acdbGetCurrentSelectionSet(idArray)!=Acad::eOk)
return Acad::eInvalidInput;
if(idArray.contains(m_nIdOfWall)) ; //墙也参与变换
else { //墙没有参与变换
XDbObject obj(m_nIdOfWall, AcDb::kForRead);
if(!(!obj)) {
TDbWall *pWall = TDbWall::cast(obj.m_pObject);
m_nRotation = pWall->Direction(m_ptLocation);
}
}
}*/
XVector3D vtRot(cos(m_nRotation), sin(m_nRotation));
((AcGeVector3d &)vtRot).transformBy(xform);
m_nRotation=ads_angle(XPoint(), vtRot);
// 对开向控制点进行变换
{
((AcGePoint3d &)ptQuadrant).transformBy(xform);
ads_real nAng=CT_std_angle(ads_angle(m_ptLocation, ptQuadrant)-m_nRotation);
if(nAng>=0.0 && nAng<PI/2.0) m_nQuadrant=0;
else if(nAng>=PI/2.0 && nAng<PI) m_nQuadrant=1;
else if(nAng>=PI && nAng<1.5*PI) m_nQuadrant=2;
else m_nQuadrant=3;
}
ads_matrix mat;
AsAdsMatrix(xform,mat);
if(IsMirrorMatrix(mat))
{
if(HasLeftSlab()&&!HasRightSlab())
SetSideSlab(3);
else if(HasRightSlab()&&!HasLeftSlab())
SetSideSlab(2);
}
return Acad::eOk;
}
// 功能: 夹点操作
// 方法:
// 1. 移动插入点: 固定门窗在墙体的轨迹上移动
// 2. 拖曳镜像点: 用来改变开启方向
Acad::ErrorStatus TDbOpening::subMoveGripPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
XPoint vtOffset=*(XPoint *)&offset;
vtOffset.z = 0;
double nSill=m_ptLocation.z;
for (int i = 0; i < indices.length(); i++) {
int idx = indices[i];
switch(idx) {
case 0:
case 1:
case 2:
{
// 移动边界,单侧改宽度
// sg modify 110120,根据8.5需求,夹点功能改变,默认为“单侧改宽”
// if(idx==0 || !GetCtrlToggle())
if(idx==0 || GetCtrlToggle()) // 移动位置
{
XVector3D vt0=vtOffset;
if(g_bModelNumber && IsLinear()) {//模数开关
ASSERT(g_nWinStep>1.0E-3);
double nLen=vt0.Length();
vt0 /= nLen;
nLen = AS_INT(nLen/g_nWinStep)*g_nWinStep;
vt0 *= nLen;
}
XDbObject objWall(m_nIdOfWall, AcDb::kForRead);
TDbWall *pWall0 = !objWall? NULL : TDbWall::cast(objWall.m_pObject);
XPoint ptDest = m_ptLocation + vt0;
m_ptLocation += vt0;
m_ptLabel += vt0;
m_ptLocation.z = nSill; //不改变窗台高度
m_ptLabel.z = 0;
}
else // 单侧改宽
{
XPoint ptSideStart, ptSideEnd;
GetSidePoints(ptSideStart, ptSideEnd);
XPoint &ptSide = (idx==1? ptSideStart:ptSideEnd);
XPoint &ptOtherSide = (idx==1? ptSideEnd : ptSideStart);
ptSide += vtOffset;
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if(pWall)
{
// sg modify 110127,获得墙体基线时,考虑保温厚,放置门窗对象拖拽夹点后发生宽度错误
// XCurveSegment segCenter=pWall->OffsetGeomCenter();
XCurveSegment segCenter=pWall->OffsetGeomCenter(LS_INFINITE, TRUE);
segCenter.SetElevation(m_ptLocation.z);
segCenter.ProjectToMe(XPoint(ptSide), ptSide);
}
OPENOBJ_END();
if(g_bModelNumber && IsLinear()) {//模数开关
ASSERT(g_nWinStep>1.0E-3);
double nAng=ads_angle(ptOtherSide, ptSide);
double nSize=ads_distance(ptOtherSide, ptSide);
nSize = AS_INT(nSize/g_nWinStep)*g_nWinStep;
ads_polar(ptOtherSide, nAng, nSize, ptSide);
}
SetSidePoints(ptSideStart, ptSideEnd);
}
}
break;
case 3: {//Move quadrant point
XPoint ptQuadrant;
ads_polar(m_ptLocation, m_nRotation+m_nQuadrant*PI/2+PI/4, m_nWidth/2.0, ptQuadrant);
ptQuadrant += vtOffset;
ptQuadrant.z = nSill;
int nOldQuadrant=m_nQuadrant;
ads_real nAng=CT_std_angle(ads_angle(m_ptLocation, ptQuadrant)-m_nRotation);
if(nAng>=0.0 && nAng<PI/2.0) m_nQuadrant=0;
else if(nAng>=PI/2.0 && nAng<PI) m_nQuadrant=1;
else if(nAng>=PI && nAng<1.5*PI) m_nQuadrant=2;
else m_nQuadrant=3;
// 假如由0/1变为2/3,或由2/3变为0/1,着对标号位置进行镜像
if((nOldQuadrant<2 && m_nQuadrant>=2) || (nOldQuadrant>=2 && m_nQuadrant<2)) {
XLine ln(m_ptLocation, m_nRotation);
ln.SetElevation(m_ptLabel.z);
XPoint ptPrj;
if(m_ptLabel.Project(&ln, ptPrj)==RTNORM) {
ptPrj.Mirror(XPoint(m_ptLabel), m_ptLabel);
}
//add by xlc on 110215 调整单侧门口线开启侧
if (!(
(m_nOpStyleEx & OPS_DOORLINE_MID) //居中
|| (m_nOpStyle & (OPS_DOORLINE1+OPS_DOORLINE2)) == 0 //无门口线
|| (m_nOpStyle | (OPS_DOORLINE1+OPS_DOORLINE2)) == m_nOpStyle //双侧门口线
)
)
{
if (m_nOpStyle & OPS_DOORLINE1)
{
m_nOpStyle &= ~OPS_DOORLINE1;
}
else
{
m_nOpStyle |= OPS_DOORLINE1;
}
if (m_nOpStyle & OPS_DOORLINE2)
{
m_nOpStyle &= ~OPS_DOORLINE2;
}
else
{
m_nOpStyle |= OPS_DOORLINE2;
}
}
}
}
break;
case 4: // move label
m_ptLabel += vtOffset;
break;
}
}
return Acad::eOk;
}
// 取夹点的说明
Acad::ErrorStatus TDbOpening::GetGripText(int i, CString &cs) const
{
Acad::ErrorStatus es=Acad::eOk;
switch(i) {
case 0:
cs=_T("移动门窗");
break;
case 1:
case 2: {
// sg modify 110120,根据8.5需求,夹点功能改变,默认为“单侧改宽”
// cs=GetCtrlToggle()? _T("单侧改宽(Ctrl-移动门窗)") : _T("移动门窗(Ctrl-单侧改宽)");
cs=GetCtrlToggle() ? _T("移动门窗(Ctrl-单侧改宽)") : _T("单侧改宽(Ctrl-移动门窗)");
}
break;
case 3:
cs=_T("改变开启方向");
break;
case 4:
cs=_T("改变编号位置");
break;
default:
es=Acad::eInvalidInput;
}
return es;
}
Acad::ErrorStatus
TDbOpening::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet, BOOL *bErase)
{
if(g_nSaveTArchVer==5)
{
Acad::ErrorStatus es=Acad::eOk;
if((nDrawMode&DRAW_2D) && GetKind()==TOpeningData::OP_DOOR)
{ //门口线
XExplodeStream dc(entSet);
dc.SetPropertiesFrom(this);//add by whl on 060218
DrawDoorLine(dc);
}
}
return TDbEntity::DownGradeSave(nDrawMode,entSet,bErase);
}
int TDbOpening::ConvertText(TConvertTextPtr ptr, void *pData)
{
XString sText;
int nRet=ptr(m_sLabel, sText, pData);
if(nRet==RTNORM) {
assertWriteEnabled();
m_sLabel=sText;
}
return nRet;
}
void TDbOpening::GetLabelText(TDbText &text) const
{
AcDbObjectId idTextStyle=m_idTextStyle;
if(!idTextStyle.isValid())
idTextStyle=InitTextStyle(TS_WINDOW,database());
XString sStyleName=GetSymbolName(idTextStyle);
text.SetStyleId(idTextStyle);
text.setPropertiesFrom(this);
text.SetHeight(m_nTextHeight);
text.SetAlignment(XExplodeDraw::kMiddleCenter);
text.SetLocation(XPoint(m_ptLabel.x, m_ptLabel.y));
double nRotLabel=m_nRotation;
if(GetKind()==OP_CORNWIN || GetKind()==OP_ARCWIN) {
if(!!m_nIdOfWall) {
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if(pWall && pWall->Is(CURVE_ARC)) {
XArc ar=pWall->GetArc();
nRotLabel=CT_std_angle(ads_angle(ar.GetCenterPt(), m_ptLabel)-PI/2);
}
OPENOBJ_END();
}
}
text.SetRotation(xg_angle(nRotLabel));
text.SetText(m_sLabel);
}
// 返回发现的位置,同时posStart往前移动(以便继续找下一个使用),
TTextPosition
TDbOpening::FindSubText(const TCHAR *sSubText, TTextPosition &posStart, TTextRange *pRange) const
{
assertReadEnabled();
TDbText text;
GetLabelText(text);
TTextPosition pos=text.FindSubText(sSubText, posStart, pRange);
return pos;
}
// 返回下一次查找的开始位置
TTextPosition
TDbOpening::ReplaceSubText(const TTextPosition &posRep, const TCHAR *sRepText, TTextRange *pRange)
{
assertWriteEnabled();
TDbText text;
GetLabelText(text);
TTextPosition pos=text.ReplaceSubText(posRep, sRepText, pRange);
SetLabel(text.GetText());
return pos;
}
// 功能: 夹点操作
Acad::ErrorStatus TDbOpening::subMoveStretchPointsAt(
const AcDbIntArray& indices,
const AcGeVector3d& offset)
{
assertWriteEnabled();
XPoint vtOffset=*(XPoint *)&offset;
vtOffset.z=0;
for (int i = 0; i < indices.length(); i++) {
int idx = indices[i];
switch(idx) {
case 0: // InsertPoint
m_ptLocation += vtOffset;
break;
case 1:
m_ptLabel += vtOffset;
break;
}
}
return Acad::eOk;
}
//通知墙体已经被修改过
Acad::ErrorStatus TDbOpening::subClose()
{
Acad::ErrorStatus es = TDbEntity::subClose();
if(es==Acad::eOk && !(!m_nIdOfWall) && isModified() && database()==acdbCurDwg())
{
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if(pWall)
{
if(!pWall->isModified())
{
if(pWall->upgradeOpen()==Acad::eOk)
pWall->recordGraphicsModified();
}
}
OPENOBJ_END();
}
return es;
}
// 解除同墙体之间的引用关系
Acad::ErrorStatus TDbOpening::subErase(Adesk::Boolean bErasing)
{
extern BOOL SkipSubErase(const TCHAR *szCmd);
Acad::ErrorStatus es = TDbEntity::subErase(bErasing);
if(es==Acad::eOk && bErasing==Adesk::kTrue && !(!m_nIdOfWall)) {
#if (ADS>14)
XString &sCmd=GetCurDocData()->m_sCurCommand;
#else
XString &sCmd=TArchCmdReactor::g_sCurCommand;
#endif
if(!TchPrivate::SkipSubErase(sCmd)) {
XDbObject obj(m_nIdOfWall, AcDb::kForWrite);
if(!(!obj)) {
TDbWall *pWall = TDbWall::cast(obj.m_pObject);
if(pWall)
pWall->RemoveReferenceOpening(objectId());
}
}
}
return es;
}
Acad::ErrorStatus TDbOpening::subOpen(AcDb::OpenMode mode)
{
Acad::ErrorStatus es=TDbEntity::subOpen(mode);
extern BOOL g_bMonitorDbAction;
if(es==Acad::eOk && mode==AcDb::kForWrite &&!isNewObject()&& database()==acdbCurDwg() && g_bDwgBegin && TchGeLib::g_bMonitorDbAction)
BackupPoints();
return es;
}
BOOL TDbOpening::DrawDoorOrWin3d(XExplodeDraw &dc, const XLine &lnPos, BOOL bDoor) const
{
//TPushProperty vProp(this, dc);
AcDbObjectId idStyle=bDoor? m_nIdStyle2d : m_nIdStyle3d;
XPoint origenalSize;
if(!GetOriginal3DSize(idStyle, origenalSize))
return FALSE;
double nScaleX, nScaleY, nScaleZ;
nScaleX = origenalSize.x>_DIST_SNAP? (lnPos.GetLength()/origenalSize.x) : 1.0;
nScaleY = 1.0; //origenalSize.y>_DIST_SNAP? (m_nThickness/origenalSize.y) : 1.0;
double nSizeZ=(bDoor? m_nHeight:m_nWinHeight);
if(m_opKind==OP_TWODOOR)
nSizeZ=m_nHeight;
nScaleZ = origenalSize.z>_DIST_SNAP? (nSizeZ/origenalSize.z) : 1.0;
if(origenalSize.y>origenalSize.x/2.0) //旋转门
nScaleY=nScaleX;
XPoint ptIns;
OPENOBJ_BEGIN(idStyle, AcDb::kForRead, AcDbBlockTableRecord, pBlock);
if(!pBlock)
return FALSE;
ptIns = lnPos.MidPoint();
OPENOBJ_END();
dc<<XBlockRef(idStyle, ptIns, AcGeScale3d(nScaleX, nScaleY, nScaleZ), m_nRotation, g_bMakeBlock);
return TRUE;
}
// 绘制或分解子母门
void TDbOpening::ExplodeOrDrawTwoDoor(XExplodeDraw &dc, BOOL bDraw3d) const
{
//double nWinWidth=m_nWidth-m_nDoorWidth;
double nWidth2=m_nDoorWidth; //大门
double nWidth1=m_nWidth-m_nDoorWidth;
ASSERT(nWidth1>_DIST_SNAP);
XPoint ptArray[5];
XPoint ptBase=m_ptLocation;
ptBase.z=0.0;
ads_polar(ptBase, m_nRotation+PI, m_nWidth/2, ptArray[0]);
ads_polar(ptArray[0], m_nRotation, nWidth1, ptArray[1]);
ads_polar(ptBase, m_nRotation, m_nWidth/2, ptArray[2]);
ads_polar(ptArray[0], m_nRotation+PI/2, nWidth1, ptArray[3]);
ads_polar(ptArray[2], m_nRotation+PI/2, nWidth2, ptArray[4]);
AcDbPolyline pline;
pline.setPropertiesFrom(this);
pline.addVertexAt(0, ptArray[0]);
pline.addVertexAt(1, ptArray[3], -tan(PI/8));
pline.addVertexAt(2, ptArray[1], -tan(PI/8));
pline.addVertexAt(3, ptArray[4]);
pline.addVertexAt(4, ptArray[2]);
AcGeMatrix3d mat;
if(m_nQuadrant==1) {
AcGeLine3d ln(ptBase, AcGeVector3d(cos(m_nRotation+PI/2),sin(m_nRotation+PI/2),0));
mat.setToMirroring(ln);
VERIFY(pline.transformBy(mat)==Acad::eOk);
} else if(m_nQuadrant==2) {
mat.setToMirroring(ptBase);
VERIFY(pline.transformBy(mat)==Acad::eOk);
} else if(m_nQuadrant==3) {
AcGeLine3d ln(ptBase, AcGeVector3d(cos(m_nRotation),sin(m_nRotation),0));
mat.setToMirroring(ln);
VERIFY(pline.transformBy(mat)==Acad::eOk);
}
if(bDraw3d) {
XPoint pt0, pt1, pt2;
pline.getPointAt(0, (AcGePoint3d &)pt0);
pline.getPointAt(2, (AcGePoint3d &)pt1);
pline.getPointAt(4, (AcGePoint3d &)pt2);
XLine ln1(pt0,pt1), ln2(pt1, pt2);
ln1.SetElevation(m_ptLocation.z);
ln2.SetElevation(m_ptLocation.z);
DrawDoorOrWin3d(dc, ln1, FALSE);
DrawDoorOrWin3d(dc, ln2, TRUE);
} else {
dc.DrawEntity(pline);
}
}
// 绘制或分解门联窗
void TDbOpening::ExplodeOrDrawDoorWin(XExplodeDraw &dc, BOOL bDraw3d) const
{
double nWinWidth=m_nWidth-m_nDoorWidth;
ASSERT(nWinWidth>0);
double nWallThick=GetWallThickness(TRUE);
if(m_nQuadrant==0 || m_nQuadrant==3) {
// 画窗
XPoint ptWinSide[2];
ads_polar(m_ptLocation, m_nRotation+PI, m_nWidth/2, ptWinSide[0]);
ads_polar(ptWinSide[0], m_nRotation, nWinWidth, ptWinSide[1]);
ptWinSide[0].z=ptWinSide[1].z=bDraw3d? m_ptLocation.z+m_nHeight-m_nWinHeight : 0.0;
XLine lnMidWin(ptWinSide[0], ptWinSide[1]);
if(!bDraw3d || !DrawDoorOrWin3d(dc, lnMidWin, FALSE)) {
if(bDraw3d)
{
dc.DrawLine(lnMidWin.Offset(nWallThick/6), m_nWinHeight);
dc.DrawLine(lnMidWin.Offset(-nWallThick/6), m_nWinHeight);
}
else
{
dc<<lnMidWin.Offset(nWallThick/6);
dc<<lnMidWin.Offset(-nWallThick/6);
XLine ln1=lnMidWin.Offset(nWallThick/2), ln2=lnMidWin.Offset(-nWallThick/2);
dc << ln1 << ln2 << XLine(ln1.EndPoint(), ln2.EndPoint());
}
}
// 画门
XPoint ptDoorSide, ptTemp, ptDoorOtherSide;
ads_polar(m_ptLocation, m_nRotation, m_nWidth/2, ptDoorSide);
ads_polar(ptDoorSide, m_nRotation+PI, m_nDoorWidth, ptDoorOtherSide);
if(!bDraw3d || !DrawDoorOrWin3d(dc, XLine(ptDoorSide, ptDoorOtherSide), TRUE)) {
if(!bDraw3d)
ptDoorSide.z=0;
ads_polar(ptDoorSide, m_nRotation + (m_nQuadrant==0? PI/2.0 : -PI/2.0), m_nDoorWidth, ptTemp);
XArc ar(ptDoorSide, m_nDoorWidth,
CT_std_angle(m_nRotation+ (m_nQuadrant==0? PI/2 : PI)),
CT_std_angle(m_nRotation+ (m_nQuadrant==0? PI : -PI/2)));
if(bDraw3d)
{
dc.DrawArc(ar, m_nHeight);
dc.DrawLine(XLine(ptDoorSide, ptTemp), m_nHeight);
}
else
{
dc<<ar;
dc<<XLine(ptDoorSide, ptTemp);
}
}
} else {
// 画窗
XPoint ptWinSide[2];
ads_polar(m_ptLocation, m_nRotation, m_nWidth/2, ptWinSide[1]);
ads_polar(ptWinSide[1], m_nRotation+PI, nWinWidth, ptWinSide[0]);
ptWinSide[0].z=ptWinSide[1].z=bDraw3d? m_ptLocation.z+m_nHeight-m_nWinHeight : 0.0;
XLine lnMidWin(ptWinSide[0], ptWinSide[1]);
if(!bDraw3d || !DrawDoorOrWin3d(dc, lnMidWin, FALSE)) {
if(bDraw3d)
{
dc.DrawLine(lnMidWin.Offset(nWallThick/6), m_nWinHeight);
dc.DrawLine(lnMidWin.Offset(-nWallThick/6), m_nWinHeight);
}
else
{
dc<<lnMidWin.Offset(nWallThick/6);
dc<<lnMidWin.Offset(-nWallThick/6);
XLine ln1=lnMidWin.Offset(nWallThick/2), ln2=lnMidWin.Offset(-nWallThick/2);
dc << ln1 << ln2 << XLine(ln1.StartPoint(), ln2.StartPoint());
}
}
// 画门
XPoint ptDoorSide, ptTemp, ptDoorOtherSide;
ads_polar(m_ptLocation, m_nRotation+PI, m_nWidth/2, ptDoorSide);
ads_polar(ptDoorSide, m_nRotation, m_nDoorWidth, ptDoorOtherSide);
if(!bDraw3d || !DrawDoorOrWin3d(dc, XLine(ptDoorSide, ptDoorOtherSide), TRUE)) {
if(!bDraw3d)
ptDoorSide.z=0;
ads_polar(ptDoorSide, m_nRotation + (m_nQuadrant==1? PI/2.0 : -PI/2.0), m_nDoorWidth, ptTemp);
XArc ar(ptDoorSide, m_nDoorWidth,
CT_std_angle(m_nRotation+ (m_nQuadrant==1? 0.0 : -PI/2)),
CT_std_angle(m_nRotation+ (m_nQuadrant==1? PI/2 : 0.0)));
if(bDraw3d)
{
dc.DrawArc(ar, m_nHeight);
dc.DrawLine(XLine(ptDoorSide, ptTemp), m_nHeight);
}
else
{
dc<<ar;
dc<<XLine(ptDoorSide, ptTemp);
}
}
}
}
//add by xlc on 120510 解决丁字行墙上的带形窗豁口问题
//判断两条曲线在pt点处方向是否相同
BOOL TDbOpening::IsSameDrtAtPt(const TGGeCurveSegment& cvThis, const TGGeCurveSegment& cvThat, const TADSGePoint3d& pt) const
{
double dDirThis = cvThis.Direction(pt);
double dDirThat = cvThat.Direction(pt);
return IsSameDrt(dDirThis, dDirThat, sin(PI / 36));
}
// 求带窗的5条关键线
BOOL TDbOpening::GetBanWinSegs(XCurveSegment &segLeftSide, XCurveSegment &segLeft,
XCurveSegment &segMid, XCurveSegment &segRight, XCurveSegment &segRightSide) const
{
XPoint ptStart, ptEnd;
GetSidePoints(ptStart, ptEnd);
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if(!pWall) {
return FALSE;
}
pWall->ProjectToMe(XPoint(ptStart), ptStart);
pWall->ProjectToMe(XPoint(ptEnd), ptEnd);
segMid = pWall->GetFinalOffsetCurveFromCenter(OFFSET_LEFT, 0.0);
segLeft = pWall->GetFinalOffsetCurveFromCenter(OFFSET_LEFT, 1.0/6.0);
segRight = pWall->GetFinalOffsetCurveFromCenter(OFFSET_RIGHT, 1.0/6.0);
//modify by xlc on 110311 墙材料不同时墙边线计算有误
//pWall->GetSideCurve(segLeftSide, segRightSide, 0.0, TRUE);
pWall->GetStandardCurve(segLeftSide, segRightSide, 0.0, TRUE);
XPoint ptLeftStart = segLeft.StartPoint(),
ptLeftEnd = segLeft.EndPoint(),
ptRightStart = segRight.StartPoint(),
ptRightEnd = segRight.EndPoint(),
ptMidStart=segMid.StartPoint(),
ptMidEnd=segMid.EndPoint(),
ptLeftSideStart = segLeftSide.StartPoint(),
ptLeftSideEnd = segLeftSide.EndPoint(),
ptRightSideStart = segRightSide.StartPoint(),
ptRightSideEnd = segRightSide.EndPoint();
BOOL bAcrossStart=FALSE, bAcrossEnd=FALSE;
if(ptStart.Distance2d(pWall->StartPoint())<_DIST_SNAP) {
if(!!pWall->m_idLeftStart) {
OPENOBJ_BEGIN(pWall->m_idLeftStart, AcDb::kForRead, TDbWall, pLeftStart);
if(pLeftStart && pLeftStart->HasCornerWinAcrossPoint(ptStart))
{
//add by xlc on 120510 解决丁字形墙上带形窗缺口问题
//转角处两个窗户平行时不作为转角窗处理
if (!IsSameDrtAtPt(*pWall, *pLeftStart, ptStart))
{
bAcrossStart=TRUE;
}
}
OPENOBJ_END();
}
if(!!pWall->m_idRightStart) {
OPENOBJ_BEGIN(pWall->m_idRightStart, AcDb::kForRead, TDbWall, pRightStart);
if(pRightStart && pRightStart->HasCornerWinAcrossPoint(ptStart))
{
//add by xlc on 120510 解决丁字形墙上带形窗缺口问题
//转角处两个窗户平行时不作为转角窗处理
if (!IsSameDrtAtPt(*pWall, *pRightStart, ptStart))
{
bAcrossStart=TRUE;
}
}
OPENOBJ_END();
}
}
if(ptEnd.Distance2d(pWall->EndPoint())<_DIST_SNAP) {
if(!!pWall->m_idLeftEnd) {
OPENOBJ_BEGIN(pWall->m_idLeftEnd, AcDb::kForRead, TDbWall, pLeftEnd);
if(pLeftEnd && pLeftEnd->HasCornerWinAcrossPoint(ptEnd))
{
//add by xlc on 120510 解决丁字形墙上带形窗缺口问题
//转角处两个窗户平行时不作为转角窗处理
if (!IsSameDrtAtPt(*pWall, *pLeftEnd, ptEnd))
{
bAcrossEnd=TRUE;
}
}
OPENOBJ_END();
}
if(!!pWall->m_idRightEnd) {
OPENOBJ_BEGIN(pWall->m_idRightEnd, AcDb::kForRead, TDbWall, pRightEnd);
if(pRightEnd && pRightEnd->HasCornerWinAcrossPoint(ptEnd))
{
//add by xlc on 120510 解决丁字形墙上带形窗缺口问题
//转角处两个窗户平行时不作为转角窗处理
if (!IsSameDrtAtPt(*pWall, *pRightEnd, ptEnd))
{
bAcrossEnd=TRUE;
}
}
OPENOBJ_END();
}
}
if(!bAcrossStart) {//不在起角点
segLeft.ProjectToMe(ptStart, ptLeftStart);
segRight.ProjectToMe(ptStart, ptRightStart);
segMid.ProjectToMe(ptStart, ptMidStart);
segLeftSide.ProjectToMe(ptStart, ptLeftSideStart);
segRightSide.ProjectToMe(ptStart, ptRightSideStart);
}
if(!bAcrossEnd) {//不在终角点
segLeft.ProjectToMe(ptEnd, ptLeftEnd);
segRight.ProjectToMe(ptEnd, ptRightEnd);
segMid.ProjectToMe(ptEnd, ptMidEnd);
segLeftSide.ProjectToMe(ptEnd, ptLeftSideEnd);
segRightSide.ProjectToMe(ptEnd, ptRightSideEnd);
}
segLeft.SetPoints(ptLeftStart, ptLeftEnd);
segRight.SetPoints(ptRightStart, ptRightEnd);
segMid.SetPoints(ptMidStart, ptMidEnd);
segLeftSide.SetPoints(ptLeftSideStart, ptLeftSideEnd);
segRightSide.SetPoints(ptRightSideStart, ptRightSideEnd);
OPENOBJ_END();
double nElev=0.0;
segLeft.SetElevation(nElev);
segRight.SetElevation(nElev);
segLeftSide.SetElevation(nElev);
segRightSide.SetElevation(nElev);
segMid.SetElevation(nElev);
return TRUE;
}
// 绘制带窗
BOOL TDbOpening::DrawBanWin(XExplodeDraw &dc, BOOL bDraw3d) const
{
XCurveSegment segLeftSide, segLeft, segMid, segRight, segRightSide;
if(!GetBanWinSegs(segLeftSide, segLeft, segMid, segRight, segRightSide))
return FALSE;
double nThick= bDraw3d? m_nHeight:0.0;
double nElev=bDraw3d? GetElevation() : 0.0;
segLeft.SetElevation(nElev);
segRight.SetElevation(nElev);
segLeftSide.SetElevation(nElev);
segRightSide.SetElevation(nElev);
segMid.SetElevation(nElev);
if(bDraw3d) {
TMasterProperties prop;
dc.BackUpProperties(prop);
dc.SetColorLayer(colorIndex(), m_idLayerGlass3d);
dc.DrawCurve(segMid, nThick);
dc.RestoreProperties(prop);
// 绘制窗框
dc.SetColorLayer(colorIndex(), m_idLayerFrame3d);
XPoly2D polyGlass;
segMid.AsPoly2D(polyGlass);
DrawFrame3d(dc, polyGlass);
dc.RestoreProperties(prop);
}
else
{
/*
if (GetPScale()>g_nCurtainWall3Scale+1.0E-3)
{
dc<<segMid;
}
else
{
dc<<segLeft;
dc<<segRight;
}
*/
// sg modify 090609,带形窗根据样式绘制
if (g_bCurtainWallFixStyle) // 固定样式
{
if (g_nCurtainWallStyle == 0) // 固定为三线
{
dc<<segMid;
}
else // 固定四线
{
dc<<segLeft;
dc<<segRight;
}
}
else // 随比例改变样式
{
if (GetPScale()>g_nCurtainWall3Scale+1.0E-3)
{
dc<<segMid;
}
else
{
dc<<segLeft;
dc<<segRight;
}
}
dc<<segLeftSide;
dc<<segRightSide;
}
return TRUE;
}
void TDbOpening::SetSideSlab(int type)
{
assertWriteEnabled();
if(type==0)
{
m_nOpStyleEx&=~OPSEX_RIGHT_SLAB;
m_nOpStyleEx&=~OPSEX_LEFT_SLAB;
}
else if(type==1)
{
m_nOpStyleEx|=OPSEX_RIGHT_SLAB;
m_nOpStyleEx|=OPSEX_LEFT_SLAB;
}
else if(type==2)
{
m_nOpStyleEx&=~OPSEX_RIGHT_SLAB;
m_nOpStyleEx|=OPSEX_LEFT_SLAB;
}
else
{
m_nOpStyleEx|=OPSEX_RIGHT_SLAB;
m_nOpStyleEx&=~OPSEX_LEFT_SLAB;
}
}
// 绘制凸窗二维
BOOL TDbOpening::DrawBayWindow2d(XExplodeDraw &dc) const
{
if (!m_pBayWin)
return FALSE;
if (m_opKind != OP_PROWIN)
return FALSE;
double nWallThick = 200;
// wlw add 100913
double dWallInsut = 0.0; // 墙线保温厚度
double dInsutAdd = 0.0; // 内保温加挡板时,由于挡板后退,补豁口
XPoint ptLoc = m_ptLocation;
TADSGePoint3d ptDir;
ptLoc.z = 0;
double nExtDir = m_nRotation + (m_nQuadrant<2 ? PI/2.0 : -PI/2.0);
// sg modify 120605,标记保温类型
int nInsulateType = 0;
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if (pWall)
{
nWallThick = pWall->GetWidth(4);
ads_polar(ptLoc, nExtDir, 10000, ptDir);
int nSide = pWall->OnWhichSide(ptDir);
// 得到外保温厚度
if (pWall->IsInsulateOnSide(nSide))
{
dWallInsut = pWall->GetInsulateThick(nSide);
if (DocGetProWinSlabInsu())
{
// 外墙和内墙同时使用这一个参数,所以内外只能有一种保温存在
dInsutAdd = GetSlotInsulateThick();
nInsulateType = 1;
}
}
// 如果有内保温需要补豁口
ads_polar(ptLoc, nExtDir, -10000, ptDir);
if (pWall->IsInsulateOnSide(pWall->OnWhichSide(ptDir)))
{
dInsutAdd = GetSlotInsulateThick();
nInsulateType = (nInsulateType==1) ? 2 : 1;
}
}
OPENOBJ_END();
// wlw add 100913
DList<XPoly2D> polyCurves;
// m_pBayWin->GetPolyCurve(ptLoc, nExtDir, m_nWidth, nWallThick, HasLeftSlab(), HasRightSlab(), polyCurves, dWallInsut, dInsutAdd);
m_pBayWin->GetPolyCurve(ptLoc, nExtDir, m_nWidth, nWallThick, HasLeftSlab(), HasRightSlab(), polyCurves, dWallInsut, dInsutAdd, nInsulateType==2);
for (int idx=0; idx<polyCurves.Length(); idx++)
dc << *polyCurves[idx];
if (GetSill()>_DIST_SNAP) // 有窗台
{
XPoint ptSide1, ptSide2;
GetSidePoints(ptSide1, ptSide2);
ads_polar(XPoint(ptSide1), nExtDir-PI, nWallThick/2.0, ptSide1);
ads_polar(XPoint(ptSide2), nExtDir-PI, nWallThick/2.0, ptSide2);
ptSide1.z = ptSide2.z = 0;
double dLine = 0.0;
m_XDataMap.GetAt(sKEY_OP_PROWIN_LINE, dLine);
if (dLine < 0.01)
{
dc << XLine(ptSide1, ptSide2);
}
}
return TRUE;
}
void TDbOpening::DrawDoorLine(XExplodeDraw &dc) const
{
// add by xlc on 110222 无门口线时不计算
if ((m_nOpStyleEx & OPS_DOORLINE_MID) //门口线居中
|| (m_nOpStyle&OPS_DOORLINE1) //门口线单侧
|| (m_nOpStyle&OPS_DOORLINE2)) //门口线单侧
{
}
else
{
return;
}
TADSGePoint3d ptSide1, ptSide2;
GetSidePoints(ptSide1, ptSide2);
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pDbWall);
if (pDbWall)
{
double dWallThick = pDbWall->GetWidth(4);
TGGeLine ln1,ln2;
TGGeLine lnMid(ptSide1, ptSide2);
TGGeCurveSegment cv1,cv2;
TGGeCurveSegment segMid = pDbWall->OffsetGeomCenter(LS_FINITE, TRUE);
// modify by xlc on 110214 增加门口线偏移距离和居中功能
//cv1 = segMid.Offset(dWallThick / 2.0, LS_FINITE);
//cv2 = segMid.Offset(-dWallThick / 2.0, LS_FINITE);
//ln1 = lnMid.Offset(dWallThick / 2.0);
//ln2 = lnMid.Offset(-dWallThick / 2.0);
if (m_nOpStyleEx & OPS_DOORLINE_MID) //门口线居中
{
segMid.SetPoints(ptSide1, ptSide2);
dc << segMid;
return;
}
double dOffsetDist = GetDoorLineOffsetDist();
cv1 = segMid.Offset(dWallThick / 2.0 - dOffsetDist, LS_FINITE);
cv2 = segMid.Offset(-dWallThick / 2.0 + dOffsetDist, LS_FINITE);
ln1 = lnMid.Offset(dWallThick / 2.0 - dOffsetDist);
ln2 = lnMid.Offset(-dWallThick / 2.0 + dOffsetDist);
cv1.SetPoints(ln1.StartPoint(), ln1.EndPoint());
cv2.SetPoints(ln2.StartPoint(), ln2.EndPoint());
AcGePoint3dArray gripPoints;
AcDbIntArray ar;
if (subGetGripPoints(gripPoints, ar, ar) == Acad::eOk && gripPoints.length() >= 4)
{
TADSGePoint3d ptGrip=gripPoints[3];
ptGrip.z=0;
segMid.SetElevation(0.0);
int nSideGrip = segMid.OnWhichSide(ptGrip);
TADSGePoint3d ptMid;
if (dWallThick / 2.0 - dOffsetDist > -_DIST_SNAP)
{
ptMid = cv1.MidPoint();
}
else
{
ptMid = cv2.MidPoint();
}
int nSide1 = segMid.OnWhichSide(ptMid);
if ((m_nOpStyle&OPS_DOORLINE1))
{
if(nSide1 != nSideGrip)
{
dc << cv2;
}
else
{
dc << cv1;
}
}
if (m_nOpStyle&OPS_DOORLINE2)
{
if(nSide1 != nSideGrip)
{
dc << cv1;
}
else
{
dc << cv2;
}
}
}
}
OPENOBJ_END();
}
bool TDbOpening::IsClipMe(const TEntityBase* pEnt)const
{
// 在此进行CAD平台判断
//TCHAR strVer[20];
//TGGetVar(_T("ACADVER"), strVer);
//CString str = strVer;
//str = str.Left(4);
//if (_T("19.1") == str) // 如果是 cad2014 则退出
// return false;//wlw cad2014崩溃
if(TDbEntity::IsClipMe(pEnt))
return true;
if(GetKind()==OP_PROWIN)
{
if(pEnt->GetMe()->isKindOf(TDbColumn::desc())||//柱裁剪
pEnt->GetMe()->isKindOf(TDbWallPatch::desc()))//墙体造型裁剪
return true;
TDbWall*pWall=TDbWall::cast(pEnt->GetMe());
if(pWall!=NULL)
{
if(pWall->GetUsageFlag()!=TDbWall::kVirtual&&//不是虚墙
GetWallId()!=pWall->objectId())//不在墙上
return true;
return false;
}
}
return false;
}
Acad::ErrorStatus TDbOpening::GetClipBoundary(XPoly2D& poly)const
{
if (GetKind()==OP_PROWIN && m_pBayWin!=NULL)
{
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if (pWall)
{
XPoint ptLoc = m_ptLocation;
ptLoc.z = m_ptLocation.z;
double nWallThick = pWall->GetWidth(4);
double nExtDir = m_nRotation + (m_nQuadrant<2? PI/2.0 : -PI/2.0);
// add by xlc on 110624 解决墙上有保温时梯形凸窗,三角凸窗,圆弧凸窗裁剪散水出错的问题
if (m_pBayWin)
{
if (m_pBayWin->m_nStyle == XBayWindow::BWS_TRIANGLE
|| m_pBayWin->m_nStyle == XBayWindow::BWS_TRAPEZIA
|| m_pBayWin->m_nStyle == XBayWindow::BWS_ARC)
{
TADSGePoint3d ptDir;
ads_polar(ptLoc, nExtDir, 10000, ptDir);
int nSide = pWall->OnWhichSide(ptDir);
// 得到保温厚度
if (pWall->IsInsulateOnSide(nSide))
{
double dWallInsut = pWall->GetInsulateThick(nSide);
nWallThick = (nWallThick*0.5-dWallInsut)*2;
}
}
}
extern Acad::ErrorStatus GetClipBoundary(const XBayWindow*pBayWin,XPoint ptLoc, double nExtDir, double nWidth,
double nWallThick,double nSlabThick,BOOL bLeftSlab,BOOL bRightSlab,XPoly2D &poly2d);
return GetClipBoundary(m_pBayWin, ptLoc, nExtDir, m_nWidth, nWallThick, m_nProWinSlabWidth, HasLeftSlab(), HasRightSlab(), poly);
}
OPENOBJ_END();
}
return Acad::eInvalidInput;
}
/////////////////////////////////////////////////////
// 炸碎或者显示二维
// ACAD2002才支持,显示图块之后还可以显示其他图元
// 高窗另存旧版有问题
Acad::ErrorStatus TDbOpening::ExplodeOrDraw2d(XExplodeDraw &dc) const
{
extern TARCH_IMPEXP BOOL g_bEnableCornWinWarning;
dc.SetStyle(m_idTextStyle);
BOOL bIsInsu = TRUE;
if (!objectId() && !!m_nIdOfWall && _tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0)
{
// 拖曳
XCurveSegment seg;
GetCenterCurve(seg);
// extern double g_nAcadVer;
if (g_nAcadVer<15.1 || !seg.Is(CURVE_LINE))
DragDraw((XAcGiViewDraw &)dc);
}
AcDbObjectId idLineDash;
TDbConfig *pConfig = NULL;
if (g_bSubEntity) // 组合门窗和带型窗
pConfig = GetDwgGlobal(AcDb::kForRead, g_pCurrentDb);
else
pConfig = GetDwgGlobal(AcDb::kForRead, database());
if (pConfig)
{
idLineDash = pConfig->GetLinetypeDash();
pConfig->close();
}
BOOL bDrawLabel = TRUE;
if (IsHighLevel())
{
}
else if (m_opKind == OP_HOLE) // 绘制洞口示意图
{
AcDbObjectId idOldLineType = dc.GetLineTypeId();
dc.SetLineType(idLineDash);
XPoly2D poly(1);
GetOutlinePoly(0.0, poly);
ASSERT(poly.TotalSegments()==4);
XCurveSegment seg1, seg2, seg3;
poly.Nth(0, seg1);
poly.Nth(2, seg2);
if (m_nOpStyle&OPS_NOT_BORE)
{
if (!IsHigh())
dc.SetLineType(idOldLineType);
else
dc << seg1 << seg2; //垂直于墙的方向的线
// modify by xlc on 110215 增加矩形洞样式
// poly.Nth(IsHigh()? 1 : 3, seg1);
// dc << seg1;
poly.Nth(IsHigh()? 1 : 3, seg3);
if (m_nOpStyle & OPS_POLY_HOLE) // 异型洞
{
dc << seg3;
}
else
{
if (!(m_nOpStyle & OPS_HOLE_FLAG1) && !(m_nOpStyle & OPS_HOLE_FLAG2)) // 空洞(上下贯通)
{
dc << seg1 << seg2; // 垂直于墙的方向的线
}
else if(!(m_nOpStyle & OPS_HOLE_FLAG1) && (m_nOpStyle & OPS_HOLE_FLAG2)) // 空门洞
{
dc.SetLineType(idLineDash);
dc << seg3;
}
else // 高洞,空窗洞
{
dc << seg3;
}
}
}
else if (!(m_nOpStyle&OPS_HOLE_FLAG1) && !(m_nOpStyle&OPS_HOLE_FLAG2)) // 空洞(上下贯通)
dc << seg1 << seg2; // 垂直于墙的方向的线
else if ((m_nOpStyle&OPS_HOLE_FLAG1) && !(m_nOpStyle&OPS_HOLE_FLAG2)) // 空窗洞
{
dc.SetLineType(idOldLineType);
poly.Nth(1, seg1);
poly.Nth(3, seg2);
dc << seg1 << seg2;
}
else if (!(m_nOpStyle&OPS_HOLE_FLAG1) && (m_nOpStyle&OPS_HOLE_FLAG2)) // 空门洞
{
// dc << seg1 << seg2; //垂直于墙的方向的线
poly.Nth(1, seg1);
poly.Nth(3, seg2);
dc << seg1 << seg2;
}
else // 高洞
dc << seg1 << seg2; // 垂直于墙的方向的线
dc.SetLineType(idOldLineType);
}
else if (m_opKind == OP_DOORWIN)
ExplodeOrDrawDoorWin(dc, FALSE);
else if (m_opKind == OP_TWODOOR)
ExplodeOrDrawTwoDoor(dc, FALSE);
else if (m_opKind == OP_ARCWIN)
{
// 弧墙上的弧窗
// XDbObject objWall(m_nIdOfWall, AcDb::kForWrite); //modify by xlc on 100528读方式打开,修改时再一些方式打开
XDbObject objWall(m_nIdOfWall, AcDb::kForRead);
if (!!objWall)
{
TDbWall *pDbWall=TDbWall::cast(objWall.m_pObject);
ASSERT(pDbWall && pDbWall->Is(CURVE_ARC));
if (pDbWall)
{ // 弧窗的宽度, 指在墙基线上的宽度
XArc ar=pDbWall->GetArc();
//修改原因 : 增加记录 boundary,hatch 命令涉及到的 动态变换矩阵 m_mat3d
// 当AcDbBlockRef 中引用到门窗时,对于boundary,hatch 这样的边界分析命令,
// 先调用 transformby,然后调用 ExplodeOrDraw2d时,对关联的墙分析有误,此时
// 墙还没有transformby,导致门窗和墙关系不同步错误,boundary,hatch 分析乱线
// 该矩阵不序列化
//修改人 : lfy 2009-11-08
BOOL bHatch=FALSE;
struct resbuf rb;
acedGetVar(_T("CMDNAMES"),&rb);
CString sCmd = rb.resval.rstring;
acutDelString(rb.resval.rstring);
if (sCmd.CompareNoCase(_T("BHATCH") ) == 0 ||
sCmd.CompareNoCase(_T("_BHATCH") ) == 0 ||
sCmd.CompareNoCase(_T("BOUNDARY")) == 0||
sCmd.CompareNoCase(_T("_BOUNDARY")) == 0)
{
bHatch=TRUE;
}
//add by xlc on 110304 解决弧墙上的门窗移动复制时飞线问题
else if (sCmd.CompareNoCase(_T("MOVE")) == 0||
sCmd.CompareNoCase(_T("COPY")) == 0||
sCmd.CompareNoCase(_T("_MOVE")) == 0||
sCmd.CompareNoCase(_T("_COPY")) == 0)
{
if(!objectId() && !!m_nIdOfWall && _tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0)
{
bHatch = TRUE;
}
}
if(bHatch)
{
TADSGePoint3d ptCen = ar.GetCenterPt();
ptCen.TransformBy(m_mat3d);
ar.SetCenterPt(ptCen);
}
double nWallThick=pDbWall->GetWidth(4);
XPoint ptLoc=m_ptLocation;
ptLoc.z=ar.GetCenterPt().z;
XPoint ptOnWall=ptLoc;
//修改原因 : 增加记录 boundary,hatch 命令涉及到的 动态变换矩阵 m_mat3d
// 当AcDbBlockRef 中引用到门窗时,对于boundary,hatch 这样的边界分析命令,
// 先调用 transformby,然后调用 ExplodeOrDraw2d时,对关联的墙分析有误,此时
// 墙还没有transformby,导致门窗和墙关系不同步错误,boundary,hatch 分析乱线
// 该矩阵不序列化
//修改人 : lfy 2009-11-08
if(bHatch)
{
Acad::ErrorStatus es = pDbWall->upgradeOpen(); //add by xlc on 100528升级打开方式
if (es == Acad::eOk || es == Acad::eWasOpenForWrite)
{
pDbWall->transformBy(m_mat3d);
}
else
{
bHatch = FALSE; //add by xlc on 100625不是写方式打开时不进行变换
}
}
pDbWall->ProjectToMe(ptLoc, ptOnWall);
if(bHatch)
{
AcGeMatrix3d matInv = m_mat3d;
matInv.invert();
pDbWall->assertWriteEnabled();
pDbWall->transformBy(matInv);
pDbWall->downgradeOpen();
}
double nRad=ads_distance(ar.GetCenterPt(), ptOnWall);
double nSweepAng=m_nWidth/nRad;
double nStartAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)-nSweepAng/2.0),
nEndAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)+nSweepAng/2.0);
XArc arMid(ar.GetCenterPt(), ads_distance(ar.GetCenterPt(), ptLoc), nStartAng, nEndAng);
TADSGePoint3d ptTmp = arMid.GetCenterPt();
ptTmp.z = 0.0;
arMid.SetCenterPt(ptTmp);
AcDbObjectId idOldLineType=dc.GetLineTypeId();
if(IsHigh() )
dc.SetLineType(idLineDash);
/*
if (GetPScale()>g_nCurtainWall3Scale+1.0E-3)
dc << arMid;
else
dc << arMid.Offset(nWallThick/6.0) << arMid.Offset(-nWallThick/6.0);
*/
// sg modify 090609,带形窗根据样式绘制
if (g_bCurtainWallFixStyle) // 固定样式
{
if (g_nCurtainWallStyle == 0) // 固定为三线
dc<<arMid;
else // 固定四线
dc << arMid.Offset(nWallThick/6.0) << arMid.Offset(-nWallThick/6.0);
}
else // 随比例改变样式
{
if (GetPScale()>g_nCurtainWall3Scale+1.0E-3)
dc<<arMid;
else
dc << arMid.Offset(nWallThick/6.0) << arMid.Offset(-nWallThick/6.0);
}
// 假如有门窗套, 则不能绘制外侧边线
if(HasSlot())
{
if((pDbWall->GetWallFlag()&WF_LEFTEXT)==0)
dc << arMid.Offset(-nWallThick/2.0);
else
dc << arMid.Offset(nWallThick/2.0);
}
else if(!IsHigh())
dc << arMid.Offset(nWallThick/2.0)<< arMid.Offset(-nWallThick/2.0);
else
{
XArc ar1=arMid.Offset(nWallThick/2.0);
XArc ar2=arMid.Offset(-nWallThick/2.0);
XPoint ptVert[4];
ar1.GetStartPoint(ptVert[0]);
ar1.GetEndPoint(ptVert[1]);
ar2.GetStartPoint(ptVert[2]);
ar2.GetEndPoint(ptVert[3]);
dc << XLine(ptVert[0], ptVert[2])
<< XLine(ptVert[1], ptVert[3]);
}
dc.SetLineType(idOldLineType);
}
}
else // 画个示意图
{
XPoly2D polyShow(1);
GetOutlinePoly(0.0, polyShow);
dc << polyShow;
}
}
else if (m_opKind == OP_CORNWIN) // 转角窗
{
if (!m_nIdOfWall)
{
if(g_bEnableCornWinWarning)
dc.DrawText(_T("请纠正无墙带形窗!"));
}
else
DrawBanWin(dc, FALSE);
}
else if (m_opKind==OP_PROWIN) // 凸窗
DrawBayWindow2d(dc);
else if (!!m_nIdStyle2d && (m_opKind==OP_DOOR || m_opKind==OP_WINDOW)) // 普通门窗
{
// 用图块表示的门窗
AcDbObjectId idOldLineType = dc.GetLineTypeId();
if(IsHigh() )
dc.SetLineType(idLineDash);
if (IsHigh())
{
XPoint ptBack, ptFront;
GetSidePoints(ptBack, ptFront);
double nWidth = GetWallThickness(TRUE);
XCurveSegment segCen(ptBack, ptFront, 0.0);
double nDirection = ads_angle(ptBack, ptFront);
XPoint ptSide[4];
ads_polar(ptFront, nDirection+PI/2, nWidth/2, ptSide[0]);
ads_polar(ptFront, nDirection-PI/2, nWidth/2, ptSide[1]);
ads_polar(ptBack, nDirection+PI/2, nWidth/2, ptSide[2]);
ads_polar(ptBack, nDirection-PI/2, nWidth/2, ptSide[3]);
dc << segCen.Offset(OFFSET_LEFT, nWidth/6.0, LS_FINITE)
<< segCen.Offset(OFFSET_RIGHT, nWidth/6.0, LS_FINITE)
<< XCurveSegment(ptSide[0], ptSide[1], 0.0)
<< XCurveSegment(ptSide[2], ptSide[3], 0.0);
}
else
{
BOOL bArcWall=FALSE;
XDbObject objWall(m_nIdOfWall, AcDb::kForRead);
BOOL bToTch3=(_tcscmp(dc.Desc(), XExplodeStream::Descriptor())==0
&&m_lstClipId.Length()==0//add by whl on 070517,有切割时按绘制走
&& dc.IsExportTch4() && m_nIdStyle2d.isValid());
// add by whl on 070515,导出上华3时就不要了,否则会多出很多线
if (m_opKind==OP_WINDOW && !!objWall&& !bToTch3)
{
TDbWall *pDbWall=TDbWall::cast(objWall.m_pObject);
if(pDbWall && pDbWall->Is(CURVE_ARC)) // 弧墙上的弦窗
{
if (!HasSlot()) // 假如有门窗套, 则不能绘制
{
double nWallThick=pDbWall->GetWidth(4);
XPoint ptSide1, ptSide2;
GetSidePoints(ptSide1, ptSide2);
ptSide1.z=ptSide2.z=0;
XCurveSegment segMid=pDbWall->OffsetGeomCenter(LS_FINITE, TRUE);
XLine lnMid(ptSide1, ptSide2);
/*
if(GetPScale()>g_nCurtainWall3Scale+1.0E-3)
dc << lnMid;
else
dc << lnMid.Offset(nWallThick/6.0) << lnMid.Offset(-nWallThick/6.0);
*/
// sg modify 090609,带形窗根据样式绘制
if (g_bCurtainWallFixStyle) // 固定样式
{
if (g_nCurtainWallStyle == 0) // 固定为三线
dc << lnMid;
else // 固定四线
dc << lnMid.Offset(nWallThick/6.0) << lnMid.Offset(-nWallThick/6.0);
}
else // 随比例改变样式
{
if (GetPScale()>g_nCurtainWall3Scale+1.0E-3)
dc << lnMid;
else
dc << lnMid.Offset(nWallThick/6.0) << lnMid.Offset(-nWallThick/6.0);
}
XCurveSegment cv1=segMid.Offset(nWallThick/2.0, LS_FINITE),
cv2=segMid.Offset(-nWallThick/2.0, LS_FINITE);
XLine ln1=lnMid.Offset(nWallThick/2.0),
ln2=lnMid.Offset(-nWallThick/2.0);
cv1.SetPoints(ln1.StartPoint(), ln1.EndPoint());
cv2.SetPoints(ln2.StartPoint(), ln2.EndPoint());
dc << cv1 << cv2;
}
bArcWall=TRUE;
}
}
if (bToTch3)
{
// 取墙的宽度作为门窗厚度
double nScaleX, nScaleY;
GetInsert2DScale(&nScaleX, &nScaleY);
XPoint ptInsert=m_ptLocation;
ptInsert.z = 0.0;
AcDbBlockReference *pInsert=new AcDbBlockReference(ptInsert, m_nIdStyle2d);
if(g_bSubEntity)//组合门窗或带型窗
{
TMasterProperties prop;
dc.BackUpProperties(prop);
prop.SetTo(pInsert);
}
else
pInsert->setPropertiesFrom(this);
pInsert->setRotation(m_nRotation);
AcDbVoidPtrArray entArray;
XExplodeStream dcExp(entArray);
dcExp.SetAutoProp(FALSE);
BOOL bEmptyLab=FALSE;
const TCHAR *szLab=(const TCHAR *)m_sLabel;
if(!szLab[0])
{
szLab=_T("MC");
bEmptyLab=TRUE;
}
DrawLabel(dcExp, szLab);
int num=entArray.length();
if(num==1)
{
AcDbText *pText=AcDbText::cast((AcDbEntity *)entArray[0]);
ASSERT(pText);
AcDbAttribute *attr = new AcDbAttribute;
attr->setPropertiesFrom(this);
attr->setLayer(m_idLayerText);
attr->setHeight(pText->height());
TCHAR *szText=pText->textString();
attr->setTextString(bEmptyLab? _T("") : szText);
if(szText) delete[] szText;
attr->setRotation(pText->rotation());
attr->setHorizontalMode(pText->horizontalMode());
attr->setVerticalMode(pText->verticalMode());
attr->setAlignmentPoint(pText->alignmentPoint());
attr->setTextStyle(pText->textStyle());
attr->setWidthFactor(pText->widthFactor());
attr->setPosition(pText->position());
attr->setTag(_T("A"));
VERIFY(pInsert->appendAttribute(attr)==Acad::eOk);
bDrawLabel=FALSE;
}
ReleaseEntSet(entArray);
// 没有注册的APPID导致崩溃
AcDbDatabase *pDb=database();
AcDbRegAppTable *pAppTab=NULL;
if(pDb)
pDb->getSymbolTable(pAppTab, AcDb::kForRead);
BOOL bReg=FALSE;
if(pAppTab)
{
bReg=pAppTab->has(_T("WTHICK"));
pAppTab->close();
}
double nWallWidth=GetWallThickness(TRUE); //Add TRUE argument on 2003/11/10
if(pDb==acdbCurDwg() && bReg)
{
pInsert->setScaleFactors(AcGeScale3d(nScaleX, nScaleY, nScaleX));
resbuf *xdata=ads_buildlist(1001, _T("WTHICK"), 1040, nWallWidth, NULL);
if(pInsert->setXData(xdata)!=Acad::eOk)
{ //只能对当前图设置
//ASSERT(0);
}
ads_relrb(xdata);
}
else
pInsert->setScaleFactors(AcGeScale3d(nScaleX, nScaleY, nWallWidth)); // Z比例=墙厚
((XExplodeStream &)dc).Append(pInsert, FALSE);
}
else
{
/////////////////////////////////////////////////////
// 显示图块
if(!bArcWall)
{
// 取墙的宽度作为门窗厚度
double nScaleX, nScaleY;
GetInsert2DScale(&nScaleX, &nScaleY);
//构造插入矩阵
XPoint ptInsert=m_ptLocation;
ptInsert.z = 0.0; //GetWallElevation(); //二维的位置同墙基的标高
BOOL bMakeBlock=g_bMakeBlock;
if(_tcsicmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0)
{
if (dc.IsPlotGeneration()) // sg add 120507,强制打印时,不使用新方法
bMakeBlock = FALSE;
else
bMakeBlock=(g_nAcadVer>15.0001);
}
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if(pWall)
{
//wlw add 110220 门窗套类型是保温材料时,不画外面的线
BOOL bRightExt = (pWall->GetWallFlag() & WF_LEFTEXT) == 0;
if (bRightExt)
{
if (!pWall->IsInsulateOnSide(OFFSET_RIGHT))
{
if (m_nMaterial == 3)
{//门窗套类型是保温材料时,不画外面的线
bIsInsu = FALSE;
}
}
else
{
if (pWall->GetInsulateThick(OFFSET_RIGHT) < 0.01)
{
if (m_nMaterial == 3)
{
bIsInsu = FALSE;
}
}
}
}
else
{
if (!pWall->IsInsulateOnSide(OFFSET_LEFT))
{
if (m_nMaterial == 3)
{//门窗套类型是保温材料时,不画外面的线
bIsInsu = FALSE;
}
}
else
{
if (pWall->GetInsulateThick(OFFSET_LEFT) < 0.01)
{
if (m_nMaterial == 3)
{
bIsInsu = FALSE;
}
}
}
}
}
OPENOBJ_END();
if (!DocGetProWinSlabInsu())
{//wlw add 110114 凸窗挡板保温套加保温为FALSE时保温材料的按照普通模式绘制
if (m_nMaterial == 3)
{
bIsInsu = FALSE;
}
}
if(HasSlot() && m_opKind==OP_WINDOW && !!m_nIdOfWall && bIsInsu)
{//有门窗套时要将外边线去除,然后分解绘制
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if(pWall)
{
//计算门窗套一侧的外边线
XPoint ptStart, ptEnd, ptExtStart,ptExtEnd;
GetSidePoints(ptStart, ptEnd);
double nExtDirStart=pWall->OrthoDirection(ptStart);
double nExtDirEnd=pWall->OrthoDirection(ptEnd);
XCurveSegment seg;
if((pWall->GetWallFlag()&WF_LEFTEXT)==0)
{
seg=pWall->GetRelativeSideCurve(OFFSET_RIGHT, pWall->StartPoint(), GetSlotExt());
ads_polar(ptStart, nExtDirStart, pWall->GetWidth(4)/2.0, ptExtStart);
ads_polar(ptEnd, nExtDirEnd, pWall->GetWidth(4)/2.0, ptExtEnd);
}
else
{
seg=pWall->GetRelativeSideCurve(OFFSET_LEFT, pWall->StartPoint(), GetSlotExt());
ads_polar(ptStart, nExtDirStart+PI, pWall->GetWidth(4)/2.0, ptExtStart);
ads_polar(ptEnd, nExtDirEnd+PI, pWall->GetWidth(4)/2.0, ptExtEnd);
}
seg.SetPoints(ptExtStart, ptExtEnd);
seg.SetElevation(0.0);
//分解图块后绘制
ads_matrix mat;
ConstructMatrix(XPoint(),ptInsert,nScaleX,nScaleY,nScaleX,m_nRotation,mat);
AcDbVoidPtrArray entSet;
XExplodeStream dc1(entSet);
dc1<<XBlockRef(m_nIdStyle2d, ptInsert, AcGeScale3d(nScaleX, nScaleY, nScaleX), m_nRotation, FALSE);//分解 
for(long i=0;i<entSet.length();i++)
{
AcDbEntity *pEnt=(AcDbEntity*)entSet[i];
if(pEnt->isKindOf(AcDbLine::desc()))
{
AcDbLine *pLine=AcDbLine::cast(pEnt);
AcGePoint3d pt1=pLine->startPoint(),pt2=pLine->endPoint();
pt1.z=0;
pt2.z=0;
if((seg.StartPoint()==pt1&&seg.EndPoint()==pt2)||
(seg.StartPoint()==pt2&&seg.EndPoint()==pt1))//端点相同视为外边线,不绘制
continue;
}
else if(pEnt->isKindOf(AcDbArc::desc()))
{
AcDbArc *pArc=AcDbArc::cast(pEnt);
AcGePoint3d pt1,pt2;
pArc->getStartPoint(pt1);
pArc->getEndPoint(pt2);
pt1.z=0;
pt2.z=0;
if((seg.StartPoint()==pt1&&seg.EndPoint()==pt2)||
(seg.StartPoint()==pt2&&seg.EndPoint()==pt1))//端点相同视为外边线,不绘制
continue;
}
pEnt->setLayer(layer());
pEnt->setColorIndex(colorIndex());
dc.DrawEntity(*pEnt);
}
ReleaseEntSet(entSet);
}
OPENOBJ_END()
}
else
dc<<XBlockRef(m_nIdStyle2d, ptInsert, AcGeScale3d(nScaleX, nScaleY, nScaleX), m_nRotation, bMakeBlock);
}
}
}
dc.SetLineType(idOldLineType);
}
if(GetKind()==TOpeningData::OP_DOOR ||
GetKind()==TOpeningData::OP_TWODOOR ||
GetKind()==TOpeningData::OP_DOORWIN||
GetKind()==TOpeningData::OP_GROUP||
GetKind()==TOpeningData::OP_HOLE)//add by whl on 051227
DrawDoorLine(dc);
if(!IsHigh() && HasSlot() && !!m_nIdOfWall && bIsInsu)
{ //门窗套的底线,用门窗的颜色和墙的图层
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if(pWall)
{
XPoint ptStart, ptEnd, ptExtStart,ptExtEnd;
GetSidePoints(ptStart, ptEnd);
double nExtDirStart=pWall->OrthoDirection(ptStart);
double nExtDirEnd=pWall->OrthoDirection(ptEnd);
double dWallInsut = 0.0;
XCurveSegment seg;
if((pWall->GetWallFlag()&WF_LEFTEXT)==0)
{
seg=pWall->GetRelativeSideCurve(OFFSET_RIGHT, pWall->StartPoint(), GetSlotExt());
if (pWall->IsInsulateOnSide(OFFSET_RIGHT))
{
dWallInsut = pWall->GetInsulateThick(OFFSET_RIGHT);
if (DocGetProWinSlabInsu())
{
dWallInsut -= GetSlotInsulateThick();
}
}
ads_polar(ptStart, nExtDirStart, GetSlotExt() - dWallInsut +pWall->GetWidth(4)/2.0, ptExtStart);
ads_polar(ptEnd, nExtDirEnd, GetSlotExt() - dWallInsut + pWall->GetWidth(4)/2.0, ptExtEnd);
}
else
{
if (pWall->IsInsulateOnSide(OFFSET_LEFT))
{
dWallInsut = pWall->GetInsulateThick(OFFSET_LEFT);
if (DocGetProWinSlabInsu())
{
dWallInsut -= GetSlotInsulateThick();
}
}
seg=pWall->GetRelativeSideCurve(OFFSET_LEFT, pWall->StartPoint(), GetSlotExt());
ads_polar(ptStart, nExtDirStart+PI, GetSlotExt() - dWallInsut + pWall->GetWidth(4)/2.0, ptExtStart);
ads_polar(ptEnd, nExtDirEnd+PI, GetSlotExt() - dWallInsut + pWall->GetWidth(4)/2.0, ptExtEnd);
}
seg.SetPoints(ptExtStart, ptExtEnd);
seg.SetElevation(0.0);
dc << seg;
// if(m_opKind==OP_WINDOW)
//{ //绘制玻璃线和里边的墙线
// seg=pWall->GetRelativeOffsetCurveFromCenter(OFFSET_RIGHT, 1.0/6.0, pWall->StartPoint());
// seg.SetElevation(0.0);
// XPoint pt1, pt2;
// seg.ProjectToMe(ptStart, pt1);
// seg.ProjectToMe(ptEnd, pt2);
// dc << XLine(pt1, pt2);
// seg=pWall->GetRelativeOffsetCurveFromCenter(OFFSET_LEFT, 1.0/6.0, pWall->StartPoint());
// seg.SetElevation(0.0);
// seg.ProjectToMe(ptStart, pt1);
// seg.ProjectToMe(ptEnd, pt2);
// dc << XLine(pt1, pt2);
// int nInternalSide = (pWall->GetWallFlag()&WF_LEFTEXT)==0? OFFSET_LEFT : OFFSET_RIGHT;
// seg=pWall->GetRelativeSideCurve(nInternalSide, pWall->StartPoint(), 0.0, TRUE);
// seg.SetElevation(0.0);
// seg.ProjectToMe(ptStart, pt1);
// seg.ProjectToMe(ptEnd, pt2);
// seg.SetPoints(pt1, pt2);
// dc << seg;
// }
}
OPENOBJ_END();
}
Acad::ErrorStatus es = Acad::eOk;
if (g_bExplodeSubText || (!!m_sLabel&& bDrawLabel)) // bug: 如果设置了图层,则插门的时候出错AcGi-SelectionMarker
DrawLabel(dc, m_sLabel);
return es;
}
// Helper functions
TSubText* TDbOpening::HitTestText(XPoint pt)const
{
TSubText* pSubText=TDbEntity::HitTestText(pt);
if(pSubText!=NULL)
pSubText->SetMenuType(4);
return pSubText;
}
TSubText* TDbOpening::GetSubText(long iText)const
{
TSubText* pSubText=TDbEntity::GetSubText(iText);
if(pSubText!=NULL)
pSubText->SetMenuType(4);
return pSubText;
}
void TDbOpening::DrawLabel(XExplodeDraw &dc, const TCHAR *szLab) const
{
if (!g_bExplodeSubText && (!szLab || !szLab[0] || !IsShowLabel()))
return;
AcDbObjectId id = m_idTextStyle;
if (!id.isValid())
{
id = GetTextStyleId(_T("STANDARD"), database());
}
ASSERT(id.isValid());
TDbText textLabel;
textLabel.setPropertiesFrom(this);
if (m_idLayerText.isValid())
textLabel.setLayer(m_idLayerText); //可否设置图层
TPushProperty vProp(&textLabel, dc); //由临时对象设置DC的熟悉
textLabel.SetStyleId(id);
textLabel.SetLocation(XPoint(m_ptLabel.x, m_ptLabel.y));
textLabel.SetAlignment(XExplodeDraw::kMiddleCenter);
double nRotLabel = Wcs2Layout(m_nRotation);
// sg add 110119,标记是否是弧窗
bool bArcWin = 0;
if (GetKind()==OP_CORNWIN || GetKind()==OP_ARCWIN)
{
if (!!m_nIdOfWall)
{
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if (pWall && pWall->Is(CURVE_ARC))
{
XArc ar = pWall->GetArc();
//修改原因 : 增加记录 boundary,hatch 命令涉及到的 动态变换矩阵 m_mat3d
// 当AcDbBlockRef 中引用到门窗时,对于boundary,hatch 这样的边界分析命令,
// 先调用 transformby,然后调用 ExplodeOrDraw2d时,对关联的墙分析有误,此时
// 墙还没有transformby,导致门窗和墙关系不同步错误,boundary,hatch 分析乱线
// 该矩阵不序列化
//修改人 : lfy 2009-11-08
struct resbuf rb;
acedGetVar(_T("CMDNAMES"),&rb);
CString sCmd = rb.resval.rstring;
acutDelString(rb.resval.rstring);
if (sCmd.CompareNoCase(_T("BHATCH") ) == 0 ||
sCmd.CompareNoCase(_T("_BHATCH") ) == 0 ||
sCmd.CompareNoCase(_T("BOUNDARY")) == 0||
sCmd.CompareNoCase(_T("_BOUNDARY")) == 0||
//add by xlc on 110304 解决弧墙上的门窗移动复制时飞线问题
sCmd.CompareNoCase(_T("MOVE")) == 0||
sCmd.CompareNoCase(_T("_MOVE")) == 0||
(!objectId()&&(sCmd.CompareNoCase(_T("COPY")) == 0||
sCmd.CompareNoCase(_T("_COPY")) == 0))
)
{
TADSGePoint3d ptTmp = ar.GetCenterPt();
ptTmp.TransformBy(m_mat3d);;
ar.SetCenterPt(ptTmp);
}
nRotLabel = CT_std_angle(ads_angle(ar.GetCenterPt(), m_ptLabel) - PI/2);
bArcWin = true; // 弧窗
}
OPENOBJ_END();
}
}
// sg modify 110307,解决经过布局旋转后,弧窗标注或者弧墙上的转角窗角度发生变化的情况
if (bArcWin) // 如果是窗标注或者弧墙上的转角窗,需要将根据墙线计算出来的角度,转换为布局转角下的角度
{
nRotLabel = Wcs2Layout(m_nRotation);
}
textLabel.SetRotation(xg_angle(nRotLabel));
textLabel.SetHeight(m_nTextHeight);
TCHAR szLabel[256]=_T("");
_tcscpy(szLabel, szLab);
TDbConfig *pConfig = GetDwgGlobal(AcDb::kForRead, database());
if (pConfig && pConfig->IsCapLabel())
_tcsupr(szLabel);
if (pConfig)
pConfig->close();
textLabel.SetText(szLabel);
if (dc.IsFullExplode())
{
textLabel.ExplodeOrDraw2d(dc);
}
else
dc.DrawEntity(textLabel);
}
bool TDbOpening::GetNeighbourPoint(XPoint &pt,bool bPre)const
{
TDbWall *pWall=NULL;
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall0);
if (pWall0 != NULL)
{
pWall=TDbWall::cast(pWall0->clone());
}
OPENOBJ_END();
if(pWall==NULL)
return false;
pWall->RemoveReferenceOpening(objectId());
pt=bPre?pWall->StartPoint():pWall->EndPoint();
XCurveSegment seg;
if(pWall->GetSubSegmentAt(m_ptLocation, seg, FALSE))
pt=bPre?seg.StartPoint():seg.EndPoint();
delete pWall;
return true;
}
// 绘制拖动时2D的显示
void TDbOpening::DragDraw(XAcGiViewDraw &dc) const
{
if(g_bSubEntity)
return;
extern GEOAPI BOOL GetWcsCursor(XPoint &ptLoc);
XPoint ptCursor;
TchExport::GetWcsCursor(ptCursor);
if(m_idTextStyle.isValid())
dc.SetStyle(m_idTextStyle);
else
dc.SetStyle(InitTextStyle(TS_WINDOW));
TDbWall *pWall=NULL;
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall0);
pWall=TDbWall::cast(pWall0->clone());
OPENOBJ_END();
ASSERT(pWall);
XCurveSegment seg;
double nTextHeight=PixelToWcs(10);
TArchPerDocData*pDocData=GetCurDocData();
if(pDocData!=NULL&&pDocData->m_sCurCommand==_T("GRIP_STRETCH")) {
//原始门窗,需要拿掉
AcDbObjectId idThis=GetPrepickEntity(RBList(RTDXF0, _T("ATS_OPENING"), NULL));
if(!!idThis)
pWall->RemoveReferenceOpening(idThis);
}
for(int nSide=0; nSide<2; nSide++) { //0--墙基上的参数,1--墙边上的参数
Adesk::UInt16 nOldColor=dc.GetColor();
dc.SetColor(nSide==0? 1 : 7);
BOOL bRet;
if(nSide) {
bRet=pWall->GetSubSegmentOnSideAt(ptCursor, seg);
if(bRet) {
XCurveSegment segThis=*pWall;
XPoint ptA, ptB;
pWall->ProjectToMe(seg.StartPoint(), ptA);
pWall->ProjectToMe(seg.EndPoint(), ptB);
segThis.SetPoints(ptA, ptB);
seg=segThis;
}
} else
bRet=pWall->GetSubSegmentAt(m_ptLocation, seg, FALSE);
if(bRet) {
XSortedVertexList lstPoints(seg.StartPoint(), seg.EndPoint(), seg.GetBulge());
XPoint pt1, pt2;
GetSidePointsOnBase(pt1, pt2);
pt1.z=pt2.z=seg.StartPoint().z;
int nTextOnSide=0;
lstPoints.Insert(pt1);
lstPoints.Insert(pt2);
if(lstPoints.Length()==4) {
XPoly2D poly(0);
lstPoints.AsPoly2D(poly);
for(int i=0; i<poly.TotalSegments(); i++) {
XCurveSegment subSeg;
poly.Nth(i, subSeg);
XPoint ptMid=subSeg.MidPoint();
double nDrt=subSeg.Direction(ptMid);
{
int nSide0=subSeg.OnWhichSide(ptCursor);
if(nSide0==OFFSET_RIGHT)
nDrt=CT_std_angle(nDrt+PI);
}
XPoint ptText;
ads_polar(ptMid, nDrt-PI/2.0+nSide*PI, 2*nTextHeight, ptText);
if(nSide==1)
nTextOnSide=pWall->OnWhichSide(ptText);
dc.SetLocation(ptText);
dc.SetAlignment(XExplodeDraw::kMiddleCenter);
dc.SetHeight(nTextHeight);
dc.SetRotation(xg_angle(nDrt));
double nDispVal=subSeg.GetLength();
XString sDispVal;
if(/*g_bDimAngle && */subSeg.Is(CURVE_ARC)) {
sDispVal << AS_INT(subSeg.GetBulge()*180.0/PI) << _T("%%d");
} else {
sDispVal << AS_INT(nDispVal);
}
dc.DrawText(sDispVal);
}
XCurveSegment lCurve, rCurve;
if(nSide==1)
pWall->GetSideCurve(lCurve, rCurve);
for(i=0; i<poly.Length(); i++) {
XPoint &ptMark=*poly[i];
if(nSide==1) {
if(nTextOnSide==OFFSET_LEFT)
lCurve.ProjectToMe(XPoint(ptMark), ptMark);
else
rCurve.ProjectToMe(XPoint(ptMark), ptMark);
}
XRectAngle box(ptMark, nTextHeight/2, nTextHeight/2);
dc << XLine(box.GetLowLeft(), box.GetUpRight())
<< XLine(box.GetLowRight(), box.GetUpLeft());
}
}
}
dc.SetColor(nOldColor);
}
delete pWall;
}
// 绘制三维窗框
BOOL TDbOpening::DrawFrame3d(XExplodeDraw &dc, const XPoly2D &polyGlass) const
{
TMasterProperties prop;
dc.BackUpProperties(prop);
dc.SetColorLayer(colorIndex(), m_idLayerFrame3d);
double nElev=GetElevation();
// 底框
XRectAngle box(XPoint(), m_vFrame, m_uFrame);
XPoly2D polyShape(1);
box.AsPoly2D(polyShape);
TDbCurveMesh mesh;
mesh.setPropertiesFrom(this);
if(m_idLayerFrame3d.isValid())
mesh.setLayer(m_idLayerFrame3d);
TPushProperty vProp(&mesh, dc);
XPoly2D polyBot(polyGlass);
polyBot.SetElevation(nElev);
mesh.SetPathPoly(polyBot,mesh.GetNormal().AsAcGeVector3d());
mesh.SetShapePoly(polyShape);
mesh.SetShapeBase(XPoint(0, -m_uFrame/2));
if(dc.IsFullExplode())
mesh.ExplodeOrDraw3d(dc);
else
dc.DrawEntity(mesh);
// 顶框
XPoly2D polyTop(polyBot);
polyTop.SetElevation(nElev+GetHeight());
mesh.SetPathPoly(polyTop,mesh.GetNormal().AsAcGeVector3d());
mesh.SetShapeBase(XPoint(0, m_uFrame/2));
if(dc.IsFullExplode())
mesh.ExplodeOrDraw3d(dc);
else
dc.DrawEntity(mesh);
// 竖框
for(int i=0; i<polyGlass.Length(); i++) {
XDirectionCurve segPrev, segNext;
double nDirPrev=0, nDirNext=0;
BOOL bPrev=FALSE, bNext=FALSE;
if(i>0) {
bPrev=TRUE;
polyGlass.Nth(i-1, segPrev);
nDirPrev=segPrev.IDirection(1);
}
if(i<polyGlass.Length()-1) {
bNext=TRUE;
polyGlass.Nth(i, segNext);
nDirNext=segNext.IDirection(0);
}
if(!bPrev) { //第一
XPoint ptFirst=polyGlass[i];
XPoint ptVert[4];
ads_polar(ptFirst, nDirNext-PI/2, m_vFrame/2, ptVert[0]);
ads_polar(ptVert[0], nDirNext, m_uFrame, ptVert[1]);
ads_polar(ptVert[1], nDirNext+PI/2, m_vFrame, ptVert[2]);
ads_polar(ptVert[0], nDirNext+PI/2, m_vFrame, ptVert[3]);
XPoly2D poly2d(1);
for(int k=0; k<4; k++)
poly2d.AppendNode(ptVert[k]);
poly2d.SetElevation(nElev);
dc.DrawMesh(poly2d, XVector3D(0,0,m_nHeight));
} else if(!bNext) { //末尾
XPoint ptEnd=polyGlass[i];
XPoint ptVert[4];
ads_polar(ptEnd, nDirPrev-PI/2, m_vFrame/2, ptVert[0]);
ads_polar(ptVert[0], nDirPrev, m_uFrame, ptVert[1]);
ads_polar(ptVert[1], nDirPrev+PI/2, m_vFrame, ptVert[2]);
ads_polar(ptVert[0], nDirPrev+PI/2, m_vFrame, ptVert[3]);
XPoly2D poly2d(1);
for(int k=0; k<4; k++)
poly2d.AppendNode(ptVert[k]);
poly2d.SetElevation(nElev);
dc.DrawMesh(poly2d, XVector3D(0,0,m_nHeight));
} else {
XPoly2D polyTemp;
XPoint ptCur=polyGlass[i];
XPoint ptPrev, ptNext;
ads_polar(ptCur, nDirPrev, m_uFrame, ptPrev);
ads_polar(ptCur, nDirNext, m_uFrame, ptNext);
polyTemp.AppendNode(ptPrev);
polyTemp.AppendNode(ptCur);
polyTemp.AppendNode(ptNext);
XPoly2D polyLeft, polyRight;
polyTemp.QuickOffset(-m_vFrame/2, polyLeft);
polyTemp.QuickOffset(m_vFrame/2, polyRight);
XPoly2D poly2d(polyRight);
poly2d.SetFlag(1);
for(int k=polyLeft.Length()-1; k>=0; k--)
poly2d.AppendNode(*polyLeft[k]);
poly2d.SetElevation(nElev);
dc.DrawMesh(poly2d, XVector3D(0,0,m_nHeight));
}
}
// 其他窗框
if(1) {
TDbCurveMesh meshEcs;
meshEcs.setPropertiesFrom(this);
if(m_idLayerFrame3d.isValid())
meshEcs.setLayer(m_idLayerFrame3d);
TPushProperty vProp1(&meshEcs, dc);
double nDistPrev=0;
XRectAngle boxTemp(XPoint(), m_uFrame, m_vFrame);
XPoly2D polySect(1);
boxTemp.AsPoly2D(polySect);
for(i=0; i<polyGlass.TotalSegments(); i++) {
XDirectionCurve seg;
polyGlass.Nth(i, seg);
XPoint ptLowLeft, ptUpRight;
ptLowLeft.x = nDistPrev;
nDistPrev += seg.GetLength();
ptUpRight.x = nDistPrev;
ptUpRight.y = m_nHeight;
XPoly2D polyClip(1);
XRectAngle(ptLowLeft, ptUpRight).AsPoly2D(polyClip);
DList<XCurveSegment> ssIn, ssOut,ssEdge;
PolyClip(m_lstFrameLines, polyClip, ssIn, ssOut, ssEdge);
double nDirNormal=CT_std_angle(seg.IDirection(0)-PI/2); //ECS 法向
BOOL bCircular=seg.Is(CURVE_ARC);
XVector3D vtEcs(cos(nDirNormal), sin(nDirNormal), 0.0);
//meshEcs.setLayer(dc.GetLayerId());
for(int n=0; n<ssIn.Length(); n++) {
XCurveSegment segIn=*ssIn[n];
if(!bCircular) {
XPoint pt1, pt2;
polyGlass.Polar2d(segIn.StartPoint().x, pt1);
polyGlass.Polar2d(segIn.EndPoint().x, pt2);
pt1.z = segIn.StartPoint().y + nElev;
pt2.z = segIn.EndPoint().y + nElev;
segIn.StartPoint() = Wcs2Ecs(pt1, vtEcs);
segIn.EndPoint() = Wcs2Ecs(pt2, vtEcs);
ASSERT(fabs(segIn.StartPoint().z-segIn.EndPoint().z)<_DIST_SNAP);
XPoly2D polyPath;
segIn.AsPoly2D(polyPath);
meshEcs.SetPathPoly(polyPath,vtEcs);
meshEcs.SetShapePoly(polySect);
if(dc.IsFullExplode())
meshEcs.ExplodeOrDraw3d(dc);
else
dc.DrawEntity(meshEcs);
} else if(segIn.Is(CURVE_LINE)) {
if(CT_IsSameDrt(segIn.XLine::Direction(), 0.0, _angSnap)) {
//水平段
XPoly2D polyBot(0);
XPoint pt1, pt2;
polyGlass.Polar2d(segIn.StartPoint().x, pt1);
polyGlass.Polar2d(segIn.EndPoint().x, pt2);
XCurveSegment segTemp(seg);
seg.SetPoints(pt1, pt2);
//polyBot.AppendNode(pt1);
//polyBot.AppendNode(pt2);
seg.AsPoly2D(polyBot);
polyBot.SetElevation(nElev+segIn.StartPoint().y);
mesh.SetPathPoly(polyBot,mesh.GetNormal().AsAcGeVector3d());
mesh.SetShapePoly(polyShape);
mesh.SetShapeBase(XPoint(0, -m_uFrame/2));
if(dc.IsFullExplode())
mesh.ExplodeOrDraw3d(dc);
else
dc.DrawEntity(mesh);
} else {
//垂直段
double nDirNext=seg.XLine::Direction();
XPoint ptFirst;
polyGlass.Polar2d(segIn.StartPoint().x, ptFirst);
XPoint ptVert[4];
ads_polar(ptFirst, nDirNext-PI/2, m_vFrame/2, ptVert[0]);
ads_polar(ptVert[0], nDirNext, m_uFrame, ptVert[1]);
ads_polar(ptVert[1], nDirNext+PI/2, m_vFrame, ptVert[2]);
ads_polar(ptVert[0], nDirNext+PI/2, m_vFrame, ptVert[3]);
XPoly2D poly2d(1);
for(int k=0; k<4; k++)
poly2d.AppendNode(ptVert[k]);
poly2d.SetElevation(nElev+segIn.StartPoint().y);
dc.DrawMesh(poly2d, XVector3D(0,0, segIn.EndPoint().y-segIn.StartPoint().y));
}
} else {
//圆弧墙上的圆弧棱,目前还不能处理
}
}
}
}
dc.RestoreProperties(prop);
return TRUE;
}
// 绘制凸窗三维
BOOL TDbOpening::DrawBayWindow3d(XExplodeDraw &dc) const
{
if (!m_pBayWin)
return FALSE;
if (m_opKind != OP_PROWIN)
return FALSE;
AcDbObjectId idOldLay = dc.GetLayerId();
int nOldColor = dc.GetColor();
XPoly2D polyGlass;
TADSGePoint3d ptDir;
//绘制玻璃和平板
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if (pWall)
{
XPoint ptLoc = m_ptLocation;
ptLoc.z = m_ptLocation.z;
double nWallThick = pWall->GetWidth(4);
double nExtDir = m_nRotation + (m_nQuadrant<2? PI/2.0 : -PI/2.0);
ads_polar(ptLoc, nExtDir, 10000, ptDir);
double dWallInsut = 0.0;
int nSide = pWall->OnWhichSide(ptDir);
if (pWall->IsInsulateOnSide(nSide)) // 得到外保温厚度
{
dWallInsut = pWall->GetInsulateThick(nSide);
}
DList<XPoly2D> polyCurves;
m_pBayWin->GetPolyCurve(ptLoc, nExtDir, m_nWidth, nWallThick, HasLeftSlab(), HasRightSlab(), polyCurves, dWallInsut);
if (polyCurves.Length() > 1)
{
polyGlass = *polyCurves[1];
DList<XCurveSegment> lstCurve;
ExplodePoly2D(polyGlass, lstCurve);
dc.SetColorLayer(colorIndex(), m_idLayerGlass3d);
dc.DrawCurveList(lstCurve, m_nHeight);
}
if ((HasLeftSlab() || HasRightSlab()) && m_pBayWin->m_nStyle==XBayWindow::BWS_RECT)
{
XPoly2D polyLeft(1),polyRight(1);
m_pBayWin->GetVertSlabPoly(ptLoc, nExtDir, m_nWidth, nWallThick, m_nProWinSlabWidth, polyLeft, polyRight);
if (HasLeftSlab())
{
dc.SetColorLayer(colorIndex(), m_idLayerSlab3d);
// wlw add 150611 pc构件增加凸窗板三维显示到墙顶
double dLine = 0.0;
m_XDataMap.GetAt(sKEY_OP_PROWIN_LINE, dLine);
if (dLine > 0.0)
{
polyLeft.SetElevation(pWall->StartPoint().z);
XVector3D vtUp(0, 0, pWall->GetHeight());
dc.DrawBody(polyLeft, vtUp);
}
else
{
polyLeft.SetElevation(ptLoc.z);
XVector3D vtUp(0, 0, m_nHeight);
dc.DrawBody(polyLeft, vtUp);
}
}
if (HasRightSlab())
{
dc.SetColorLayer(colorIndex(), m_idLayerSlab3d);
// wlw add 150611 pc构件增加凸窗板三维显示到墙顶
double dLine = 0.0;
m_XDataMap.GetAt(sKEY_OP_PROWIN_LINE, dLine);
if (dLine > 0.0)
{
polyRight.SetElevation(pWall->StartPoint().z);
XVector3D vtUp(0,0,pWall->GetHeight());
dc.DrawBody(polyRight, vtUp);
}
else
{
polyRight.SetElevation(ptLoc.z);
XVector3D vtUp(0,0,m_nHeight);
dc.DrawBody(polyRight, vtUp);
}
}
polyCurves.Reset();
m_pBayWin->GetPolyCurve(ptLoc, nExtDir, m_nWidth, nWallThick,FALSE,FALSE, polyCurves,dWallInsut);
}
if (polyCurves.Tail())
{
dc.SetColorLayer(colorIndex(), m_idLayerSlab3d);
XPoly2D polyOut = *polyCurves.Tail();
polyOut.SetFlag(1);
polyOut.SetElevation(ptLoc.z);
XVector3D vtUp(0,0,m_nSlabThickness), vtDown(0,0,-m_nSlabThickness);
dc.DrawBody(polyOut, vtDown);
polyOut.SetElevation(ptLoc.z+m_nHeight);
dc.DrawBody(polyOut, vtUp);
}
dc.SetLayer(idOldLay);
dc.SetColor(nOldColor);
}
OPENOBJ_END();
// 绘制窗框
if (polyGlass.Length())
{
DrawFrame3d(dc, polyGlass);
}
dc.SetLayer(idOldLay);
dc.SetColor(nOldColor);
return TRUE;
}
// 绘制圆弧窗
BOOL TDbOpening::DrawArcWin3d(XExplodeDraw &dc) const
{
Acad::ErrorStatus es=Acad::eOk;
XDbObject objWall(m_nIdOfWall, AcDb::kForRead);
if(!!objWall) {
TDbWall *pDbWall=TDbWall::cast(objWall.m_pObject);
ASSERT(pDbWall && pDbWall->Is(CURVE_ARC));
if(pDbWall) {
XArc ar=pDbWall->GetArc();
double nWallThick=pDbWall->GetWidth();
XPoint ptLoc=m_ptLocation;
TADSGePoint3d ptCen = ar.GetCenterPt();
ptCen.z = ptLoc.z;
ar.SetCenterPt(ptCen);
XPoint ptOnWall=ptLoc;
pDbWall->ProjectToMe(ptLoc, ptOnWall);
double nRad=ar.GetCenterPt().Distance2d(ptOnWall);
double nSweepAng=m_nWidth/nRad;
double nStartAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)-nSweepAng/2.0),
nEndAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)+nSweepAng/2.0);
XArc arMid(ar.GetCenterPt(), ads_distance(ar.GetCenterPt(), ptLoc), nStartAng, nEndAng);
TMasterProperties prop;
dc.BackUpProperties(prop);
//AcDbObjectId idLay=dc.GetLayerId();
int nOldColor=dc.GetColor();
dc.SetColorLayer(colorIndex(),m_idLayerGlass3d);
dc.DrawArc(arMid, m_nHeight);
dc.RestoreProperties(prop);
XCurveSegment seg;
seg=arMid;
XPoly2D polyGlass;
seg.AsPoly2D(polyGlass);
DrawFrame3d(dc, polyGlass);
}
} else { //画个示意图
XPoly2D polyShow(1);
GetOutlinePoly(0.0, polyShow);
dc << polyShow;
es=Acad::eInvalidInput;
}
return es;
}
// 炸碎或者绘制三维门窗
Acad::ErrorStatus TDbOpening::ExplodeOrDraw3d(XExplodeDraw &dc) const
{
if(!Has3D())
return Acad::eOk;
Acad::ErrorStatus es=Acad::eCannotExplodeEntity;
//下面代码导致工程管理导出三维实体时洞口被屏蔽,特此注释,但该代码以前的用处并不明朗,如发现其确实有用,再商讨是否打开。2015-7-21
/*if(m_opKind==OxianzaP_HOLE && _tcscmp(dc.Desc(), XExplodeStream::Descriptor())==0)
return es;*/
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if(pWall) {
if(!g_bIntWall3DVisible && !pWall->IsExternal(OFFSET_LEFT) && !pWall->IsExternal(OFFSET_RIGHT))
return Acad::eOk; //关闭内墙显示
}
OPENOBJ_END();
if(!objectId() && !!m_nIdOfWall && _tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) {
//拖曳
DragDraw((XAcGiViewDraw &)dc);
}
if(m_opKind==OP_HOLE) {
XPoly2D poly(1);
GetElevOutline(poly); //已经折线化了
dc << poly;
return Acad::eOk;
}
if(m_opKind==OP_ARCWIN) { //弧墙上的弧窗
DrawArcWin3d(dc);
} else if(m_opKind==OP_CORNWIN) { //转角窗
DrawBanWin(dc, TRUE);
} else if(m_opKind==OP_DOORWIN) {
ExplodeOrDrawDoorWin(dc, TRUE);
} else if(m_opKind==OP_TWODOOR) {
ExplodeOrDrawTwoDoor(dc, TRUE);
} else if(m_opKind==OP_PROWIN) { //凸窗
DrawBayWindow3d(dc);
} else if(g_bOsnapExpl) { // OSNAP需要加速
XPoly2D poly(1);
GetElevOutline(poly); //已经折线化了
dc << poly;
} else {
if(m_lstFrameLines.Length()) {
XPoly2D polyGlass;
XCurveSegment segGlass;
GetSidePoints(segGlass.StartPoint(), segGlass.EndPoint());
segGlass.AsPoly2D(polyGlass);
DrawFrame3d(dc, polyGlass);
TMasterProperties prop;
dc.BackUpProperties(prop);
segGlass.SetElevation(GetElevation());
dc.SetColorLayer(colorIndex(), m_idLayerGlass3d);
dc.DrawCurve(segGlass, m_nHeight);
dc.RestoreProperties(prop);
} else {
double nScaleX, nScaleY, nScaleZ;
if(GetInsert3DScale(&nScaleX, &nScaleY, &nScaleZ)!=Acad::eOk)
return es;
AcDbObjectId idStyle=!m_nIdStyle3d? m_nIdStyle2d:m_nIdStyle3d;
XPoint ptInsert=m_ptLocation;
if(!(!m_nIdStyle3d)) { //显示真三维
dc<<XBlockRef(idStyle, ptInsert, AcGeScale3d(nScaleX, nScaleY, nScaleZ), m_nRotation, g_bMakeBlock);
} else if(!!m_nIdStyle2d) {
dc<<XBlockRef(idStyle, ptInsert, AcGeScale3d(nScaleX, nScaleY, m_nHeight), m_nRotation, g_bMakeBlock);
}
}
}
return Acad::eOk;
}
//展开
// entSetFix-固定的窗框,entSetCustom-客户定义的窗棱
BOOL TDbOpening::ExpandFrame(AcDbVoidPtrArray &entSetFix, AcDbVoidPtrArray &entSetCustom) const
{
XPoly2D polyGlass;
if(m_opKind==OP_HOLE)
return FALSE;
if(m_opKind==OP_ARCWIN) { //弧墙上的弧窗
XDbObject objWall(m_nIdOfWall, AcDb::kForRead);
if(!!objWall) {
TDbWall *pDbWall=TDbWall::cast(objWall.m_pObject);
ASSERT(pDbWall && pDbWall->Is(CURVE_ARC));
if(pDbWall) {
XArc ar=pDbWall->GetArc();
double nWallThick=pDbWall->GetWidth();
XPoint ptLoc=m_ptLocation;
TADSGePoint3d ptCen = ar.GetCenterPt();
ptCen.z = ptLoc.z;
ar.SetCenterPt(ptCen);
XPoint ptOnWall=ptLoc;
pDbWall->ProjectToMe(ptLoc, ptOnWall);
double nRad=ar.GetCenterPt().Distance2d(ptOnWall);
double nSweepAng=m_nWidth/nRad;
double nStartAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)-nSweepAng/2.0),
nEndAng=CT_std_angle(ads_angle(ar.GetCenterPt(), ptOnWall)+nSweepAng/2.0);
XArc arMid(ar.GetCenterPt(), ads_distance(ar.GetCenterPt(), ptLoc), nStartAng, nEndAng);
XCurveSegment seg;
seg=arMid;
seg.AsPoly2D(polyGlass);
}
} else {
return FALSE;
}
} else if(m_opKind==OP_CORNWIN) { //带形窗
XCurveSegment segLeftSide, segLeft, segMid, segRight, segRightSide;
if(!GetBanWinSegs(segLeftSide, segLeft, segMid, segRight, segRightSide))
return FALSE;
segMid.AsPoly2D(polyGlass);
} else if(m_opKind==OP_DOORWIN) {
return FALSE;
} else if(m_opKind==OP_TWODOOR) {
return FALSE;
} else if(m_opKind==OP_PROWIN) { //凸窗
if(!m_pBayWin)
return FALSE;
DList<XPoly2D> polyCurves;
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if(pWall)
{
XPoint ptLoc=m_ptLocation,ptDir;
ptLoc.z = m_ptLocation.z;
double nWallThick=pWall->GetWidth(4);
double nExtDir=m_nRotation + (m_nQuadrant<2? PI/2.0 : -PI/2.0);
ads_polar(ptLoc, nExtDir, 10000, ptDir);
double dWallInsut = 0.0;
int nSide = pWall->OnWhichSide(ptDir);
//得到外保温厚度
if (pWall->IsInsulateOnSide(nSide))
{
dWallInsut = pWall->GetInsulateThick(nSide);
}
m_pBayWin->GetPolyCurve(ptLoc, nExtDir, m_nWidth, nWallThick,HasLeftSlab(),HasRightSlab(),polyCurves);
polyGlass=*polyCurves[1];
}
OPENOBJ_END();
} else { //普通门窗
XCurveSegment segLine;
GetSidePoints(segLine.StartPoint(), segLine.EndPoint());
segLine.AsPoly2D(polyGlass);
}
if(!polyGlass)
return FALSE;
XPoly2D polyOut(1);
XPoint ptOut[4];
ptOut[1].x = ptOut[2].x = polyGlass.Distance2d();
ptOut[2].y = ptOut[3].y = m_nHeight;
for(int n=0; n<4; n++)
polyOut.AppendNode(ptOut[n]);
AcDbPolyline *pOutline=new AcDbPolyline;
PolyConvert(polyOut, *pOutline);
entSetFix.append(pOutline);
double nDist=0.0;
for(int i=1; i<polyGlass.Length()-1; i++) {
XCurveSegment seg;
polyGlass.Nth(i-1, seg);
nDist += seg.GetLength();
XPoint ptSep[2];
ptSep[0].x=ptSep[1].x=nDist;
ptSep[1].y=m_nHeight;
entSetFix.append(new AcDbLine(ptSep[0], ptSep[1]));
}
for(i=0; i<m_lstFrameLines.Length(); i++)
entSetCustom.append(m_lstFrameLines[i].AsAcDbCurve());
return TRUE;
}
//modified by whl on 0806024
//子母门作为门,组合门窗根据KindString识别
const TCHAR * TDbOpening::GetDefaultLayer() const
{
const TCHAR *pLay = NULL;
// if (m_opKind==OP_DOOR || m_opKind==OP_DOORWIN || m_opKind==OP_TWODOOR)
// pLay = LAY_DOOR;
// sg modify 110217,对防火门、防火卷帘进行了特殊图层设置
if (m_opKind == OP_DOOR) // 门
{
CString csSubType = GetSubKind(); // 子类型
if (csSubType.Find(_T("防火门")) >= 0)
{
pLay = LAY_FIRE_DOOR;
}
else if (csSubType.Find(_T("防火卷帘")) >= 0)
{
pLay = LAY_FIRE_JL;
}
// sg add 111018,增加考虑隔断门在特殊的图层上,以前没有考虑
else if ((m_nOpStyle&OPS_LVTRY) || csSubType.Compare(_T("隔断门"))==0)
{
pLay = LAY_LATRINE;
}
else
{
pLay = LAY_DOOR;
}
}
else if (m_opKind==OP_DOORWIN || m_opKind==OP_TWODOOR) // 门连窗、子母门
pLay = LAY_DOOR;
else if (m_opKind == OP_HOLE) // 洞口
pLay = LAY_HOLE2D;
else
{
// sg modify 110217,对防火门、防火卷帘进行了特殊图层设置
CString csSubType = GetSubKind(); // 子类型
if (csSubType.Find(_T("防火窗")) >= 0)
{
pLay = LAY_FIRE_WIN;
}
else if (csSubType.Find(_T("防火卷帘")) >= 0)
{
pLay = LAY_FIRE_JL;
}
else
{
CString sKind = GetKindString();
if (sKind.Find(_T("门")) >= 0)
pLay = LAY_DOOR;
else
pLay = LAY_WIN;
}
}
return pLay;
}
// 设置类型: 门,窗,洞
void TDbOpening::SetKind(OpeningKind opk)
{
m_opKind=opk;
const TCHAR *szLay=NULL;
switch(m_opKind)
{
case OP_HWINDOW: szLay=LAY_DOOR; break;
case OP_WINDOW: szLay=LAY_WIN; break;
case OP_DOOR: szLay=LAY_DOOR; break;
case OP_HOLE: szLay=LAY_HOLE2D; break;
}
if(szLay)
setLayer(szLay);
}
bool TDbOpening::IsDoorAsWin()const
{
if(GetKind()!=OP_DOOR)
return false;
if(!m_nIdStyle2d)
return false;
OPENOBJ_BEGIN(m_nIdStyle2d, AcDb::kForRead, AcDbBlockTableRecord, pBlock);
if(pBlock!=NULL)
{
// 从扩展实体数据取出原始墙厚
resbuf *pxData=pBlock->xData(TCHXD);
if(pxData!=NULL)
{
resbuf *pNext=pxData->rbnext;
if(pNext && pNext->restype==1040)
{
double nWallThick= pNext->resval.rreal;
if(fabs(nWallThick)>1E-6)//这个墙厚只用来判断是不是推拉门
return true;
}
ads_relrb(pxData);
}
}
OPENOBJ_END();
return false;
}
Acad::ErrorStatus TDbOpening::GetInsert2DScale(double *pScaleX, double *pScaleY) const
{
assertReadEnabled();
double nScaleX, nScaleY;
nScaleY = GetWallThickness(TRUE);
if(m_opKind==OP_DOOR
&&!IsDoorAsWin())//add by whl on 050728,不是推拉门等与墙厚有关的门
nScaleY=m_nWidth;
nScaleX=m_nWidth;
if(m_nQuadrant==1)
nScaleX = -nScaleX;
else if(m_nQuadrant==2)
{
nScaleX = -nScaleX;
nScaleY = -nScaleY;
}
else if(m_nQuadrant==3)
nScaleY = -nScaleY;
*pScaleX = nScaleX;
*pScaleY = nScaleY;
return Acad::eOk;
}
///////////////////////////////////////////////////////////
// static 求3D图块的原始尺寸
BOOL TDbOpening::GetOriginal3DSize(AcDbObjectId idStyle3d, XPoint &sizeXYZ)
{
if(!idStyle3d)
return FALSE;
BOOL nRet=FALSE;
OPENOBJ_BEGIN(idStyle3d, AcDb::kForRead, AcDbBlockTableRecord, pBlock);
if(!pBlock)
return FALSE;
// 从扩展实体数据取出原始尺寸
resbuf *pxData=pBlock->xData(TCHXD);
if(!pxData) {
AcDbBlockReference entInsert;
entInsert.setBlockTableRecord(idStyle3d);
AcDbExtents ext;
if(entInsert.getGeomExtents(ext)!=Acad::eOk)
return FALSE;
AcGePoint3d ptMax=ext.maxPoint(), ptMin=ext.minPoint();
double sx=ptMax.x-ptMin.x;
double sz=ptMax.z-ptMin.z;
if(sx<_DIST_SNAP || sz<_DIST_SNAP)
return FALSE;
sizeXYZ=XPoint(sx,60.0,sz);
nRet=TRUE;
} else {
resbuf *pNext=pxData->rbnext;
if(pNext && pNext->restype==1040) {
double sx = pNext->resval.rreal;
pNext=pNext->rbnext;
if(pNext && pNext->restype==1040) {
double sz = pNext->resval.rreal;
ASSERT(sx>_DIST_SNAP && sz>_DIST_SNAP);
sizeXYZ = XPoint(sx,60.0,sz);
nRet = TRUE;
}
}
ads_relrb(pxData);
}
OPENOBJ_END();
return nRet;
}
// 求3D插入比例
Acad::ErrorStatus TDbOpening::GetInsert3DScale(double *pScaleX, double *pScaleY, double *pScaleZ) const
{
assertReadEnabled();
double nScaleX, nScaleY, nScaleZ;
if(!(!m_nIdStyle3d)) { // Use 3dStyle
XPoint origenalSize;
if(!GetOriginal3DSize(m_nIdStyle3d, origenalSize))
return Acad::eInvalidInput;
nScaleX = origenalSize.x>_DIST_SNAP? (m_nWidth/origenalSize.x) : 1.0;
nScaleY = origenalSize.y>_DIST_SNAP? (m_nThickness/origenalSize.y) : 1.0;
nScaleZ = origenalSize.z>_DIST_SNAP? (m_nHeight/origenalSize.z) : 1.0;
if(origenalSize.y>origenalSize.x/2.0) //旋转门
nScaleY=nScaleX;
else
nScaleY=1.0;
} else { // Use 2d Extrude
XDbObject objBlock(m_nIdStyle2d, AcDb::kForRead);
if(!objBlock)
return Acad::eInvalidInput;
AcDbBlockTableRecord *pBlock = AcDbBlockTableRecord::cast(objBlock.m_pObject);
if(m_opKind==OP_DOOR) nScaleY=m_nWidth;
else nScaleY=GetWallThickness();
nScaleX=m_nWidth;
nScaleZ=1.0;
}
// 镜像情况
if(m_nQuadrant==1) nScaleX = -nScaleX;
else if(m_nQuadrant==2) {
nScaleX = -nScaleX;
nScaleY = -nScaleY;
} else if(m_nQuadrant==3) nScaleY = -nScaleY;
*pScaleX = nScaleX;
*pScaleY = nScaleY;
*pScaleZ = nScaleZ;
return Acad::eOk;
}
// 把门窗插入墙内
Acad::ErrorStatus
TDbOpening::InsertIntoWall(TDbWall *pWall)
{
assertWriteEnabled();
m_nRotation = pWall->Direction(m_ptLocation);
//m_nThickness = pWall->GetWidth();
XPoint ptNewLoc;
pWall->GetOpeningLocation(m_ptLocation, GetKind(), m_nWidth, ptNewLoc);
m_ptLocation = ptNewLoc;
m_nIdOfWall = pWall->objectId();
AcDbObjectId idTextStyle = m_idTextStyle; //
if(!idTextStyle.isValid())
idTextStyle=InitTextStyle(TS_WINDOW,database());
XDbObject objTextStyle(idTextStyle, AcDb::kForRead);
ads_real nDistToLocation=pWall->GetWidth();
if(!objTextStyle) ;
else {
AcDbTextStyleTableRecord *pTextStyle=AcDbTextStyleTableRecord::cast(objTextStyle.m_pObject);
if(pTextStyle) nDistToLocation += pTextStyle->textSize()*GetPScale();
}
//门的标号搁到开向的另一侧,窗总搁到外侧
/*
ads_real nExtDrt = pWall->ExtDirection(m_ptLocation);
ads_real nDrtLabel= CT_std_angle(nExtDrt+PI);
ads_polar(m_ptLocation, nDrtLabel, nDistToLocation, m_ptLabel);
m_ptLabel.z = 0;
*/
double nWallWidth=pWall->GetWidth();
nDistToLocation=nWallWidth/2;
double nDist2Wall=GetTextHeight()/2;
nDist2Wall += DocGetText2Base();
nDistToLocation += nDist2Wall*GetPScale();
XPoint ptLab;
ads_polar(m_ptLocation, m_nRotation+(m_nQuadrant>=2? 1.0 : -1.0)*PI/2, nDistToLocation, ptLab);
ptLab.z = 0;
m_ptLabel= ptLab;
return Acad::eOk;
}
XPoint TDbOpening::GetDefaultLabPos() const
{
double nWallWidth=GetWallThickness(TRUE);
ads_real nDistToLocation=nWallWidth/2;
double nDist2Wall=GetTextHeight()/2;
nDist2Wall += DocGetText2Base();
nDistToLocation += nDist2Wall*GetPScale();
XPoint ptLab;
ads_polar(m_ptLocation, m_nRotation+(m_nQuadrant>=2? 1.0 : -1.0)*PI/2, nDistToLocation, ptLab);
ptLab.z = 0;
return ptLab;
}
// 验证调整和墙的配属关系
// 方法: 如果有配属的墙则验证是否成立配属关系; 否则寻找一配属墙,确立新的关系
// 注意: 在命令结束时处理
void TDbOpening::ValidateContainership(DList<AcDbObjectId> &lstWalls)
{
assertWriteEnabled();
// add by xlc on 110131 普通的独立门窗不进行验证
if ((m_opKind == OP_DOOR || m_opKind == OP_WINDOW) && IsLoneOpening())
{
return;
}
if(!(!m_nIdOfWall))
{ //验证原来的配属关系是否成立
XDbObject obj(m_nIdOfWall, AcDb::kForRead);
if(!(!obj))
{
TDbWall *pWall = TDbWall::cast(obj.m_pObject);
if(pWall)
{
if(!pWall->CanContain(*this))
{
if(pWall->upgradeOpen()==Acad::eOk)
{
pWall->assertWriteEnabled();
::RemoveContainership(pWall, this);
pWall->downgradeOpen();
}
}
else
{ //确保互相引用关系
AcDbObjectId __id = objectId();
if(!pWall->m_lstOpeningId.FindNode(&__id, CompareObjectId))
{
if(pWall->upgradeOpen()==Acad::eOk)
{
pWall->assertWriteEnabled();
pWall->m_lstOpeningId.Append(new AcDbSoftPointerId(objectId()));
pWall->downgradeOpen();
}
}
XPoint ptLoc;
if(pWall->GetOpeningLocation(m_ptLocation, GetKind(), GetWidth(), ptLoc))
{
m_ptLocation=ptLoc;
ptLoc.z = pWall->GetElevation();
double nWallDirection = pWall->Direction(ptLoc);
double nDirectionOld=m_nRotation;
m_nRotation=nWallDirection;
//计算相对角(<=PI)
double nA=CT_std_angle(m_nRotation-nDirectionOld);
if(nA>PI)
nA=PI*2-nA;
if(nA>(PI/2+1E-6))//墙方向与当前方向夹角大于90度时,尽量维持原开启方向
{
if(m_nQuadrant==0)
m_nQuadrant=2;
else if(m_nQuadrant==2)
m_nQuadrant=0;
else if(m_nQuadrant==1)
m_nQuadrant=3;
else
m_nQuadrant=1;
}
}
}
}
}
}
// 如果没有配属关系,则重新建立
if(!m_nIdOfWall)
{
for(int i=0; i<lstWalls.Length(); i++)
{
XDbObject obj(*lstWalls[i], AcDb::kForWrite);
if(!obj) continue;
TDbWall *pWall = TDbWall::cast(obj.m_pObject);
if(!pWall) continue;
if(pWall->CanContain(*this))
{
XPoint ptOld=m_ptLabel;
double nDirectionOld=m_nRotation;
pWall->InsertOpening(this);
resbuf *xdata=xData(_T("TDOTE"));
if(xdata && xdata->rbnext && xdata->rbnext->restype==1010)
{ //转换旧图
XPoint ptData=xdata->rbnext->resval.rpoint;
if(CT_IsExactSameDrt(ptData.z, m_nRotation, _angSnap))
{
if(ptData.x>0)
{
if(ptData.y>0)
m_nQuadrant=0;
else
m_nQuadrant=3;
}
else
{
if(ptData.y>0) m_nQuadrant=1;
else m_nQuadrant=2;
}
}
else
{
ptData.x = - ptData.x;
ptData.y = - ptData.y;
if(ptData.x>0)
{
if(ptData.y>0)
m_nQuadrant=0;
else
m_nQuadrant=3;
}
else
{
if(ptData.y>0)
m_nQuadrant=1;
else
m_nQuadrant=2;
}
}
if(xdata->rbnext)
ads_relrb(xdata->rbnext);
xdata->rbnext=NULL;
m_ptLabel=ptOld;
setXData(xdata);
ads_relrb(xdata);
}
else
{
//modified by whl on 070611
//计算相对角(<=PI)
double nA=CT_std_angle(m_nRotation-nDirectionOld);
if(nA>PI)
nA=PI*2-nA;
if(nA>(PI/2+1E-6))//墙方向与当前方向夹角大于90度时,尽量维持原开启方向
{
if(m_nQuadrant==0)
m_nQuadrant=2;
else if(m_nQuadrant==2)
m_nQuadrant=0;
else if(m_nQuadrant==1)
m_nQuadrant=3;
else
m_nQuadrant=1;
}
if(CT_IsSameDrt(nDirectionOld, m_nRotation, _angSnap))//墙方向不变时,编号位置不变,否则成为默认位置
m_ptLabel=ptOld;
}
break;
}
}
}
}
void TDbOpening::ValidateDim(DList<AcDbObjectId> &lstDims)
{
if(lstDims.Length()<1)
return;
assertWriteEnabled();
bool bErased=isErased()==Adesk::kTrue;
XPoint ptNew0,ptNew1;
GetSidePoints(ptNew0,ptNew1);
for(long i=0;i<lstDims.Length();i++)
{
AcDbObjectId id=*lstDims[i];
TDbDimension2 *pDim=NULL;
acdbOpenObject(pDim,id,AcDb::kForRead);
if(pDim!=NULL)
{
if(pDim->ownerId()==ownerId()&&//add by whl on 060829,属于同一块内
!pDim->IsAngular()&&pDim->IsAssociate())
pDim->UpdateFrom(ptNew0,ptNew1,m_ptBackOld,m_ptFrontOld,bErased);
pDim->close();
}
}
}
void TDbOpening::MirrorSelf(BOOL bLeftRight) //左右镜像或上下进行
{
assertWriteEnabled();
int nQua=m_nQuadrant;
switch(nQua) {
case 0:
nQua=bLeftRight? 1 : 3;
break;
case 1:
nQua=bLeftRight? 0 : 2;
break;
case 2:
nQua=bLeftRight? 3: 1;
break;
case 3:
nQua=bLeftRight? 2 : 0;
break;
}
m_nQuadrant=nQua;
if(!bLeftRight) { //编号位置镜像
XLine ln(m_ptLocation, m_nRotation);
ln.SetElevation(m_ptLabel.z);
XPoint ptPrj;
if(m_ptLabel.Project(&ln, ptPrj)==RTNORM) {
ptPrj.Mirror(XPoint(m_ptLabel), m_ptLabel);
}
//add by xlc on 110215 调整单侧门口线开启侧
if (!(
(m_nOpStyleEx & OPS_DOORLINE_MID) //居中
|| (m_nOpStyle & (OPS_DOORLINE1+OPS_DOORLINE2)) == 0 //无门口线
|| (m_nOpStyle | (OPS_DOORLINE1+OPS_DOORLINE2)) == m_nOpStyle //双侧门口线
)
)
{
if (m_nOpStyle & OPS_DOORLINE1)
{
m_nOpStyle &= ~OPS_DOORLINE1;
}
else
{
m_nOpStyle |= OPS_DOORLINE1;
}
if (m_nOpStyle & OPS_DOORLINE2)
{
m_nOpStyle &= ~OPS_DOORLINE2;
}
else
{
m_nOpStyle |= OPS_DOORLINE2;
}
}
}
}
/* * * * * * * * * * 取 动 态 属 性 显 示 数 据 的 函 数 * * * * * * * * * */
void TDbOpening::GetTips(DList<TObjInfoUnit> &lstInfo) const
{
//add by whl
AcDbHandle h;
getAcDbHandle(h);
TCHAR pBuf[1024];
h.getIntoAsciiBuffer(pBuf);
lstInfo.Append(new TObjInfoUnit(_T("对象句柄"), pBuf));
XString sName=GetKindString();
lstInfo.Append(new TObjInfoUnit(_T("门窗类型"), sName));
lstInfo.Append(new TObjInfoUnit(_T("门窗编号"), m_sLabel));
lstInfo.Append(new TObjInfoUnit(_T("宽度"), Dist2Str(m_nWidth)));
lstInfo.Append(new TObjInfoUnit(_T("高度"), Dist2Str(m_nHeight)));
lstInfo.Append(new TObjInfoUnit(_T("离地高度"), Dist2Str(m_ptLocation[2])));
lstInfo.Append(new TObjInfoUnit(_T("转角"), Angle2Str(m_nRotation*180.0/PI)));
lstInfo.Append(new TObjInfoUnit(_T("洞墙面积比"), XString(_T("%.3f"), GetAreaIndex())));
}
//只能用于当前图对象,设置缺省子图层和文字样式
void TDbOpening::InitHardPointerId()
{
m_idTextStyle=InitTextStyle(TS_WINDOW);
m_idLayerFrame3d=InitLayer(LAY_3DFRAME, FALSE);
m_idLayerGlass3d=InitLayer(LAY_3DGLASS, FALSE);
m_idLayerSlab3d=InitLayer(LAY_WALL, FALSE);
// sg modify 110223,防火门、防火窗、防火卷帘中的门窗标注单独存放一个图层
// m_idLayerText=InitLayer(LAY_OPENING_DIM, FALSE);
if (m_opKind==OP_DOOR || m_opKind==OP_WINDOW || m_opKind==OP_ARCWIN)
{
CString csSubType = GetSubKind(); // 子类型
if (csSubType.Find(_T("防火门"))>=0 || csSubType.Find(_T("防火卷帘"))>=0 || csSubType.Find(_T("防火窗"))>=0)
{
m_idLayerText=InitLayer(LAY_FILEOPENING_DIM, FALSE);
}
else
{
m_idLayerText=InitLayer(LAY_OPENING_DIM, FALSE);
}
}
else
{
m_idLayerText=InitLayer(LAY_OPENING_DIM, FALSE);
}
TDbConfig *pConfig=GetDwgGlobal(AcDb::kForWrite,g_pCurrentDb);
if(pConfig)
pConfig->close();
}
/* ----------------------------------------------------------------------- */
void TDbOpening::UpdateOwnerWallGraphic() const
{
if(!!m_nIdOfWall) {
PickSet ss(SS_FREE);
ss += m_nIdOfWall;
UpdateGraphic(ss);
}
}
//--------------------------------------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////////////////////////////////
// 节能属性
//窗墙面积比:>0正常,其他为错误发生
double TDbOpening::GetAreaIndex() const
{
double nRatio=0.0;
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if(pWall && pWall->IsValid()) {
XCurveSegment segCen=pWall->OffsetGeomCenter(LS_FINITE, TRUE);
double nAreaWall=_AS_METER(segCen.GetLength())*_AS_METER(pWall->GetHeight())*pWall->GetShapeRatio();
double nAreaWin=_AS_SQMETER(GetOutlineArea());
nRatio=nAreaWin/nAreaWall;
}
OPENOBJ_END();
return nRatio;
}
//求方位角:弧窗取中心点的朝向
//弧度:>=0正常,<0错误发生:如内门窗等
double TDbOpening::GetAzimuth() const
{
double nAzimuth=-1.0;
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if(pWall && pWall->IsValid()) {
int nSide=pWall->GetExtSide();
if(nSide==0 || nSide==1) {
nAzimuth=pWall->GetAzimuth(nSide, m_ptLocation);
}
}
OPENOBJ_END();
return nAzimuth;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//--------------------------------------------------------------------------------------------------------
#if 0
///////////////////////////////////////////////////////////////////
// 通过量化属性取得属性量
Acad::ErrorStatus TDbOpening::GetQuantumByName(const TCHAR *pszName, double *pQuantum) const
{
ASSERT(pszName && pQuantum);
Acad::ErrorStatus es = Acad::eOk;
double nRes=0.0;
if(_tcscmp(pszName, OP_QUANTUM_1)==0) {
nRes = AS_METER(GetOutlineLength());
} else if(_tcscmp(pszName, OP_QUANTUM_2)==0) {
nRes = _AS_SQMETER(GetOutlineArea());
} else if(_tcscmp(pszName, OP_QUANTUM_3)==0) {
nRes = AS_METER(GetWidth());
} else {
es = Acad::eInvalidInput;
}
*pQuantum = nRes;
return es;
}
///////////////////////////////////////////////////////////
// 初始化注册量化的属性名字
void TDbOpening::InitQuantumProtocol(BOOL bTrue)
{
static XQuantumProtocol *pProtocol=NULL;
if(bTrue) {
pProtocol=new XQuantumProtocol;
pProtocol->m_lstQuantumNames.Append(strnew(OP_QUANTUM_1));
pProtocol->m_lstQuantumNames.Append(strnew(OP_QUANTUM_2));
pProtocol->m_lstQuantumNames.Append(strnew(OP_QUANTUM_3));
desc()->addX(XQuantumProtocol::desc(), pProtocol);
} else {
desc()->delX(XQuantumProtocol::desc());
delete pProtocol;
pProtocol = NULL;
}
}
void TDbOpening::InitProperty(BOOL bTrue)
{
m_lstProperties.Reset();
if(!bTrue)
return;
m_lstProperties.Append(new XAccessObjectProperty(/*UMSG*/_T("类别"), (PropertyFun)AccessKind, FALSE));
m_lstProperties.Append(new XAccessObjectProperty(/*UMSG*/"编号", (PropertyFun)AccessLabel, TRUE));
m_lstProperties.Append(new XAccessObjectProperty(
/*UMSG*/"宽度,(mm)", (PropertyFun)AccessWidth, TRUE, VT_I4, "%d"));
m_lstProperties.Append(new XAccessObjectProperty(
/*UMSG*/"高度,(mm)", (PropertyFun)AccessHeight, TRUE, VT_I4, "%d"));
m_lstProperties.Append(new XAccessObjectProperty(
/*UMSG*/"厚度,(mm)", (PropertyFun)AccessThickness, TRUE, VT_I4, "%d"));
m_lstProperties.Append(new XAccessObjectProperty(
/*UMSG*/"窗台高度,(mm)", (PropertyFun)AccessSill, TRUE, VT_I4, "%d"));
m_lstProperties.Append(new XAccessObjectProperty(
/*UMSG*/"面积,(m^2)", (PropertyFun)AccessArea, FALSE, VT_R8, "%6.2f"));
m_lstProperties.Append(new XAccessObjectProperty(
/*UMSG*/"周长,(mm)", (PropertyFun)AccessPerimeter, FALSE, VT_I4, "%d"));
}
#endif
void InitDbOpening(BOOL bTrue)
{
if(bTrue) {
TDbOpening::rxInit();
acrxBuildClassHierarchy();
TDbOpening::InitMatchProtocol(TRUE);
//TDbOpening::InitProperty(TRUE);
//TDbOpening::InitQuantumProtocol(TRUE);
} else {
//TDbOpening::InitQuantumProtocol(FALSE);
//TDbOpening::InitProperty(FALSE);
TDbOpening::InitMatchProtocol(FALSE);
deleteAcRxClass(TDbOpening::desc());
}
}
TARCH_IMPEXP void CheckOp3dStyle(AcDbObjectId idStyle3d)
{
AssureLayer(LAY_KEY, LAYSTAT_UNLOCK);
OPENOBJ_BEGIN(idStyle3d, AcDb::kForWrite, AcDbBlockTableRecord, pBlockRec);
if(pBlockRec) {
resbuf *rbxdOld=pBlockRec->xData(TCHXD);
if(!rbxdOld) {
BOOL bSetXD=FALSE;
XPoint ptMin, ptMax;
BOOL bInitExt=FALSE;
XString sBoundHandle;
RBList rbPointMask(RTDXF0, _T("POINT"), 8, LAY_KEY, 62, 1, NULL);
RBList rbBoundMask(RTDXF0, _T("LWPOLYLINE,POLYLINE"), 8, LAY_BOUNDARY, 70, 1, NULL);
RBList rbShadeMask(8, _T("ASHADE"), NULL);
RBList rbMaterMask(RTDXF0,_T("INSERT"),2, _T("RM_SDB"), NULL);
//遍历块表记录,寻找轮廓的POLYLINE
AcDbBlockTableRecordIterator* pBlockIterator=NULL;
VERIFY(pBlockRec->newIterator(pBlockIterator)==Acad::eOk);
for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) {
AcDbEntity *pEntity;
VERIFY(pBlockIterator->getEntity(pEntity, AcDb::kForRead)==Acad::eOk);
Entity ent;
acdbGetAdsName(ent.name, pEntity->objectId());
if(ent.MatchBase(rbPointMask)) {
resbuf *rbxd=pEntity->xData(TCHXD);
if(pEntity->upgradeOpen()==Acad::eOk) {
pEntity->erase();
pEntity->downgradeOpen();
}
if(rbxd) {
pBlockRec->setXData(rbxd);
ads_relrb(rbxd);
bSetXD=TRUE;
pEntity->close();
break;
}
} else if(ent.MatchBase(rbBoundMask)){
ent.GetData(5, (TCHAR *)sBoundHandle);
} else if(ent.MatchBase(rbShadeMask)) {
} else if(ent.MatchBase(rbMaterMask)) {
} else {
XPoint pt1, pt2;
if(ent.GetExtend(pt1, pt2)==RTNORM) {
if(!bInitExt) {
ptMin=pt1;
ptMax=pt2;
} else {
ptMin=Min(ptMin, pt1);
ptMax=Max(ptMax, pt2);
}
bInitExt=TRUE;
}
}
pEntity->close();
}
delete pBlockIterator;
if(!bSetXD && bInitExt) {
XVector3D vtSize=ptMax-ptMin;
resbuf *rbxd=NULL;
if(!sBoundHandle)
rbxd=ads_buildlist(1001, TCHXD, 1040, vtSize.x, 1040, vtSize.z,NULL);
else
rbxd=ads_buildlist(1001, TCHXD, 1040, vtSize.x, 1040, vtSize.z, 1005, (const TCHAR *)sBoundHandle, NULL);
if(!XSymbolTable(_T("APPID"), TCHXD))
ads_regapp(TCHXD);
pBlockRec->setXData(rbxd);
ads_relrb(rbxd);
}
} else {
ads_relrb(rbxdOld);
}
}
OPENOBJ_END();
AssureLayer(LAY_KEY, LAYSTAT_LOCK);
}
TARCH_IMPEXP void CheckOp2dStyle(AcDbObjectId idStyle2d)
{
AssureLayer(LAY_KEY, LAYSTAT_UNLOCK);
OPENOBJ_BEGIN(idStyle2d, AcDb::kForWrite, AcDbBlockTableRecord, pBlockRec);
if(pBlockRec)
{
resbuf *rbxdOld=pBlockRec->xData(TCHXD);
if(!rbxdOld)
{
BOOL bSetXD=FALSE;
RBList rbPointMask(RTDXF0, _T("POINT"), 8, LAY_KEY, 62, 1, NULL);
AcDbBlockTableRecordIterator* pBlockIterator=NULL;
VERIFY(pBlockRec->newIterator(pBlockIterator)==Acad::eOk);
for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step())
{
AcDbEntity *pEntity;
VERIFY(pBlockIterator->getEntity(pEntity, AcDb::kForRead)==Acad::eOk);
Entity ent;
acdbGetAdsName(ent.name, pEntity->objectId());
if(ent.MatchBase(rbPointMask))
{
resbuf *rbxd=pEntity->xData(TCHXD);
if(pEntity->upgradeOpen()==Acad::eOk)
{
pEntity->erase();
pEntity->downgradeOpen();
}
if(rbxd)
{
pBlockRec->setXData(rbxd);
ads_relrb(rbxd);
bSetXD=TRUE;
pEntity->close();
break;
}
}
pEntity->close();
}
delete pBlockIterator;
}
else
ads_relrb(rbxdOld);
}
OPENOBJ_END();
AssureLayer(LAY_KEY, LAYSTAT_LOCK);
}
// 门窗套材料
int TDbOpening::GetSlotMaterial() const
{
double dThick = 0.0;
int nMat = 0;
BOOL bSlotInsCap = TRUE;
ReadInsulateFromXData(nMat, dThick,bSlotInsCap);
return nMat;
}
void TDbOpening::SetSlotMaterial(int nMat)
{
double dThick = 0.0;
int nMatT = 0;
BOOL bSlotInsCap = TRUE;
ReadInsulateFromXData(nMatT, dThick,bSlotInsCap);
WriteInsulateToXData(nMat,dThick,bSlotInsCap);
//wlw add 100913
m_nMaterial = nMat;
}
// 门窗套保温厚
double TDbOpening::GetSlotInsulateThick() const
{
if (!DocGetProWinSlabInsu())
{
return 0.0;
}
double dThick = 0.0;
int nMat = 0;
BOOL bSlotInsCap = TRUE;
ReadInsulateFromXData(nMat, dThick, bSlotInsCap);
if (nMat == 2 || nMat == 3)
{//材质是保温和轻质材料时,没有保温层
return 0.0;
}
return dThick;
}
void TDbOpening::SetSlotInsulateThick(double dThick)
{
double dThickT = 0.0;
int nMat = 0;
BOOL bSlotInsCap = TRUE;
ReadInsulateFromXData(nMat, dThickT, bSlotInsCap);
WriteInsulateToXData(nMat,dThick,bSlotInsCap);
//wlw add 100913
m_dInsWidth = dThick;
}
// 门窗套保温是否封口,默认封口
BOOL TDbOpening::HasSlotInsulateCap() const
{
assertReadEnabled();
double dThickT = 0.0;
int nMat = 0;
BOOL bSlotInsCap = TRUE;
ReadInsulateFromXData(nMat, dThickT, bSlotInsCap);
return bSlotInsCap;
}
void TDbOpening::SetSlotInsulateCap(BOOL bSlotInsCap)
{
assertWriteEnabled();
double dThick = 0.0;
int nMat = 0;
BOOL bSlotInsCapT = TRUE;
ReadInsulateFromXData(nMat, dThick, bSlotInsCapT);
WriteInsulateToXData(nMat,dThick, bSlotInsCap);
//wlw add 110118
m_bSlotInsCap = bSlotInsCap;
}
// 凸窗挡板保温厚与门窗套共用
double TDbOpening::GetProWinSlabInsuThick() const
{
return GetSlotInsulateThick();
}
void TDbOpening::SetProWinSlabInsuThick(double dThick)
{
SetSlotInsulateThick(dThick);
}
// 门口线偏移距离(只对单侧、双侧起作用)
double TDbOpening::GetDoorLineOffsetDist() const
{
assertReadEnabled();
const TEntityFields &fd = GetFields();
double dOffsetDist = 0;
fd.GFD(_T("门口线偏移距离"), dOffsetDist);
return dOffsetDist;
}
void TDbOpening::SetDoorLineOffsetDist(double dOffsetDist)
{
assertWriteEnabled();
TEntityFields &fd = Fields();
fd.SFD(_T("门口线偏移距离"), dOffsetDist);
}
// 门、窗、弧窗的自类型(支持用户设置,无法用枚举类型)
CString TDbOpening::GetSubKind() const
{
assertReadEnabled();
const TEntityFields &fd = GetFields();
CString csSubKind = _T("普通门");
switch (m_opKind)
{
case TDbOpening::OP_DOOR: // 门
break;
case TDbOpening::OP_WINDOW: // 窗
csSubKind = _T("普通窗");
break;
case TDbOpening::OP_ARCWIN: // 弧窗
csSubKind = _T("弧窗");
break;
default: // 其他类型
csSubKind = GetKindString();
break;
}
fd.GFD(_T("门窗用途"), csSubKind);
return csSubKind;
}
void TDbOpening::SetSubKind(const TCHAR *csKind)
{
assertWriteEnabled();
if (GetKind() == TOpeningData::OP_DOOR) // 门
{
bool bAddFlag1 = _tcsicmp(csKind, _T("隔断门"))==0,
bAddFlag2 = _tcsicmp(csKind, _T("电梯门"))==0;
if (bAddFlag1) // 是隔断门
{
m_nOpStyle |= OPS_LVTRY;
m_nOpStyle &= ~OPS_LIFTDOOR;
}
else if (bAddFlag2) // 是电梯门
{
m_nOpStyle |= OPS_LIFTDOOR;
m_nOpStyle &= ~OPS_LVTRY;
}
else // 都不是
{
m_nOpStyle &= ~OPS_LVTRY;
m_nOpStyle &= ~OPS_LIFTDOOR;
}
}
TEntityFields &fd = Fields();
fd.SFD(_T("门窗用途"), csKind);
}
BOOL TDbOpening::HasInsulate() const
{
return ((m_nOpStyle & OPS_SLOT_INSULATE) != 0);
}
void TDbOpening::SetInsulate(BOOL bTrue)
{
if (bTrue)
{
m_nOpStyle |= OPS_SLOT_INSULATE;
}
else
{
m_nOpStyle &= ~OPS_SLOT_INSULATE;
}
}
bool TDbOpening::ReadInsulateFromXData(int& nMaterial, double& dThick, BOOL &bSlotInsCap)const
{
assertReadEnabled();
nMaterial = 0;
dThick = 0.0;
bSlotInsCap = TRUE;
AcGeVector3d vtTemp;
resbuf *pXData = NULL;
pXData = this->xData(TDBOPENING_INSULATE);
if (pXData != NULL)
{
resbuf* pRb = pXData;
pRb = pRb->rbnext;
if (NULL != pRb && pRb->restype == AcDb::kDxfXdInteger32)
{
nMaterial = pRb->resval.rint;
}
pRb = pRb->rbnext;
if (NULL != pRb && pRb->restype == AcDb::kDxfXdReal)
{
dThick = pRb->resval.rreal;
}
pRb = pRb->rbnext;
if (NULL != pRb && pRb->restype == AcDb::kDxfXdInteger32)
{
bSlotInsCap = pRb->resval.rint;
}
acutRelRb(pXData);
return true;
}
return false;
}
bool TDbOpening::WriteInsulateToXData(int nMaterial, double dThick, BOOL bSlotInsCap)
{
assertWriteEnabled();
resbuf *pXData = NULL;
TGRegApp(TDBOPENING_INSULATE, database());
pXData = this->xData(TDBOPENING_INSULATE);
if (pXData == NULL)
{
pXData = ads_buildlist(1001, TDBOPENING_INSULATE, NULL);
}
resbuf* pRbTemp = NULL;
resbuf* pRb = NULL;
pRbTemp = acutNewRb(AcDb::kDxfXdInteger32);
pRbTemp->resval.rint = nMaterial;
pXData->rbnext = pRbTemp;
pRb = pRbTemp;
pRbTemp = acutNewRb(AcDb::kDxfXdReal);
pRbTemp->resval.rreal = dThick;
pRb->rbnext = pRbTemp;
pRb = pRbTemp;
pRbTemp = acutNewRb(AcDb::kDxfXdInteger32);
pRbTemp->resval.rint = bSlotInsCap;
pRb->rbnext = pRbTemp;
pRb = pRbTemp;
Acad::ErrorStatus es = this->setXData(pXData);
acutRelRb(pXData);
if (es == Acad::eOk)
{
return true;
}
return false;
}
// sg add 101115,支持统一标高
// 需要特殊说明,此类中的dElevation形参,表示的是门窗所在墙,未来会变成的标高值
bool TDbOpening::UnifyElevation(double dElevation)
{
assertWriteEnabled();
// 获得当前门槛高、窗台高
double dSill = GetSill();
// 仿照SetSill函数的实现,在门槛高、窗台高不变的情况下,修改门窗的绝对标高
m_ptLocation.z = dElevation + dSill;
return true;
}
void Matrix3D2String( const AcGeMatrix3d &mat, CString &str )
{
#if ADS <= 15
std::ostringstream stream;
#else
std::wostringstream stream;
#endif
for (int ln = 0; ln < 4; ++ln)
{
for (int col = 0; col < 4; ++col)
{
stream << mat.entry[ln][col];
#if ADS <= 15
stream << " ";
#else
stream << L" ";
#endif
}
}
str = stream.str().c_str();
}
//add by xlc on 101112
CString TDbOpening::GetXml(const AcGeMatrix3d& mat) const
{
TXmlTree xmlTree;
POSITION posRoot = xmlTree.Insert(_T("ATS_OPENING"), 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 posItem = NULL;
POSITION posItem2 = xmlTree.Insert(_T("Link_WALL"), posRoot, posItem1);
{
xmlTree.SetAttribute(posItem2, _T("name"), _T("连接墙体"));
posItem = xmlTree.Insert(_T("Link_ID"), posItem2, NULL);
{
xmlTree.SetAttribute(posItem, _T("name"), _T("墙体句柄"));
strText.Format(_T("%ld"), m_nIdOfWall);
xmlTree.SetItemText(posItem, strText);
}
}
POSITION posItem3 = xmlTree.Insert(_T("Property"), posRoot, posItem2);
{
xmlTree.SetAttribute(posItem3, _T("name"), _T("门窗类型"));
xmlTree.SetAttribute(posItem3, _T("comment"), _T("门窗的类型"));
xmlTree.SetItemText(posItem3, GetKindString());
}
// double m_nProtrude; //突出宽
// double m_nTrapezia; //梯形宽
if (GetKind()==OP_PROWIN && m_pBayWin!=NULL)
{
POSITION posType = xmlTree.Insert(_T("PrType"), posRoot, posItem3);
{
xmlTree.SetAttribute(posType, _T("name"), _T("凸窗类型"));
strText.Format(_T("%d"), m_pBayWin->m_nStyle);
xmlTree.SetItemText(posType,strText);
}
POSITION posStrude = xmlTree.Insert(_T("ProTrude"), posRoot, posType);
{
xmlTree.SetAttribute(posStrude, _T("name"), _T("出挑长"));
strText.Format(_T("%f"), m_pBayWin->m_nProtrude);
xmlTree.SetItemText(posStrude,strText);
}
POSITION posZia = xmlTree.Insert(_T("B"), posRoot, posStrude);
{
xmlTree.SetAttribute(posZia, _T("name"), _T("梯形宽"));
strText.Format(_T("%f"), m_pBayWin->m_nTrapezia);
xmlTree.SetItemText(posZia,strText);
}
posItem3 = posZia;
}
POSITION posItem4 = xmlTree.Insert(_T("Height"), posRoot, posItem3);
{
xmlTree.SetAttribute(posItem4, _T("name"), _T("门窗高"));
xmlTree.SetAttribute(posItem4, _T("comment"), _T("从门窗底起算的窗高"));
strText.Format(_T("%f"), GetHeight());
xmlTree.SetItemText(posItem4, strText);
}
POSITION posItem5 = xmlTree.Insert(_T("Length"), posRoot, posItem4);
{
xmlTree.SetAttribute(posItem5, _T("name"), _T("门窗宽"));
xmlTree.SetAttribute(posItem5, _T("comment"), _T("门窗沿墙面的宽度"));
strText.Format(_T("%f"), GetWidth());
xmlTree.SetItemText(posItem5, strText);
}
POSITION posItem51 = xmlTree.Insert(_T("LengthTwoDoor"), posRoot, posItem5);
{
xmlTree.SetAttribute(posItem51, _T("name"), _T("主门宽"));
xmlTree.SetAttribute(posItem51, _T("comment"), _T("门连窗、子母门"));
strText.Format(_T("%f"), m_nDoorWidth);
xmlTree.SetItemText(posItem51, strText);
}
POSITION posItem52 = xmlTree.Insert(_T("LengthDoorWinH"), posRoot, posItem51);
{
xmlTree.SetAttribute(posItem52, _T("name"), _T("窗高"));
xmlTree.SetAttribute(posItem52, _T("comment"), _T("门连窗"));
strText.Format(_T("%f"), m_nWinHeight);
xmlTree.SetItemText(posItem52, strText);
}
POSITION posItem6 = xmlTree.Insert(_T("Thickness"), posRoot, posItem5);
{
xmlTree.SetAttribute(posItem6, _T("name"), _T("窗厚"));
xmlTree.SetAttribute(posItem6, _T("comment"), _T("窗厚与推拉门厚随墙"));
strText.Format(_T("%f"), GetWallThickness());
xmlTree.SetItemText(posItem6, strText);
}
POSITION posItem7 = xmlTree.Insert(_T("Ang"), posRoot, posItem6);
{
xmlTree.SetAttribute(posItem7, _T("name"), _T("圆心角"));
strText = _T("0");
if (GetKind() == TOpeningData::OP_ARCWIN)
{
TAcDbObjectPtr objWall(m_nIdOfWall, AcDb::kForRead);
if(!!objWall)
{
TDbWall *pDbWall = TDbWall::cast(objWall.m_pObject);
if(pDbWall)
{
TGGeArc ar = pDbWall->GetArc();
double dRadius = ar.GetRadius();
if(dRadius > _DIST_SNAP)
{
double dAng = GetWidth() / dRadius;
strText.Format(_T("%f"), dAng);
}
}
}
}
xmlTree.SetItemText(posItem7, strText);
}
// 旋转角度
POSITION posRotate = xmlTree.Insert(_T("RoataeAngle"), posRoot, posItem7);
{
xmlTree.SetAttribute(posRotate, _T("name"), _T("旋转角度"));
strText.Format(_T("%f"), m_nRotation);
xmlTree.SetItemText(posRotate, strText);
posItem7 = posRotate;
}
POSITION posItem8 = xmlTree.Insert(_T("Open_ang"), posRoot, posItem7);
{
xmlTree.SetAttribute(posItem8, _T("name"), _T("开启方向"));
strText.Format(_T("%d"), m_nQuadrant);
xmlTree.SetItemText(posItem8, strText);
}
POSITION posItem9 = xmlTree.Insert(_T("Highwin_ID"), posRoot, posItem8);
{
xmlTree.SetAttribute(posItem9, _T("name"), _T("高窗标志"));
xmlTree.SetAttribute(posItem9, _T("comment"), _T("高窗为1"));
strText.Format(_T("%d"), IsHigh());
xmlTree.SetItemText(posItem9, strText);
}
POSITION posItem10 = xmlTree.Insert(_T("Upperwin_ID"), posRoot, posItem9);
{
xmlTree.SetAttribute(posItem10, _T("name"), _T("上层窗标志"));
xmlTree.SetAttribute(posItem10, _T("comment"), _T("上层窗为1"));
strText.Format(_T("%d"), IsHighLevel());
xmlTree.SetItemText(posItem10, strText);
}
POSITION posItem11 = xmlTree.Insert(_T("Center_point"), posRoot, posItem10);
{
// sg modify 120117,对点进行坐标变换
TADSGePoint3d ptTransformBy = GetLocation();
ptTransformBy.TransformBy(mat);
xmlTree.SetAttribute(posItem11, _T("name"), _T("基点"));
xmlTree.SetAttribute(posItem11, _T("comment"), _T("窗台中点坐标"));
// strText.Format(_T("%f,%f,%f"), GetLocation().x, GetLocation().y, GetLocation().z);
strText.Format(_T("%f,%f,%f"), ptTransformBy.x, ptTransformBy.y, ptTransformBy.z);
xmlTree.SetItemText(posItem11, strText);
}
POSITION posItem12 = xmlTree.Insert(_T("Lib_Block"), posRoot, posItem11);
{
xmlTree.SetAttribute(posItem12, _T("name"), _T("图块符号表"));
posItem = NULL;
posItem = xmlTree.Insert(_T("Lib_2D"), posItem12, posItem);
{
xmlTree.SetAttribute(posItem, _T("name"), _T("二维门窗块名"));
TCString sName;
GetStyle2dName(sName);
xmlTree.SetItemText(posItem, sName);
}
posItem = xmlTree.Insert(_T("Lib_3D"), posItem12, posItem);
{
xmlTree.SetAttribute(posItem, _T("name"), _T("三维门窗块名"));
TCString sName;
GetStyle3dName(sName);
xmlTree.SetItemText(posItem, sName);
}
}
POSITION pos = posItem12;
AcDbObjectId idStyle = !m_nIdStyle3d ? m_nIdStyle2d : m_nIdStyle3d;
if(idStyle != NULL)
{
POSITION posItem13 = xmlTree.Insert(_T("Matrix3d"), posRoot, posItem12);
{
double dScaleX(0), dScaleY(0), dScaleZ(0),
dRotation(m_nRotation);
GetInsert3DScale(&dScaleX, &dScaleY, &dScaleZ);
AcDbBlockReference block(GetLocation(), idStyle);
block.setRotation(dRotation);
if (!(!m_nIdStyle3d)) // 显示真三维
block.setScaleFactors(AcGeScale3d(dScaleX, dScaleY, dScaleZ));
else if (!!m_nIdStyle2d)
block.setScaleFactors(AcGeScale3d(dScaleX, dScaleY, m_nHeight));
AcGeMatrix3d matBlock = block.blockTransform();
matBlock = mat * matBlock;
CString sMat;
Matrix3D2String(matBlock, sMat);
xmlTree.SetAttribute(posItem13, _T("name"), _T("矩阵"));
xmlTree.SetAttribute(posItem13, _T("comment"), _T("图块转换矩阵"));
xmlTree.SetItemText(posItem13, sMat);
}
pos = posItem13;
}
if (IsShowLabel())
{
POSITION posLabel = xmlTree.Insert(_T("Label"), posRoot, pos);
xmlTree.SetAttribute(posLabel, _T("name"), _T("门窗编号"));
xmlTree.SetItemText(posLabel, m_sLabel);
pos = posLabel;
}
// add by hh 2013-9-6 从xData中读取节能相关的数据
if(11 == g_nProductId)
{
acdbRegApp(_T("TBEC_XDAPP_OPENING"));
resbuf* xdata = xData(_T("TBEC_XDAPP_OPENING"));
if(NULL != xdata)
{
static struct _XDataList{
int nCode; // CODE
LPCTSTR pszItem; // 节点
LPCTSTR pszName; // 节点名称
} xDList1[] = { // 门
{ AcDb::kDxfXdAsciiString, _T("Struct_name"), _T("构造名称") },
{ AcDb::kDxfXdReal, _T("Struct_K"), _T("传热系数") },
}, xDList2[] = { // 外窗
{ AcDb::kDxfXdAsciiString, _T("Struct_name"), _T("构造名称") },
{ AcDb::kDxfXdReal, _T("Struct_K"), _T("传热系数") },
{ AcDb::kDxfXdReal, _T("Struct_SC"), _T("遮阳系数") },
{ AcDb::kDxfXdAsciiString, _T("SD_name"), _T("外遮阳类型") },
{ AcDb::kDxfXdReal, _T("Struct_SDs"), _T("夏季外遮阳系数") },
{ AcDb::kDxfXdReal, _T("Struct_SDw"), _T("冬季外遮阳系数") },
}, xDList3[] = { // 内窗
{ AcDb::kDxfXdAsciiString, _T("Struct_name"), _T("构造名称") },
{ AcDb::kDxfXdReal, _T("Struct_K"), _T("传热系数") },
{ AcDb::kDxfXdReal, _T("Struct_SC"), _T("遮阳系数") },
}, xDList4[] = { // 外凸窗
{ AcDb::kDxfXdAsciiString, _T("Struct_name"), _T("构造名称") },
{ AcDb::kDxfXdReal, _T("Struct_K"), _T("传热系数") },
{ AcDb::kDxfXdReal, _T("Struct_SC"), _T("遮阳系数") },
{ AcDb::kDxfXdAsciiString, _T("SD_name"), _T("外遮阳类型") },
{ AcDb::kDxfXdReal, _T("Struct_SDs"), _T("夏季外遮阳系数") },
{ AcDb::kDxfXdReal, _T("Struct_SDw"), _T("冬季外遮阳系数") },
{ AcDb::kDxfXdAsciiString, _T("TopSlab_name"), _T("顶板构造名称") },
{ AcDb::kDxfXdReal, _T("TopSlab_K"), _T("顶板传热系数") },
{ AcDb::kDxfXdReal, _T("TopSlab_D"), _T("顶板热惰性指标") },
{ AcDb::kDxfXdReal, _T("TopSlab_R"), _T("顶板热阻") },
{ AcDb::kDxfXdAsciiString, _T("BottomSlab_name"), _T("底板构造名称") },
{ AcDb::kDxfXdReal, _T("BottomSlab_K"), _T("底板传热系数") },
{ AcDb::kDxfXdReal, _T("BottomSlab_D"), _T("底板热惰性指标") },
{ AcDb::kDxfXdReal, _T("BottomSlab_R"), _T("底板热阻") },
{ AcDb::kDxfXdAsciiString, _T("SideSlab_name"), _T("侧板构造名称") },
{ AcDb::kDxfXdReal, _T("SideSlab_K"), _T("侧板传热系数") },
{ AcDb::kDxfXdReal, _T("SideSlab_D"), _T("侧板热惰性指标") },
{ AcDb::kDxfXdReal, _T("SideSlab_R"), _T("侧板热阻") },
}, xDListShadow[] = { // 外遮阳绘制参数
{ AcDb::kDxfXdInteger32, _T("SD_mask%d"), _T("外遮阳") },
{ AcDb::kDxfXdReal, _T("SD_para%d"), _T("参数A") },
{ AcDb::kDxfXdReal, _T("SD_parb%d"), _T("参数B") },
{ AcDb::kDxfXdReal, _T("SD_parc%d"), _T("参数C") },
};
// 取得门窗标记
resbuf* px = xdata;
px = px->rbnext;
int nOpening = 1; // 1 门 2 窗 3 凸窗
if(NULL != px && AcDb::kDxfXdInteger32 == px->restype)
{
nOpening = px->resval.rint;
}
int nOut = 0; // 0 内窗; 1 外窗; 2 带外遮阳的外窗
if(1 != nOpening) // 如果是窗户或者凸窗 再读取一下内外窗标记
{
px = px->rbnext;
if(NULL != px && AcDb::kDxfXdInteger32 == px->restype)
{
nOut = px->resval.rint;
}
}
// 根据门窗标记 选择数据
_XDataList* xDList = NULL;
int nSize = 0;
if(1 == nOpening) // 门
{
xDList = xDList1;
nSize = sizeof(xDList1) / sizeof(xDList1[0]);
}
else // 窗 凸窗
{
if(0 == nOut) // 内窗
{
xDList = xDList3;
nSize = sizeof(xDList3) / sizeof(xDList3[0]);
}
else
{
if(3 == nOpening) // 外凸窗
{
xDList = xDList4;
nSize = sizeof(xDList4) / sizeof(xDList4[0]);
}
else // 普通外窗
{
xDList = xDList2;
nSize = sizeof(xDList2) / sizeof(xDList2[0]);
}
}
}
// 根节点
POSITION posBec = xmlTree.Insert(_T("TBecParam"), posRoot, pos);
xmlTree.SetAttribute(posBec, _T("name"), _T("节能参数"));
// 节能数据
CString sTemp;
posItem = NULL;
for(int i = 0; i < nSize && NULL != px; i++)
{
px = px->rbnext;
if(NULL != px && xDList[i].nCode == px->restype)
{
if(AcDb::kDxfXdAsciiString == xDList[i].nCode)
sTemp = px->resval.rstring;
else if(AcDb::kDxfXdReal == xDList[i].nCode)
sTemp.Format(_T("%.2f"), px->resval.rreal);
posItem = xmlTree.Insert(xDList[i].pszItem, posBec, posItem);
xmlTree.SetAttribute(posItem, _T("name"), xDList[i].pszName);
xmlTree.SetItemText(posItem, sTemp);
}
}
// 外遮阳绘制参数
if(NULL != px && 2 == nOut)
{
CString sItem;
px = px->rbnext;
if(NULL != px && AcDb::kDxfXdInteger32 == px->restype)
{
int nLoop = ((1 == px->resval.rint) ? 2 : 1); // 单一遮阳/组合遮阳
nSize = sizeof(xDListShadow) / sizeof(xDListShadow[0]);
for(int k = 0; k < nLoop; k++)
{
for(int j = 0; j < nSize && NULL != px; j++)
{
px = px->rbnext;
if(NULL != px && xDListShadow[j].nCode == px->restype)
{
if(AcDb::kDxfXdInteger32 == xDListShadow[j].nCode)
sTemp.Format(_T("%d"), px->resval.rint);
else if(AcDb::kDxfXdReal == xDListShadow[j].nCode)
sTemp.Format(_T("%.2f"), px->resval.rreal);
sItem.Format(xDListShadow[j].pszItem, k + 1);
posItem = xmlTree.Insert(sItem, posBec, posItem);
xmlTree.SetAttribute(posItem, _T("name"), xDListShadow[j].pszName);
xmlTree.SetItemText(posItem, sTemp);
}
}
}
}
}
acutRelRb(xdata);
pos = posBec;
}
}
CString strBase = TEntityBase::GetXml(mat);
CString strXml = xmlTree.GetXml();
int nIndex = strXml.Find(_T("<Object_ID"));
strXml.Insert(nIndex, strBase);
return strXml;
}
bool TDbOpening::GetSection( const AcDbFace &face, const AcGeVector3d& vtPlaneSecDir,
std::vector<TObjSectionRecord> &sectionRecords,
AcDbVoidPtrArray& arFillPtrs ) const
{
TGGeSectionPlane section(face, vtPlaneSecDir); // 构造投影面
OpeningKind kind = GetKind();
AcDbObjectId id = objectId();
AcDbObjectId layer = layerId();
double elev = GetElevation();
double height = GetHeight();
TGGePoly2D poly_elev, poly_xy; // 立面曲线,x-y面曲线
TObjSectionRecord::SectionType type = TObjSectionRecord::eTCH_OPENING;
GetElevOutline(poly_elev);
GetOutlinePoly(0., poly_xy);
switch (kind)
{
case OP_DOOR:
case OP_WINDOW:
case OP_HOLE:
case OP_TWODOOR:
case OP_GROUP:
case OP_ARCWIN:
{
SectionUtility::FillRecordsByPoly(poly_xy, section, sectionRecords,
elev, height, *this, type);
}
break;
case OP_DOORWIN:
{
// 利用 立面曲线 左右拉伸得到两个立面
AcGeMatrix3d mat;
TGGePoly2D poly;
TGGePoly2D poly1(poly_elev), poly2(poly_elev);
TADSGePoint3d ptB, ptF;
GetSidePoints(ptB, ptF);
AcGeVector3d vt = ptB - ptF;
vt.normalize();
vt *= GetWallThickness() * .5;
vt.rotateBy(PI * -.5, AcGeVector3d::kZAxis);
mat.setTranslation(vt);
poly1.TransformBy(mat);
vt.rotateBy(PI, AcGeVector3d::kZAxis);
mat.setTranslation(vt);
poly2.TransformBy(mat);
TGGeSectionPlane plane1(poly1, AcGeVector3d::kZAxis), plane2(poly2, AcGeVector3d::kZAxis);
// 两个立面进行投影
poly.Reset();
double dDis = SectionUtility::Projection_plane2plane(section, plane1, poly);
if (poly.Length())
sectionRecords.push_back(TObjSectionRecord(id, layer, type, dDis, poly));
poly.Reset();
dDis = SectionUtility::Projection_plane2plane(section, plane2, poly);
if (poly.Length())
sectionRecords.push_back(TObjSectionRecord(id, layer, type, dDis, poly));
}
break;
// case OP_ARCWIN:
// {
// SectionUtility::DrawPoly2D(poly_elev);
// SectionUtility::DrawPoly2D(poly_xy);
// }
// break;
case OP_PROWIN:
{
double nWallThick = 200.;
double dWallInsut = 0., dInsutAdd = 0.;
TADSGePoint3d ptDir;
double nExtDir = m_nRotation + (m_nQuadrant<2? PI/2.0 : -PI/2.0);
TADSGePoint3d ptLoc = GetLocation();
ptLoc.z = 0;
// sg modify 120605,标记保温类型
int nInsulateType = 0;
OPENOBJ_BEGIN(m_nIdOfWall, AcDb::kForRead, TDbWall, pWall);
if(pWall)
{
nWallThick = pWall->GetWidth(4);
ads_polar(ptLoc, nExtDir, 10000, ptDir);
int nSide = pWall->OnWhichSide(ptDir);
if (pWall->IsInsulateOnSide(nSide))
{
dWallInsut = pWall->GetInsulateThick(nSide);
if (DocGetProWinSlabInsu())
{
dInsutAdd = GetSlotInsulateThick();
nInsulateType = 1;
}
}
ads_polar(ptLoc, nExtDir, -10000, ptDir);
if (pWall->IsInsulateOnSide(pWall->OnWhichSide(ptDir)))
{
dInsutAdd = GetSlotInsulateThick();
nInsulateType = (nInsulateType==1) ? 2 : 1;
}
}
OPENOBJ_END();
DList<XPoly2D> polyCurves;
//m_pBayWin->GetPolyCurve(ptLoc, nExtDir, GetWidth(), nWallThick, HasLeftSlab(), HasRightSlab(), polyCurves, dWallInsut, dInsutAdd);
m_pBayWin->GetPolyCurve(ptLoc, nExtDir, GetWidth(), nWallThick, HasLeftSlab(), HasRightSlab(), polyCurves, dWallInsut, dInsutAdd, nInsulateType==2);
if (m_pBayWin->m_nStyle != 3)
{
SectionUtility::FillRecordsByPoly(*polyCurves[polyCurves.Length()-1],
section, sectionRecords, elev, height, *this, type);
}
else// 拱形
{
TGGePoly2D poly = *polyCurves[polyCurves.Length() - 1];
if (poly.Length() == 2)
{
double dAng = poly.GetBulge(0) * .5;
AcGePoint3d pt1(*poly[0]), pt2(*poly[1]);
double dLen = pt1.distanceTo(pt2) * .5;
AcGeVector3d vt = pt1 - pt2;
vt.normalize();
vt *= (dLen/sin(dAng) - dLen/tan(dAng));
vt.rotateBy(PI*.5, AcGeVector3d::kZAxis);
AcGePoint3d pt3 = pt2 + vt;
AcGePoint3d pt4 = pt1 + vt;
TGGePoly2D _poly;
_poly.AppendNode(pt1);
_poly.AppendNode(pt2);
_poly.AppendNode(pt3);
_poly.AppendNode(pt4);
_poly.SetClosed();
SectionUtility::FillRecordsByPoly(_poly, section, sectionRecords,
elev, height, *this, type);
}
}
}
break;
case OP_CORNWIN:
break;
default:
break;
}
// 处理添充线
switch (kind)
{
case OP_DOOR:
break;
case OP_WINDOW:
break;
case OP_DOORWIN:
break;
case OP_TWODOOR:
break;
default:
break;
}
return true;
}