1013 lines
27 KiB
C++
1013 lines
27 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();
|
|
|
|
}
|