972 lines
25 KiB
C++
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 §Wall1, 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 §Wall2, const Entity §Wall1, const XPoint &ptres);
|
|
BOOL GetHoleHigh(double &high, XPoint &ptIns, AcGeVector3d &vhole, const XPoint &ptres, const Entity &entName);
|
|
BOOL ComparePoint(const Entity §Wall1, const Entity §Wall2, const XPoint &ptIns, const AcGeVector3d &vhole);
|
|
void BreakWall(Entity §Wall1, Entity §Wall2, const XPoint &ptIns, const AcGeVector3d &vhole);
|
|
|
|
void GetInsertPoint(XPoint &ptIns, const AcGeVector3d &vhole, const Entity §Wall2);
|
|
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 §Wall1, 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 §Wall2, const Entity §Wall1, 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 §Wall2)
|
|
{
|
|
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 §Wall1, const Entity §Wall2
|
|
, 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 §Wall1, Entity §Wall2
|
|
, 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);
|
|
}
|