363 lines
12 KiB
C++
363 lines
12 KiB
C++
#include "stdafx.h"
|
|
#include "FortifyColumnDlg.h"
|
|
extern int IsPoint2dEqual(XPoint pt1, XPoint pt2);
|
|
extern int IsWallIntersect(TDbWall* pWall1, TDbWall* pWall2, XPoint& ptInter);
|
|
|
|
AcDbObjectId SortOneWall(const AcDbObjectIdArray &idArray,XPoint p1,XPoint p2)
|
|
{
|
|
int len=idArray.length();
|
|
for (int i=0;i<len;i++)
|
|
{
|
|
AcDbObjectId id=idArray[i];
|
|
XDbObject objWall(id, AcDb::kForRead);
|
|
if (!objWall) return NULL;
|
|
TDbWall* pWall=TDbWall::cast(objWall.m_pObject);
|
|
if (!pWall) return NULL;
|
|
XPoint pS,pE;
|
|
pWall->getStartPoint(pS);
|
|
pWall->getEndPoint(pE);
|
|
XCurveSegment s(pS,pE,0);
|
|
XLine l(p1,p2);
|
|
s.SetElevation(0.0);
|
|
l.SetElevation(0.0);
|
|
if (s.Intersection(l,pS,pE)) return id;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
static int g_iStackDepth;//控制堆栈深度,add by whl on 060228
|
|
//modified by whl on 060228
|
|
bool SortAllWall(AcDbObjectIdArray *idArray,XPoint *pt1,XPoint *pt2,XPoint *pt3,XPoint *pt4)
|
|
{
|
|
//add by whl on 060228
|
|
g_iStackDepth++;
|
|
if (g_iStackDepth>20)
|
|
return false;
|
|
|
|
AcDbObjectId id1,id2,id3,id4;
|
|
if ((*idArray).length()==1)
|
|
{// single wall case -> no need to sort
|
|
id1=(*idArray)[0];
|
|
id2=id3=id4=NULL;
|
|
}
|
|
else
|
|
{
|
|
id1=SortOneWall(*idArray,*pt1,*pt2);
|
|
id2=SortOneWall(*idArray,*pt2,*pt3);
|
|
id3=SortOneWall(*idArray,*pt3,*pt4);
|
|
id4=SortOneWall(*idArray,*pt4,*pt1);
|
|
}
|
|
|
|
if (id1)
|
|
{// until wall 1 match to ref. point 1
|
|
(*idArray).setLogicalLength(0);
|
|
(*idArray).append(id1);
|
|
(*idArray).append(id2);
|
|
(*idArray).append(id3);
|
|
(*idArray).append(id4);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
XPoint p=*pt1;
|
|
*pt1=*pt2;
|
|
*pt2=*pt3;
|
|
*pt3=*pt4;
|
|
*pt4=p;
|
|
|
|
return SortAllWall(idArray,pt1,pt2,pt3,pt4);
|
|
}
|
|
}
|
|
|
|
void GetReferencePoint(AcDbObjectIdArray idArray,XPoint *pt1,XPoint *pt2,XPoint *pt3,XPoint *pt4) {
|
|
int len=idArray.length();
|
|
if (len==4) {// + 墙角 -> 4 walls case
|
|
idArray.removeAt(0);
|
|
|
|
GetReferencePoint(idArray,pt1,pt2,pt3,pt4);
|
|
}
|
|
else if (len==3) {// T 墙角 -> 3 walls case
|
|
XDbObject objWall1(idArray[0], AcDb::kForRead);
|
|
if (!objWall1) return;
|
|
TDbWall* pWall1=TDbWall::cast(objWall1.m_pObject);
|
|
if (!pWall1) return;
|
|
XDbObject objWall2(idArray[1], AcDb::kForRead);
|
|
if (!objWall2) return;
|
|
TDbWall* pWall2=TDbWall::cast(objWall2.m_pObject);
|
|
if (!pWall2) return;
|
|
|
|
XPoint pS,pE;
|
|
pWall1->getStartPoint(pS); pWall1->getEndPoint(pE);
|
|
XCurveSegment s1(pS,pE,0); s1.SetElevation(0.0);
|
|
pWall2->getStartPoint(pS); pWall2->getEndPoint(pE);
|
|
XCurveSegment s2(pS,pE,0); s2.SetElevation(0.0);
|
|
|
|
if (s1.Intersection(s2,pS,pE)) idArray.removeAt(2);
|
|
else idArray.removeAt(0);
|
|
|
|
GetReferencePoint(idArray,pt1,pt2,pt3,pt4);
|
|
}
|
|
else if (len==2) {// L 墙角 -> 2 walls case
|
|
XDbObject objWall1(idArray[0], AcDb::kForRead);
|
|
if (!objWall1) return;
|
|
TDbWall* pWall1=TDbWall::cast(objWall1.m_pObject);
|
|
if (!pWall1) return;
|
|
XDbObject objWall2(idArray[1], AcDb::kForRead);
|
|
if (!objWall2) return;
|
|
TDbWall* pWall2=TDbWall::cast(objWall2.m_pObject);
|
|
if (!pWall2) return;
|
|
|
|
XCurveSegment lCurve1,rCurve1,lCurve2,rCurve2;
|
|
pWall1->GetSideCurve(lCurve1,rCurve1);
|
|
pWall2->GetSideCurve(lCurve2,rCurve2);
|
|
lCurve1.SetElevation(0.0); rCurve1.SetElevation(0.0);
|
|
lCurve2.SetElevation(0.0); rCurve2.SetElevation(0.0);
|
|
XLine lLine1(lCurve1.StartPoint(),lCurve1.EndPoint(),LS_INFINITE),
|
|
rLine1(rCurve1.StartPoint(),rCurve1.EndPoint(),LS_INFINITE),
|
|
lLine2(lCurve2.StartPoint(),lCurve2.EndPoint(),LS_INFINITE),
|
|
rLine2(rCurve2.StartPoint(),rCurve2.EndPoint(),LS_INFINITE);
|
|
if (!lLine1.Intersection(&lLine2,*pt1) ||
|
|
!lLine1.Intersection(&rLine2,*pt2) ||
|
|
!rLine1.Intersection(&rLine2,*pt3) ||
|
|
!rLine1.Intersection(&lLine2,*pt4))
|
|
return;
|
|
}
|
|
else {// 墙中 -> single wall case
|
|
XDbObject objWall(idArray[0], AcDb::kForRead);
|
|
if (!objWall) return;
|
|
TDbWall* pWall=TDbWall::cast(objWall.m_pObject);
|
|
if (!pWall) return;
|
|
|
|
XCurveSegment lCurve,rCurve;
|
|
pWall->GetSideCurve(lCurve,rCurve);
|
|
lCurve.SetElevation(0.0);
|
|
rCurve.SetElevation(0.0);
|
|
(*pt1).Project(&lCurve,*pt1);
|
|
(*pt1).Project(&rCurve,*pt2);
|
|
XLine l(*pt1,*pt2);
|
|
XLine lLeft=l.Offset(-300),lRight=l.Offset(300);// 1000 -> max. column size allowed
|
|
*pt1=lLeft.StartPoint(); *pt2=lLeft.EndPoint();
|
|
*pt4=lRight.StartPoint(); *pt3=lRight.EndPoint();
|
|
}
|
|
}
|
|
|
|
BOOL GetValidWall(XPoint ptCornUcs, AcDbObjectIdArray &idWallArray) {
|
|
int nWallCount=0;
|
|
XPoint ptLowLeft,ptLowRight,ptUpRight,ptUpLeft,ptInter;
|
|
double nSpace=500, nStep=500, nSpaceMax=1600;
|
|
XPoint ptCorn=Ucs2Wcs(ptCornUcs);
|
|
ptLowLeft=ptLowRight=ptUpRight=ptUpLeft=ptCornUcs;
|
|
HWND hWndACAD = adsw_acadMainWnd();
|
|
|
|
while(1) {
|
|
ptLowLeft.x-=nSpace; ptLowLeft.y-=nSpace; ptLowRight.x+=nSpace; ptLowRight.y-=nSpace;
|
|
ptUpRight.x+=nSpace; ptUpRight.y+=nSpace; ptUpLeft.x-=nSpace; ptUpLeft.y+=nSpace;
|
|
RBList rbCP=ads_buildlist(RT3DPOINT,&ptLowLeft,RT3DPOINT,&ptLowRight,RT3DPOINT,&ptUpRight,RT3DPOINT,&ptUpLeft,NULL);
|
|
PickSet ssWalls(SS_FREE);
|
|
if (ssWalls.Get(_T("CP"), rbCP, NULL, RBList(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL))!=RTNORM)
|
|
return FALSE;
|
|
|
|
AcDbObjectId idStWall;
|
|
AcDbObjectIdArray idWallArr;
|
|
nWallCount=int(ssWalls.Length());
|
|
for(long i=0; i<nWallCount; i++) {
|
|
Entity idWall=ssWalls[i];
|
|
XDbObject objWall(idWall, AcDb::kForRead);
|
|
if (!objWall) continue;
|
|
TDbWall* pWall=TDbWall::cast(objWall.m_pObject);
|
|
if (!pWall || pWall->GetUsageFlag()!=TWallData::kNormal) continue;
|
|
XPoly2D poly(1);
|
|
pWall->GetOutlinePoly(ptCorn.z, poly);
|
|
int nPrRes=ptCorn&poly;
|
|
if ((nPrRes==PR_INSIDE||nPrRes==PR_EDGE)&&!idStWall)
|
|
idStWall=pWall->objectId();
|
|
else idWallArr.append(pWall->objectId());
|
|
}
|
|
if (!idStWall) {
|
|
if (nSpace<nSpaceMax) {
|
|
nSpace+=nStep;
|
|
continue;
|
|
}
|
|
else MessageBox(hWndACAD,_T("您选取的点不在墙体内!"),_T("提示"),MB_OK|MB_ICONINFORMATION);
|
|
return NULL;
|
|
}
|
|
|
|
nWallCount=idWallArr.length();
|
|
if (nWallCount==0) {// 墙中 -> single wall case
|
|
idWallArray.setLogicalLength(0);
|
|
idWallArray.append(idStWall);
|
|
break;
|
|
}
|
|
XPoint ptInt;
|
|
DList<XPoint> ptList;
|
|
XDbObject objStWall(idStWall, AcDb::kForRead);
|
|
if (!objStWall) return NULL;
|
|
TDbWall* pStWall=TDbWall::cast(objStWall.m_pObject);
|
|
if (!pStWall) return NULL;
|
|
for(i=0; i<nWallCount; i++) {
|
|
XDbObject objWall(idWallArr[i], AcDb::kForRead);
|
|
if (!objWall) continue;
|
|
TDbWall* pWall=TDbWall::cast(objWall.m_pObject);
|
|
if (!pWall) continue;
|
|
if (!IsWallIntersect(pStWall, pWall, ptInt)) {
|
|
idWallArr.removeAt(i);
|
|
nWallCount=idWallArr.length();
|
|
i--;
|
|
}
|
|
else ptList.Append(new XPoint(ptInt));
|
|
}
|
|
if (!nWallCount) {
|
|
if (nSpace<nSpaceMax) {
|
|
nSpace+=nStep;
|
|
continue;
|
|
}
|
|
else break;
|
|
}
|
|
int nLen=ptList.Length();
|
|
if (nLen>1) {
|
|
double nMinDist=2000;
|
|
for(i=0; i<nLen; i++) {
|
|
double nDist=ptCorn.Distance(*ptList[i]);
|
|
if (nDist<nMinDist) {
|
|
ptInter=*ptList[i];
|
|
nMinDist=nDist;
|
|
}
|
|
}
|
|
for(i=0; i<nWallCount; i++) {
|
|
XDbObject objWall(idWallArr[i], AcDb::kForRead);
|
|
if (!objWall) continue;
|
|
TDbWall* pWall=TDbWall::cast(objWall.m_pObject);
|
|
if (!pWall) continue;
|
|
if (IsWallIntersect(pStWall, pWall, ptInt)) {
|
|
if (!IsPoint2dEqual(ptInter,ptInt)) {
|
|
idWallArr.removeAt(i);
|
|
nWallCount=idWallArr.length();
|
|
i--;
|
|
}
|
|
}
|
|
}
|
|
if (!nWallCount) {
|
|
if (nSpace<nSpaceMax) {
|
|
nSpace+=nStep;
|
|
continue;
|
|
}
|
|
else break;
|
|
}
|
|
}
|
|
else if (nLen==1) ptInter=*ptList[0];
|
|
XPoint ptSearch;
|
|
BOOL bFromStart=FALSE;
|
|
idWallArray.setLogicalLength(0);
|
|
XCurveSegment lCurve, rCurve;
|
|
idWallArr.append(idStWall);
|
|
objStWall.Close();
|
|
AcDbObjectId idStWallSrh=idStWall;
|
|
nWallCount=idWallArr.length();
|
|
while(1) {
|
|
XDbObject objStWallSrh(idStWallSrh, AcDb::kForRead);
|
|
if (!objStWallSrh) return NULL;
|
|
TDbWall* pStWallSrh=TDbWall::cast(objStWallSrh.m_pObject);
|
|
if (!pStWallSrh) return NULL;
|
|
pStWallSrh->GetSideCurve(lCurve, rCurve);
|
|
if (IsPoint2dEqual((*pStWallSrh).StartPoint(),ptInter)) bFromStart=TRUE;
|
|
else bFromStart=FALSE;
|
|
if (bFromStart) ptSearch=lCurve.StartPoint();
|
|
else ptSearch=rCurve.EndPoint();
|
|
for(i=0; i<nWallCount; i++) {
|
|
AcDbObjectId nId=idWallArr[i];
|
|
XDbObject objWall(nId, AcDb::kForRead);
|
|
if (!objWall) continue;
|
|
TDbWall* pWall=TDbWall::cast(objWall.m_pObject);
|
|
if (!pWall) continue;
|
|
if (pStWallSrh==pWall) continue;
|
|
pWall->GetSideCurve(lCurve, rCurve);
|
|
if (IsPoint2dEqual((*pWall).StartPoint(),ptInter)) bFromStart=TRUE;
|
|
else bFromStart=FALSE;
|
|
if (bFromStart&&IsPoint2dEqual(rCurve.StartPoint(),ptSearch)||
|
|
!bFromStart&&IsPoint2dEqual(lCurve.EndPoint(),ptSearch)) {
|
|
idStWallSrh=nId;
|
|
idWallArray.append(nId);
|
|
break;
|
|
}
|
|
}
|
|
if (i==nWallCount) {
|
|
idWallArray.setLogicalLength(0);
|
|
break;
|
|
}
|
|
else if (idStWallSrh==idStWall||idWallArray.length()==nWallCount) {
|
|
break;
|
|
}
|
|
}
|
|
nWallCount=idWallArray.length();
|
|
if (nWallCount<=1) {
|
|
if (nSpace<nSpaceMax) {
|
|
nSpace+=nStep;
|
|
continue;
|
|
}
|
|
else break;
|
|
}
|
|
else break;
|
|
}
|
|
|
|
nWallCount=idWallArray.length();
|
|
if ((nWallCount<1)||(nWallCount>4)) {
|
|
MessageBox(hWndACAD,_T("您选取的不是墙中或墙角!"),_T("提示"),MB_OK|MB_ICONINFORMATION);
|
|
return FALSE;
|
|
}
|
|
|
|
/* 不需要比较z标高和高度
|
|
BOOL bContinue=TRUE;
|
|
double nZLoc=0, nHeight=0;
|
|
for(int i=0; i<nWallCount; i++) {
|
|
XDbObject objWall(idWallArray[i], AcDb::kForRead);
|
|
if (!objWall) continue;
|
|
TDbWall* pWall=TDbWall::cast(objWall.m_pObject);
|
|
if (!pWall) continue;
|
|
if (!i) {
|
|
nZLoc=pWall->GetElevation();
|
|
nHeight=pWall->GetHeight();
|
|
} else {
|
|
if (fabs(nZLoc-pWall->GetElevation())>1E-3||
|
|
fabs(nHeight-pWall->GetHeight())>1E-3) {
|
|
CString szTxt;
|
|
if (fabs(nZLoc-pWall->GetElevation())>1E-3)
|
|
szTxt=_T("墙体底标高不相等! 继续生成吗?");
|
|
else if (fabs(nHeight-pWall->GetHeight())>1E-3)
|
|
szTxt=_T("墙体高度不相等! 继续生成吗?");
|
|
int nRet=MessageBox(hWndACAD,szTxt,_T("提示"),MB_OKCANCEL|MB_ICONINFORMATION);
|
|
if (nRet==IDCANCEL) bContinue=FALSE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if (!bContinue) return FALSE;
|
|
*/
|
|
|
|
return TRUE;
|
|
}
|
|
void myFortifyColumn()
|
|
{
|
|
XPoint ptCornUcs;
|
|
if (XGetPoint(NULL, _T("\n请选取墙角"), ptCornUcs)!=RTNORM) return;
|
|
|
|
AcDbObjectIdArray idWallArray;
|
|
if (!GetValidWall(ptCornUcs, idWallArray))
|
|
return;
|
|
|
|
XPoint ptRef1,ptRef2,ptRef3,ptRef4;
|
|
if (idWallArray.length()==1) ptRef1=Ucs2Wcs(ptCornUcs);
|
|
ptRef1.z=0;
|
|
GetReferencePoint(idWallArray,&ptRef1,&ptRef2,&ptRef3,&ptRef4);
|
|
|
|
g_iStackDepth=0;//add by whl on 060228
|
|
if (!SortAllWall(&idWallArray,&ptRef1,&ptRef2,&ptRef3,&ptRef4))
|
|
return;
|
|
|
|
CWnd* pWnd=acedGetAcadFrame();
|
|
CFortifyColumnDlg dlg(idWallArray,ptRef1,ptRef2,ptRef3,ptRef4,pWnd);
|
|
CAcModuleResourceOverride vTemp;
|
|
dlg.DoModal();
|
|
|
|
ads_redraw(NULL, 0);
|
|
}
|