Files
envi-code/SourceCode/Code2026/tg_shs/shs_kerncmd/SanShuiDlg.cpp
T
2026-09-28 15:28:50 +08:00

1204 lines
31 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 "SanShuiDlg.h"
#include "InputPoly.h"
extern void MakeWallSet(PickSet &ssWalls);
int CSanShuiDlg::s_nMode = 0;
CSanShuiDlg::CSanShuiDlg(CWnd* pParent)
: CModelessDialog(CSanShuiDlg::IDD, pParent)
, m_bCheck(TRUE), m_dDiff(0), m_dOffset(0), m_dWidth(600), m_bRoudWallPatch(TRUE), m_bUseEsc(TRUE)
{
// add by xly on 110114,散水对话框工具条按钮
m_tbButtom[0].tbID = ID_SANSHUI_SEARCHAUTO;
m_tbButtom[0].BitmapID = 0;
m_tbButtom[0].Style = TBSTYLE_CHECKGROUP;
m_tbButtom[1].tbID = ID_SANSHUI_ANYDRAW;
m_tbButtom[1].BitmapID = 1;
m_tbButtom[1].Style = TBSTYLE_CHECKGROUP;
m_tbButtom[2].tbID = ID_SANSHUI_FIXPATH;
m_tbButtom[2].BitmapID = 2;
m_tbButtom[2].Style = TBSTYLE_CHECKGROUP;
}
void CSanShuiDlg::DoDataExchange(CDataExchange* pDX)
{
CModelessDialog::DoDataExchange(pDX);
DDX_Check(pDX, IDC_CHECK_CREATESLAB, m_bCheck);
DDX_Text(pDX, IDC_EDIT_DIFF, m_dDiff);
DDX_Text(pDX, IDC_EDIT_OFFSET, m_dOffset);
DDX_Text(pDX, IDC_EDIT_WIDTH, m_dWidth);
DDX_Check(pDX, IDC_CHECK_ROUNDCOLU, m_bRoundColu);
DDX_Check(pDX, IDC_CHECK_ROUNDBALCONY, m_bRoundBalcony);
DDX_Check(pDX, IDC_CHK_ROUNDWALLPATCH, m_bRoudWallPatch);
if (!pDX->m_bSaveAndValidate)
{
m_toolbar.CheckButton(ID_SANSHUI_SEARCHAUTO, s_nMode==0);
m_toolbar.CheckButton(ID_SANSHUI_ANYDRAW, s_nMode==1);
m_toolbar.CheckButton(ID_SANSHUI_FIXPATH, s_nMode==2);
}
}
BEGIN_MESSAGE_MAP(CSanShuiDlg, CModelessDialog)
ON_COMMAND(ID_SANSHUI_SEARCHAUTO, OnToolButAuto)
ON_COMMAND(ID_SANSHUI_ANYDRAW, OnToolButAny)
ON_COMMAND(ID_SANSHUI_FIXPATH, OnToolButFixPath)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText)
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText)
ON_EN_KILLFOCUS(IDC_EDIT_WIDTH, OnKillFocusWidth)
ON_EN_KILLFOCUS(IDC_EDIT_DIFF, OnKillFocusDiff)
ON_EN_KILLFOCUS(IDC_EDIT_OFFSET, OnKillFocusOffSet)
END_MESSAGE_MAP()
BOOL CSanShuiDlg::OnInitDialog()
{
CModelessDialog::OnInitDialog();
CAcModuleResourceOverride vTmp;
m_toolbar.Create( WS_VISIBLE | WS_CHILD |CCS_BOTTOM| TBSTYLE_TOOLTIPS
| CCS_ADJUSTABLE ,CRect(0,0,0,0),this, IDR_TOOLBAR_SANSHUI);
TBBUTTON *pIndex,
*pRTF_Button = new TBBUTTON[3];
pIndex = pRTF_Button;
for (long lIndex = 0; lIndex < 3; lIndex++)
{
memset(pIndex ,NULL, sizeof(TBBUTTON));
pIndex->iBitmap = m_tbButtom[lIndex].BitmapID;
pIndex->idCommand = m_tbButtom[lIndex].tbID;
pIndex->fsStyle = m_tbButtom[lIndex].Style;
pIndex->fsState = TBSTATE_ENABLED;
pIndex++;
}
CSize size(16, 15);
m_toolbar.SetButtonSize(size);
m_toolbar.AddButtons(3, pRTF_Button);
delete[] pRTF_Button;
m_toolbar.AddBitmap(3, IDR_TOOLBAR_SANSHUI);
m_toolbar.AutoSize();
m_wndToolTip.Create(this);
m_wndToolTip.Activate(true);
// add by xly on 11o120 设置控件的显示与灰显
SetItemEnable(s_nMode==0);
UpdateData(FALSE);
return TRUE;
}
// add by xly on 11o120 设置控件的显示与灰显
void CSanShuiDlg::SetItemEnable(BOOL bEnable)
{
GetDlgItem(IDC_CHECK_ROUNDCOLU)->EnableWindow(bEnable);
GetDlgItem(IDC_CHK_ROUNDWALLPATCH)->EnableWindow(bEnable);
GetDlgItem(IDC_CHECK_ROUNDBALCONY)->EnableWindow(bEnable);
}
// 搜索自动生成
void CSanShuiDlg::OnToolButAuto()
{
if (s_nMode == 0)
return;
UpdateData(TRUE);
s_nMode = 0;
SetItemEnable(TRUE);
UpdateData(FALSE);
m_bUseEsc = FALSE;
acedPostCommand(_T("\33"));
}
// 任意绘制
void CSanShuiDlg::OnToolButAny()
{
if (s_nMode == 1)
return;
UpdateData(TRUE);
s_nMode = 1;
SetItemEnable(FALSE);
UpdateData(FALSE);
m_bUseEsc = FALSE;
acedPostCommand(_T("\33"));
}
// 按已有固定路径生成
void CSanShuiDlg::OnToolButFixPath()
{
if (s_nMode == 2)
return;
UpdateData(TRUE);
s_nMode = 2;
SetItemEnable(FALSE);
UpdateData(FALSE);
m_bUseEsc = FALSE;
acedPostCommand(_T("\33"));
}
// 工具栏提示
BOOL CSanShuiDlg::OnToolTipText( UINT, NMHDR * pNMHDR, LRESULT * pResult )
{
ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
if (GetRoutingFrame() != NULL)
return FALSE;
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
CString strTipText;
UINT nID = (UINT)pNMHDR->idFrom;
if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
{
return FALSE;
}
if (nID != 0)
{
{
CAcModuleResourceOverride vTmp;
strTipText.LoadString(nID);
}
#ifndef _UNICODE
if (pNMHDR->code == TTN_NEEDTEXTA)
{
lstrcpyn(pTTTA->szText, strTipText, sizeof(pTTTA->szText));
}
else
{
_mbstowcsz(pTTTW->szText, strTipText, sizeof(pTTTW->szText));
}
#else
if (pNMHDR->code == TTN_NEEDTEXTA)
{
_wcstombsz(pTTTA->szText, strTipText,sizeof(pTTTA->szText));
}
else
{
lstrcpyn(pTTTW->szText, strTipText, sizeof(pTTTW->szText));
}
#endif
*pResult = 0;
::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,SWP_NOACTIVATE|
SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER); return TRUE;
}
return TRUE;
}
// add by xly on 110126 散水宽度失去焦点时编辑框的内容的判断
void CSanShuiDlg::OnKillFocusWidth()
{
UpdateData(TRUE);
UpdateData(FALSE);
}
// add by xly on 110126 散水室内外高度差失去焦点时编辑框的内容的判断
void CSanShuiDlg::OnKillFocusDiff()
{
UpdateData(TRUE);
UpdateData(FALSE);
}
// add by xly on 110126 散水偏移距离失去焦点时编辑框的内容的判断
void CSanShuiDlg::OnKillFocusOffSet()
{
UpdateData(TRUE);
UpdateData(FALSE);
}
// add by xly on 110114 任意绘制散水的jig
// 函数说明:ptStart任意散水的起点;poly2dRet绘制散水的路径包括偏移;pApron:散水对象;
// dOff:偏移墙皮距离;dDist:散水宽度
int DragInputPolySanShui(XPoint ptStart, XPoly2D &poly2dRet, TDbApron *pApron, double dOff, double dDist)
{
// 写打开散水对象
TDbApron *pEnt= NULL;
if(acdbOpenObject(pEnt,pApron->objectId(), AcDb::kForRead)!=Acad::eOk)
{
return RTERROR;
}
// 拖动绘制的多段线
AcDbPolyline pline;
pline.addVertexAt(0, ptStart);
TPolyEdJig2 jig(&pline);
CAcModuleResourceOverride resOverride(acedGetAcadResourceInstance());
// 设置jig的提示
jig.SetPrompt(_T("\n下一点或[弧段(A)]<退出>: "));
jig.SetOperCode(TPolyEdJig2::kLinePoint);
jig.SetKeyword(_T("A"));
int nKeyIndex=-1;
int nRetCode(0);
XPoly2D poly,
polyTemp;
// 第2点的生成
while(1)
{
nRetCode = jig.DoIt(&nKeyIndex);
if (nRetCode==RTNORM)// 点取成功
{
pline.addVertexAt(pline.numVerts(), (AcGePoint2d &)jig.GetPickPoint());
if (jig.GetOperCode() == TPolyEdJig2::kArcPoint)
{
TPolyEdJig2 jig1(&pline);
jig1.SetOperCode(TPolyEdJig2::kArcMidPoint);
jig1.SetPrompt(_T("\n点取弧上任意一点<取消>:"));
if(jig1.DoIt()==RTCAN)// 取消操作
{
break;
}
// 更新散水实体
PolyConvert(pline, poly);
poly.Offset(dOff, polyTemp);
if(pApron->upgradeOpen()==Acad::eOk)
{
pApron->SetPathPoly(polyTemp,pApron->GetNormal());
pApron->SetAllDists(dDist);
pApron->downgradeOpen();
}
jig.SetPrompt(_T("\n弧段终点或 [直段(L)/回退(U)]<退出>:"));
jig.SetOperCode(TPolyEdJig2::kArcPoint);
jig.SetKeyword(_T("L U"));
}
else
{
// 更新散水实体
PolyConvert(pline, poly);
poly.Offset(dOff, polyTemp);
if(pApron->upgradeOpen()==Acad::eOk)
{
pApron->SetPathPoly(polyTemp,pApron->GetNormal());
pApron->SetAllDists(dDist);
pApron->downgradeOpen();
}
jig.SetPrompt(_T("\n下一点或 [弧段(A)/回退(U)]<退出>: "));
jig.SetOperCode(TPolyEdJig2::kLinePoint);
jig.SetKeyword(_T("A U"));
}
break;
}
else if (nRetCode==RTKWORD) // 输入关键字
{
if (nKeyIndex==0) // 切换到圆弧
{
if (jig.GetOperCode() == TPolyEdJig2::kArcPoint)
{
jig.SetPrompt(_T("\n下一点或[弧段(A)]<退出>: "));
jig.SetOperCode(TPolyEdJig2::kLinePoint);
jig.SetKeyword(_T("A"));
}
else // 切换到直线
{
jig.SetOperCode(TPolyEdJig2::kArcPoint);
jig.SetPrompt(_T("\n弧段终点或[直段(L)]<退出>:"));
jig.SetKeyword(_T("L"));
}
}
}
else
{
return RTERROR;
}
}
// 绘制过程中反复提示
while(1) // 循环提示
{
nRetCode=jig.DoIt(&nKeyIndex);
if (nRetCode==RTNORM)// 点取点
{
// 更新多段线
pline.addVertexAt(pline.numVerts(), (AcGePoint2d &)jig.GetPickPoint());
// 绘制的是圆弧
if (jig.GetOperCode()==TPolyEdJig2::kArcPoint)
{
TPolyEdJig2 jig1(&pline);
jig1.SetOperCode(TPolyEdJig2::kArcMidPoint);
jig1.SetPrompt(_T("\n点取弧上任意一点<取消>:"));
if(jig1.DoIt()==RTCAN)// 如果取消操作
{
break;
}
// 更新散水实体
PolyConvert(pline, poly);
poly.Offset(dOff, polyTemp);
if(pApron->upgradeOpen()==Acad::eOk)
{
pApron->SetPathPoly(polyTemp,pApron->GetNormal());
pApron->SetAllDists(dDist);
pApron->downgradeOpen();
}
// 更新提示
jig.SetPrompt(_T("\n弧段终点或 [直段(L)/回退(U)/闭合(C)]<退出>: "));
jig.SetOperCode(TPolyEdJig2::kArcPoint);
jig.SetKeyword(_T("L U C"));
}
else// 绘制直线
{
// 更新散水实体
PolyConvert(pline, poly);
poly.Offset(dOff, polyTemp);
if(pApron->upgradeOpen()==Acad::eOk)
{
pApron->SetPathPoly(polyTemp,pApron->GetNormal());
pApron->SetAllDists(dDist);
pApron->downgradeOpen();
}
// 更新提示
jig.SetPrompt(_T("\n下一点或 [弧段(A)/回退(U)/闭合(C)]<退出>: "));
jig.SetOperCode(TPolyEdJig2::kLinePoint);
jig.SetKeyword(_T("A U C"));
}
}
else if (nRetCode==RTKWORD) // 输入关键字
{
// 绘制直线
if (jig.GetOperCode()==TPolyEdJig2::kLinePoint)
{
if (nKeyIndex==0) // 关键字1
{
jig.SetOperCode(TPolyEdJig2::kArcPoint);
jig.SetPrompt(_T("\n弧段终点或 [直段(L)/回退(U)/闭合(C)]<退出>: "));
jig.SetKeyword(_T("L U C"));
}
else if (nKeyIndex==1) // 关键字2 回退
{
int numVert=pline.numVerts();
if (numVert>1)
{
pline.removeVertexAt(numVert-1);
pline.setBulgeAt(numVert-2, 0.0);
// 退回操作时更新多段线的同时,刷新散水对象
PolyConvert(pline, poly);
poly.Offset(dOff, polyTemp);
if(pApron->upgradeOpen()==Acad::eOk)
{
pApron->SetPathPoly(polyTemp,pApron->GetNormal());
pApron->SetAllDists(dDist);
pApron->downgradeOpen();
}
}
}
else if (nKeyIndex==2) // 关键字3 闭合
{
// 更新散水实体
PolyConvert(pline, poly);
poly.Offset(dOff, polyTemp);
polyTemp.SetFlag(1);
if(pApron->upgradeOpen()==Acad::eOk)
{
pApron->SetPathPoly(polyTemp,pApron->GetNormal());
pApron->SetAllDists(dDist);
pApron->downgradeOpen();
}
pEnt->close();
poly2dRet = polyTemp;
return RTERROR;
}
}
else if (jig.GetOperCode()==TPolyEdJig2::kArcPoint) // 绘制圆弧
{
if (nKeyIndex==0) // 关键字1
{
jig.SetOperCode(TPolyEdJig2::kLinePoint);
jig.SetPrompt(_T("\n下一点或 [弧段(A)/回退(U)/闭合(C)]<退出>: "));
jig.SetKeyword(_T("A U C"));
}
else if (nKeyIndex==1) // 关键字2
{
int numVert=pline.numVerts();
if (numVert>1)
{
pline.removeVertexAt(numVert-1);
pline.setBulgeAt(numVert-2, 0.0);
// 退回操作时更新多段线的同时,刷新散水对象
PolyConvert(pline, poly);
poly.Offset(dOff, polyTemp);
if(pApron->upgradeOpen()==Acad::eOk)
{
pApron->SetPathPoly(polyTemp,pApron->GetNormal());
pApron->SetAllDists(dDist);
pApron->downgradeOpen();
}
}
}
else if (nKeyIndex==2) // 关键字3闭合
{
// 更新散水实体
PolyConvert(pline, poly);
poly.Offset(dOff, polyTemp);
polyTemp.SetFlag(1);
if(pApron->upgradeOpen()==Acad::eOk)
{
pApron->SetPathPoly(polyTemp,pApron->GetNormal());
pApron->SetAllDists(dDist);
pApron->downgradeOpen();
}
pApron->close();
poly2dRet = polyTemp;
return RTERROR;
}
}
}
else if (nRetCode==RTNONE) // 点取失败
{
break;
}
else if (nRetCode==RTCAN) // 取消
{
pEnt->close();
return RTERROR;
}
}
pEnt->close();
return RTNORM;
}
// 散水绘制
void SanShui()
{
static double dSanShuiDist = 600.0;
static double dElevDiffDist = 0.0;
static BOOL bCheck = TRUE;
static BOOL bRoundColu = TRUE; // sg add 081016,记录绕柱子和绕阳台的设置
static BOOL bRoundBalcony = TRUE;
static BOOL bRoundWallWallPatch = TRUE; // add by xly on 110114,记录绕墙体造型的设置
CSanShuiDlg dlg(acedGetAcadFrame());
double nElevDiff = DocGetElevDiff();
dlg.m_bCheck = bCheck;
// dlg.m_dDiff = nElevDiff;
// dlg.m_dOffset = nElevDiffDist;
// dlg.m_dWidth = nSanShuiDist;
dlg.m_dDiff = _AS_SYS_UNIT(nElevDiff); // sg modify 080829,兼容M、MM单位
dlg.m_dOffset = _AS_SYS_UNIT(dElevDiffDist);
dlg.m_dWidth = _AS_SYS_UNIT(dSanShuiDist);
dlg.m_bRoundColu = bRoundColu; // sg add 081016,绕柱子、绕阳台
dlg.m_bRoundBalcony = bRoundBalcony;
dlg.m_bRoudWallPatch = bRoundWallWallPatch;
{
CAcModuleResourceOverride vTemp;
if ( !dlg.Create(dlg.IDD, acedGetAcadFrame()) )
return;
}
dlg.ShowWindow(SW_SHOW);
acedGetAcadDwgView()->SetFocus();
g_ssPickFirst.Free();
PickSet ssWalls(SS_FREE);
// modify by xly on 110114 增加绘制类型
/*
// sg modify 081017,改为只需要用户框选一次
// if (SelectEntities(_T("\n请选择构成一完整建筑物的所有墙体(或门窗):"), ssWalls,
// RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL,TCH_OPENING"), NULL))!=RTNORM)
if (SelectEntities(_T("\n请选择构成一完整建筑物的所有墙体(或门窗、阳台):"), ssWalls,
RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL,TCH_OPENING,TCH_BALCONY"), NULL))!=RTNORM)
{
dlg.DestroyWindow();
return;
}
*/
XPoly2D dest(0);
while(1) // 命令提示
{
int nRet = 0;
switch(dlg.s_nMode)
{
case 0: // 搜索自动生成
{
nRet = SelectEntities(_T("\n请选择构成一完整建筑物的所有墙体(或门窗、阳台)<退出>:"), ssWalls,
RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL,TCH_OPENING,TCH_BALCONY"), NULL));
if (nRet == RTCAN)
{
if (dlg.m_bUseEsc)
{
dlg.DestroyWindow();
return;
}
else
{
dlg.m_bUseEsc = TRUE;
continue;
}
}
else if (nRet == RTERROR)
{
dlg.DestroyWindow();
return;
}
// 获得对话框数据
dlg.UpdateData();
bCheck = dlg.m_bCheck;
nElevDiff = dlg.m_dDiff;
dElevDiffDist = dlg.m_dOffset;
dSanShuiDist = dlg.m_dWidth;
bRoundColu = dlg.m_bRoundColu; // sg add,081016
bRoundBalcony = dlg.m_bRoundBalcony;
bRoundWallWallPatch = dlg.m_bRoudWallPatch;
dlg.DestroyWindow();
// DocSetElevDiff(nElevDiff);
DocSetElevDiff(_AS_MM(nElevDiff)); // sg modify 080901,兼容M、MM单位
// 增加门、窗所在的墙
MakeWallSet(ssWalls);
// 找出柱子
DList<AcDbObjectId> lstColu;
GetEntFromBlockByDxf(lstColu, _T("TCH_COLUMN"));
// sg add 081017,从选择集中过滤出阳台
PickSet ssBalcony(SS_FREE);
ssBalcony += ssWalls;
ssBalcony.BaseFilter(RBList(RTDXF0, _T("TCH_BALCONY"), NULL));
ssWalls -= ssBalcony; // 只剩下墙
XSearchSpaceFromWall aSearch;
try
{
aSearch.InitStart(ssWalls, lstColu);
}
catch(...)
{
adsout << /*UMSG*/_T("\n发生例外情况!");
dlg.DestroyWindow();
dElevDiffDist = _AS_MM(dElevDiffDist); // sg modify 080901,兼容M、MM单位
dSanShuiDist = _AS_MM(dSanShuiDist);
return;
}
XAecSpaceCell *extCell = aSearch.SearchSpaces();
if (extCell != NULL)
{
aSearch.UpdateWallFlags();
XPoly2D poly(1);
// sg add 081016,根据设置,获取是否绕柱子的外墙线
int nType = dlg.m_bRoundColu?2:0;
int nPatchType = bRoundWallWallPatch?2:0;
// modify by xly,根据设置,确定外墙线是否绕墙体造型
// extCell->InternalPoly2D(poly, nType, FALSE); // 外墙线,不绕墙体造型
extCell->InternalPoly2D(poly, nType, nPatchType);
// sg add 081016,添加阳台的轮廓线
if (dlg.m_bRoundBalcony)
{
int nBalconyNum = ssBalcony.Length();
for (long i=0; i<nBalconyNum; i++)
{
// sg delete 091111,改用第一套和第三套结合的布尔运算,不需要使用以下代码
/*
// sg add 081210,解决Union的不稳定问题
DList<XCurveSegment> lstCurve;
ExplodePoly2D(poly, lstCurve); // 分解为线
*/
Entity balcony = ssBalcony[i];
OPENOBJ_BEGIN(balcony, AcDb::kForRead, TDbBalcony, pBalcony);
if (pBalcony != NULL)
{
XPoly2D polyTmp = pBalcony->GetOutline();
polyTmp.SetFlag(1); // 强制封闭
polyTmp.SetElevation(0.0);
// sg delete 091111,改用第一套和第三套结合的布尔运算,不需要使用以下代码
// ExplodePoly2D(polyTmp, lstCurve);
// sg modify 091120,恢复使用第一套布尔运算
// sg modify 081210,解决Union的不稳定问题,换用第二套布尔运算
DList<XPoly2D> lstPoly2D;
TchSubExport::Union(poly, polyTmp, lstPoly2D); // 求并集
if (lstPoly2D.Length() > 0)
{
poly = *lstPoly2D[0];
}
else // sg add 091111,不成功的时候,改用第三套布尔运算,将墙外轮廓与阳台外轮廓求布尔并集
{
lstPoly2D.Reset();
RegionBoolOper(poly, polyTmp, lstPoly2D, AcDb::kBoolUnite);
if (lstPoly2D.Length() > 0)
{
poly = *lstPoly2D[0];
}
}
// sg delete 091111,改用第一套和第三套结合的布尔运算,不需要使用以下代码
/*
XPoly2D polyOutline; // 最终union后外轮廓线
GetExternalBoundaryFromCurves(lstCurve, polyOutline);
// sg add 090526,防止生成平台有问题
double dArea = polyOutline.PathArea();
if (fabs(dArea) > 0.0)
poly = polyOutline;
*/
}
OPENOBJ_END();
}
}
// sg add 091120,减点操作,减掉角度小于5度的顶点
AutoDelExPoly2DPt(poly);
poly.SetElevation(0);
// sg add 090326,解决“在用户坐标系下散水的搜索线预览不正确”的问题
XPoly2D polyTemp(poly);
polyTemp.TransUCS(Groups(0), Groups(1));
XScreenDc dc(1,1);
// dc << poly; // sg modify 090326
dc << polyTemp;
poly.Compress();
if (poly.PathArea() > 0.0) // 顺时针的Poly
{
poly.Reverse(); // nDist = -nDist;
}
XPoly2D dest(1);
if (fabs(dElevDiffDist) < _DIST_SNAP)
{
dest = poly;
}
if (fabs(dElevDiffDist)<_DIST_SNAP || poly.Offset(dElevDiffDist, dest)==RTNORM)
{
if (dest.PathArea() > 0)
{
dest.Reverse();
}
// 生成平板对象
if (bCheck)
{
TDbSlab *pSlab = new TDbSlab;
pSlab->SetOutline(dest);
pSlab->SetThickness(-nElevDiff);
pSlab->SetVisibilityAll(FALSE);
pSlab->setLayer(InitLayer(LAY_GROUND, FALSE));
AddToModelSpace(pSlab, Adesk::kTrue);
}
// sg modify,080828
// XPoly2D polyShape(1);
// XPoint ptVert;
// polyShape.AppendNode(ptVert);
// ptVert.x += nSanShuiDist;
// polyShape.AppendNode(ptVert);
// ptVert.y += 10*_UNIT_SCALE;
// polyShape.AppendNode(ptVert);
// ptVert.x = 0;
// ptVert.y = 20*_UNIT_SCALE;
// polyShape.AppendNode(ptVert);
//
// TDbCurveMesh2 *pMesh=new TDbCurveMesh2;
// dest.SetElevation(-nElevDiff);
// pMesh->SetPathPoly(dest,pMesh->GetNormal());
// pMesh->SetShapePoly(polyShape);
// pMesh->SetShapeBase(XPoint());
// Mesh->SetHas2D(TRUE);
// pMesh->SetHasDivide2D(TRUE);
// pMesh->SetHas3D(TRUE);
// pMesh->setLayer(InitLayer(LAY_GROUND, FALSE));
// AddToModelSpace(pMesh, Adesk::kTrue);
// 散水实体
TDbApron *pApron = new TDbApron;
dest.SetElevation(-nElevDiff);
pApron->SetPathPoly(dest, pApron->GetNormal());
pApron->SetInHeight(_AS_SYS_UNIT(20));
pApron->SetOutHeight(_AS_SYS_UNIT(10));
pApron->SetAllDists(dSanShuiDist);
pApron->setLayer(InitLayer(LAY_GROUND, FALSE));
AddToModelSpace(pApron, Adesk::kTrue);
}
else
{
adsout << _T("\n给定距离不合适,不能偏移!");
}
}
else
{
adsout << _T("\n找不到外墙!");
}
// add by xly on 110126 搜索完成直接返回
dElevDiffDist = _AS_MM(dElevDiffDist); // sg modify 080901,兼容M、MM单位
dSanShuiDist = _AS_MM(dSanShuiDist);
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
return;
}
break;
case 1: // 任意绘制
{
XPoint ptStart;
nRet = ads_getpoint(NULL, _T("\n请点取散水起点<退出>:"), ptStart);
XPoly2D poly2dRet;
if (nRet == RTNORM)
{
// 获得对话框数据
dlg.UpdateData();
bCheck = dlg.m_bCheck;
nElevDiff = dlg.m_dDiff;
dElevDiffDist = dlg.m_dOffset;
dSanShuiDist = dlg.m_dWidth;
DocSetElevDiff(_AS_MM(nElevDiff)); // sg modify 080901,兼容M、MM单位
// 构造散水对象
dest.SetElevation(-nElevDiff);
TDbApron *pApron = new TDbApron;
pApron->SetPathPoly(dest, pApron->GetNormal());
pApron->SetInHeight(_AS_SYS_UNIT(20));
pApron->SetOutHeight(_AS_SYS_UNIT(10));
pApron->SetAllDists(dSanShuiDist);
pApron->setLayer(InitLayer(LAY_GROUND, FALSE));
AddToModelSpace(pApron, Adesk::kTrue);
// jig散水
ptStart = Ucs2Wcs(ptStart);
nRet = DragInputPolySanShui(ptStart, poly2dRet, pApron, dElevDiffDist, dSanShuiDist);
if (nRet == RTNORM)
{
continue;
}
else if (nRet == RTERROR)
{
if (bCheck && poly2dRet.IsClosed()) // 生成平板对象
{
poly2dRet.SetElevation(nElevDiff);
TDbSlab *pSlab = new TDbSlab;
pSlab->SetOutline(poly2dRet);
pSlab->SetThickness(-nElevDiff);
pSlab->SetVisibilityAll(FALSE);
pSlab->setLayer(InitLayer(LAY_GROUND, FALSE));
AddToModelSpace(pSlab, Adesk::kTrue);
}
dElevDiffDist = _AS_MM(dElevDiffDist); // sg modify 080901,兼容M、MM单位
dSanShuiDist = _AS_MM(dSanShuiDist);
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
dlg.DestroyWindow();
return;
}
}
else if (nRet == RTCAN) // 取消或者切换绘制状态
{
if (dlg.m_bUseEsc)
{
dElevDiffDist = _AS_MM(dElevDiffDist); // sg modify 080901,兼容M、MM单位
dSanShuiDist = _AS_MM(dSanShuiDist);
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
dlg.DestroyWindow();
return;
}
else
{
dlg.m_bUseEsc = TRUE;
continue;
}
}
else if (nRet == RTNONE) // 右键回车
{
dElevDiffDist = _AS_MM(dElevDiffDist); // sg modify 080901,兼容M、MM单位
dSanShuiDist = _AS_MM(dSanShuiDist);
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
dlg.DestroyWindow();
return;
}
else
{
break;
}
}
break;
case 2: // 固定路径
{
TADSGePoint3d ptSel;
Entity ent;
RBList mask(RTDXF0, _T("CIRCLE,LWPOLYLINE,POLYLINE"), NULL);
int nRetP = SelectEntity1(_T("\n请选择作为散水路径的多段线或圆<退出>:"), ent, ptSel, mask);
if (nRetP == RTCAN)
{
if (dlg.m_bUseEsc)
{
dlg.DestroyWindow();
return;
}
else
{
dlg.m_bUseEsc = TRUE;
continue;
}
}
else if (nRetP == RTNORM)
{
dest = XPoly2D(ent);
// 获得对话框数据
dlg.UpdateData();
bCheck = dlg.m_bCheck;
nElevDiff = dlg.m_dDiff;
dElevDiffDist = dlg.m_dOffset;
dSanShuiDist = dlg.m_dWidth;
DocSetElevDiff(_AS_MM(nElevDiff)); // sg modify 080901,兼容M、MM单位
dest.SetElevation(0);
// 闭合轮廓、首尾相交轮廓的处理
bool bIsclosed = false;
if (dest.IsClosed() || *dest.GetAt(0)==*dest.Tail())
{
if (*dest.GetAt(0)==*dest.Tail())
{
dest.Remove(dest.Length()-1);
}
else if(!ent.Is(_T("CIRCLE")))// 忽略对圆的闭合判断
{
int nNumSeg = dest.TotalSegments();
dest.SetFlag(0);
TGGeCurveSegment seg;
dest.Nth(nNumSeg-1,seg);
}
bIsclosed = true;
// 减点操作,减掉角度小于5度的顶点
AutoDelExPoly2DPt(dest);
}
// sg add 090326,解决“在用户坐标系下散水的搜索线预览不正确”的问题
XPoly2D polyTemp(dest);
polyTemp.TransUCS(Groups(0), Groups(1));
XScreenDc dc(1,1);
dc << polyTemp;
dest.Compress();
if (dest.PathArea() > 0.0) // 顺时针的Poly
{
dest.Reverse();
}
// 偏移墙皮距离
dest.Offset(dElevDiffDist, polyTemp);
// 生成平板对象,闭合或者封闭曲线
if (bCheck && bIsclosed)
{
TDbSlab *pSlab = new TDbSlab;
pSlab->SetOutline(polyTemp);
pSlab->SetThickness(-nElevDiff);
pSlab->SetVisibilityAll(FALSE);
pSlab->setLayer(InitLayer(LAY_GROUND, FALSE));
AddToModelSpace(pSlab, Adesk::kTrue);
}
// 散水实体
TDbApron *pApron = new TDbApron;
polyTemp.SetElevation(-nElevDiff);
pApron->SetPathPoly(polyTemp, pApron->GetNormal());
pApron->SetInHeight(_AS_SYS_UNIT(20));
pApron->SetOutHeight(_AS_SYS_UNIT(10));
pApron->SetAllDists(dSanShuiDist);
pApron->setLayer(InitLayer(LAY_GROUND, FALSE));
AddToModelSpace(pApron, Adesk::kTrue);
continue;
}
else
{
dElevDiffDist = _AS_MM(dElevDiffDist); // sg modify 080901,兼容M、MM单位
dSanShuiDist = _AS_MM(dSanShuiDist);
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
dlg.DestroyWindow();
return;
}
dlg.DestroyWindow();
}
break;
default:
break;
}
}
}
// 编辑散水对象
int EditApron(AcDbObjectId id)
{
// [2010-3-25 wubo] C008-05 增加修改散水整体宽度的参数。
// 用户上次输入的散水整体宽度值
static double g_sdApronWidthPre = 600.0;
XVector3D vtNormal = Ucs2Wcs(XVector3D(0, 0, 1), TRUE);
((AcGeVector3d &)vtNormal).normalize();
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbApron, pApron);
if (pApron == NULL)
{
return RTERROR;
}
while(1)
{
int nRet(0);
XString sKeyword;
// [2010-3-25 wubo] C008-05 增加修改散水整体宽度的参数。
//INITGET_BEG(0, _T("A D S W E"));
//nRet = ads_getkword(_T("\n选择 [加顶点(A)/减顶点(D)/改夹角(S)/改宽度(W)/改标高(E)]<退出>:"), sKeyword);
INITGET_BEG(0, _T("A D S W Z E"));
nRet = ads_getkword(_T("\n选择 [加顶点(A)/减顶点(D)/改夹角(S)/改单边宽度(W)/改全局宽度(Z)/改标高(E)]<退出>:"), sKeyword);
INITGET_END();
if (nRet != RTNORM)
{
break;
}
TCHAR cKey = sKeyword[0];
if (cKey==_T('A') || cKey==_T('D'))
{
if (vtNormal.AsAcGeVector3d() != pApron->GetNormal())
{
adsout << _T("\n当前构造平面与对象的构造平面不一致!");
continue;
}
}
XPushMemVar<BOOL> vTemp(g_bSnapCurveBase, TRUE);
XPoint ptVert;
if (sKeyword[0] == _T('A')) // 加顶点
{
while (ads_getpoint(NULL, _T("\n点取新的顶点位置:"), ptVert) == RTNORM)
{
ptVert = Ucs2Ecs(ptVert, vtNormal);
if (pApron->upgradeOpen() != Acad::eOk)
{
return RTERROR;
}
if (!pApron->AddNewVertex(ptVert)) // 点取错误
{
adsout << _T("\n请正确点取!");
}
else // 正常情况,自动添加
{
int nPos = pApron->HitTestOnBase2d(ptVert);
if (nPos > 0)
{
nPos--;
double dFirstDist = pApron->GetDistAt(0);
pApron->InsertDistAt(nPos, dFirstDist);
}
}
pApron->downgradeOpen();
}
}
else if (sKeyword[0] == _T('D')) // 减顶点
{
XPushVar<int> osmode(_T("OSMODE"), OS_END);
while (ads_getpoint(NULL, _T("\n选取顶点: "), ptVert) == RTNORM)
{
ptVert = Ucs2Ecs(ptVert, vtNormal);
int nPos = pApron->HitTestOnBase2d(ptVert);
if (nPos > 0)
{
nPos--;
if (pApron->upgradeOpen() != Acad::eOk)
{
return RTERROR;
}
pApron->RemoveVertexAt(nPos);
pApron->RemoveDistAt(nPos);
pApron->downgradeOpen();
}
else
{
adsout << _T("\n请正确点取!");
}
}
}
else if (sKeyword[0] == _T('S')) // 改角度
{
XPushVar<int> osmode(_T("OSMODE"), OS_END);
while (ads_getpoint(NULL, _T("\n选取顶点: "), ptVert) == RTNORM)
{
int nPos = pApron->HitTestOnBase2d(ptVert);
if (nPos > 0)
{
nPos--;
double nOldAng = pApron->GetSweepAngleAt(nPos)*180.0/PI;
int nCode = GetReal(_T("\n输入夹角"), nOldAng);
if (nCode == RTNORM)
{
nOldAng *= PI/180.0;
if (pApron->upgradeOpen() != Acad::eOk)
{
return RTERROR;
}
pApron->SetSweepAngleAt(nPos, nOldAng);
pApron->downgradeOpen();
}
}
else
{
adsout << _T("\n请正确点取!");
}
}
}
else if (sKeyword[0] == _T('W')) // 改单边宽度
{
XPushVar<int> osMode(_T("OSMODE"), OS_NEA);
while (ads_getpoint(NULL, _T("\n选取边: "), ptVert) == RTNORM)
{
ptVert = Ucs2Ecs(ptVert, vtNormal);
int nPos = pApron->HitTestOnBase2d(ptVert);
if (nPos < 0)
{
nPos = abs(nPos) - 1;
double nOldDist = pApron->GetDistAt(nPos);
// modify by xly on 110126 单侧修改散水的宽度规则:如果当前宽>0,只允
//许输入正数或0;如果当前宽<0只允许输入负数或0
/*int nCode = GetReal(_T("\n输入新宽度"), nOldDist);
if (nCode == RTNORM)
{
if (nOldDist < 1.0E-5)
{
adsout << _T("\n请输入正确!");
continue;
}
if (pApron->upgradeOpen() != Acad::eOk)
{
return RTERROR;
}
pApron->SetDistAt(nPos, nOldDist);
pApron->downgradeOpen();
}*/
double dOldDisTemp = nOldDist;
while(GetReal(_T("\n输入新宽度"), nOldDist)==RTNORM)
{
if ((dOldDisTemp*nOldDist)<-1.0E-5)// 输入的新宽度与就宽度符号相反
{
adsout << _T("\n请输入正确!");
nOldDist = dOldDisTemp;
continue;
}
else
{
break;
}
}
if (pApron->upgradeOpen() != Acad::eOk)
{
return RTERROR;
}
pApron->SetDistAt(nPos, nOldDist);
pApron->downgradeOpen();
}
else
{
adsout << _T("\n请正确点取!");
}
}
}
// [2010-3-25 wubo] C008-05 增加修改散水整体宽度的参数。
else if (sKeyword[0] == _T('Z')) // 改全局宽度
{
// 如果散水的各边宽度相同,则显示的全局宽度为边的宽度,
// 如果不同,则全局宽度为用户上次输入的值
double dApronWidthPre = pApron->GetDistAt(0);
int iDistNum = pApron->GetDistNum();
for (int i = 1; i < iDistNum; i++)
{
if (dApronWidthPre != pApron->GetDistAt(i))
{
dApronWidthPre = _AS_SYS_UNIT(g_sdApronWidthPre);
break;
}
}
int nCode = GetReal(_T("\n输入新宽度"), dApronWidthPre);
if (nCode == RTNORM)
{
g_sdApronWidthPre = _AS_MM(dApronWidthPre);
if (pApron->upgradeOpen() != Acad::eOk)
{
return RTERROR;
}
pApron->SetAllDists(dApronWidthPre);
pApron->downgradeOpen();
}
}
else if (sKeyword[0] == _T('E')) // 改标高
{
XPushVar<int> osmode(_T("OSMODE"), OS_END);
double dElev = pApron->GetElevationAt(0);
adsout << _T("\n输入顶点标高<") << Dist2Str(dElev) << _T(">: ");
int nCode = ads_getreal(_T(""), &dElev);
if (nCode == RTNORM)
{
if (pApron->upgradeOpen() != Acad::eOk)
{
return RTERROR;
}
XPoly2D polyPath;
pApron->GetPathPoly(polyPath, vtNormal);
polyPath.SetElevation(dElev);
pApron->SetPathPoly(polyPath, pApron->GetNormal());
pApron->downgradeOpen();
}
}
if (pApron->upgradeOpen() != Acad::eOk)
{
return RTERROR;
}
pApron->downgradeOpen();
}
OPENOBJ_END();
return RTNORM;
}