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

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);
}