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

2796 lines
77 KiB
C++

#include "stdafx.h"
#include "resource.h"
#include "InsertOpeningDlg.h"
#include "arcWindowDlg.h"
#include "doorWinDlg.h"
#include "InsDoorWinDlg.h"
#include "bayWindowDlg.h"
#include "TwoDoorDlg.h"
#include "RectHoleDlg.h"
extern AcDbObjectId GetOpeingLocation(const TCHAR *prompt, TDbOpening *&pWin,bool bFreeInsert=false);
//add by lgy 20120517 智能插入门窗
extern AcDbObjectId GetOpeingLocationApt(const TCHAR *prompt, TDbOpening *&pWin, XPoint &ptPick, XCurveSegment &cvSeg, int &nRetCode,
int nAptType, DList<TWallAxisData> &lstIds);
extern BOOL ValidateLabelInCurDwg(TDbOpening &op);
// Command: 重定门窗
void RelocateOpening()
{
RBList mask(RTDXF0, _T("TCH_OPENING"), NULL);
Entity ent;
XPoint ptPick;
ent.FilterSelect(_T("\n请点取门窗一侧:"), mask, ptPick);
// ...
}
// add by xlc on 070514
BOOL ValidateCurLabel(TDbOpening &pWin)
{
while(TRUE)
{
if (!ValidateLabelInCurDwg(pWin))
{
XString sPostFix;
sPostFix = pWin.GetLabel();
adsout << _T("\n与图中已有同样编号的门窗参数不一致!请重新输入编号<")<<sPostFix<<_T(">: ");
//modify by xlc on 070716
//sPostFix=_T("");
XString sPostFix1;
int nRet=acedGetString(TRUE,_T(""),sPostFix1);
if (nRet == RTNORM)
{
if (sPostFix1!=_T(""))
{
pWin.assertWriteEnabled();
pWin.SetLabel(sPostFix1);
continue;
}
else
break;
}
else
{
return FALSE;
}
}
break;
}
return TRUE;
}
// add by xly on 110224 圆弧上一点沿着圆弧偏移dDis的距离得到的点
XPointDir2d GetPtArc(XCurveSegment seg,double nDist, bool bFromStart, XPoint pt)
{
XArc arc=seg.GetArc();
XPoint ptS,
ptEnd;
arc.GetStartPoint(ptS);
arc.GetEndPoint(ptEnd);
XPoint ptCen = arc.GetCenterPt();
pt.z=0.0;
AcGeVector3d verS = ptS - ptCen,
verEnd = ptEnd - ptCen,
ver = pt- ptCen;
double dAngle(0.0);
if (bFromStart)
{
dAngle = verS.angleTo(ver, AcGeVector3d::kZAxis);
nDist += dAngle*arc.GetRadius();
}
else
{
dAngle = verEnd.angleTo(ver, AcGeVector3d::kZAxis);
nDist -= dAngle*arc.GetRadius();
}
XPointDir2d ptRes;
seg.Polar(nDist, ptRes,bFromStart);
return ptRes;
}
// add by xly on 110228 找到墙体上的所有的门窗对象
bool GetNearOpenings(AcDbObjectId idWall, XPoint ptLoc, XPoint &ptRet)
{
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
if (!pWall)
{
return false;
}
double dDist(0.0);
ptLoc.z = 0;
bool bRet(false);
const DList<AcDbSoftPointerId> &lstWin = pWall->GetOpeningIdList();
if (lstWin.Length()>0)// 墙体上的门窗对象的个数大于等于1
{
// 遍历墙体中的所有的门窗对象,找到距ptLoc最近的对象
for(int n = 0;n < lstWin.Length();n++)
{
AcDbObjectId id = lstWin[n];
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbOpening, pWin);
if(pWin)
{
XPoint pt = pWin->GetLocation();
if (n==0)
{
dDist = ptLoc.Distance(pt);
}
else
{
double dDistNew = pt.Distance(pt);
if (dDistNew<dDist && fabs(dDistNew)>_DIST_SNAP)
{
dDist = dDistNew;
ptRet = pt;
bRet = true;
}
}
}
OPENOBJ_END();
}
}
return bRet;
OPENOBJ_END();
}
// add by xly on 110217 增加支持多个数门窗插入门窗
void InsertNewOpening(int nNums, TDbOpening *pWin, AcDbObjectId idWall, AcGePoint3dArray aryPts, int nType=0, bool isPier = false);
void InsertNewOpening(int nNums, TDbOpening *pWin, AcDbObjectId idWall, AcGePoint3dArray aryPts, int nType,bool isPier)
{
if (aryPts.length()<1)
{
return;
}
XPoint ptLoc = pWin->GetLocation(),
ptPos;
double dWidth = pWin->GetWidth();
double dAngle = pWin->GetRotation();
double dDist(0.0);
// add by xly on 110316 获得高度
double dHeighSill = pWin->GetSill();
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
if (!pWall)
{
return;
}
bool bIsStart(false);
if (nType==0)
{
for(int n=0; n<aryPts.length(); n++)
{
ptLoc = aryPts[n];
dDist = 0.0;
if (nNums%2 == 0)// 偶数个门
{
for (int i=0; i<nNums; i++)
{
bIsStart = !bIsStart;
if (i==0)
{
dDist += dWidth/2.0;
}
else if (i%2 == 0)
{
dDist += dWidth;
}
XPointDir2d ptTemp;
// 计算门的插入点
if (pWall->Is(CURVE_ARC))// 圆弧门窗插入
{
XCurveSegment segSide=pWall->OffsetGeomCenter(LS_INFINITE, TRUE);
ptTemp = GetPtArc(segSide, dDist, bIsStart, ptLoc);
ptPos = ptTemp.AsAcGePoint3d();
}
else
{
ads_polar(ptLoc,dAngle,dDist,ptPos);
}
if (pWall->CanInsertOpening(*pWin))
{
// 插入门
TDbOpening *pNewOpening = (TDbOpening*)pWin->clone();
pNewOpening->InitHardPointerId();
if (isPier&&pWall->Is(CURVE_ARC))
{
pNewOpening->SetRotation(ptTemp.nDirection);
}
pNewOpening->SetLocation(ptPos);
pNewOpening->SetWallId(pWall->objectId());
pNewOpening->SetLayoutRotation(Ucs2Wcs(0));
// add by xly on 110316 设置高度
pNewOpening->SetSill(dHeighSill);
pNewOpening->m_ptLabel=pNewOpening->GetDefaultLabPos();
pNewOpening->AddToMSpace(Adesk::kFalse);
pWall->upgradeOpen();
pWall->AddOpeningId(pNewOpening->objectId());
pWall->downgradeOpen();
pNewOpening->close();
}
else
{
adsout << _T("\n不能插到该墙上(门窗高度或宽度方向超出墙体)!");
}
dAngle = PI+dAngle;
}
}
else// 奇数个门
{
XPointDir2d ptTemp;
if (pWall->CanInsertOpening(*pWin))
{
// 插入门
TDbOpening *pNewOpening = (TDbOpening*)pWin->clone();
pNewOpening->InitHardPointerId();
if (isPier)
{
if (pWall->Is(CURVE_ARC))// 圆弧门窗插入
{
XCurveSegment segSide=pWall->OffsetGeomCenter(LS_INFINITE, TRUE);
if (isPier)
{
ptTemp = GetPtArc(segSide, 0, 1, ptLoc);
ptLoc = ptTemp.AsAcGePoint3d();
}
pNewOpening->SetRotation(ptTemp.nDirection);
}
}
pNewOpening->SetLocation(ptLoc);
pNewOpening->SetWallId(pWall->objectId());
pNewOpening->SetLayoutRotation(Ucs2Wcs(0));
// add by xly on 110316 设置高度
pNewOpening->SetSill(dHeighSill);
pNewOpening->m_ptLabel=pNewOpening->GetDefaultLabPos();
pNewOpening->AddToMSpace(Adesk::kFalse);
pWall->upgradeOpen();
pWall->AddOpeningId(pNewOpening->objectId());
pWall->downgradeOpen();
pNewOpening->close();
}
else
{
adsout << _T("\n不能插到该墙上(门窗高度或宽度方向超出墙体)!");
}
for (int i=1; i<nNums; i++)
{
bIsStart = !bIsStart;
if (i%2 != 0)
{
dDist += dWidth;
}
if (pWall->Is(CURVE_ARC)) // 圆弧门窗的插入
{
XCurveSegment segSide=pWall->OffsetGeomCenter(LS_INFINITE, TRUE);
ptTemp = GetPtArc(segSide, dDist, bIsStart, ptLoc);
ptPos = ptTemp.AsAcGePoint3d();
}
else
{
ads_polar(ptLoc,dAngle,dDist,ptPos);
}
if (pWall->CanInsertOpening(*pWin))
{
TDbOpening *pNewOpening = (TDbOpening*)pWin->clone();
pNewOpening->InitHardPointerId();
if (isPier && pWall->Is(CURVE_ARC))
{
pNewOpening->SetRotation(ptTemp.nDirection);
}
pNewOpening->SetLocation(ptPos);
pNewOpening->SetWallId(pWall->objectId());
pNewOpening->SetLayoutRotation(Ucs2Wcs(0));
pNewOpening->m_ptLabel=pNewOpening->GetDefaultLabPos();
// add by xly on 110316 设置高度
pNewOpening->SetSill(dHeighSill);
pNewOpening->AddToMSpace(Adesk::kFalse);
pWall->upgradeOpen();
pWall->AddOpeningId(pNewOpening->objectId());
pWall->downgradeOpen();
pNewOpening->close();
}
else
{
adsout << _T("\n不能插到该墙上(门窗高度或宽度方向超出墙体)!");
}
dAngle = PI+dAngle;
}
}
}
}
else if (nType==2)// 等分插入
{
dDist = dWidth;
for(int n=0; n<aryPts.length(); n++)
{
ptLoc = aryPts[n];
if (pWall->CanInsertOpening(*pWin))
{
XPointDir2d ptTemp;
// 计算门的插入点
if (pWall->Is(CURVE_ARC))// 圆弧门窗插入
{
XCurveSegment segSide=pWall->OffsetGeomCenter(LS_INFINITE, TRUE);
ptTemp = GetPtArc(segSide, 0, 1, ptLoc);
ptLoc = ptTemp.AsAcGePoint3d();
}
// 插入门
TDbOpening *pNewOpening = (TDbOpening*)pWin->clone();
pNewOpening->InitHardPointerId();
pNewOpening->SetLocation(ptLoc);
pNewOpening->SetWallId(pWall->objectId());
pNewOpening->SetLayoutRotation(Ucs2Wcs(0));
if (pWall->Is(CURVE_ARC))
{
pNewOpening->SetRotation(ptTemp.nDirection);
}
// add by xly on 110316 设置高度
pNewOpening->SetSill(dHeighSill);
pNewOpening->m_ptLabel=pNewOpening->GetDefaultLabPos();
pNewOpening->AddToMSpace(Adesk::kFalse);
pWall->upgradeOpen();
pWall->AddOpeningId(pNewOpening->objectId());
pWall->downgradeOpen();
pNewOpening->close();
if (isPier)
{
XPoint ptRet;
XPoint ptS = pWall->GetStartPoint(),
ptE = pWall->GetEndPoint();
double dTemp(0.0);
bool bIsHas(false);
const DList<AcDbSoftPointerId> &lstWin = pWall->GetOpeningIdList();
if (lstWin.Length()>0)// 墙体上的门窗对象的个数大于等于1
{
// 遍历墙体中的所有的门窗对象,找到距ptLoc最近的对象
for(int n = 0;n < lstWin.Length();n++)
{
AcDbObjectId id = lstWin[n];
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbOpening, pWin);
if(pWin)
{
XPoint pt = pWin->GetLocation();
if (n==0)
{
dTemp = ptLoc.Distance(pt);
}
else
{
double dDistNew = ptLoc.Distance(pt);
if (dDistNew<dTemp && fabs(dDistNew)>_DIST_SNAP)
{
dTemp = dDistNew;
ptRet = pt;
bIsHas = true;
}
}
}
OPENOBJ_END();
}
}
if (bIsHas)
{
AcGeVector3d verSE = ptE-ptS;
AcGeVector3d verS = ptLoc-ptS;
AcGeVector3d verE = ptLoc-ptE;
AcGeVector3d verNear = ptLoc-ptRet;
if (verNear.length()>verE.length())// E小
{
if (verE.length()>verS.length())// s小
{
if (verS.dotProduct(verSE)>_DIST_SNAP)
{
dAngle = pWin->GetRotation();
}
else
{
dAngle += PI;
}
}
else
{
if (verE.dotProduct(verSE)>_DIST_SNAP)
{
dAngle = pWin->GetRotation();
}
else
{
dAngle += PI;
}
}
}
else
{
if (verNear.length()>verS.length())//s小
{
if (verS.dotProduct(verSE)>_DIST_SNAP)
{
dAngle = pWin->GetRotation();
}
else
{
dAngle += PI;
}
}
else
{
if (verNear.dotProduct(verSE)>_DIST_SNAP)
{
dAngle = pWin->GetRotation();
}
else
{
dAngle += PI;
}
}
}
}
else if (ptLoc.Distance(ptS)>ptLoc.Distance(ptE))
{
dAngle += PI;
}
}
// 一串门窗中门窗的个数
for (int i=1; i<nNums; i++)
{
XPointDir2d ptTemp;
// 计算门的插入点
if (pWall->Is(CURVE_ARC))// 圆弧门窗插入
{
XPoint ptS = pWall->GetStartPoint(),
ptE = pWall->GetEndPoint();
XCurveSegment segSide=pWall->OffsetGeomCenter(LS_INFINITE, TRUE);
if (isPier)
{
ptTemp = GetPtArc(segSide, dDist*i, (ptLoc.Distance(ptS)<ptLoc.Distance(ptE)), ptLoc);
}
else
{
ptTemp = GetPtArc(segSide, dDist*i, 1, ptLoc);
}
ptPos = ptTemp.AsAcGePoint3d();
}
else
{
ads_polar(ptLoc, dAngle, dDist*i, ptPos);
}
if (pWall->CanInsertOpening(*pWin))
{
// 插入门
TDbOpening *pNewOpening = (TDbOpening*)pWin->clone();
pNewOpening->InitHardPointerId();
pNewOpening->SetLocation(ptPos);
pNewOpening->SetWallId(pWall->objectId());
pNewOpening->SetLayoutRotation(Ucs2Wcs(0));
if (pWall->Is(CURVE_ARC))// 圆弧门窗插入
{
pNewOpening->m_nRotation = ptTemp.nDirection;
}
pNewOpening->m_ptLabel=pNewOpening->GetDefaultLabPos();
// add by xly on 110316 设置高度
pNewOpening->SetSill(dHeighSill);
pNewOpening->AddToMSpace(Adesk::kFalse);
pWall->upgradeOpen();
pWall->AddOpeningId(pNewOpening->objectId());
pWall->downgradeOpen();
pNewOpening->close();
}
else
{
adsout << _T("\n不能插到该墙上(门窗高度或宽度方向超出墙体)!");
}
}
}
else
{
adsout << _T("\n不能插到该墙上(门窗高度或宽度方向超出墙体)!");
}
}
}
OPENOBJ_END();
}
// 自由插入门窗
// 0:Exit; 1:Change Insert Mode
BOOL FreeInsert()
{
//add by whl
ASSERT(CInsertOpeningDlg::g_pCurDlg!=NULL);
CInsertOpeningDlg*& pDlg=CInsertOpeningDlg::g_pCurDlg;
BOOL bRetCode=FALSE;
XPoint ptOld, ptNew;
while(1)
{
pDlg->EnableWindow(TRUE); //让对话框出于活动状态
TDbOpening *pWin=pDlg->NewOpening();
pDlg->AttachOpening(pWin);
ASSERT(pWin);
AcDbObjectId idWall;
idWall=GetOpeingLocation(_T("\n点取门窗插入位置(Shift-左右开)<退出>:"),pWin,true);
//add by whl
if (pDlg!=NULL&&pDlg->IsWindowVisible())
pDlg->UpdateOpening(*pWin);
// add by xly on 110301是否不穿透,但是厚度大于墙体厚度
if (pWin->GetKind() == TDbOpening::OP_HOLE)
{
if (CRectHoleDlg::m_bIsHasPassWall)
{
acutPrintf(_T("\n注意:墙厚小于洞深,请重新设置参数!"));
CRectHoleDlg::m_bIsHasPassWall = false;
}
}
if (!idWall)
{
bRetCode=(pDlg->GetInsertMode()!=ID_FREE_INSERT);
delete pWin;
break;
}
//modify by xlc on 070511
// if (!ValidateLabelInCurDwg(*pWin))
// {
// adsout << _T("\n与图中已有同样编号的门窗参数不一致!");
// delete pWin;
// continue;
// }
if (!ValidateCurLabel(*pWin))
{
delete pWin;
continue;
}
// add by xly on 110218 增加支持多个数门窗插入门窗
AcGePoint3dArray aryPts;
OPENOBJ_BEGIN(idWall, AcDb::kForWrite, TDbWall, pWall);
if (pWall)
{
if (pWall->Is(CURVE_LINE) && pWin->GetKind()==TOpeningData::OP_ARCWIN)
{
adsout << _T("\n请点取弧墙!");
delete pWin;
continue;
}
pWin->m_ptLocation.z = pDlg->GetOpeningSill() + pWall->GetElevation();//modified by fxj 090316
if (pWall->CanInsertOpening(*pWin)) {
pWin->SetWallId(idWall);
pWin->InitHardPointerId();
// add by xly on 110125 设置门窗对象的转角布局
pWin->SetLayoutRotation(Ucs2Wcs(0));
// modify by xly on 110217 增加支持多个数门窗插入门窗
//pWin->AddToMSpace(Adesk::kFalse);
int nType = pWin->GetKind();
if (nType!=TOpeningData::OP_DOOR && nType!=TOpeningData::OP_WINDOW && nType!=TOpeningData::OP_ARCWIN)
{
pWin->AddToMSpace(Adesk::kFalse);
}
else
{
pWin->SetSubKind(pDlg->GetOpeningStyle());
aryPts.append(pWin->m_ptLocation);
}
pWall->assertWriteEnabled();
pWall->AddOpeningId(pWin->objectId());
pWin->close();
}
else
{
adsout << _T("\n不能插到该墙上(门窗高度或宽度方向超出墙体)!");
delete pWin;
}
}
OPENOBJ_END();
// add by xly on 110217 增加支持多个数门窗插入门窗
InsertNewOpening(pDlg->GetOpeningNums(), pWin, idWall, aryPts);
// add by xly on 110503 解决内存泄露
if (aryPts.length()>0)
{
delete pWin;
}
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
}
return bRetCode;
}
// 墙垛定距插门窗
BOOL FixInsertOnPier()
{
//add by whl
ASSERT(CInsertOpeningDlg::g_pCurDlg!=NULL);
CInsertOpeningDlg*& pDlg=CInsertOpeningDlg::g_pCurDlg;
BOOL bRetCode=FALSE;
RBList wallMask(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL);
while(1)
{
XPoint ptNew;
pDlg->EnableWindow(TRUE);
TDbOpening *pWin=pDlg->NewOpening();
ASSERT(pWin);
AcDbObjectId idWall=GetOpeingLocation(_T("\n点取门窗大致的位置和开向(Shift-左右开)<退出>: "), pWin);
//add by whl
if (pDlg!=NULL&&pDlg->IsWindowVisible())
pDlg->UpdateOpening(*pWin);
// add by xly on 110301是否不穿透,但是厚度大于墙体厚度
if (pWin->GetKind() == TDbOpening::OP_HOLE)
{
if (CRectHoleDlg::m_bIsHasPassWall)
{
acutPrintf(_T("\n注意:墙厚小于洞深,请重新设置参数!"));
CRectHoleDlg::m_bIsHasPassWall = false;
}
}
if (!idWall) {
bRetCode=(pDlg->GetInsertMode()!=ID_FIXDIST_ONPIER);
delete pWin;
break;
}
// add by xly on 110218 增加支持多个数门窗插入门窗
AcGePoint3dArray aryPts;
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
ASSERT(pWall);
if (pWall->Is(CURVE_LINE) && pWin->GetKind()==TOpeningData::OP_ARCWIN) {
adsout << _T("\n请点取弧墙!");
delete pWin;
continue;
}
pWall->ProjectToMe(pWin->GetLocation(), ptNew);
ptNew.z =pWall->GetElevation();
pDlg->UpdateData(TRUE);
pDlg->EnableWindow(FALSE);
//modify by xlc on 070514
// if (!ValidateLabelInCurDwg(*pWin)) {
// adsout << _T("\n同样编号的门窗参数不一致!");
// delete pWin;
// continue;
// }
if (!ValidateCurLabel(*pWin))
{
delete pWin;
continue;
}
double nFixDist=_tstof(pDlg->g_csDist);
/*
if (pWall->GetHeight()+_DIST_SNAP < pDlg->GetOpeningSill()+pDlg->GetOpeningHeight()) {
adsout << _T("\n门窗高度方向超出墙体!");
delete pWin;
continue;
}*/
XPoint ptRef;
XCurveSegment subSeg;
if (!pWall->GetSubSegmentByPierAt(ptNew, subSeg) || subSeg.GetLength()<pDlg->GetOpeningWidth()-_DIST_SNAP) {
adsout << _T("\n点取的位置不能插入门窗(洞)!");
delete pWin;
continue;
}
ptRef=subSeg.NearPoint(ptNew);
double nFixDist1=nFixDist;
// 以基线弧长为准
//MODIFIED BY WHL ON 050706
//if (nFixDist1<0.1) nFixDist1=0.1;
if (nFixDist1<1E-9)
nFixDist1=1E-9;
XPoint ptRefOnWall;
XPointDir2d ptLoc1, ptLoc2;
if (pWall->ProjectToMe(ptRef, ptRefOnWall)!=RTNORM) {
delete pWin;
continue;
}
ads_real nPathDistRef=pWall->PathDistance(ptRefOnWall);
pWall->Polar(nPathDistRef+nFixDist1+pDlg->GetOpeningWidth()/2.0, ptLoc1);
pWall->Polar(nPathDistRef-nFixDist1-pDlg->GetOpeningWidth()/2.0, ptLoc2);
XPoint ptLoc = XLine(ptLoc1, ptLoc2).NearPoint(ptNew);
ptLoc.z = pWall->GetElevation()+pDlg->GetOpeningSill();
if (pWall->GetOpeningLocation(ptLoc, (TOpeningData::OpeningKind)pDlg->GetOpeningKind(), pDlg->GetOpeningWidth(), pWin->m_ptLocation)==TRUE
&& pWall->upgradeOpen()==Acad::eOk) {
pWin->m_ptLocation.z=ptLoc.z;
pWin->SetWallId(idWall);
pWin->InitHardPointerId();
// add by xly on 110125 设置门窗对象的转角布局
pWin->SetLayoutRotation(Ucs2Wcs(0));
// delete by xly on 110218 增加支持多个数门窗插入门窗
//pWin->AddToMSpace(Adesk::kFalse);
int nType = pWin->GetKind();
if (nType==TOpeningData::OP_DOOR || nType==TOpeningData::OP_WINDOW || nType==TOpeningData::OP_ARCWIN)
{
pWin->SetSubKind(pDlg->GetOpeningStyle());
aryPts.append(pWin->m_ptLocation);
}
else
{
pWin->AddToMSpace(Adesk::kFalse);
}
pWall->assertWriteEnabled();
pWall->AddOpeningId(pWin->objectId());
pWall->downgradeOpen();
pWin->m_ptLabel=pWin->GetDefaultLabPos();
pWin->close();
} else {
adsout << _T("\n不能插入门窗!");
delete pWin;
}
OPENOBJ_END();
// add by xly on 110218 增加支持多个数门窗插入门窗
InsertNewOpening(pDlg->GetOpeningNums(), pWin, idWall,aryPts, 2, true);
// add by xly on 110503 解决内存泄露
if (aryPts.length()>0)
{
delete pWin;
}
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
}
return bRetCode;
}
// 轴线定距插门窗
BOOL FixInsertOnAxis()
{
//add by whl
ASSERT(CInsertOpeningDlg::g_pCurDlg!=NULL);
CInsertOpeningDlg*& pDlg=CInsertOpeningDlg::g_pCurDlg;
BOOL bRetCode=FALSE;
RBList wallMask(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL);
while(1) {
XPoint ptNew;
pDlg->EnableWindow(TRUE);
TDbOpening *pWin=pDlg->NewOpening();
ASSERT(pWin);
AcDbObjectId idWall=GetOpeingLocation(_T("\n点取门窗大致的位置和开向(Shift-左右开)<退出>: "), pWin);
//add by whl
if (pDlg!=NULL&&pDlg->IsWindowVisible())
pDlg->UpdateOpening(*pWin);
// add by xly on 110301是否不穿透,但是厚度大于墙体厚度
if (pWin->GetKind() == TDbOpening::OP_HOLE)
{
if (CRectHoleDlg::m_bIsHasPassWall)
{
acutPrintf(_T("\n注意:墙厚小于洞深,请重新设置参数!"));
CRectHoleDlg::m_bIsHasPassWall = false;
}
}
if (!idWall) {
bRetCode=(pDlg->GetInsertMode()!=ID_FIXDIST_ONAXIS);
delete pWin;
break;
}
// add by xly on 110218 增加支持多个数门窗插入门窗
AcGePoint3dArray aryPts;
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
ASSERT(pWall);
if (pWall->Is(CURVE_LINE) && pWin->GetKind()==TOpeningData::OP_ARCWIN) {
adsout << _T("\n请点取弧墙!");
delete pWin;
continue;
}
pWall->ProjectToMe(pWin->GetLocation(), ptNew);
ptNew.z =pWall->GetElevation();
pDlg->UpdateData(TRUE);
pDlg->EnableWindow(FALSE);
//modify by xlc on 070514
//if (!ValidateLabelInCurDwg(*pWin)) {
// adsout << _T("\n同样编号的门窗参数不一致!");
// delete pWin;
// continue;
//}
if (!ValidateCurLabel(*pWin))
{
delete pWin;
continue;
}
double nFixDist=_tstof(pDlg->g_csDist);
/*
if (pWall->GetHeight()+_DIST_SNAP < pDlg->GetOpeningSill()+pDlg->GetOpeningHeight()) {
adsout << _T("\n门窗高度方向超出墙体!");
delete pWin;
continue;
}*/
XPoint ptRef;
XCurveSegment subSeg;
if (!pWall->GetSubSegmentByAxisAt(ptNew, subSeg) || subSeg.GetLength()<pDlg->GetOpeningWidth()-_DIST_SNAP) {
adsout << _T("\n点取的位置不能插入门窗(洞)!");
delete pWin;
continue;
}
ptRef=subSeg.NearPoint(ptNew);
double nFixDist1=nFixDist;
// 以基线弧长为准
if (nFixDist1<0.1) nFixDist1=0.1;
XPoint ptRefOnWall;
XPointDir2d ptLoc1, ptLoc2;
if (pWall->ProjectToMe(ptRef, ptRefOnWall)!=RTNORM) {
delete pWin;
continue;
}
ads_real nPathDistRef=pWall->PathDistance(ptRefOnWall);
pWall->Polar(nPathDistRef+nFixDist1+pDlg->GetOpeningWidth()/2.0, ptLoc1);
pWall->Polar(nPathDistRef-nFixDist1-pDlg->GetOpeningWidth()/2.0, ptLoc2);
XPoint ptLoc = XLine(ptLoc1, ptLoc2).NearPoint(ptNew);
ptLoc.z = pWall->GetElevation()+pDlg->GetOpeningSill();
if (pWall->GetOpeningLocation(ptLoc, (TOpeningData::OpeningKind)pDlg->GetOpeningKind(), pDlg->GetOpeningWidth(), pWin->m_ptLocation)==TRUE
&& pWall->upgradeOpen()==Acad::eOk) {
pWin->m_ptLocation.z=ptLoc.z;
pWin->SetWallId(idWall);
pWin->InitHardPointerId();
// modify by xly on 110218 增加支持多个数门窗插入门窗
//pWin->AddToMSpace(Adesk::kFalse);
int nType = pWin->GetKind();
if (nType!=TOpeningData::OP_DOOR && nType!=TOpeningData::OP_WINDOW && nType!=TOpeningData::OP_ARCWIN)
{
pWin->AddToMSpace(Adesk::kFalse);
}
else
{
pWin->SetSubKind(pDlg->GetOpeningStyle());
aryPts.append(pWin->m_ptLocation);
}
pWall->assertWriteEnabled();
// add by xly on 110125 设置门窗对象的转角布局
pWin->SetLayoutRotation(Ucs2Wcs(0));
pWall->AddOpeningId(pWin->objectId());
pWall->downgradeOpen();
pWin->m_ptLabel=pWin->GetDefaultLabPos();
pWin->close();
} else {
adsout << _T("\n不能插入门窗!");
delete pWin;
}
OPENOBJ_END();
// add by xly on 110218 增加支持多个数门窗插入门窗
InsertNewOpening(pDlg->GetOpeningNums(), pWin, idWall,aryPts, 2, true);
// add by xly on 110503 解决内存泄露
if (aryPts.length()>0)
{
delete pWin;
}
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
}
return bRetCode;
}
BOOL ArcWallInsert()
{
//add by whl
ASSERT(CInsertOpeningDlg::g_pCurDlg!=NULL);
CInsertOpeningDlg*& pDlg=CInsertOpeningDlg::g_pCurDlg;
BOOL bRetCode=FALSE;
RBList wallMask(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), -4, _T(">"), 50, _angSnap, NULL);
while(1) {
XPoint ptOld, ptNew;
pDlg->EnableWindow(TRUE);
Entity entWall;
int nRetCode=entWall.FilterSelect(_T("\n点取弧墙<退出>:"), wallMask);
if (nRetCode==RTCAN)
break;
if ((nRetCode==RTNONE || nRetCode==RTERROR)) {
bRetCode=(pDlg->GetInsertMode()!=ID_ARCWALL_INSERT);
break;
}
if (!entWall)
break;
pDlg->UpdateData(TRUE);
pDlg->EnableWindow(FALSE);
OPENOBJ_BEGIN(entWall, AcDb::kForRead, TDbWall, pWall);
if (pWall && pWall->Is(CURVE_ARC)) {
XArc ar=pWall->GetArc();
XPoint ptCen=ar.GetCenterPt();
double nAng=0.0;
int nCode=ads_getangle(Wcs2Ucs(ptCen), _T("\n门窗中心的角度<退出>:"), &nAng);
if (nCode==RTCAN)
return FALSE;
if (nCode!=RTNORM) continue;
XPoint ptInsert, ptLoc1;
ads_polar(Wcs2Ucs(ptCen), nAng, ar.GetRadius(), ptInsert);
ptInsert=Ucs2Wcs(ptInsert);
if (!pWall->GetOpeningLocation(ptInsert, (TOpeningData::OpeningKind)pDlg->GetOpeningKind(), pDlg->GetOpeningWidth(), ptLoc1)) { //投影到墙心上
adsout << _T("\n不能插到该墙上!");
} else {
if (!pDlg->NewEntityToModelSpace(pWall, ptLoc1).isValid())
adsout << _T("\n不能插到该墙上!");
}
}
OPENOBJ_END();
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
}
return bRetCode;
}
// 顺序插门窗
// Modify on 2002/2/25 by ZJQ, 弧墙应当按照基线顺序插入
BOOL SequenceInsert()
{
extern AcDbObjectId SnapOnWall(const XPoint &ptWcs);
//add by whl
ASSERT(CInsertOpeningDlg::g_pCurDlg!=NULL);
CInsertOpeningDlg*& pDlg=CInsertOpeningDlg::g_pCurDlg;
BOOL bRetCode=FALSE;
RBList wallMask(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL);
// modify by xly on 110113修改距离的默认参数
//static ads_real nFixDist=300.0;
static ads_real nFixDist = 1200;
XPoint ptRef;
BOOL bInit=FALSE;
while(1) {
XPoint ptPick;
pDlg->EnableWindow(TRUE);
Entity entWall;
CInsertOpeningDlg::bLineWall=false;//add by whl
int nRetCode=entWall.FilterSelect(_T("\n点取墙体<退出>:"), wallMask, ptPick);
if (nRetCode==RTCAN)
break;
if ((nRetCode==RTNONE || nRetCode==RTERROR)) {
bRetCode=(pDlg->GetInsertMode()!=ID_SEQUENCE_INSERT);
break;
}
if (!entWall)
break;
ptPick=Ucs2Wcs(ptPick);
XCurveSegment segSide;
OPENOBJ_BEGIN(entWall, AcDb::kForRead, TDbWall, pWall);
ASSERT(pWall);
if (pWall->Is(CURVE_ARC))
{
if (!pWall->GetSubSegmentAt(ptPick, segSide)) {
adsout << _T("\n请正确点取!");
continue;
}
} else {
//add by whl
if (pDlg->GetOpeningKind()==TOpeningData::OP_ARCWIN)
{
adsout <<_T("当前门窗类型是弧窗,请点取弧墙!");
continue;
}
if (!pWall->GetSubSegmentOnSideAt(ptPick, segSide)) {
adsout << _T("\n请正确点取!");
continue;
}
CInsertOpeningDlg::bLineWall=true;//add by whl
}
OPENOBJ_END();
BOOL bFromStart=(segSide.NearPoint(ptPick)==(double *)segSide.StartPoint());
// 2001/7/21
XPointList lstPoints;
XPoint ptFen1, ptFen2;
ptFen1=Wcs2Ucs(segSide.StartPoint());
ptFen2=Wcs2Ucs(segSide.EndPoint());
RBList rbFence=ads_buildlist(RT3DPOINT, &ptFen1, RT3DPOINT, &ptFen2, NULL);
PickSet ssAxis(SS_FREE);
RBList rbAxisMask=ads_buildlist(RTDXF0, _T("LINE"), 8, LAY_AXIS, NULL);
lstPoints.Append(new XPoint(segSide.GetStartPoint()));
lstPoints.Append(new XPoint(segSide.GetEndPoint()));
if (ssAxis.Get(_T("F"), rbFence, NULL, rbAxisMask)==RTNORM) {
XLine lnSide=segSide;
lnSide.SetLineFlag(LS_FINITE);
long lAxisNum=ssAxis.Length();
for(long i=0L; i<lAxisNum; i++) {
Entity ent=ssAxis[i];
XLine lnAxis(ent, LS_FINITE);
XPoint ptInt;
if (lnSide.Intersection(&lnAxis, ptInt))
lstPoints.Append(new XPoint(ptInt));
}
}
XPoint ptBase;
for(int i=0; i<lstPoints.Length(); i++) {
if (i==0) ptBase=*lstPoints[i];
else {
if (ptPick.Distance2d(*lstPoints[i])<ptPick.Distance2d(ptBase))
ptBase=*lstPoints[i];
}
}
// add by xly on 110220 增加支持多个数门窗插入门窗
double dDis(0.0);
if (pDlg->GetOpeningNums()>1)
{
dDis = (pDlg->GetOpeningNums()-1)*pDlg->GetOpeningWidth();
}
//XPoint ptBase=bFromStart? segSide.StartPoint() : segSide.EndPoint();
double nBaseDist=segSide.PathDistance(ptBase, bFromStart);
Entity entLastWin;
while(1) {
// modify by xly on 110113 修交互的提示
//const TCHAR *pszPrompt=NULL;
/*if (!entLastWin) {
pszPrompt=segSide.Is(CURVE_ARC)?
_T("\n输入从基点到门窗侧边的弧长<退出>:") :
_T("\n输入从基点到门窗侧边的距离<退出>:");
} else {
pszPrompt=segSide.Is(CURVE_ARC)?
_T("\n输入从基点到门窗侧边的弧长或 [左右翻转(S)/内外翻转(D)]<退出>:") :
_T("\n输入从基点到门窗侧边的距离或 [左右翻转(S)/内外翻转(D)]<退出>:") ;
}*/
CString pszPrompt=_T("");
if (!entLastWin)
{
if(segSide.Is(CURVE_ARC))
{
pszPrompt.Format(_T("\n输入从基点到门窗侧边的弧长或 [取间距%.0f(L)] <退出>:"),(double)nFixDist);
}
else
{
pszPrompt.Format(_T("\n输入从基点到门窗侧边的距离或 [取间距%.0f(L)] <退出>:"),(double)nFixDist);
}
}
else
{
if (segSide.Is(CURVE_ARC))
{
pszPrompt.Format(_T("\n输入从基点到门窗侧边的弧长或 [左右翻转(S)/内外翻转(D)/取间距%.0f(L)]<退出>:"),(double)nFixDist);
}
else
{
pszPrompt.Format(_T("\n输入从基点到门窗侧边的距离或 [左右翻转(S)/内外翻转(D)/取间距%.0f(L)]<退出>:"),(double)nFixDist);
}
}
// modify by xly on 110125 修改门窗对象支持转角布局
OPENOBJ_BEGIN(entLastWin, AcDb::kForWrite, TDbOpening, pLastWin);
if (pLastWin)
{
pLastWin->SetLayoutRotation(Ucs2Wcs(0));
}
OPENOBJ_END();
// add by xly on 110302 支持用户坐标
ptBase = Wcs2Ucs(ptBase);
if (!entLastWin) {
// modify by xly on 110113 支持关键字L
INITGET_BEG(RSG_NONEG, _T("L"));
nRetCode=ads_getdist(ptBase, pszPrompt, &nFixDist);
INITGET_END();
} else {
INITGET_BEG(RSG_NONEG, _T("S D L"));
nRetCode=ads_getdist(ptBase, pszPrompt, &nFixDist);
INITGET_END();
}
// modify by xly on 110113 拾取距离时支持关键字L
/* if (nRetCode==RTKWORD) {
XString sInput;
ads_getinput(sInput);
bool bLeftRight=(sInput[0]==_T('S'));
OPENOBJ_BEGIN(entLastWin, AcDb::kForWrite, TDbOpening, pLastWin);
if (pLastWin)
pLastWin->MirrorSelf(bLeftRight);
OPENOBJ_END();
continue;
} else if (nRetCode!=RTNORM)
break;*/
if (!entLastWin)
{
if (nRetCode==RTKWORD)
{
nFixDist = nFixDist;
}
else if (nRetCode!=RTNORM)
break;
}
else
{
if (nRetCode==RTKWORD)
{
XString sInput;
ads_getinput(sInput);
if (sInput[0]==_T('L')) // 输入L关键字
{
nFixDist = nFixDist;
}
else // 输入SD关键字
{
bool bLeftRight=(sInput[0]==_T('S'));
OPENOBJ_BEGIN(entLastWin, AcDb::kForWrite, TDbOpening, pLastWin);
if (pLastWin)
pLastWin->MirrorSelf(bLeftRight);
OPENOBJ_END();
continue;
}
}
else if (nRetCode!=RTNORM)
break;
}
pDlg->UpdateData(TRUE);
XPointDir2d ptIns;
segSide.Polar(nBaseDist+nFixDist+pDlg->GetOpeningWidth()/2, ptIns, bFromStart);
AcDbObjectId idWall=SnapOnWall(ptIns);
if (!idWall) {
adsout << _T("\n给定的位置没有墙体!");
continue;
}
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
ASSERT(pWall);
/*
if (pWall->GetHeight()+_DIST_SNAP < pDlg->GetOpeningSill()+pDlg->GetOpeningHeight()) {
adsout << _T("\n门窗高度方向超出墙体!");
continue;
}*/
XPoint ptLoc1;
if (!pWall->GetOpeningLocation(ptIns, (TOpeningData::OpeningKind)pDlg->GetOpeningKind(), pDlg->GetOpeningWidth(), ptLoc1)) { //投影到墙心上
adsout << _T("\n不能插到该墙上!");
continue;
}
if (!pDlg->NewEntityToModelSpace(pWall, ptLoc1).isValid()) {
adsout << _T("\n不能插到该墙上!");
continue;
} else
entLastWin.GetLast();
OPENOBJ_END();
// modify by xly on 110220 增加多门窗绘制
/*nBaseDist += nFixDist+pDlg->GetOpeningWidth();*/
nBaseDist += nFixDist+pDlg->GetOpeningWidth()+dDis;
segSide.Polar(nBaseDist, ptIns, bFromStart);
ptBase=ptIns;
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
}
if (nRetCode==RTCAN)
break;
if ((nRetCode==RTNONE || nRetCode==RTERROR)) {
bRetCode=(pDlg->GetInsertMode()!=ID_SEQUENCE_INSERT);
break;
}
}
CInsertOpeningDlg::bLineWall=false;//add by whl
return bRetCode;
}
// 轴线等分插门窗
BOOL IsoInsert()
{
//add by whl
ASSERT(CInsertOpeningDlg::g_pCurDlg!=NULL);
CInsertOpeningDlg*& pDlg=CInsertOpeningDlg::g_pCurDlg;
int nOsMode=0;
xg_getvar(_T("OSMODE"), &nOsMode);
nOsMode |= 0x4000;
XPushVar<int> osmode(_T("OSMODE"), nOsMode);
BOOL bRetCode=FALSE;
XPoint ptOld, ptNew;
while(1) {
pDlg->EnableWindow(TRUE);
TDbOpening *pWin=pDlg->NewOpening();
ASSERT(pWin);
AcDbObjectId idWall=GetOpeingLocation(_T("\n点取门窗大致的位置和开向(Shift-左右开)<退出>: "), pWin);
//add by whl
if (pDlg!=NULL&&pDlg->IsWindowVisible())
pDlg->UpdateOpening(*pWin);
// add by xly on 110301是否不穿透,但是厚度大于墙体厚度
if (pWin->GetKind() == TDbOpening::OP_HOLE)
{
if (CRectHoleDlg::m_bIsHasPassWall)
{
acutPrintf(_T("\n注意:墙厚小于洞深,请重新设置参数!"));
CRectHoleDlg::m_bIsHasPassWall = false;
}
}
if (!idWall) {
bRetCode=(pDlg->GetInsertMode()!=ID_LINE_INSERT);
delete pWin;
break;
}
// add by xly on 110218 增加支持多个数门窗插入门窗
AcGePoint3dArray aryPts;
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
ASSERT(pWall);
if (pWall->Is(CURVE_LINE) && pWin->GetKind()==TOpeningData::OP_ARCWIN) {
adsout << _T("\n请点取弧墙!");
delete pWin;
continue;
}
pWall->ProjectToMe(pWin->GetLocation(), ptNew);
ptNew.z =pWall->GetElevation();
pDlg->UpdateData(TRUE);
pDlg->EnableWindow(FALSE);
//modify by xlc on 070514
// if (!ValidateLabelInCurDwg(*pWin)) {
// adsout << _T("\n同样编号的门窗参数不一致!");
// delete pWin;
// continue;
// }
if (!ValidateCurLabel(*pWin))
{
delete pWin;
continue;
}
static int nOpNum=1;
XCurveSegment segThis=*pWall;
double nUnitLen=0.0;
// midify by xly on 110222 支持多个门窗插入
int nNums = pDlg->GetOpeningNums();
//int nRet=pWall->GetIsoParameters(pDlg->GetOpeningWidth(), ptNew, segThis, &nOpNum, &nUnitLen);
if (nNums<1)
{
nNums = 1;
}
int nRet=pWall->GetIsoParameters(pDlg->GetOpeningWidth()*nNums, ptNew, segThis, &nOpNum, &nUnitLen);
if (nRet==RTCAN) {
delete pWin;
return FALSE;
}
if (nRet==RTERROR ) {
adsout << _T("\n不能插入门窗!");
delete pWin;
continue;
}
/*
if (pWall->GetHeight()+_DIST_SNAP < pWin->GetSill()+pWin->GetHeight()) {
adsout << _T("\n门窗高度方向超出墙体!");
delete pWin;
continue;
}*/
// add by xly on 110218 增加支持多个数门窗插入门窗
if (nUnitLen<(pDlg->GetOpeningNums()*pDlg->GetOpeningWidth()))
{
adsout << _T("\n轴线间距小于门窗总宽,不能插入门窗!");
delete pWin;
continue;
}
for(int n=0; n<nOpNum; n++) {
XPointDir2d ptLoc;
segThis.Polar((n+0.5)*nUnitLen, ptLoc);
XPoint ptLoc1;
if (!pWall->GetOpeningLocation(ptLoc, (TOpeningData::OpeningKind)pDlg->GetOpeningKind(), pDlg->GetOpeningWidth(), ptLoc1)) { //投影到墙心上
adsout << _T("\n不能插到该墙上!");
continue;
}
if (pWall->upgradeOpen()==Acad::eOk) {
TDbOpening *pNewOp=(TDbOpening *)pWin->clone();
double nSill=pDlg->GetOpeningSill();
ptLoc1.z = pWall->GetElevation()+nSill;
pNewOp->m_ptLocation = ptLoc1;
pNewOp->m_ptLabel += ptLoc1-pWin->GetLocation();
pNewOp->m_ptLabel.z =0;
pNewOp->m_nRotation = ptLoc.nDirection;
pNewOp->InitHardPointerId();
// add by xly on 110125 设置门窗对象的转角布局
pNewOp->SetLayoutRotation(Ucs2Wcs(0));
// modify by xly on 110218 增加支持多个数门窗插入门窗
//pNewOp->AddToMSpace(Adesk::kFalse);
int nType = pNewOp->GetKind();
if (nType!=TOpeningData::OP_DOOR && nType!=TOpeningData::OP_WINDOW && nType!=TOpeningData::OP_ARCWIN)
{
pNewOp->AddToMSpace(Adesk::kFalse);
}
else
{
pWin->SetSubKind(pDlg->GetOpeningStyle());
aryPts.append(ptLoc1);
}
pNewOp->SetWallId(pWall->objectId());
pWall->assertWriteEnabled();
pWall->AddOpeningId(pNewOp->objectId());
pNewOp->close();
pWall->downgradeOpen();
}
}
//delete pWin; // modify by xly on 110218 增加支持多个数门窗插入门窗
OPENOBJ_END();
// add by xly on 110218 增加支持多个数门窗插入门窗
InsertNewOpening(pDlg->GetOpeningNums(), pWin, idWall,aryPts,0,true);
delete pWin;
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
}
return bRetCode;
}
// 墙段等分插门窗
BOOL IsoWallInsert()
{
//add by whl
ASSERT(CInsertOpeningDlg::g_pCurDlg!=NULL);
CInsertOpeningDlg*& pDlg=CInsertOpeningDlg::g_pCurDlg;
int nOsMode=0;
xg_getvar(_T("OSMODE"), &nOsMode);
nOsMode |= 0x4000;
XPushVar<int> osmode(_T("OSMODE"), nOsMode);
BOOL bRetCode=FALSE;
XPoint ptOld, ptNew;
while(1) {
pDlg->EnableWindow(TRUE);
TDbOpening *pWin=pDlg->NewOpening();
ASSERT(pWin);
AcDbObjectId idWall=GetOpeingLocation(_T("\n点取门窗大致的位置和开向(Shift-左右开)<退出>: "), pWin);
//add by whl
if (pDlg!=NULL&&pDlg->IsWindowVisible())
pDlg->UpdateOpening(*pWin);
// add by xly on 110301是否不穿透,但是厚度大于墙体厚度
if (pWin->GetKind() == TDbOpening::OP_HOLE)
{
if (CRectHoleDlg::m_bIsHasPassWall)
{
acutPrintf(_T("\n注意:墙厚小于洞深,请重新设置参数!"));
CRectHoleDlg::m_bIsHasPassWall = false;
}
}
if (!idWall) {
bRetCode=(pDlg->GetInsertMode()!=ID_WALL_INSERT);
delete pWin;
break;
}
//modify by xlc on 070514
//if (!ValidateLabelInCurDwg(*pWin)) {
// adsout << _T("\n同样编号的门窗参数不一致!");
// delete pWin;
// continue;
//}
if (!ValidateCurLabel(*pWin))
{
delete pWin;
continue;
}
// add by xly on 110218 增加支持多个数门窗插入门窗
AcGePoint3dArray aryPtsPos;// 保存每组门窗的插入点
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
ASSERT(pWall);
if (pWall->Is(CURVE_LINE) && pWin->GetKind()==TOpeningData::OP_ARCWIN) {
adsout << _T("\n请点取弧墙!");
delete pWin;
continue;
}
/*
if (pWall->GetHeight()+_DIST_SNAP < pWin->GetSill()+pWin->GetHeight()) {
adsout << _T("\n门窗高度方向超出墙体!");
delete pWin;
continue;
}*/
pWall->ProjectToMe(pWin->GetLocation(), ptNew);
ptNew.z =pWall->GetElevation();
pDlg->UpdateData(TRUE);
pDlg->EnableWindow(FALSE);
XDbObject objWall(pWall);
XCurveSegment segOn; //发生等分的墙段
if (!pWall->GetSubSegmentByPierAt(ptNew, segOn)) {
adsout << _T("\n点取的位置不能等分!");
delete pWin;
continue;
}
// modify by xly on 110222 支持门窗个数插入
// int nMaxNum=AS_INT(segOn.GetLength()/pDlg->GetOpeningWidth());
int nNums = pDlg->GetOpeningNums();
if (nNums<1)
{
nNums = 1;
}
// sg modify 110802,解决当门窗个数不止1个时候的计算错误问题,由于操作符的结合顺序不清楚导致
//int nMaxNum=AS_INT(segOn.GetLength()/pDlg->GetOpeningWidth()*nNums);
int nMaxNum=AS_INT(segOn.GetLength()/(pDlg->GetOpeningWidth()*nNums));
if (nMaxNum<1) {
adsout << _T("\n点取的位置不能等分!");
delete pWin;
continue;
}
ASSERT(!!segOn && segOn.GetLength()>_DIST_SNAP);
static int nOpNum=1;
if (nOpNum>nMaxNum)
nOpNum=1;
// modify by xly on110218 修改命令行提示
//adsout << _T("\n门窗个数(1~") << nMaxNum << _T(")<") << nOpNum << _T(">: ");
adsout << _T("\n门窗\\门窗组个数(1~") << nMaxNum << _T(")<") << nOpNum << _T(">: ");
ads_initget(RSG_NONEG|RSG_NOZERO, NULL);
int nRet=ads_getint(_T(""), &nOpNum);
if (nRet==RTCAN || nOpNum>nMaxNum) {
delete pWin;
if (nRet==RTCAN)
return nRet;
adsout << _T("\n不能按指定的数目等分!");
continue;
}
ASSERT(nOpNum>0);
//double nUnitLen=0.0;
ads_real nCurveLen=segOn.GetLength();
//nUnitLen=nCurveLen/nOpNum; //单元长度
double b=pDlg->GetOpeningWidth();// 门窗宽度
// modify by xly on 110218 增加多门窗绘制
//double a=(nCurveLen-nOpNum*b)/(nOpNum+1);//门窗间距
double a=(nCurveLen-nOpNum*b*nNums)/(nOpNum+1);//门窗间距
double dSingleWidth = b;
b = nNums*dSingleWidth;
if (a<-_DIST_SNAP) {
// modify by xly on 110222 修改提示语
//adsout << _T("\n点取的位置不能等分!");
adsout << _T("\n不能插入指定个数的门窗(洞)!");
delete pWin;
continue;
}
// 插入门窗
for(int n=0; n<nOpNum; n++) {
XPointDir2d ptLoc;
// modify by xly on 110218 增加多个门窗
//segOn.Polar((n+1)*a+(n+0.5)*b, ptLoc);
segOn.Polar((n+1)*a+(n)*b+dSingleWidth*0.5, ptLoc);
XPoint ptLoc1;
if (!pWall->GetOpeningLocation(ptLoc, (TOpeningData::OpeningKind)pDlg->GetOpeningKind(), pDlg->GetOpeningWidth(), ptLoc1)) { //投影到墙心上
adsout << _T("\n不能插到该墙上!");
continue;
}
if (pWall->upgradeOpen()==Acad::eOk) {
TDbOpening *pNewOp=(TDbOpening *)pWin->clone();
double nSill=pDlg->GetOpeningSill();
ptLoc1.z = pWall->GetElevation()+nSill;
pNewOp->m_ptLocation = ptLoc1;
pNewOp->m_ptLabel += ptLoc1-pWin->GetLocation();
pNewOp->m_ptLabel.z =0;
pNewOp->m_nRotation = ptLoc.nDirection;
pNewOp->InitHardPointerId();
// add by xly on 110125 设置门窗对象的转角布局
pNewOp->SetLayoutRotation(Ucs2Wcs(0));
// delete by xly on 110218 增加支持多个数门窗插入门窗
//pNewOp->AddToMSpace(Adesk::kFalse);
int nType = pNewOp->GetKind();
if (nType==TOpeningData::OP_DOOR || nType==TOpeningData::OP_WINDOW || nType==TOpeningData::OP_ARCWIN)
{
pWin->SetSubKind(pDlg->GetOpeningStyle());
// 保存门窗的插入点
aryPtsPos.append(ptLoc1);
}
else
{
pNewOp->AddToMSpace(Adesk::kFalse);
}
pNewOp->SetWallId(pWall->objectId());
pWall->assertWriteEnabled();
pWall->AddOpeningId(pNewOp->objectId());
pNewOp->close();
pWall->downgradeOpen();
}
}
// delete pWin;// delete by xly on 110218 增加支持多个数门窗插入门窗
OPENOBJ_END();
// add by xly on 110218 增加支持多个数门窗插入门窗
InsertNewOpening(pDlg->GetOpeningNums(), pWin, idWall,aryPtsPos,2);
delete pWin;
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
}
return bRetCode;
}
// 满墙插门窗
BOOL ColInsert()
{
//add by whl
ASSERT(CInsertOpeningDlg::g_pCurDlg!=NULL);
CInsertOpeningDlg*& pDlg=CInsertOpeningDlg::g_pCurDlg;
int nOsMode=0;
xg_getvar(_T("OSMODE"), &nOsMode);
nOsMode |= 0x4000;
XPushVar<int> osmode(_T("OSMODE"), nOsMode);
BOOL bRetCode=FALSE;
while(1) {
pDlg->EnableWindow(TRUE); //让对话框出于活动状态
TDbOpening *pWin=pDlg->NewOpening();
ASSERT(pWin);
AcDbObjectId idWall=GetOpeingLocation(_T("\n点取门窗大致的位置和开向(Shift-左右开)<退出>: "), pWin);
//add by whl
if (pDlg!=NULL&&pDlg->IsWindowVisible())
pDlg->UpdateOpening(*pWin);
// add by xly on 110301是否不穿透,但是厚度大于墙体厚度
if (pWin->GetKind() == TDbOpening::OP_HOLE)
{
if (CRectHoleDlg::m_bIsHasPassWall)
{
acutPrintf(_T("\n注意:墙厚小于洞深,请重新设置参数!"));
CRectHoleDlg::m_bIsHasPassWall = false;
}
}
if (!idWall) {
bRetCode=(pDlg->GetInsertMode()!=ID_COLUMN_INSERT);
delete pWin;
break;
}
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
ASSERT(pWall);
/*
if (pWall->GetHeight()+_DIST_SNAP<pDlg->GetOpeningHeight()+pDlg->GetOpeningSill()) {
adsout << _T("\n门窗超出墙体高度!");
delete pWin;
continue;
}*/
if (pWall->Is(CURVE_LINE) && pWin->GetKind()==TOpeningData::OP_ARCWIN
|| pWall->Is(CURVE_ARC) && pWin->GetKind()!=TOpeningData::OP_ARCWIN) {
adsout << _T("\n门窗和墙不匹配!");
delete pWin;
continue;
}
XPoint ptNew;
pWall->ProjectToMe(pWin->GetLocation(), ptNew);
ptNew.z =pWall->GetElevation();
pDlg->UpdateData(TRUE);
pDlg->EnableWindow(FALSE);
XCurveSegment segOn; //发生等分的墙段
if (!pWall->GetSubSegmentByPierAt(ptNew, segOn)) {
adsout << _T("\n点取的位置不能插入!");
delete pWin;
continue;
}
pWin->SetWidth(segOn.GetLength());
//pWin->SetWidth(segOn.Length()-0.01);//modified by whl,为解决三角化问题
//add by whl on 070606
if (pDlg!=NULL)
// if (pDlg!=NULL&&_tcscmp(_T("自动编号"),pDlg->GetOpeningLabel())==0)
{
// modify by xly on 110224 增加bool变量
//pWin->SetLabel(pWin->GetAutoLabel());
// bool bAddNum(true);
// pWin->SetLabel(pWin->GetAutoLabel(bAddNum));
// sg add 110805,解决“充满墙段插入”的方式插入的门窗,其自动编号值有问题的问题
// 主要数据是在UpdateOpening函数里,直接更新的对象,而没有更新对话框,所以没有自动计算
// 考虑满墙插门窗后,一般宽度、高度都会发生变化,一定要进行重新编号,这么写应该也可以
pDlg->InvalidateOldLabel();
// lgh modify 20110325
pWin->SetLabel(pDlg->GetAutoLabel(pWin));
pDlg->InvalidateOldLabel(); // 该编号变的无效
}
// 插入门窗
XPointDir2d ptLoc;
segOn.Polar(pWin->GetWidth()/2, ptLoc);
XPoint ptLoc1;
if (!pWall->GetOpeningLocation(ptLoc, (TOpeningData::OpeningKind)pDlg->GetOpeningKind(), pDlg->GetOpeningWidth(), ptLoc1)) { //投影到墙心上
adsout << _T("\n不能插到该墙上!");
delete pWin;
continue;
}
if (pWall->upgradeOpen()==Acad::eOk) {
double nSill=pDlg->GetOpeningSill();
ptLoc1.z = pWall->GetElevation()+nSill;
pWin->m_ptLocation = ptLoc1;
pWin->InitHardPointerId();
// add by xly on 110125 设置门窗对象的转角布局
pWin->SetLayoutRotation(Ucs2Wcs(0));
// add by xly on 110222 设置门窗弧窗类型
int nType =pWin->GetKind();
if (nType==TOpeningData::OP_DOOR || nType==TOpeningData::OP_WINDOW || nType==TOpeningData::OP_ARCWIN)
{
pWin->SetSubKind(pDlg->GetOpeningStyle());
}
pWin->AddToMSpace(Adesk::kFalse);
pWin->SetWallId(pWall->objectId());
pWall->assertWriteEnabled();
pWall->AddOpeningId(pWin->objectId());
pWall->downgradeOpen();
pWin->SetLabelPos(pWin->GetDefaultLabPos());
pWin->close();
}
OPENOBJ_END();
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
}
return bRetCode;
}
// 插入上层窗
BOOL UplevelInsert()
{
// add by whl
ASSERT(CInsertOpeningDlg::g_pCurDlg!=NULL);
CInsertOpeningDlg*& pDlg=CInsertOpeningDlg::g_pCurDlg;
XPushVar<int> vOsMode(_T("OSMODE"), 0);
//BOOL bRet=FALSE;
Entity ent;
RBList mask(RTDXF0, _T("TCH_OPENING"), NULL);
pDlg->EnableWindow(TRUE);
while(ent.FilterSelect(_T("\n选择下层门窗<退出>: "), mask)==RTNORM) {
if (!pDlg->UpdateData(TRUE))
continue;
double nSill=_tstof(pDlg->g_csDist),
nWidth=pDlg->GetOpeningWidth(), nHeight=pDlg->GetOpeningHeight();
AcDbObjectId idWall, idStyle2d, idStyle3d;
XPoint ptLoc, ptLabel;
double nWinRot=0.0;
double nTextSize=3.5;
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbOpening, pWin);
if (!pWin) continue;
nSill += pWin->GetSill() + pWin->GetHeight();
nWidth = pWin->GetWidth();
idWall = pWin->GetWallId();
ptLoc = pWin->GetLocation();
ptLabel = pWin->GetLabelPos();
nWinRot=pWin->GetRotation();
nTextSize=pWin->GetTextHeight();
OPENOBJ_END();
if (!idWall) {
adsout << _T("\n下层门窗必须在墙体内!");
continue;
}
AcDbObjectId idNewWin;
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
if (!pWall)
return FALSE;
idNewWin=pDlg->NewEntityToModelSpace(pWall, ptLoc, TRUE, nWidth, nSill);
OPENOBJ_END();
if (idNewWin.isValid()) {
XLine ln(ptLoc, nWinRot);
ln.SetElevation(0.0);
int nSide=ln.OnWhichSide(ptLabel);
double nDist2Text=DocGetText2Base();
double nDir= (nSide==0? PI/2.0 : -PI/2.0) + ln.Direction(); // add by lgh 20110119,修正上层编号跟下层编号在非水平墙上重叠的问题
OPENOBJ_BEGIN(idNewWin, AcDb::kForWrite, TDbOpening, pNewWin);
if (pNewWin) {
XPoint ptNewPos;
ads_polar(ptLabel, nDir, (nTextSize+nDist2Text)*pNewWin->GetPScale(), ptNewPos);
pNewWin->assertWriteEnabled();
pNewWin->SetLabelPos(ptNewPos);
// add by xly on 110125 设置门窗对象的转角布局
pNewWin->SetLayoutRotation(Ucs2Wcs(0));
// add by xly on 110222 设置门窗弧窗类型
int nType =pNewWin->GetKind();
if (nType==TOpeningData::OP_DOOR || nType==TOpeningData::OP_WINDOW || nType==TOpeningData::OP_ARCWIN)
{
pNewWin->SetSubKind(pDlg->GetOpeningStyle());
}
}
OPENOBJ_END();
}
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
}
pDlg->UpdateData(TRUE);
return (pDlg->GetInsertMode()!=ID_UPLEVEL_INSERT);
}
// 替换门窗
BOOL ReplaceOpening()
{
//add by whl
ASSERT(CInsertOpeningDlg::g_pCurDlg!=NULL);
CInsertOpeningDlg*& pDlg=CInsertOpeningDlg::g_pCurDlg;
XPushVar<int> vOsMode(_T("OSMODE"), 0);
RBList mask(RTDXF0, _T("TCH_OPENING"), NULL);
PickSet ss(SS_FREE);
adsout << _T("\n选择被替换的门窗!");
pDlg->EnableWindow(TRUE);
ads_sssetfirst(NULL, NULL);
while(ss.Get(NULL, NULL, NULL, mask)==RTNORM) {
if (!pDlg->UpdateData(TRUE)) {
ss.Free();
continue;
}
long lCount=ss.Length();
for(long i=0L; i<lCount; i++) {
Entity ent=ss[i];
//AcDbObjectId idWall, idStyle2d, idStyle3d;
XPoint ptLoc;
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbOpening, pWin);
if (pWin) {
pDlg->ModifyOpening(*pWin);
// add by xly on 110222 设置门窗弧窗类型
int nType =pWin->GetKind();
if (nType==TOpeningData::OP_DOOR || nType==TOpeningData::OP_WINDOW || nType==TOpeningData::OP_ARCWIN)
{
if (pWin->upgradeOpen()==Acad::eOk)
{
pWin->SetSubKind(pDlg->GetOpeningStyle());
pWin->downgradeOpen();
}
}
}
OPENOBJ_END();
}
// add bu xly on 110301 判断有多少个墙体的深度发生变化
if (CInsertOpeningDlg::curType == 6)
{
acutPrintf(_T("注意:共有%d个位置的墙厚小于洞深,请重新设置参数!"),CRectHoleDlg::m_nHasPassWallNums);
CRectHoleDlg::m_nHasPassWallNums = 0;
}
ss.Free();
TArchCmdReactor::UpdateOpenings();
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
}
pDlg->UpdateData(TRUE);
return (pDlg->GetInsertMode()!=ID_REPLACE_INSERT);
}
// add by xly on 110115 添加门窗对象
// 函数说明: id:原有门窗的id; nType:门窗对象的类型;nNums:生成门窗的个数;
// dWith:门窗洞的总宽度;
void AddOpenning(AcDbObjectId id, int nType, int nNums, double dWith, AcGePoint3d ptS, AcGePoint3d ptEnd,CInsertOpeningDlg* pDlg)
{
// 打开原门窗
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbOpening, pWin);
if(pWin)
{
// 门窗类型与原门窗类型一致
if (pWin->GetKind()==nType)
{
double dNewWith = dWith/nNums;
double dDist = dNewWith/2;
double dAngle = pWin->GetRotation();
// 生成新的门窗对象
for(int i=0; i<nNums; i++)
{
TDbOpening *pNewOp=(TDbOpening *)pWin->clone();
ASSERT(pWin);
pDlg->UpdateOpening(*pNewOp);
// 设置门窗的基本信息
pNewOp->SetKind((TOpeningData::OpeningKind)pWin->GetKind());
pNewOp->SetWidth(dNewWith);
pNewOp->SetHeight(pWin->GetHeight());
pNewOp->SetThickness(pWin->GetThickness());
pNewOp->SetSill(pWin->GetSill());
XPoint ptNewLoc;
AcGeVector3d ver = ptEnd - ptS;
double d1 = 1+2*i;
double d2 = nNums*2;
// 计算门窗的位置
ptNewLoc = ptS + ver*(d1/d2);
pNewOp->SetLocation(ptNewLoc);
pNewOp->m_ptLabel=pNewOp->GetDefaultLabPos();
pNewOp->SetWallId(NULL);
pNewOp->InitHardPointerId();
// add by xly on 110222 设置门窗弧窗类型
int nType =pNewOp->GetKind();
if (nType==TOpeningData::OP_DOOR || nType==TOpeningData::OP_WINDOW || nType==TOpeningData::OP_ARCWIN)
{
pNewOp->SetSubKind(pDlg->GetOpeningStyle());
}
pNewOp->SetLayoutRotation(Ucs2Wcs(0));
pNewOp->SetLoneOpening(TRUE);
// sg add 110805,解决“在已有洞口插入多个门窗”方式下插入的门窗,其自动顺序编号有问题的问题
// 主要数据是在UpdateOpening函数里更新的,其实只支持尺寸的方式更新,不支持顺序的方式
if (_tcscmp(_T("自动编号"), pDlg->GetOpeningLabel()) == 0)
{
pNewOp->SetLabel(pDlg->CalcAutoLabel(pNewOp));
}
pNewOp->AddToMSpace(Adesk::kTrue);
}
}
}
OPENOBJ_END();
}
// add by xly on 110113 在已有洞口插入
BOOL HasHoleInsert()
{
ASSERT(CInsertOpeningDlg::g_pCurDlg!=NULL);
CInsertOpeningDlg*& pDlg=CInsertOpeningDlg::g_pCurDlg;
XPushVar<int> vOsMode(_T("OSMODE"), 0);
PickSet ss(SS_FREE);
RBList mask(RTDXF0, _T("TCH_OPENING"), NULL);
pDlg->EnableWindow(TRUE);
while (SelectEntities(_T("选择已有门窗<退出>:"),ss,mask)==RTNORM)
{
if (!pDlg->UpdateData(TRUE))
continue;
AcDbObjectIdArray arIds;// 保存墙体ID
// 获得当前对话框中绘制门窗对象的类型:门 或者 窗
int nType = pDlg->GetOpeningKind();
XPoint ptBack, ptFront;
double dHeigh(0.0),
dHeighSill(0.0);
bool bIsDoor(false);
// 遍历所有选择到的门窗对象
long lCount=ss.Length();
for(long nL=0L; nL<lCount; nL++)
{
Entity ent=ss[nL];
XPoint ptLoc;
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbOpening, pWin);
// 选择到门对象同时绘制门对象
if ((pWin->GetKind()==TOpeningData::OP_DOOR||pWin->GetKind()==TOpeningData::OP_WINDOW) && nType== pWin->GetKind())
{
AcDbObjectId idWall = pWin->GetWallId();
int nPos(-1);
if (!arIds.find(idWall, nPos))
{
arIds.append(idWall);
}
}
else
continue;
OPENOBJ_END();
}
double dTotalWith(0.0);
// 查找门窗对象的边界点
int nIdsNums = arIds.length();
AcDbObjectIdArray arIdsSS;// 保存选择到的门窗的id
ss.AsIdArray(arIdsSS);
// 获得门窗的个数
int nNums = pDlg->GetOpeningNums();
double dWith(0.0);// 记录每个门洞的宽度
// 遍历选择集选到的门窗所在的墙体
int i=0;
for(i=0; i<nIdsNums; i++)
{
// 保存门窗对象ID
AcDbObjectIdArray arIdsOpenning;
AcGePoint3dArray aryPts;// 保存门窗对象的两边的点
AcDbObjectId idWall = arIds[i];
OPENOBJ_BEGIN(idWall, AcDb::kForRead, TDbWall, pWall);
if (pWall)
{
// 获得墙体上的所有的门窗对象
const DList<AcDbSoftPointerId> &lstWin = pWall->GetOpeningIdList();
if (lstWin.Length()>1)// 墙体上的门窗对象的个数大于等于2
{
for(int n = 0;n < lstWin.Length();n++)
{
AcDbObjectId id = lstWin[n];
int nPos(-1);
if (!arIdsSS.find(id, nPos))
{
continue;
}
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbOpening, pWin);
if(pWin)
{
// 将门窗对象的两个点添加到数组中记录
if (pWin->GetKind()==nType)
{
pWin->GetSidePoints(ptBack, ptFront);
aryPts.append(ptBack);
aryPts.append(ptFront);
// 记录门窗的id
arIdsOpenning.append(id);
}
}
OPENOBJ_END();
}
int nLen = aryPts.length();
AcGePoint3dArray aryPtsNew;// 保存门窗对象的两边的点
int j=0;
for(j=0; j<nLen; j++)
{
bool bIsFir(false);// 标记点时否是重合点
for(int t=0;t<nLen; t++)
{
// 在数组中是重合点
if(aryPts[j].distanceTo(aryPts[t])<_DIST_SNAP && t!=j)
{
bIsFir=true;
break;
}
}
// 保存同一个墙体中不同的点
if (!bIsFir)
{
aryPtsNew.append(aryPts[j]);
bIsFir=false;
}
}
// 遍历每个门窗洞,生成新的门窗对象
nLen = aryPtsNew.length();
for(j=0; j<nLen; j++)
{
// 获得原有门窗的Id
dWith=aryPtsNew[j].distanceTo(aryPtsNew[j+1]);
int nPos(-1);
aryPts.find(aryPtsNew[j], nPos);
nPos = nPos/2;
AcDbObjectId idNew = arIdsOpenning[nPos];
// 生成门窗对象
AddOpenning(idNew, nType, nNums, dWith, aryPtsNew[j], aryPtsNew[j+1],pDlg);
j++;
}
}
else // 墙体上的门窗对象的个数小于2个 直接生成相应的门窗个数
{
if (lstWin.Length()>0)
{
AcDbObjectId id = lstWin[0];
XPoint ptS,ptEnd;
OPENOBJ_BEGIN(id, AcDb::kForRead, TDbOpening, pWin);
if(pWin)
{
dWith = pWin->GetWidth();
pWin->GetSidePoints(ptEnd,ptS);
}
OPENOBJ_END();
// 生成门窗对象
AddOpenning(id, nType, nNums, dWith, ptS, ptEnd, pDlg);
}
}
}
OPENOBJ_END();
}
ss.Free();
}
return (pDlg->GetInsertMode()!=ID_HASHOLE_INSERT);
}
// 专门用于智能插入门窗,建立墙体和墙体范围内的轴网的关系
void GetWallAndAxisIds(DList<TWallAxisData> &lstIds)
{
RBList maskWall(RTDXF0, _T("TCH_WALL"), NULL),
maskAxis(RTDXF0, _T("LINE,ARC"), 8, LAY_AXIS, NULL);
PickSet ssWall(SS_FREE);
ssWall.Get(_T("X"), NULL, NULL, maskWall); // 全图搜索所有墙体
long lLen = ssWall.Length();
for (long m=0; m<lLen; m++)
{
Entity entWall = ssWall[m];
OPENOBJ_BEGIN(entWall, AcDb::kForRead, TDbWall, pWall);
if (pWall != NULL)
{
XCurveSegment segThis = pWall->GetLongBaseLine();
segThis.SetElevation(0.0);
segThis.SetLineFlag(LS_FINITE);
XPointDir2d ptExtStart, ptExtEnd;
segThis.Polar(-_AS_SYS_UNIT(g_nDistPrec), ptExtStart, TRUE);
segThis.Polar(-_AS_SYS_UNIT(g_nDistPrec), ptExtEnd, FALSE);
segThis.SetPoints(ptExtStart, ptExtEnd);
XPoly2D poly;
segThis.AsPoly2D(poly);
XPoly poly1;
poly.MapToPolygon(poly1);
PickSet ssAxis(SS_FREE);
ssAxis.Get(_T("F"), TRBList(poly1.Fence()), NULL, maskAxis);
TWallAxisData wallData(pWall->objectId());
for (long n=0; n<ssAxis.Length(); n++)
{
Entity entAxis = ssAxis[n];
TGGeCurveSegment segAxis(entAxis, LS_FINITE);
segAxis.SetElevation(0.0);
if (pWall->Is(CURVE_ARC))
{
if (!segAxis.Is(CURVE_LINE))
{
ssAxis -= entAxis;
continue;
}
TGGeArc ar = pWall->GetArc();
double nDistTo = ar.GetCenterPt().Distance(&segAxis);
if (nDistTo > _DIST_SNAP)
{
ssAxis -= entAxis;
continue;
}
}
TADSGePoint3d ptInt[2];
int nInt = segThis.Intersection(segAxis, ptInt[0], ptInt[1]);
if (nInt == 0)
{
ssAxis -= entAxis;
continue;
}
}
AcDbObjectIdArray idAxiss;
ssAxis.AsIdArray(idAxiss);
wallData.m_aryAxisIds.append(idAxiss);
lstIds.Append(new TWallAxisData(wallData));
}
OPENOBJ_END();
}
}
//add by lgy 20120517 智能插入门窗
BOOL AptitudeInsert()
{
ASSERT(CInsertOpeningDlg::g_pCurDlg != NULL);
CInsertOpeningDlg * &pDlg = CInsertOpeningDlg::g_pCurDlg;
XPushVar<int> vOsMode(_T("OSMODE"), 0);
pDlg->EnableWindow(TRUE);
// sg add 120626,获得所有的墙以及和墙相交的轴网
DList<TWallAxisData> lstIds;
GetWallAndAxisIds(lstIds);
TDbOpening *pWin = pDlg->NewOpening();
pDlg->AttachOpening(pWin);
if (pWin == NULL)
{
delete pWin;
return FALSE;
}
Entity ent;
XPoint ptPick;
XCurveSegment seg;
AcDbObjectId idWall;
int nRet = 0;
int nAptType = 0; // 0——墙线定距,1——轴线定距
static bool bIsWallLine = true; // 墙线定距
bool bReturn(false);
LAB_RECURSIONPROMPT:
while(1)
{
if (bIsWallLine) // 墙线定距
{
nAptType = 0;
idWall = GetOpeingLocationApt(_T("\n点取门窗的大致位置或[设为轴线定距(Q),当前:墙线定距]<退出>:"), pWin, ptPick, seg, nRet, nAptType, lstIds);
if (nRet == RTKWORD)
{
bIsWallLine = !bIsWallLine;
continue;
}
bReturn = nRet!=RTNORM;
break;
}
else // 轴线定距
{
nAptType = 1;
idWall = GetOpeingLocationApt(_T("\n点取门窗的大致位置或[设为墙线定距(Q),当前:轴线定距]<退出>:"), pWin, ptPick, seg, nRet, nAptType, lstIds);
if (nRet == RTKWORD)
{
bIsWallLine = !bIsWallLine;
continue;
}
bReturn = nRet!=RTNORM;
break;
}
}
int nType = pWin->GetKind(),
nLocType = 2; // 用于传递给InsertNewOpening函数的形参
bool bIsPier = true;
AcGePoint3dArray aryPts; // 支持多个门窗插入
OPENOBJ_BEGIN(idWall, AcDb::kForWrite, TDbWall, pWall);
if (pWall == NULL)
{
// sg modify 120713,重新循环提示
if (bReturn)
{
delete pWin;
return (pDlg->GetInsertMode() != ID_BUTTON_APTITUDE);
}
else
{
goto LAB_RECURSIONPROMPT;
}
}
XCurveSegment segmentGeom = pWall->OffsetGeomCenter(LS_INFINITE, TRUE),
segmentBase(*(XCurveSegment*)pWall);
if (seg.GetLength() < _DIST_SNAP) // 首先全部投影到墙基线上
{
seg = segmentBase;
}
else
{
XPoint ptStart, ptEnd;
segmentBase.ProjectToMe(seg.GetStartPoint(), ptStart);
segmentBase.ProjectToMe(seg.GetEndPoint(), ptEnd);
seg.SetStartPoint(ptStart);
seg.SetEndPoint(ptEnd);
}
if (pWall->Is(CURVE_LINE) && pWin->GetKind()==TOpeningData::OP_ARCWIN)
{
adsout << _T("\n请点取弧墙!");
delete pWin;
pWall->close();
return TRUE;
}
pWin->m_ptLocation.z = pDlg->GetOpeningSill() + pWall->GetElevation();
if (!ValidateCurLabel(*pWin))
{
delete pWin;
pWall->close();
return FALSE;
}
if (pWall->CanInsertOpening(*pWin))
{
pWin->SetWallId(idWall);
pWin->InitHardPointerId();
pWin->SetLayoutRotation(Ucs2Wcs(0));
XPoint ptLocal,
ptTemp = seg.StartPoint();
double dLenSeg = seg.GetLength(),
dLen = seg.PathDistance(ptPick);
TADSGePointDir2d pt;
{
// sg modify 120709,只有下面三种类型,才设置自类型
if (nType==TOpeningData::OP_DOOR || nType==TOpeningData::OP_WINDOW || nType==TOpeningData::OP_ARCWIN)
{
pWin->SetSubKind(pDlg->GetOpeningStyle());
}
double dDlgDist = _tstof(pDlg->g_csDist), // 对话框上的距离
dDist = dDlgDist + pWin->GetWidth()/2;
if (dLen < dLenSeg/3)
{
seg.Polar(dDist, pt);
ptLocal = pt.AsAcGePoint3d();
}
else if (dLen < 2*dLenSeg/3)
{
seg.Polar(dLenSeg/2, pt);
ptLocal = pt.AsAcGePoint3d();
nLocType = 0;
bIsPier = false;
}
else
{
seg.Polar(dLenSeg - dDist, pt);
ptLocal = pt.AsAcGePoint3d();
}
XPoint ptGeoLoc;
segmentGeom.ProjectToMe(ptLocal, ptGeoLoc);
aryPts.append(ptGeoLoc);
}
if (nType == TOpeningData::OP_ARCWIN)
{
pWin->m_nBulge = seg.Direction(ptLocal);
}
pWall->assertWriteEnabled();
pWall->AddOpeningId(pWin->objectId());
pWin->close();
}
else
{
adsout << _T("\n不能插到该墙上(门窗高度或宽度方向超出墙体)!");
delete pWin;
}
OPENOBJ_END();
if (nType!=TOpeningData::OP_DOOR && nType!=TOpeningData::OP_WINDOW && nType!=TOpeningData::OP_ARCWIN)
{
InsertNewOpening(1, pWin, idWall, aryPts);
}
else
{
InsertNewOpening(pDlg->GetOpeningNums(), pWin, idWall, aryPts, nLocType, bIsPier);
}
if (aryPts.length()>0)
{
delete pWin;
}
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
return TRUE;
}
BOOL PickUpDoorOrWin()
{
ASSERT(CInsertOpeningDlg::g_pCurDlg!=NULL);
CInsertOpeningDlg*& pDlg=CInsertOpeningDlg::g_pCurDlg;
XPushVar<int> vOsMode(_T("OSMODE"), 0);
Entity ent;
RBList mask(RTDXF0, _T("TCH_OPENING"), NULL);
pDlg->EnableWindow(TRUE);
int nType = pDlg->GetOpeningKind();
if (!pDlg->UpdateData(TRUE))
{
return TRUE;
}
while (TRUE)
{
if (RTNORM != SelectEntity(_T("\n请拾取参考门窗<返回对话框>:"), ent, mask))
{
return TRUE;
}
// 获得当前对话框中绘制门窗对象的类型:门 或者 窗
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbOpening, pWin);
// 选择到门对象同时绘制门对象
if (nType== pWin->GetKind())
{
pDlg->ObjToDlg(pWin);
break;
}
else
{
acutPrintf(_T("请重新点取同类门窗!"));
}
OPENOBJ_END();
}
return TRUE;
}
//创建CInsertOpeningDlg对话框的唯一正确方法!
bool CreateInsWDHDlg(bool bReplacing=false)//new
{
UINT resID;
CWnd *pFrame=acedGetAcadFrame();
CInsertOpeningDlg::g_pCurDlg=NULL;
PickSet ss(SS_FREE);
if (bReplacing)
{
ss.Get(_T("I"),NULL,NULL,RBList(RTDXF0, _T("TCH_OPENING"), NULL));
if (ss.Length()>0)
{
Entity ent(ss[0L]);
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbOpening, pWin);
if (pWin)
{
switch(pWin->GetKind())
{
case TDbOpening::OP_DOOR:
CInsertOpeningDlg::curType=0;
break;
case TDbOpening::OP_WINDOW:
CInsertOpeningDlg::curType=1;
break;
case TDbOpening::OP_DOORWIN:
CInsertOpeningDlg::curType=2;
break;
case TDbOpening::OP_TWODOOR:
CInsertOpeningDlg::curType=3;
break;
case TDbOpening::OP_ARCWIN:
CInsertOpeningDlg::curType=4;
break;
case TDbOpening::OP_PROWIN:
CInsertOpeningDlg::curType=5;
break;
case TDbOpening::OP_HOLE:
CInsertOpeningDlg::curType=6;
break;
case TDbOpening::OP_GROUP:
CInsertOpeningDlg::curType=-1;
break;
}
}
OPENOBJ_END();
}
}
switch(CInsertOpeningDlg::curType)
{
case 0:
{
CInsertOpeningDlg::g_pCurDlg=new CDoorOrWinDlg(TOpeningData::OP_DOOR,pFrame);
resID=IDD_DOOR_OR_WIN;
}
break;
case 1:
{
CInsertOpeningDlg::g_pCurDlg=new CDoorOrWinDlg(TOpeningData::OP_WINDOW,pFrame);
resID=IDD_DOOR_OR_WIN;
}
break;
case 2:
{
CInsertOpeningDlg::g_pCurDlg=new CDoorWinDlg(pFrame);
resID=IDD_DOORWIN;
}
break;
case 3:
{
CInsertOpeningDlg::g_pCurDlg=new CTwoDoorDlg(pFrame);
resID=IDD_TWO_DOOR;
}
break;
case 4:
{
CInsertOpeningDlg::g_pCurDlg=new CArcWindowDlg(pFrame);
resID=IDD_ARCWIN;
}
break;
case 5:
{
CInsertOpeningDlg::g_pCurDlg=new CBayWindowDlg(pFrame);
resID=IDD_BAYWINDOW;
}
break;
case 6:
{
CInsertOpeningDlg::g_pCurDlg=new CRectHoleDlg(pFrame);
resID=IDD_RECT_HOLE;
}
break;
case -1:
{
CInsertOpeningDlg::g_pCurDlg=new CGroupOpeningDlg(pFrame);
resID=IDD_GROUP_OPENING;
}
break;
}
if (CInsertOpeningDlg::g_pCurDlg!=NULL)
{
CAcModuleResourceOverride vTemp;
if (!CInsertOpeningDlg::g_pCurDlg->Create(resID,pFrame))
{
delete CInsertOpeningDlg::g_pCurDlg;
CInsertOpeningDlg::g_pCurDlg=NULL;
}
if (CInsertOpeningDlg::g_pCurDlg!=NULL&&bReplacing)
{
if (ss.Length()>0)
{
Entity ent(ss[0L]);
OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbOpening, pWin);
if (pWin)
CInsertOpeningDlg::g_pCurDlg->SetDlgParamFrom(*pWin);
OPENOBJ_END();
}
CInsertOpeningDlg::g_pCurDlg->SetReplacing();
}
}
ss.Free();
return CInsertOpeningDlg::g_pCurDlg!=NULL;
}
void RefreshInsWDHDlg()
{
CInsertOpeningDlg::bRefreshDlg=true;
CInsertOpeningDlg*pDlg0=CInsertOpeningDlg::g_pCurDlg;
if (pDlg0!=NULL&&pDlg0->IsWindowVisible()) {
if (pDlg0->m_bModeless) {
if (!pDlg0->IsIconic()) {
CRect rect;
pDlg0->GetWindowRect(&rect);
pDlg0->WriteReg(rect.TopLeft().x,rect.TopLeft().y);
}
}
/*
CRect rect;
pDlg0->GetWindowRect(&rect);
CInsertOpeningDlg::oldPos.x=rect.left;
CInsertOpeningDlg::oldPos.y=rect.top;
*/
pDlg0->WriteParamToRegistry();
}
if (!CreateInsWDHDlg())
return;
if (pDlg0!=NULL)
{
pDlg0->DestroyWindow();
delete pDlg0;
}
CInsertOpeningDlg::bRefreshDlg=false;
}
//COMMAND: Insert window,door or hole;
//在交互过程中,对话框对象可以自动重构,
//但无论对话框对象如何动态变化,CInsertOpeningDlg::g_pCurDlg始终指向它。
void InsWDH()//new
{
//组合门窗
if (CInsertOpeningDlg::curType<0)
CInsertOpeningDlg::curType=0;
if (!CreateInsWDHDlg())
return;
acedGetAcadFrame()->SetFocus();
BOOL bContinue=TRUE;
while(bContinue&&CInsertOpeningDlg::g_pCurDlg!=NULL&&
CInsertOpeningDlg::g_pCurDlg->IsWindowVisible())
{
switch(CInsertOpeningDlg::g_pCurDlg->GetInsertMode())
{
case ID_FREE_INSERT:
bContinue=FreeInsert();
break;
case ID_SEQUENCE_INSERT:
bContinue=SequenceInsert();
break;
case ID_FIXDIST_ONPIER:
bContinue=FixInsertOnPier();
break;
case ID_FIXDIST_ONAXIS:
bContinue=FixInsertOnAxis();
break;
case ID_ARCWALL_INSERT:
bContinue=ArcWallInsert();
break;
case ID_LINE_INSERT:
bContinue=IsoInsert();
break;
case ID_COLUMN_INSERT:
bContinue=ColInsert();
break;
case ID_WALL_INSERT:
bContinue=IsoWallInsert();
break;
case ID_UPLEVEL_INSERT:
bContinue=UplevelInsert();
break;
case ID_REPLACE_INSERT:
bContinue=ReplaceOpening();
break;
case ID_HASHOLE_INSERT:// add by xly on 110113 在已有洞口插入
bContinue=HasHoleInsert();
break;
case ID_BUTTON_APTITUDE:
bContinue = AptitudeInsert();//add by lgy 20120517 智能插入门窗
break;
default:
bContinue=FALSE;
}
//add by lgy 20120201 添加拾取按钮时对话框隐藏,等提取参数显示对话框
if (CInsertOpeningDlg::g_iOldInsertMode == 0)
{
CInsertOpeningDlg::g_pCurDlg->ShowWindow(SW_HIDE);
bContinue = PickUpDoorOrWin();
CInsertOpeningDlg::g_iOldInsertMode = 1;
CInsertOpeningDlg::g_pCurDlg->UpdateData(TRUE);
CInsertOpeningDlg::g_pCurDlg->UpdateData(FALSE);
CInsertOpeningDlg::g_pCurDlg->ShowWindow(SW_SHOW);
}
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
}
if (CInsertOpeningDlg::g_pCurDlg!=NULL)
{
CInsertOpeningDlg::g_pCurDlg->DestroyWindow();
delete CInsertOpeningDlg::g_pCurDlg;
CInsertOpeningDlg::g_pCurDlg=NULL;
}
}
namespace
{
void ins(int ntype)
{
//组合门窗
CInsertOpeningDlg::curType = ntype;
if (!CreateInsWDHDlg())
return;
acedGetAcadFrame()->SetFocus();
BOOL bContinue = TRUE;
while (bContinue&&CInsertOpeningDlg::g_pCurDlg != NULL&&
CInsertOpeningDlg::g_pCurDlg->IsWindowVisible())
{
switch (CInsertOpeningDlg::g_pCurDlg->GetInsertMode())
{
case ID_FREE_INSERT:
bContinue = FreeInsert();
break;
case ID_SEQUENCE_INSERT:
bContinue = SequenceInsert();
break;
case ID_FIXDIST_ONPIER:
bContinue = FixInsertOnPier();
break;
case ID_FIXDIST_ONAXIS:
bContinue = FixInsertOnAxis();
break;
case ID_ARCWALL_INSERT:
bContinue = ArcWallInsert();
break;
case ID_LINE_INSERT:
bContinue = IsoInsert();
break;
case ID_COLUMN_INSERT:
bContinue = ColInsert();
break;
case ID_WALL_INSERT:
bContinue = IsoWallInsert();
break;
case ID_UPLEVEL_INSERT:
bContinue = UplevelInsert();
break;
case ID_REPLACE_INSERT:
bContinue = ReplaceOpening();
break;
case ID_HASHOLE_INSERT:// add by xly on 110113 在已有洞口插入
bContinue = HasHoleInsert();
break;
case ID_BUTTON_APTITUDE:
bContinue = AptitudeInsert();//add by lgy 20120517 智能插入门窗
break;
default:
bContinue = FALSE;
}
//add by lgy 20120201 添加拾取按钮时对话框隐藏,等提取参数显示对话框
if (CInsertOpeningDlg::g_iOldInsertMode == 0)
{
CInsertOpeningDlg::g_pCurDlg->ShowWindow(SW_HIDE);
bContinue = PickUpDoorOrWin();
CInsertOpeningDlg::g_iOldInsertMode = 1;
CInsertOpeningDlg::g_pCurDlg->UpdateData(TRUE);
CInsertOpeningDlg::g_pCurDlg->UpdateData(FALSE);
CInsertOpeningDlg::g_pCurDlg->ShowWindow(SW_SHOW);
}
TArchCmdReactor::UpdateClip();
TArchCmdReactor::ResetAll();
}
if (CInsertOpeningDlg::g_pCurDlg != NULL)
{
CInsertOpeningDlg::g_pCurDlg->DestroyWindow();
delete CInsertOpeningDlg::g_pCurDlg;
CInsertOpeningDlg::g_pCurDlg = NULL;
}
}
}
void InsBayWDH()
{
ins(5);
}
void InsHoleWDH()
{
ins(6);
}
//COMMAND:门窗替换
void ReplaceWDH()
{
if (!CreateInsWDHDlg(true))
return;
BOOL bContinue=TRUE;
acedGetAcadFrame()->SetFocus();
while(bContinue&&CInsertOpeningDlg::g_pCurDlg!=NULL&&
CInsertOpeningDlg::g_pCurDlg->IsWindowVisible())
{
switch(CInsertOpeningDlg::g_pCurDlg->GetInsertMode())
{
case ID_FREE_INSERT:
bContinue=FreeInsert();
break;
case ID_SEQUENCE_INSERT:
bContinue=SequenceInsert();
break;
case ID_FIXDIST_ONPIER:
bContinue=FixInsertOnPier();
break;
case ID_FIXDIST_ONAXIS:
bContinue=FixInsertOnAxis();
break;
case ID_ARCWALL_INSERT:
bContinue=ArcWallInsert();
break;
case ID_LINE_INSERT:
bContinue=IsoInsert();
break;
case ID_COLUMN_INSERT:
bContinue=ColInsert();
break;
case ID_WALL_INSERT:
bContinue=IsoWallInsert();
break;
case ID_UPLEVEL_INSERT:
bContinue=UplevelInsert();
break;
case ID_HASHOLE_INSERT:// add by xly on 110113 在已有洞口插入
bContinue=HasHoleInsert();
break;
case ID_REPLACE_INSERT:
bContinue=ReplaceOpening();
break;
default:
bContinue=FALSE;
}
}
if (CInsertOpeningDlg::g_pCurDlg!=NULL)
{
CInsertOpeningDlg::g_pCurDlg->DestroyWindow();
delete CInsertOpeningDlg::g_pCurDlg;
CInsertOpeningDlg::g_pCurDlg=NULL;
}
}