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

972 lines
25 KiB
C++

/*
文件名称:SectionOpening.cpp
功 能:剖面门窗,门窗过梁
作 者:刘春峰
完成日期:2004年8月10日
*/
#include "stdafx.h"
#include "dbxline.h"
#include "resource.h"
extern BOOL InvokeTkwMan(const TCHAR *pszLib, BOOL bSelOnly, XString &sBlockName);
static BOOL g_bHatchGrider = TRUE;
XString g_sSectWinBlock=_T("EWDLib(00001159)");//剖面门窗图块
class CSectionOpening : public CModelessDialog
{
public:
DECLARE_DYNAMIC(CSectionOpening)
CSectionOpening(CWnd* pParent = NULL);
// 对话框
enum { IDD = IDD_SECTWIN };
virtual BOOL OnInitDialog();
afx_msg void OnStnClickedSlide();
afx_msg void OnPaint();
afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
void UpdateImage();
// 门窗操作
BOOL InsertOpening(Entity &sectWall1, XPoint ptres);
BOOL SelectOpening(XString &sBlockName);
BOOL ReplaceOpening();
BOOL ModifySillHigh();
BOOL ModifyWindowHigh();
protected:
CImageDCEx m_image;
virtual void DoDataExchange(CDataExchange *pDX);
private:
BOOL GetHoleWidth(double &width, Entity &sectWall2, const Entity &sectWall1, const XPoint &ptres);
BOOL GetHoleHigh(double &high, XPoint &ptIns, AcGeVector3d &vhole, const XPoint &ptres, const Entity &entName);
BOOL ComparePoint(const Entity &sectWall1, const Entity &sectWall2, const XPoint &ptIns, const AcGeVector3d &vhole);
void BreakWall(Entity &sectWall1, Entity &sectWall2, const XPoint &ptIns, const AcGeVector3d &vhole);
void GetInsertPoint(XPoint &ptIns, const AcGeVector3d &vhole, const Entity &sectWall2);
BOOL InsertBlock(const XPoint &ptIns, const double &width, const double &high, const double &angle, const XString &sBlockName);
BOOL ReplaceBlock(const XString &sBlockName, AcDbObjectId &idOld);
void GetVailidPoints(const AcDbBlockReference *pRef, XPointList &points, BOOL bFlag);
BOOL ChangeWallLine(const AcGeVector3d &vec, XPointList &points);
DECLARE_MESSAGE_MAP()
};
// 剖面门窗命令定义
void SectionOpening()
{
CAcModuleResourceOverride vTemp;
CSectionOpening dlg;
dlg.Create(dlg.IDD, acedGetAcadFrame());
acedGetAcadDwgView()->SetFocus();
XPushVar<int> osmode(_T("OSMODE"), 0);
XPushVar<int> ormode(_T("ORTHOMODE"), 1);
while(true)
{
Entity entres;
XPoint ptres;
int nRet;
INITGET_BEG(0, _T("S R E H"));
nRet = acedEntSel(_T("\n请点取剖面墙线下端或 [选择剖面门窗样式(S)/替换剖面门窗(R)/改窗台高(E)/改窗高(H)]<退出>:"), entres, ptres);
INITGET_END();
if (nRet == RTNORM)// 插入门窗
dlg.InsertOpening(entres, ptres);
else if (nRet == RTKWORD)// 替换门窗
{
TCHAR buf[256];
acedGetInput(buf);
if (buf[0]==_T('S'))
{
dlg.SelectOpening(g_sSectWinBlock);
dlg.UpdateImage();
continue;
}
else if (buf[0]==_T('R'))
dlg.ReplaceOpening();
else if (buf[0]==_T('E'))
{
//多选窗...
//根据相对高度来改窗台高、窗高不变,同时调整墙线...
dlg.ModifySillHigh();
continue;
}
else if (buf[0]==_T('H'))
{
//多选窗...
//改窗高,窗台高不变,同时调整墙线...
dlg.ModifyWindowHigh();
continue;
}
}
break;
}
dlg.DestroyWindow();
}
//剖面门窗加过梁
void OpeningGirder()
{
static double s_girderHigh = 120.0;
PickSet ss(SS_FREE);
RBList mask(RTDXF0, _T("INSERT,TCH_BLOCK_INSERT"),8,LAY_S_WIN, NULL);
if (RTNORM==SelectEntities(_T("\n选择需加过梁的剖面门窗:"), ss, mask)){
int iRet=acedGetReal(XString(_T("\n输入梁高<%s>:"),Dist2Str(s_girderHigh)),
&s_girderHigh);
AcDbObjectId idHatchLay=InitLayer(LAY_HATCH);
if (iRet==RTNORM||iRet==RTNONE){
AcDbObjectIdArray id;
ss.AsIdArray(id);
double nScale=DocGetPScale();
BOOL bDrawDetail=(nScale-g_nDetailScale<-1.0E-3);
TDbConfig *p = GetDwgGlobal(AcDb::kForRead);
TCHAR szHatch[256]=_T("SOLID");
if (p) {
_tcscpy(szHatch, p->GetHatchConcrete(bDrawDetail));
p->close();
}
for(long i=0;i<id.length();i++){
AcGePoint3d ptBase;
double angle = 0.0;
XPoint ptMax;
OPENOBJ_BEGIN(id[i], AcDb::kForRead, AcDbBlockReference, pBlock);
if (pBlock)
{
ptBase = pBlock->position();
angle = pBlock->rotation();
}
GetBlcCtrlPoint(pBlock->blockTableRecord(), ptMax);
AcGeScale3d scale = pBlock->scaleFactors();
ptMax.x *= scale.sx;
ptMax.y *= scale.sy;
OPENOBJ_END()
double width, high;
width = ptMax.x;
high = ptMax.y;
AcGePoint3d ptGirder;
ptGirder.x = ptBase.x;
ptGirder.y = ptBase.y + high;
AcGePoint3d pt0(ptGirder), pt1(ptGirder);
pt1.x += width;
AcGePoint3d pt2(pt0), pt3(pt1);
pt2.y += s_girderHigh;
pt3.y += s_girderHigh;
pt0.rotateBy(angle, AcGeVector3d::kZAxis, ptBase);
pt1.rotateBy(angle, AcGeVector3d::kZAxis, ptBase);
pt2.rotateBy(angle, AcGeVector3d::kZAxis, ptBase);
pt3.rotateBy(angle, AcGeVector3d::kZAxis, ptBase);
if (!g_bHatchGrider){
AcDbSolid *pSolid=new AcDbSolid;
pSolid->setPointAt(0,pt0);
pSolid->setPointAt(1,pt1);
pSolid->setPointAt(2,pt2);
pSolid->setPointAt(3,pt3);
pSolid->setLayer(idHatchLay);
AddToModelSpace(pSolid,Adesk::kTrue);
}else{
XPoly2D poly2d(1);
poly2d.AppendNode(pt0);
poly2d.AppendNode(pt1);
poly2d.AppendNode(pt3);
poly2d.AppendNode(pt2);
AcDbHatch *pHatch=NewHatchFromPoly2D(poly2d, szHatch, nScale);
if (pHatch) {
pHatch->setLayer(idHatchLay);
AddToModelSpace(pHatch,Adesk::kTrue);
}
// zjq add these lines
AcDbLine *pLine=new AcDbLine(pt2, pt3);
pLine->setLayer(InitLayer(LAY_S_LINE));
pLine->setColorIndex(256);
AddToModelSpace(pLine, Adesk::kTrue);
}
}
}
}
}
//************************************************************************
// 类实现
//************************************************************************
CSectionOpening::CSectionOpening(CWnd* pParent)
: CModelessDialog(CSectionOpening::IDD, pParent)
{
}
void CSectionOpening::DoDataExchange(CDataExchange *pDX)
{
CModelessDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CSectionOpening, CModelessDialog)
ON_STN_CLICKED(IDC_SLIDE, OnStnClickedSlide)
ON_WM_PAINT()
ON_WM_SETCURSOR()
END_MESSAGE_MAP()
BOOL CSectionOpening::OnInitDialog()
{
CModelessDialog::OnInitDialog();
UpdateImage();
return TRUE;
}
// 插入门窗
BOOL CSectionOpening::InsertOpening(Entity &sectWall1, XPoint ptres)
{
AcDbObjectId eId;
if (acdbGetObjectId(eId, sectWall1) != Acad::eOk)
{
acutPrintf(_T("\n获得实体对象标志符失败!"));
return FALSE;
}
AcDbEntity *pEnt = NULL;
if (acdbOpenObject(pEnt, eId, AcDb::kForRead) != Acad::eOk)
{
acutPrintf(_T("\n打开实体失败!"));
return FALSE;
}
CString layName = pEnt->layer();
if (!pEnt->isKindOf(AcDbLine::desc()) || (layName != LAY_S_LINE))
{
acutPrintf(_T("\n选中实体不是剖面墙线!"));
pEnt->close();
return FALSE;
}
pEnt->close();
// 得到宽度与另一条墙线
double holeWidth = 0.0;
Entity sectWall2;
ptres = Ucs2Wcs(ptres);
if (!GetHoleWidth(holeWidth, sectWall2, sectWall1, ptres))
{
acutPrintf(_T("\n找不到另一条剖面墙线!"));
return FALSE;
}
while(1)
{
// 得到高度
double holeHigh = 0.0;
XPoint ptIns;
AcGeVector3d vhole;
if (!GetHoleHigh(holeHigh, ptIns, vhole, ptres, sectWall1))
break;
// 比较选择的两点是否在墙体范围内
if (!ComparePoint(sectWall1, sectWall2, ptIns, vhole))
{
acutPrintf(_T("\n指定的门窗洞口超出墙体范围!"));
break;
}
// 得到插入点、角度
double holeAngle = vhole.angleTo(AcGeVector3d::kYAxis);
if (vhole.x > 0)
holeAngle = -holeAngle;
GetInsertPoint(ptIns, vhole, sectWall2);
// 插入剖面门窗
if (!InsertBlock(ptIns, holeWidth, holeHigh, holeAngle, g_sSectWinBlock))
{
acutPrintf(_T("\n插入图块失败!"));
break;
}
// 打断墙并重新绘制
BreakWall(sectWall1, sectWall2, ptIns, vhole);
}
return TRUE;
}
// 替换门窗
BOOL CSectionOpening::ReplaceOpening()
{
PickSet ssOpening(SS_FREE);
RBList rbMask(RTDXF0, _T("INSERT,TCH_BLOCK_INSERT"), 8,LAY_S_WIN, NULL);
const TCHAR *szPrompts[2]={_T("\n请选择所需替换的剖面门窗<退出>:"), _T("")};
int nRet = ssOpening.Get(_T(":$"), szPrompts, NULL, rbMask);
if (nRet != RTNORM)
return FALSE;
AcDbObjectIdArray eIds;
ssOpening.AsIdArray(eIds);
ssOpening.Free();
long nLen = eIds.length();
for(long i=0; i<nLen; i++)
ReplaceBlock(g_sSectWinBlock, eIds[i]);
return TRUE;
}
//根据相对高度来改窗台高、窗高不变,同时调整墙线...
BOOL CSectionOpening::ModifySillHigh()
{
PickSet ss(SS_FREE);
RBList rbMask(RTDXF0, _T("INSERT,TCH_BLOCK_INSERT"), 8,LAY_S_WIN, NULL);
const TCHAR *szPrompts[2] = {_T("\n请选择剖面门窗<退出>:"), _T("")};
if (ss.Get(_T(":$"), szPrompts, NULL, rbMask) != RTNORM)
return FALSE;
long lCount = ss.Length();
if (lCount <= 0)
return FALSE;
XPoint ptBase;
double angle = 0.0;
OPENOBJ_BEGIN(ss[(long)0], AcDb::kForRead, AcDbBlockReference, pRef);
if (pRef == NULL)
return FALSE;
ptBase = Wcs2Ucs(pRef->position());
angle = pRef->rotation();
OPENOBJ_END();
double dLength = 0.0;
int nRet;
INITGET_BEG(0, _T("S"));
nRet = acedGetReal(_T("\n请输入窗台相对高度或 [点取窗台位置(S)]<退出>:"), &dLength);
INITGET_END();
if (nRet == RTNORM)
{
}
else if (nRet == RTKWORD)
{
XPoint ptTo;
XPushVar<int> osmode(_T("OSMODE"), 0);
acedInitGet(RSG_2D|RSG_DASH, NULL);
if (acedGetPoint(ptBase, _T("\n请点取窗台位置<退出>:"), ptTo) != RTNORM)
return FALSE;
dLength = ptBase.Distance2d(ptTo);
if (ptBase.y > ptTo.y)
dLength = -dLength;
}
else
{
return FALSE;
}
for(long i=0; i<lCount; i++)
{
OPENOBJ_BEGIN(ss[i], AcDb::kForRead, AcDbBlockReference, pRef);
if (pRef == NULL)
continue;
XPointList points;
GetVailidPoints(pRef, points, TRUE);
AcGeVector3d vec(0, dLength, 0);
vec.rotateBy(pRef->rotation(), AcGeVector3d::kZAxis);
if (ChangeWallLine(vec, points))
{
if (pRef->upgradeOpen() == Acad::eOk)
pRef->setPosition(pRef->position() + vec);
}
else
{
pRef->close();
return FALSE;
}
OPENOBJ_END();
}
return TRUE;
}
//改窗高,窗台高不变,同时调整墙线...
BOOL CSectionOpening::ModifyWindowHigh()
{
PickSet ss(SS_FREE);
RBList rbMask(RTDXF0, _T("INSERT,TCH_BLOCK_INSERT"), 8,LAY_S_WIN, NULL);
const TCHAR *szPrompts[2] = {_T("\n请选择剖面门窗<退出>:"), _T("")};
int nRet = ss.Get(_T(":$"), szPrompts, NULL, rbMask);
if (nRet != RTNORM)
return FALSE;
long lCount = ss.Length();
if (lCount <= 0)
return FALSE;
double dLength = 0.0;
OPENOBJ_BEGIN(ss[(long)0], AcDb::kForRead, AcDbBlockReference, pRef);
if (pRef != NULL)
{
XPoint ptBase = Wcs2Ucs(pRef->position());
XPushVar<int> osmode(_T("OSMODE"), 0);
acedInitGet(RSG_2D|RSG_DASH, NULL);
if (acedGetDist(ptBase, _T("\n请指定门窗高度<退出>:"), &dLength) != RTNORM)
{
pRef->close();
return FALSE;
}
if (dLength < 0)
dLength = -dLength;
}
OPENOBJ_END();
for(long i=0; i<lCount; i++)
{
OPENOBJ_BEGIN(ss[i], AcDb::kForRead, AcDbBlockReference, pRef);
if (pRef == NULL)
continue;
XPointList points;
GetVailidPoints(pRef, points, FALSE);
XPoint ptMax;
GetBlcCtrlPoint(pRef->blockTableRecord(), ptMax);
AcGeScale3d scale = pRef->scaleFactors();
AcGeVector3d vec(0, dLength - scale.sy * ptMax.y, 0);
vec.rotateBy(pRef->rotation(), AcGeVector3d::kZAxis);
if (ChangeWallLine(vec, points))
{
scale.sy = dLength / ptMax.y;
if (pRef->upgradeOpen() == Acad::eOk)
pRef->setScaleFactors(scale);
}
else
{
pRef->close();
return FALSE;
}
OPENOBJ_END();
}
return TRUE;
}
void CSectionOpening::GetVailidPoints(const AcDbBlockReference *pRef, XPointList &points, BOOL bFlag)
{
XPoint ptMax;
GetBlcCtrlPoint(pRef->blockTableRecord(), ptMax);
AcGeScale3d scale = pRef->scaleFactors();
double width = ptMax.x * scale.sx;
double high = ptMax.y * scale.sy;
AcGePoint3d ptBase = pRef->position();
AcGePoint3d ptLowLeft, ptLowRight, ptUpRight, ptUpLeft;
if (bFlag)
{
ptLowLeft.x = ptBase.x;
ptLowLeft.y = ptBase.y;
ptLowRight.x = ptLowLeft.x + width;
ptLowRight.y = ptLowLeft.y;
ptUpRight.x = ptLowRight.x;
ptUpRight.y = ptLowRight.y + high;
ptUpLeft.x = ptLowLeft.x;
ptUpLeft.y = ptLowLeft.y + high;
}
else
{
ptLowLeft.x = ptBase.x;
ptLowLeft.y = ptBase.y + high;
ptLowRight.x = ptLowLeft.x + width;
ptLowRight.y = ptLowLeft.y;
ptUpRight.x = ptLowRight.x;
ptUpRight.y = ptLowRight.y + _DIST_SNAP;
ptUpLeft.x = ptLowLeft.x;
ptUpLeft.y = ptLowLeft.y + _DIST_SNAP;
}
double angle = pRef->rotation();
ptLowLeft.rotateBy(angle, AcGeVector3d::kZAxis, ptBase);
ptLowRight.rotateBy(angle, AcGeVector3d::kZAxis, ptBase);
ptUpRight.rotateBy(angle, AcGeVector3d::kZAxis, ptBase);
ptUpLeft.rotateBy(angle, AcGeVector3d::kZAxis, ptBase);
points.Append(new XPoint(ptLowLeft));
points.Append(new XPoint(ptLowRight));
points.Append(new XPoint(ptUpRight));
points.Append(new XPoint(ptUpLeft));
}
BOOL CSectionOpening::ChangeWallLine(const AcGeVector3d &vec, XPointList &points)
{
if (points.Length() < 4)
return FALSE;
XPoly2D poly;
points.AsPoly2D(poly);
poly.TransUCS(Groups(0), Groups(1));
RBList rbFence = poly.Polygon();
RBList rbMask(RTDXF0, _T("LINE"), 8, LAY_S_LINE, NULL);
PickSet ss(SS_FREE);
if (ss.Get(_T("CP"), rbFence, NULL, rbMask) != RTNORM)
return FALSE;
long i, j;
long lCount = ss.Length();
//for(i=0; i<lCount; i++)
//{
// OPENOBJ_BEGIN(ss[i], AcDb::kForRead, AcDbLine, pLine);
// if (pLine != NULL)
// {
// AcGeVector3d vLine = pLine->endPoint() - pLine->startPoint();
// double angle = vec.angleTo(vLine);
// if (angle < 1E-6 || fabs(angle - PI) < 1E-6)
// {
// if (vec.length() > vLine.length())
// {
// acutPrintf(_T("\n不能继续,门窗超出墙体范围!"));
// return FALSE;
// }
// }
// }
// OPENOBJ_END();
//}
for(i=0; i<lCount; i++)
{
OPENOBJ_BEGIN(ss[i], AcDb::kForWrite, AcDbLine, pLine);
if (pLine == NULL)
continue;
for(j=0; j<4; j++)
{
double disSta = points[j]->Distance2d(pLine->startPoint());
if (disSta < _DIST_SNAP)
{
pLine->setStartPoint(pLine->startPoint() + vec);
break;
}
}
for(j=0; j<4; j++)
{
double disEnd = points[j]->Distance2d(pLine->endPoint());
if (disEnd < _DIST_SNAP)
{
pLine->setEndPoint(pLine->endPoint() + vec);
break;
}
}
OPENOBJ_END();
}
return TRUE;
}
// 找到另一条墙线,得到宽度
BOOL CSectionOpening::GetHoleWidth(double &width, Entity &sectWall2, const Entity &sectWall1, const XPoint &ptres)
{
XLine line1(sectWall1, LS_FINITE);
XPoint pt1;
ptres.Project(&line1, pt1);
AcGeVector3d vec1 = line1.EndPoint().AsAcGePoint3d() - line1.StartPoint().AsAcGePoint3d();
double dSpace = 500;
double dStep = 500;
double dSpaceMax = 1000;
XPoint ptLow(Wcs2Ucs(pt1));
XPoint ptUp(Wcs2Ucs(pt1));
while(1)
{
ptLow.x -= dSpace;
ptLow.y -= dSpace;
ptUp.x += dSpace;
ptUp.y += dSpace;
PickSet ss(SS_FREE);
if (ss.Get(_T("C"), ptLow, ptUp, RBList(RTDXF0, _T("LINE"), 8, LAY_S_LINE, NULL)) != RTNORM)
break;
ss -= sectWall1;
double dMinDist = 0.0;
long nLen = ss.Length();
for(long i=0; i<nLen; i++)
{
Entity ent = ss[i];
XLine line2(ent, LS_FINITE);
double dDist = pt1.Distance(&line2);
AcGeVector3d vec2 = line1.EndPoint().AsAcGePoint3d() - line1.StartPoint().AsAcGePoint3d();
double angleTo = vec1.angleTo(vec2);
if (dDist > dMinDist && (angleTo < 1E-6 || fabs(angleTo-PI) < 1E-6))
{
dMinDist = dDist;
sectWall2 = ent;
}
}
if (dMinDist > 1E-6)
{
width = dMinDist;
break;
}
dSpace += dStep;
if (dSpace > dSpaceMax)
break;
}
return (width < 1E-6) ? FALSE : TRUE;
}
// 得到高度
BOOL CSectionOpening::GetHoleHigh(double &high, XPoint &ptIns, AcGeVector3d &vhole, const XPoint &ptres, const Entity &entName)
{
AcGePoint3d ptBase;
AcGeVector3d vLine;
XLine lnSel(entName, LS_FINITE);
AcGePoint3d ptStart = lnSel.StartPoint();
AcGePoint3d ptEnd = lnSel.EndPoint();
if (ptres.Distance2d(ptStart) < ptres.Distance2d(ptEnd))
{
ptBase = ptStart;
vLine = ptEnd - ptStart;
}
else
{
ptBase = ptEnd;
vLine = ptStart - ptEnd;
}
vLine.normalize();
static double s_winDis = 900;
TCHAR szPromptDis[256];
_stprintf(szPromptDis, _T("\n门窗下口到墙下端距离<%s>:"), Dist2Str(s_winDis));
acedInitGet(RSG_2D|RSG_DASH, NULL);
int nRetDis = acedGetDist(Wcs2Ucs(ptBase), szPromptDis, &s_winDis);
if (nRetDis == RTNORM || nRetDis == RTNONE)
{
//modify by xlc on 070508 0的绝对值显示为-0
//s_winDis = fabs(s_winDis);
if (s_winDis < 0.0)
s_winDis = -s_winDis;
ptIns = ptBase + vLine * s_winDis;
}
else
{
return FALSE;
}
static double s_winHigh = 1500.0;
TCHAR szPromptHigh[256];
while(TRUE)//add by xlc on 070509
{
_stprintf(szPromptHigh, _T("\n门窗的高度<%s>:"), Dist2Str(s_winHigh));
acedInitGet(RSG_2D|RSG_DASH, NULL);
//add by xlc on 070509 记录上次的高度
double winHigh = s_winHigh;
int nRet = acedGetDist(Wcs2Ucs(ptIns), szPromptHigh, &s_winHigh);
if (nRet == RTNORM || nRet == RTNONE)
{
//modify by xlc on 070509 0的绝对值显示为-0
//s_winHigh = fabs(s_winHigh);
if (s_winHigh < 0.0)
s_winHigh = -s_winHigh;
//add by xlc on 070509 门窗高度不能为0
if (s_winHigh < 1e-6)
{
acutPrintf(_T("\n门窗高度不能为0"));
s_winHigh = winHigh;
continue;
}
acutPrintf(_T("%.0f"), s_winHigh);
vhole = vLine * s_winHigh;
high = s_winHigh;
//add by xlc on 070509
break;
}
else
{
return FALSE;
}
}
return TRUE;
}
BOOL CSectionOpening::InsertBlock(const XPoint &ptIns, const double &width, const double &high, const double &angle,
const XString &sBlockName)
{
InitLayer(LAY_S_WIN, TRUE);
XPushVarStr clayer(_T("CLAYER"), LAY_S_WIN);
XString sBlock(256);
if (LoadDwbBlock(sBlockName, sBlock)!=RTNORM)
return FALSE;
AcDbObjectId BlockId = InitBlock(sBlock);
XPoint ptNewMax;
if (!GetBlcCtrlPoint(BlockId, ptNewMax))
return FALSE;
double xFact = width / ptNewMax.x;
double yFact = high / ptNewMax.y;
double zFact = 1;
AcGeScale3d scale(xFact, yFact, zFact);
AcDbBlockReference *pBlockRef = new AcDbBlockReference();
pBlockRef->setBlockTableRecord(BlockId);
pBlockRef->setPosition(ptIns);
pBlockRef->setRotation(angle);
pBlockRef->setScaleFactors(scale);
AddToModelSpace(pBlockRef, Adesk::kTrue);
return TRUE;
}
void CSectionOpening::GetInsertPoint(XPoint &ptIns, const AcGeVector3d &vhole, const Entity &sectWall2)
{
XPoint ptOther;
XLine lnWall(sectWall2, LS_FINITE);
ptIns.Project(&lnWall, ptOther);
AcGeVector3d vec = ptOther.AsAcGePoint3d() - ptIns.AsAcGePoint3d();
AcGeVector3d vRotate = vhole;
vRotate.rotateBy(PI/2, AcGeVector3d::kZAxis);
double angle = vec.angleTo(vRotate);
if (angle < 1E-3)
ptIns = ptOther;
}
BOOL CSectionOpening::ReplaceBlock(const XString &sBlockName, AcDbObjectId &idOld)
{
InitLayer(LAY_S_WIN, TRUE);
XPushVarStr clayer(_T("CLAYER"), LAY_S_WIN);
XString sBlock(256);
if (LoadDwbBlock(sBlockName, sBlock)!=RTNORM)
return FALSE;
AcDbObjectId idNew = InitBlock(sBlock);
OPENOBJ_BEGIN(idOld, AcDb::kForWrite, AcDbBlockReference, pRef);
if (pRef != NULL)
{
XPoint ptOldMax, ptNewMax;
if (!GetBlcCtrlPoint(pRef->blockTableRecord(), ptOldMax))
{
pRef->close();
return FALSE;
}
if (!GetBlcCtrlPoint(idNew, ptNewMax))
{
pRef->close();
return FALSE;
}
double xFact = ptOldMax.x / ptNewMax.x;
double yFact = ptOldMax.y / ptNewMax.y;
AcGeScale3d scale = pRef->scaleFactors();
scale.sx *= xFact;
scale.sy *= yFact;
pRef->setBlockTableRecord(idNew);
pRef->setScaleFactors(scale);
}
OPENOBJ_END();
return TRUE;
}
BOOL CSectionOpening::ComparePoint(const Entity &sectWall1, const Entity &sectWall2
, const XPoint &ptIns, const AcGeVector3d &vhole)
{
XLine line1(sectWall1, LS_FINITE);
XLine line2(sectWall2, LS_FINITE);
AcGeVector3d vStart1 = line1.StartPoint().AsAcGePoint3d() - ptIns.AsAcGePoint3d();
AcGeVector3d vEnd1 = line1.EndPoint().AsAcGePoint3d()- ptIns.AsAcGePoint3d();
AcGeVector3d vStart2 = line2.StartPoint().AsAcGePoint3d() - ptIns.AsAcGePoint3d();
AcGeVector3d vEnd2 = line2.EndPoint().AsAcGePoint3d() - ptIns.AsAcGePoint3d();
double lenHole = vhole.length();
//modify by xlc on 070508
//if (vhole.angleTo(vStart1) < 1E-3 && lenHole > vStart1.length())
// return FALSE;
//if (vhole.angleTo(vEnd1) < 1E-3 && lenHole > vEnd1.length())
// return FALSE;
//if (vhole.angleTo(vStart2) < 1E-3 && lenHole > vStart2.length())
// return FALSE;
//if (vhole.angleTo(vEnd2) < 1E-3 && lenHole > vEnd2.length())
// return FALSE;
if ((vStart1.isZeroLength()&&vEnd1.isZeroLength())
||(vStart2.isZeroLength()&&vEnd2.isZeroLength()))//门窗两端都存在0向量
return TRUE;
if (vStart1.isZeroLength())//门窗起始端存在0向量
{
if (vhole.angleTo(vStart1) < 1E-3 && lenHole > vEnd1.length())
return FALSE;
}
else
{
if (vhole.angleTo(vStart1) < 1E-3 && lenHole > vStart1.length())
return FALSE;
}
if (vEnd1.isZeroLength())//门窗终端存在0向量
{
if (vhole.angleTo(vEnd1) < 1E-3 && lenHole > vStart1.length())
return FALSE;
}
else
{
if (vhole.angleTo(vEnd1) < 1E-3 && lenHole > vEnd1.length())
return FALSE;
}
if (vStart2.isZeroLength())//门窗起始端存在0向量
{
if (vhole.angleTo(vStart2) < 1E-3 && lenHole > vEnd2.length())
return FALSE;
}
else
{
if (vhole.angleTo(vStart2) < 1E-3 && lenHole > vStart2.length())
return FALSE;
}
if (vEnd2.isZeroLength())//门窗终端存在0向量
{
if (vhole.angleTo(vEnd2) < 1E-3 && lenHole > vStart2.length())
return FALSE;
}
else
{
if (vhole.angleTo(vEnd2) < 1E-3 && lenHole > vEnd2.length())
return FALSE;
}
return TRUE;
}
void CSectionOpening::BreakWall(Entity &sectWall1, Entity &sectWall2
, const XPoint &ptIns, const AcGeVector3d &vhole)
{
XPoint ptFirst = ptIns;
XPoint ptSecond = ptIns + vhole;
Entity sect1 = sectWall1;
Entity sect2 = sectWall2;
XLine line1(sect1, LS_FINITE);
XLine line2(sect2, LS_FINITE);
XPoint pt1Start = line1.StartPoint();
XPoint pt1End = line1.EndPoint();
XPoint pt2Start = line2.StartPoint();
XPoint pt2End = line2.EndPoint();
sect1.Erase();
sect2.Erase();
BOOL bFlag = FALSE;
double angle = acutAngle(ptFirst, ptSecond);
double angle1 = acutAngle(pt1Start, pt1End);
double angle2 = acutAngle(pt2Start, pt2End);
if (fabs(angle1 - angle) > 1E-3)
{
XPoint ptTemp = ptFirst;
ptFirst = ptSecond;
ptSecond = ptTemp;
bFlag = TRUE;
}
angle = acutAngle(ptFirst, ptSecond);
if (fabs(angle2 - angle) > 1E-3)
{
XPoint ptTemp = pt2Start;
pt2Start = pt2End;
pt2End = ptTemp;
}
XPoint ptFirst1, ptFirst2;
XPoint ptSecond1, ptSecond2;
ptFirst.Project(&line1, ptFirst1);
ptFirst.Project(&line2, ptFirst2);
ptSecond.Project(&line1, ptSecond1);
ptSecond.Project(&line2, ptSecond2);
XLine lnSta1(pt1Start, ptFirst1);
XLine lnSta2(ptFirst1, ptFirst2);
XLine lnSta3(pt2Start, ptFirst2);
XLine lnEnd1(ptSecond1, pt1End);
XLine lnEnd2(ptSecond1, ptSecond2);
XLine lnEnd3(ptSecond2, pt2End);
XPushVarStr clayer(_T("CLAYER"), LAY_S_LINE);
lnSta2.Make();
lnEnd2.Make();
PickSet ss(SS_FREE);
if (!bFlag)
{
lnSta1.Make();
lnSta3.Make();
ss.IncludeBegin();
lnEnd1.Make();
lnEnd3.Make();
ss.IncludeEnd();
}
else
{
lnEnd1.Make();
lnEnd3.Make();
ss.IncludeBegin();
lnSta1.Make();
lnSta3.Make();
ss.IncludeEnd();
}
if (ss.Length() > 1)
{
sectWall1 = ss[(long)0];
sectWall2 = ss[(long)1];
}
}
IMPLEMENT_DYNAMIC(CSectionOpening,CModelessDialog)
// 打开图库
BOOL CSectionOpening::SelectOpening(XString &sBlockName)
{
XString sLibFile, sBlock(256);
sLibFile << g_sDwbPath << _T("EWDLib.TKW");
return InvokeTkwMan(sLibFile, TRUE, sBlockName);
}
// 预览图
void CSectionOpening::UpdateImage()
{
CWnd *pImageBox = GetDlgItem(IDC_SLIDE);
ASSERT(pImageBox);
CRect rect;
pImageBox->GetClientRect(rect);
CDC *pDC = pImageBox->GetDC();
m_image.InitDC(pDC, rect, GetAcadBackColor());
XString sFullSlide(256);
sFullSlide << g_sDwbPath << g_sSectWinBlock;
m_image.PaintSlide(sFullSlide);
m_image.SetDC(NULL);
pImageBox->ReleaseDC(pDC);
}
void CSectionOpening::OnStnClickedSlide()
{
SelectOpening(g_sSectWinBlock);
UpdateImage();
}
void CSectionOpening::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: 在此添加消息处理程序代码
// 不为绘图消息调用 CModelessDialog::OnPaint()
CWnd *pImageBox = GetDlgItem(IDC_SLIDE);
ASSERT(pImageBox);
CDC *pDC = pImageBox->GetDC();
m_image.SetDC(pDC);
m_image.Redraw();
m_image.SetDC(NULL);
pImageBox->ReleaseDC(pDC);
}
BOOL CSectionOpening::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CWnd *pImageBox = GetDlgItem(IDC_SLIDE);
if (pWnd && pWnd->m_hWnd == pImageBox->m_hWnd) {
CAcModuleResourceOverride vTemp;
HCURSOR hIcon = AfxGetApp()->LoadCursor( IDC_CUR_PICK );
SetCursor( hIcon );
return TRUE;
}
return CModelessDialog::OnSetCursor(pWnd, nHitTest, message);
}