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

1013 lines
28 KiB
C++

#include "stdafx.h"
#include "BalconyDlg.h"
#include "DrawBalconyDlg.h"
#include "InputPoly.h"
///////////////////////////////////////////
// Command: 阳台
// 必须在WCS下
static int CompareInt(const int *p1, const void *p2)
{
if (*p1==*(const int *)p2)
return 0;
return 1;
}
// extern GEOAPI int FindNearestEdge(const XPoly2D &poly, const XPoint &ptEdge);
extern void MakeWallSet(PickSet &ssWalls);
/* 算法:
1. 根据栏板轮廓线确定相关的关键两墙线(注意两墙线可能是同一个)
2. 确定两墙线的路径: 两条, 并判断出所需的一条
3. 修正挡板的端点
4. 传人一条路径, 合并成底面
状态: 目前还没有到位
1. 只有一个关键墙时, 没有对较远的路径进行考虑
2. 对于关键墙, 只考虑了直线
3. 栏板轮廓线端点的修正方法很简单
4. 没有考虑轮廓线位于墙角
*/
int AsSimpleBalcony(XPoly2D &polyBalc, XPoly2D &polyWall, XPoly2D &polyOutline)
{
if (YesNoQuestion(_T("\n是否认为两端点接邻一段直墙"), Q_YES)!=Q_YES)
return RTERROR;
polyOutline = polyBalc;
polyOutline.SetFlag(1);
if (polyOutline.PathArea()>0)
polyOutline.Reverse();
if (fabs(polyOutline.PathArea())<1.0E-6)
return RTERROR;
polyWall.SetFlag(0);
polyWall.AppendNode(*polyBalc.Tail());
polyWall.AppendNode(*polyBalc.Head());
return RTNORM;
}
// polyBalc不封闭
int SearchBalcony(XPoly2D &polyBalc, XPoly2D &polyWall, XPoly2D &polyOutline)
{
PickSet ssBound(SS_FREE);
g_ssPickFirst.Free();
if (SelectEntities(_T("\n请选择邻接的墙(或门窗)和柱:"), ssBound,
RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL,TCH_OPENING,TCH_COLUMN"), NULL))!=RTNORM)
return AsSimpleBalcony(polyBalc, polyWall, polyOutline); // 直接连接首末点
MakeWallSet(ssBound);
long lCount=ssBound.Length();
DList<XCurveSegment> lstCurves;
ExplodePoly2D(polyBalc, lstCurves);
for(long i=0L; i<lCount; i++) {
Entity ent=ssBound[i];
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbEntity, pEnt);
if (pEnt->isKindOf(TDbWall::desc())) {
TDbWall *pWall=TDbWall::cast(pEnt);
XCurveSegment lCurve, rCurve;
pWall->GetSideCurve(lCurve, rCurve, 0.0, TRUE);
lstCurves.Append(new XCurveSegment(lCurve));
lstCurves.Append(new XCurveSegment(rCurve));
} else if (pEnt->isKindOf(TDbColumn::desc())) {
TDbColumn *pColu=TDbColumn::cast(pEnt);
XPoly2D polyTemp;
pColu->GetOutline(polyTemp);
ExplodePoly2D(polyTemp, lstCurves);
}
OPENOBJ_END();
}
for(int n=0; n<lstCurves.Length(); n++)
lstCurves[n]->SetElevation(0.0);
ASSERT(polyBalc.Length()>=1);
XCurveSegment segBalc;
polyBalc.Nth(0, segBalc);
XPoint ptMid=segBalc.MidPoint();
ptMid.z=0;
RemoveDupCurves(lstCurves);
IntersectCurves(lstCurves,_DIST_SNAP);
XSearchRegionFromCurve aSearch;
try {
aSearch.InitStart(lstCurves);
} catch(...) {
adsout << /*UMSG*/_T("\n发生例外情况!");
return RTERROR;
}
XRegionSide *pSide=aSearch.HitTest(ptMid);
if (!pSide)
return RTERROR;
XRegion lReg, rReg;
if (aSearch.SerachTwoRegion(*pSide, lReg, rReg)!=RTNORM)
return RTERROR;
XPoly2D lPoly(1), rPoly(1);
lReg.CenterPoly2D(lPoly);
rReg.CenterPoly2D(rPoly);
ASSERT(lPoly.Length()>1 && rPoly.Length()>1);
if (lPoly.Area()<rPoly.Area())
polyOutline=lPoly;
else
polyOutline=rPoly;
polyOutline.Compress();
if (polyOutline.PathArea()>0) //确保逆时针
polyOutline.Reverse();
XPoint ptS=*polyBalc.Head();
XPoint ptE=*polyBalc.Tail();
ptS.z=ptE.z=0;
XPoly2D polySide1, polySide2;
VERIFY(SplitPoly2D(polyOutline, ptS, ptE, polySide1, polySide2)==RTNORM);
if (polySide1.HitTestOnCurve(ptMid))
polyWall=polySide2;
else
polyWall=polySide1;
return RTNORM;
}
#if 0
// polyBalc不封闭
int SearchBalcony(XPoly2D &polyBalc, XPoly2D &polyWall, XPoly2D &polyOutline)
{
XPoint ptStart = *polyBalc.Head(); //挡板起点
XPoint ptEnd = *polyBalc.Tail(); //挡板终点
RBList wallMask(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL);
//确定关键两墙线(单线)
Entity eStart, eEnd;
for(int i=0; i<2; i++) {
XPoint &ptLoc = i? ptEnd:ptStart;
Entity &ent = i? eEnd:eStart;
ads_real nSize = GetPickBoxWcs()/2.0;
XPoint ptLow = Wcs2Ucs(ptLoc) - XPoint(nSize, nSize),
ptUp = Wcs2Ucs(ptLoc) + XPoint(nSize, nSize);
PickSet ss(SS_FREE);
if (ss.Get(_T("C"), ptLow, ptUp, wallMask)!=RTNORM) {
adsout << _T("\n没有找到相关的墙!");
return AsSimpleBalcony(polyBalc, polyWall, polyOutline);
}
long ssLen=ss.Length();
if (ssLen==1) ent = ss[0L];
else {
adsout << _T("\n端点出处发现多个墙段, 请确定相关的墙!");
for(long n=0; n<ssLen; n++) {
Entity e=ss[n];
e.Redraw(3);
int nAnswer = YesNoQuestion(_T("\n是否为该墙段"));
e.Redraw(4);
if (nAnswer==RTCAN)
return nAnswer;
if (nAnswer==Q_YES) {
ent = e;
break;
}
}
if (n==ssLen)
return RTCAN;
}
}
// 找到所有墙
PickSet ssWalls(SS_FREE), ssWins(SS_FREE);
adsout << _T("\n选择所邻接的墙或窗(首末点的沿着直墙边可空回车)!");
if (ssWalls.Get(NULL, NULL, NULL, RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL,TCH_OPENING"), NULL))!=RTNORM)
return AsSimpleBalcony(polyBalc, polyWall, polyOutline);
ssWins += ssWalls;
ssWins.BaseFilter(RBList(RTDXF0, _T("TCH_OPENING"),NULL));
ssWalls.BaseExclude(RBList(RTDXF0, _T("TCH_OPENING"),NULL));
long lWinNum=ssWins.Length();
for(long iWin=0L; iWin<lWinNum; iWin++) {
Entity entWin=ssWins[iWin];
OPENOBJ_BEGIN(entWin, AcDb::kForRead, TDbOpening, pWin);
if (pWin){
AcDbObjectId idWall=pWin->GetWallId();
if (!!idWall)
ssWalls += idWall;
}
OPENOBJ_END();
}
XAecSpaceWall *pWallStart=NULL, *pWallEnd=NULL;
// 寻找外墙
DList<AcDbObjectId> lstColu;
GetEntFromBlockByDxf(lstColu, _T("TCH_COLUMN"));
XSearchSpaceFromWall aSearch;
try {
aSearch.InitStart(ssWalls, lstColu);
} catch(...) {
adsout << /*UMSG*/_T("\n发生例外情况!");
return RTERROR;
}
int nWallNum=aSearch.walls.Length();
for(i=0; i<nWallNum; i++) {
XAecSpaceWall *pWall=aSearch.walls[i];
if (pWall->m_ent == eStart)
pWallStart=pWall;
if (pWall->m_ent == eEnd)
pWallEnd = pWall;
}
if (!pWallStart || !pWallEnd) {
adsout << _T("\n找不到外墙轮廓!");
return AsSimpleBalcony(polyBalc, polyWall, polyOutline);
}
XPoly2D polyPath(0);
if (aSearch.SearchPath(*pWallStart, *pWallEnd, polyPath, TRUE)==RTNORM) {
double nThick=pWallStart->GetWidth();
XPoly2D polySide1(0), polySide2(0);
polyPath.Offset(nThick/2.0, polySide1);
polyPath.Offset(-nThick/2.0, polySide2);
if (!polySide1 || !polySide2)
return RTERROR;
// 判断哪一条离阳台最近
XPoint ptCen1, ptCen2, ptCenBal;
polySide1.Center(ptCen1);
polySide2.Center(ptCen2);
polyBalc.Center(ptCenBal);
if (ads_distance(ptCenBal, ptCen1)<ads_distance(ptCenBal, ptCen2))
polyWall=polySide1;
else
polyWall=polySide2;
XCurveSegment cv1, cv2;
polyWall.Nth(0, cv1);
polyWall.Nth(polyWall.TotalSegments()-1, cv2);
cv1.flag=cv2.flag=LS_INFINITE;
XPoint ptStartOnWall=ptStart, ptEndOnWall=ptEnd; //修正后的阳台挡板端点
int nNumOutlineSeg = polyBalc.TotalSegments();
XCurveSegment segBalStart, segBalEnd;
polyBalc.Nth(0, segBalStart);
polyBalc.Nth(nNumOutlineSeg-1, segBalEnd);
segBalStart.flag=segBalEnd.flag=LS_INFINITE;
XPoint ptModify[2];
int nIntNum = cv1.Intersection(segBalStart, ptModify[0], ptModify[1]);
if (nIntNum==2)
ptStartOnWall = XLine(ptModify[0], ptModify[1]).NearPoint(ptStart);
else if (nIntNum==1)
ptStartOnWall = ptModify[0];
nIntNum = cv2.Intersection(segBalEnd, ptModify[0], ptModify[1]);
if (nIntNum==2)
ptEndOnWall = XLine(ptModify[0], ptModify[1]).NearPoint(ptEnd);
else if (nIntNum==1)
ptEndOnWall = ptModify[0];
// 修正挡板轮廓线
*polyBalc.Head() = *polyWall.Head() = ptStartOnWall;
*polyBalc.Tail() = *polyWall.Tail() = ptEndOnWall;
} else {
adsout << _T("\n找不到外墙轮廓!");
return AsSimpleBalcony(polyBalc, polyWall, polyOutline);
}
#if 0
} else {
ads_real lArea = lSpace.PathArea(),
rArea = rSpace.PathArea();
XAecSpaceCell *pExtSpace= fabs(lArea)>fabs(rArea)? &lSpace:&rSpace;
if (fabs(lArea-rArea)<0.01) { // only one space, then >0 is ext
if (lArea>0.01) pExtSpace=&lSpace;
else pExtSpace=&rSpace;
}
int nSideOfSpace = pExtSpace->Length();
int nSideStart=0, nSideEnd=0; //阳台轮廓的起点所在的墙, 阳台轮廓终点所在的墙
for(i=0; i<nSideOfSpace; i++) {
if ((*pExtSpace)[i]==pWallEnd) {
nSideEnd = i;
break;
}
}
if (i==nSideOfSpace) {
adsout << _T("\n找不到相关外墙!");
return AsSimpleBalcony(polyBalc, polyWall, polyOutline);
}
XPoly2D polySpace(1);
pExtSpace->InternalPoly2D(polySpace, 0);
polySpace.SetElevation(polyBalc[0]->z);
//确定两墙线之间的两条路径
XPoly2D polySide1(0), polySide2(0); //把房间分解为两半, 从阳台的终点方向出发
XCurveSegment cv1, cv2;
polySpace.Nth(nSideStart, cv1);
polySpace.Nth(nSideEnd, cv2);
cv1.flag=cv2.flag=LS_INFINITE;
XPoint ptStartOnWall=ptStart, ptEndOnWall=ptEnd; //修正后的阳台挡板端点
int nNumOutlineSeg = polyBalc.TotalSegments();
XCurveSegment segBalStart, segBalEnd;
polyBalc.Nth(0, segBalStart);
polyBalc.Nth(nNumOutlineSeg-1, segBalEnd);
segBalStart.flag=segBalEnd.flag=LS_INFINITE;
XPoint ptModify[2];
int nIntNum = cv1.Intersection(segBalStart, ptModify[0], ptModify[1]);
if (nIntNum==2)
ptStartOnWall = XLine(ptModify[0], ptModify[1]).NearPoint(ptStart);
else if (nIntNum==1)
ptStartOnWall = ptModify[0];
nIntNum = cv2.Intersection(segBalEnd, ptModify[0], ptModify[1]);
if (nIntNum==2)
ptEndOnWall = XLine(ptModify[0], ptModify[1]).NearPoint(ptEnd);
else if (nIntNum==1)
ptEndOnWall = ptModify[0];
// 修正挡板轮廓线, 简单修正, 今后改进
*polyBalc.Head() = ptStartOnWall;
*polyBalc.Tail() = ptEndOnWall;
VERIFY(SplitPoly2D(polySpace, ptStartOnWall, ptEndOnWall, polySide1, polySide2)==RTNORM);
// 判断哪一条离阳台最近
XPoint ptCen1, ptCen2, ptCenBal;
polySide1.Center(ptCen1);
polySide2.Center(ptCen2);
polyBalc.Center(ptCenBal);
if (ads_distance(ptCenBal, ptCen1)<ads_distance(ptCenBal, ptCen2))
polyWall=polySide1;
else
polyWall=polySide2;
}
#endif
// 合并wallpoly和polyBalc
polyOutline = polyBalc;
if (polyWall.Head()->Distance(*(polyBalc.Tail()))>_DIST_SNAP)
polyWall.Reverse();
int nSeg=polyWall.TotalSegments();
for(i=0; i<nSeg; i++) {
XCurveSegment seg;
polyWall.Nth(i, seg);
polyOutline.AppendSegment(seg);
}
polyOutline.flag=1;
polyWall.Compress();
polyOutline.Compress();
if (polyOutline.PathArea()>0) //确保逆时针
polyOutline.Reverse();
return RTNORM;
}
#endif
/////////////////////////////////////
class RectBalconyJig : public AcEdJig
{
public:
RectBalconyJig(const XPoint&,CDarwBalconyDlg*);
int DoIt();
virtual DragStatus sampler();
virtual Adesk::Boolean update();
virtual AcDbEntity* entity() const;
public:
CDarwBalconyDlg* m_pBalconyDlg;
TDbBalcony* m_pBalcony;
protected:
int GetRetCode(int nRetCode) const;
protected:
XPoint pt0;
XPoint pt1;
XPoint pt3;
XPoint pt4;
static int nSide;
};
int RectBalconyJig::nSide=OFFSET_RIGHT;
///////////////////////////////////////////////////////////
RectBalconyJig::RectBalconyJig(const XPoint& pt,CDarwBalconyDlg* pDlg)
{
pt0=pt;
pt1=pt;
pt3=pt4=pt;
m_pBalcony=new TDbBalcony;
m_pBalconyDlg=pDlg;
}
int RectBalconyJig::GetRetCode(int nRetCode) const
{
int ret =nRetCode;
if (ret == AcEdJig::kCancel)
ret = RTCAN;
else if (ret == AcEdJig::kNull)
ret = RTNONE;
else if (ret <= 0)
ret = RTNORM;
else
{
ret = RTKWORD;
}
return ret;
}
int RectBalconyJig::DoIt()
{
AcEdJig::DragStatus stat;
int nCode=0;
while(true)
{
adsout << _T("\n阳台终点或 [翻转到另一侧(F)]<取消>:");
setKeywordList(_T("F"));
INITGET_BEG(-1, _T("F"))
try
{
stat = drag();
}
catch(...)
{
stat=AcEdJig::kCancel;
}
INITGET_END()
nCode=GetRetCode(stat);
if (nCode==RTKWORD)
{
if (nSide==OFFSET_RIGHT)
nSide=OFFSET_LEFT;
else
nSide=OFFSET_RIGHT;
}
else if (nCode!=RTNORM)
return RTCAN;
else
break;
}
return nCode;
}
AcEdJig::DragStatus
RectBalconyJig::sampler()
{
DragStatus stat;
setUserInputControls((UserInputControls)
(AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted));
setKeywordList(_T("F"));
static XPoint PointTemp1;
stat=acquirePoint(pt1,pt0);
if (PointTemp1!=pt1)
PointTemp1=pt1;
else if (stat == AcEdJig::kNormal)
return AcEdJig::kNoChange;
return stat;
}
Adesk::Boolean
RectBalconyJig::update()
{
m_pBalconyDlg->UpdateData(TRUE);
XPoly2D aPoly(1);
XCurveSegment aLine(pt0,pt1,LS_INFINITE);
//add by xlc on 090505 崩溃问题
if (pt0.Distance(pt1)<_DIST_SNAP)
return Adesk::kTrue;
/*double nLen=_tstof(m_pBalconyDlg->m_Lenth);*/
double nLen=m_pBalconyDlg->m_Lenth;// [11/12/2007 nsh]
XCurveSegment aLine1=aLine.Offset(nSide,nLen,LS_INFINITE);
pt3=aLine1.EndPoint();
pt4=aLine1.StartPoint();
aPoly.AppendNode(pt0);
aPoly.AppendNode(pt1);
aPoly.AppendNode(pt3);
aPoly.AppendNode(pt4);
if (aPoly.PathArea()>0)
aPoly.Reverse();
aPoly.SetElevation(m_pBalconyDlg->m_Elev);// [11/12/2007 nsh]
m_pBalcony->SetOutline(aPoly);
if (m_pBalconyDlg->g_nBalPath==0)
{
if (nSide==OFFSET_LEFT)
{
m_pBalcony->SetRailAt(0, FALSE);
m_pBalcony->SetRailAt(1, FALSE);
m_pBalcony->SetRailAt(2,TRUE);
m_pBalcony->SetRailAt(3, FALSE);
}
else
{
m_pBalcony->SetRailAt(0, FALSE);
m_pBalcony->SetRailAt(1, TRUE);
m_pBalcony->SetRailAt(2,FALSE);
m_pBalcony->SetRailAt(3, FALSE);
}
}
else if (m_pBalconyDlg->g_nBalPath==1)
{
if (nSide==OFFSET_LEFT)
{
m_pBalcony->SetRailAt(0, FALSE);
m_pBalcony->SetRailAt(1, TRUE);
m_pBalcony->SetRailAt(2,TRUE);
m_pBalcony->SetRailAt(3, TRUE);
}
else
{
m_pBalcony->SetRailAt(0, TRUE);
m_pBalcony->SetRailAt(1, TRUE);
m_pBalcony->SetRailAt(2,TRUE);
m_pBalcony->SetRailAt(3, FALSE);
}
}
else if (m_pBalconyDlg->g_nBalPath==2)
{
m_pBalcony->SetRailAt(0, FALSE);
m_pBalcony->SetRailAt(1,TRUE);
m_pBalcony->SetRailAt(2,TRUE);
m_pBalcony->SetRailAt(3, FALSE);
}
// [11/12/2007 nsh]
m_pBalcony->SetRailWidth(m_pBalconyDlg->m_Railwidth);
m_pBalcony->SetRailHeight(m_pBalconyDlg->m_Railheight);
if (m_pBalconyDlg->m_bhasGirder&&m_pBalconyDlg->m_Girderthick>=m_pBalconyDlg->m_Slabthick)
m_pBalcony->SetGirderThickness(m_pBalconyDlg->m_Girderthick);
else
m_pBalcony->SetGirderThickness(m_pBalconyDlg->m_Slabthick);
m_pBalcony->SetSlabThickness(m_pBalconyDlg->m_Slabthick);
m_pBalcony->SetLayerGround3d(InitLayer(LAY_GROUND));
return Adesk::kTrue;
}
AcDbEntity*
RectBalconyJig::entity() const
{
return m_pBalcony;
}
/////////////////////////////////////////////
//阳台 //////////////////////////////////////////////////////////////////////////////////////////////////
void Poly2Balcony()
{
CAcModuleResourceOverride vTemp;
CDarwBalconyDlg dlg;
if (!dlg.Create(dlg.IDD, NULL))
return;
// 修改描述:在绘制阳台时,添加最近点捕捉,不改变原有的设置
// 修改人,修改时间:Zyu modify on 100324
// Begin
int iOsMode = 0;
TGGetVar(_T("OSMODE"), &iOsMode);
iOsMode %= 0x4000; // 在对象捕捉关闭时,打开对象捕捉
TPushAcadVar<int> vOsMode(_T("OSMODE"), iOsMode | OS_NEA);
// End
dlg.ShowWindow(SW_SHOW);
while(1)
{
dlg.m_bUseEsc=TRUE;
if (dlg.g_nBalPath==0||dlg.g_nBalPath==1||dlg.g_nBalPath==2)
{
XPoint pt0;
int nRet0 = ads_getpoint(NULL, _T("\n阳台起点<退出>: "), pt0);
if (nRet0==RTNORM)
{
dlg.SetToolbarBtState1(dlg.g_nBalPath);
pt0=Ucs2Wcs(pt0);
RectBalconyJig jig(pt0,&dlg);
//add by xlc on 090505 06以下平台资源冲突
CAcModuleResourceOverride resOverride(acedGetAcadResourceInstance());
int nCode=jig.DoIt();
if (nCode==RTNORM)
{
jig.m_pBalcony->AddToMSpace(Adesk::kTrue);
}
else
delete jig.m_pBalcony;
dlg.SetToolbarBtState2();
}
else if (nRet0==RTCAN)
{
if (!dlg.m_bUseEsc)
continue;
else
{
if (::IsWindow(dlg.m_hWnd))
dlg.DestroyWindow();
return;
}
}
else
break;
}
else if (dlg.g_nBalPath==3)
{
XPoint pt;
int nRet1 ;
nRet1 = ads_getpoint(NULL, _T("\n请点取墙上一点<退出>: "), pt);
if (nRet1==RTCAN)
{
if (!dlg.m_bUseEsc)
continue;
else
{
if (::IsWindow(dlg.m_hWnd))
dlg.DestroyWindow();
return;
}
}
else if (nRet1!=RTNORM)
break;
PickSet ssStart(SS_FREE);
RBList entmask(RTDXF0,_T("TCH_WALL,TCH_CURTAIN_WALL"),NULL);
ssStart.Get(pt,entmask);
if (ssStart.Length()==0)
continue;
dlg.SetToolbarBtState1(3);
dlg.doExtend(pt);
dlg.SetToolbarBtState2();
}
else if (dlg.g_nBalPath==4)
{
int nRet2;
XPoint ptStart;
nRet2 = ads_getpoint(NULL, _T("\n起点<退出>: "), ptStart);
XPoly2D poly2dRet;
XPoly2D poly(1);
if (nRet2 == RTNORM)
{
dlg.SetToolbarBtState1(4);
ptStart=Ucs2Wcs(ptStart);
nRet2=DragInputPoly(ptStart, poly2dRet);
}
else if (nRet2==RTCAN)
{
if (!dlg.m_bUseEsc)
continue;
else
{
if (::IsWindow(dlg.m_hWnd))
dlg.DestroyWindow();
return;
}
}
else
break;
if (nRet2==RTNORM)
{
poly2dRet.Compress();
XScreenDc dc(1,1);// [11/29/2007 nsh]
DList<int> lstEdgeIndex;
if (!poly2dRet.IsClosed())
{
XScreenDc dc0;
XPoly2D polyTemp(poly2dRet);
polyTemp.TransUCS(Groups(0), Groups(1));
dc0 << polyTemp;
XPoly2D polyWall(0);
if (SearchBalcony(poly2dRet, polyWall, poly)!=RTNORM)
{
ads_redraw(NULL,0);
break;
}
for(int n=0; n<polyWall.TotalSegments(); n++)
{
XCurveSegment cvSeg;
polyWall.Nth(n, cvSeg);
XPoint ptEdge = cvSeg.MidPoint();
int nEdge=FindNearestEdge(poly, ptEdge);
if (nEdge>=0 && !lstEdgeIndex.FindNode(&nEdge, CompareInt))
{
lstEdgeIndex.Append(new int(nEdge));
XCurveSegment seg;
poly.Nth(nEdge, seg);
seg.StartPoint()=Wcs2Ucs(seg.StartPoint());
seg.EndPoint()=Wcs2Ucs(seg.EndPoint());
dc << seg;
}
}
// [11/29/2007 nsh]
while(1)
{
XPushVar<int> tVar(_T("OSMODE"), OS_NEA);
XPoint ptEdge;
int nRet=ads_getpoint(NULL, _T("\n请点取接墙的边: "), ptEdge);
if (nRet!=RTNORM)
break;
dlg.UpdateData(TRUE);
ptEdge=Ucs2Wcs(ptEdge);
int nEdge=FindNearestEdge(poly, ptEdge);
if (nEdge>=0 && !lstEdgeIndex.FindNode(&nEdge, CompareInt))
{
lstEdgeIndex.Append(new int(nEdge));
XCurveSegment seg;
poly.Nth(nEdge, seg);
seg.StartPoint()=Wcs2Ucs(seg.StartPoint());
seg.EndPoint()=Wcs2Ucs(seg.EndPoint());
dc << seg;
}
}
//-------------------------------------------
}
else
{
poly=poly2dRet;
if (poly.PathArea()>0) //确保逆时针
poly.Reverse();
XScreenDc dc(1,1);
while(1)
{
XPushVar<int> tVar(_T("OSMODE"), OS_NEA);
XPoint ptEdge;
int nRet=ads_getpoint(NULL, _T("\n请点取接墙的边: "), ptEdge);
if (nRet!=RTNORM)
break;
dlg.UpdateData(TRUE);
ptEdge=Ucs2Wcs(ptEdge);
int nEdge=FindNearestEdge(poly, ptEdge);
if (nEdge>=0 && !lstEdgeIndex.FindNode(&nEdge, CompareInt))
{
lstEdgeIndex.Append(new int(nEdge));
XCurveSegment seg;
poly.Nth(nEdge, seg);
seg.StartPoint()=Wcs2Ucs(seg.StartPoint());
seg.EndPoint()=Wcs2Ucs(seg.EndPoint());
dc << seg;
}
}
}
dlg.UpdateData();///add by fxj on 070328
TDbBalcony *pBalcony = new TDbBalcony;
poly.SetElevation(dlg.m_Elev);
pBalcony->SetOutline(poly);// [11/12/2007 nsh]
pBalcony->SetRailWidth(dlg.m_Railwidth);
pBalcony->SetRailHeight(dlg.m_Railheight);
if (dlg.m_bhasGirder&&dlg.m_Girderthick>=dlg.m_Slabthick)
pBalcony->SetGirderThickness(dlg.m_Girderthick);
else
pBalcony->SetGirderThickness(dlg.m_Slabthick);
pBalcony->SetSlabThickness(dlg.m_Slabthick);
pBalcony->SetLayerGround3d(InitLayer(LAY_GROUND));
for(int i=0; i<lstEdgeIndex.Length(); i++)
pBalcony->SetRailAt(*lstEdgeIndex[i], FALSE);
pBalcony->AddToMSpace(Adesk::kTrue);
ads_redraw(NULL,0);
dlg.SetToolbarBtState2();
}
else
break;
}
else if (dlg.g_nBalPath==5)
{
acedGetAcadFrame()->SetFocus();
XString szPrompt;
szPrompt << _T("点取图中曲线");
RBList mask(RTDXF0, _T("POLYLINE,LWPOLYLINE,LINE,ARC"), NULL);
Entity ent;
while(1)
{
int nRet3=ent.FilterSelect(_T("\n选择一曲线(LINE/ARC/PLINE)<退出>:"), mask);
if (nRet3==RTCAN)
{
if (!dlg.m_bUseEsc)
break;
else
{
if (::IsWindow(dlg.m_hWnd))
dlg.DestroyWindow();
return;
}
}
else if (nRet3!=RTNORM)
{
if (::IsWindow(dlg.m_hWnd))
dlg.DestroyWindow();
return;
}
dlg.UpdateData();//add by fxj on 070508
dlg.SetToolbarBtState1(5);
dlg.doSelect(ent);
dlg.SetToolbarBtState2();
}
}
}
if (::IsWindow(dlg.m_hWnd))
dlg.DestroyWindow();
}
// Command:编辑阳台
int EditBalcony(AcDbObjectId id)
{
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbBalcony, pBalcony);
if (!pBalcony)
return RTERROR;
//判断是不是上海城建阳台板实体
CString strCmdName(_T(""));
TDbXDataMap map;
map.Read(pBalcony, _T("TGZZCL"));
map.GetAt(_T("cmdName"), strCmdName);
if (strCmdName == _T("TGZZCLBY") || strCmdName == _T("TGZZCLBK"))
{
struct resbuf rbUr;
rbUr.restype = RTSTR;
rbUr.resval.rstring = _T("EditObj");
rbUr.rbnext = NULL;
acedSetVar(_T("USERS3"), &rbUr);
acedPostCommand(strCmdName);
acedPostCommand(_T("\n"));
return RTNORM;
}
else
{
CBalconyDlg dlgBalcony(acedGetAcadFrame());
dlgBalcony.m_GirderThick = (const TCHAR *)Dist2Str(pBalcony->GetGirderThickness());
dlgBalcony.m_RailWidth = (const TCHAR *)Dist2Str(pBalcony->GetRailWidth());
dlgBalcony.m_RailHeight = (const TCHAR *)Dist2Str(pBalcony->GetRailHeight());
dlgBalcony.m_SlabThick = (const TCHAR *)Dist2Str(pBalcony->GetSlabThickness());
dlgBalcony.m_Elev = (const TCHAR *)Dist2Str(pBalcony->GetElevation());
dlgBalcony.m_bhasGirder=pBalcony->HasGirder();
CAcModuleResourceOverride tVar;
if (dlgBalcony.DoModal()==IDOK) {
if (pBalcony->upgradeOpen()!=Acad::eOk)
return RTERROR;
pBalcony->assertWriteEnabled();
pBalcony->SetElevation(_tstof(dlgBalcony.m_Elev));
pBalcony->SetRailWidth(_tstof(dlgBalcony.m_RailWidth));
pBalcony->SetRailHeight(_tstof(dlgBalcony.m_RailHeight));
pBalcony->SetSlabThickness(_tstof(dlgBalcony.m_SlabThick));
pBalcony->SetGirderThickness(!dlgBalcony.m_bhasGirder?
_tstof(dlgBalcony.m_SlabThick) : _tstof(dlgBalcony.m_GirderThick));
pBalcony->downgradeOpen();
}
}
OPENOBJ_END();
return RTNORM;
}
// sg add 111129,根据9.0需求,增加栏板切换命令
void RailingSwitchCmd()
{
//对象捕捉增加“最近点”
int iOsMode = 0;
TGGetVar(_T("OSMODE"), &iOsMode);
iOsMode %= 0x4000; // 在对象捕捉关闭时,打开对象捕捉
XPushVar<int> vOsMode(_T("OSMODE"), iOsMode | OS_NEA);
//选择阳台
RBList mask(RTDXF0, _T("TCH_BALCONY"), NULL);
Entity entBalcony;
int istats = entBalcony.FilterSelect1(0,_T("\n请选择阳台<退出>: "), mask, NULL);
if(istats != RTNORM)
{
return;
}
//高亮显示
OPENOBJ_BEGIN(entBalcony,AcDb::kForRead,TDbBalcony,pEntHighlight);
if (pEntHighlight)
{
pEntHighlight->draw();
pEntHighlight->highlight();
}
OPENOBJ_END();
//栏板操作
while (true)
{
//取点
AcGePoint3d pt;
if (acedGetPoint(NULL,_T("\n请点取需添加或删除栏板的阳台边界<退出>:"),asDblArray(pt)) != RTNORM)
{
break;
}
OPENOBJ_BEGIN(entBalcony,AcDb::kForWrite,TDbBalcony,pBalcony);
if (pBalcony)
{
//计算单板位置
int iEdNum = pBalcony->GetEdgeNum(); //边数
XPoly2D outline = pBalcony->GetOutline(); //轮廓线
double dMin = 1000000.0;
int index = -1; //需切换栏板索引
for (int i=0;i<iEdNum;i++)
{
TGGeCurveSegment cvSegent;
outline.Nth(i,cvSegent);
TADSGePoint3d ptProject;//投影点
cvSegent.ProjectToMe(pt,ptProject);
int iType = cvSegent.GetCurveType();
bool bOnSegent= false;
if (iType == CURVE_ARC)//弧
{
TGGeArc arc = cvSegent.GetArc();
TADSGePoint3d ptCenter = arc.GetCenterPt();
ads_real startAngle = arc.GetStarAngle();
ads_real endAngle = arc.GetEndAngle();
if (startAngle > endAngle)
{
endAngle+=2*PI;
}
ads_real angle = ads_angle(ptCenter,ptProject);
if (startAngle< angle && angle<endAngle)
{
bOnSegent = true;
}
}
else
{
int iRe = cvSegent.HitTest2d(ptProject);
if (iRe == 5)
{
bOnSegent = true;
}
}
if (bOnSegent)
{
double dDist = acutDistance(asDblArray(pt),asDblArray(ptProject.AsAcGePoint3d()));
if (dDist < dMin)
{
dMin = dDist;
index = i;
}
}
}
if (index >=0)//找到切换挡板位置
{
if (pBalcony->HasRailAt(index))
{
pBalcony->SetRailAt(index,false);
}
else
{
pBalcony->SetRailAt(index,true);
}
}
}
//高亮显示
pBalcony->draw();
pBalcony->highlight();
OPENOBJ_END();
}
//取消高亮
OPENOBJ_BEGIN(entBalcony,AcDb::kForRead,TDbBalcony,pEntunHighlight);
if (pEntunHighlight)
{
pEntunHighlight->draw();
pEntunHighlight->unhighlight();
}
OPENOBJ_END();
}