#include "stdafx.h" #include "Elevator.h" // Add by Zyu on 100323 #define SYS_LD12D _T("DORLIB2D(00000128)") // 旁开电梯门 #define SYS_LD22D _T("DORLIB2D(00000127)") // 中分电梯门 // Add by Zyu on 100323 // 保证门对象绘制在正确的位置上 // Begin extern TARCH_IMPEXP void CheckOp3dStyle(AcDbObjectId idStyle3d); extern TARCH_IMPEXP void CheckOp2dStyle(AcDbObjectId idStyle2d); // End // 插洞口 int InsertHole(int nType, ads_real nWidth, TDbWall *pWall, const XPoint &ptNew, const XPoint &ptIn) { // 问题描述:插入的电梯门其实是一个窗 // 解决方法:改为以门的方式插入 // Zyu modify on 100323 // TOpeningData::OpeningKind nK = TOpeningData::OP_WINDOW; TOpeningData::OpeningKind nK = TOpeningData::OP_DOOR; XPoint ptLoc1; if (!pWall->GetOpeningLocation(ptNew, nK, nWidth, ptLoc1) || //投影到墙心上 !pWall->CanInsertOpening(ptLoc1, 0.0, nWidth, 2100, nK)) { ads_printf(_T("\n插入后, 该墙上的洞口将发生干涉! 拒绝插入!")); return RTERROR; } // 问题描述:使用了DORLIB2D图库中的电梯门 // 修改人,修改时间:Zyu modify on 100323 // const TCHAR *pszDoor2d=nType? SYS_LDOR12D : SYS_LDOR22D; //, *pszDoor3d=_T("DOOR(_door001)"); const TCHAR *pszDoor2d=nType? SYS_LD12D : SYS_LD22D; XString sDoorDwg; sDoorDwg << g_sDwbPath << pszDoor2d; XString szDoor2d(256), szDoor3d(256); AcDbObjectId idStyle2d, idStyle3d; if (LoadDwbBlock(sDoorDwg, szDoor2d)!=RTNORM) return RTERROR; idStyle2d = InitBlock(szDoor2d); if (LoadDwbBlock(XString(_T("%s%s"), g_sDwbPath, SYS_LDOOR3D), szDoor3d)!=RTNORM) return RTERROR; idStyle3d = InitBlock(szDoor3d); // Add by Zyu on 100323 // 保证门对象绘制在正确的位置上 // Begin CheckOp3dStyle(idStyle3d); CheckOp2dStyle(idStyle2d); // End TDbOpening *pOpening = new TDbOpening(pWall->objectId(), idStyle2d, idStyle3d); pOpening->InitHardPointerId(); pOpening->m_ptLocation = ptLoc1; pOpening->SetWidth(nWidth); pOpening->SetHeight(2100); pOpening->SetThickness(60); // Zyu modify on 100323 //pOpening->SetKind(TOpeningData::OP_WINDOW); pOpening->SetKind(TOpeningData::OP_DOOR); pOpening->m_nOpStyle |= OPS_LIFTDOOR; // add by xly on 110314 设置电梯门的类型 pOpening->SetSubKind(_T("电梯门")); pOpening->AddToMSpace(Adesk::kFalse); pWall->InsertOpening(pOpening); XCurveSegment segCen = pWall->OffsetGeomCenter(); int nSide = segCen.OnWhichSide(ptIn); if (nSide == OFFSET_LEFT) { if (pOpening->m_nQuadrant == 2) pOpening->m_nQuadrant = 1; else if (pOpening->m_nQuadrant == 3) pOpening->m_nQuadrant = 0; } else if (nSide==OFFSET_RIGHT) { if (pOpening->m_nQuadrant == 1) pOpening->m_nQuadrant = 2; else if (pOpening->m_nQuadrant == 0) pOpening->m_nQuadrant = 3; } pOpening->close(); return RTNORM; } int GetClosestEdge(const XPoly2D &poly, XPoint ptPick) { int nDoorEdge = -1; double nMinDist = 0.0; for (int n=0; n<4; n++) { XLine ln; poly.Nth(n, ln, XArc()); XPoint ptOnEdge; if (ptPick.Project(&ln, ptOnEdge)!=RTNORM || (ptOnEdge&ln)!=PR_INSIDE) continue; if (nDoorEdge<0) { nMinDist = ptPick.Distance2d(ptOnEdge); nDoorEdge = n; } else { double nDist = ptPick.Distance2d(ptOnEdge); if (nDist osmode(_T("OSMODE"), nOsMode); if (XGetPoint(NULL, _T("\n请给出电梯间的一个角点"), ptCorn1) != RTNORM || XGetCorner(ptCorn1, _T("\n再给出上一角点的对角点: "), ptCorn2)!=RTNORM) { return false; } ptCorn1 = Ucs2Wcs(ptCorn1); ptCorn2 = Ucs2Wcs(ptCorn2); ptCorn1.z = ptCorn2.z = 0; return true; } // 获取门所在的墙体上一点ptPick,并返回这面墙的角度dRot和这个墙对象 bool GetPntOnWall(TADSGePoint3d &ptPick, double &dRot, Entity &entSel) { RBList rbWallFilter(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL); // 过滤器 if (entSel.FilterSelect(_T("\n请点取开电梯门的墙线<退出>: "), rbWallFilter, ptPick) != RTNORM) { return false; } ptPick = Ucs2Wcs(ptPick); // Modify on 2002/2/25 by ZJQ 支持转角的墙 OPENOBJ_BEGIN(entSel, AcDb::kForRead, TDbWall, pWall); if (!pWall || !pWall->Is(CURVE_LINE)) { adsout << _T("\n请正确点取开电梯门的墙!"); return false; } dRot = pWall->XLine::Direction(); OPENOBJ_END(); return true; } // 得到所有组成平衡块和轿厢的点 void GetCrossPnts(const TGGeLine *lnBalSides, const TGGeLine *lnOtherSides, TADSGePoint3d *ptBalances, TADSGePoint3d *ptTanks) { lnBalSides[0].Intersection(&lnOtherSides[0], ptBalances[0]); lnBalSides[1].Intersection(&lnOtherSides[0], ptBalances[1]); lnBalSides[1].Intersection(&lnOtherSides[1], ptBalances[2]); lnBalSides[0].Intersection(&lnOtherSides[1], ptBalances[3]); lnBalSides[2].Intersection(&lnOtherSides[2], ptTanks[0]); lnBalSides[3].Intersection(&lnOtherSides[2], ptTanks[1]); lnBalSides[3].Intersection(&lnOtherSides[3], ptTanks[2]); lnBalSides[2].Intersection(&lnOtherSides[3], ptTanks[3]); } // 画平衡块和轿厢 void DrawBalAndTank(const TADSGePoint3d *ptBalances, const TADSGePoint3d *ptTanks) { XWcsStream dc; // Zyu modify on 100401 // dc.sLayer = LAY_STAIR; dc.sLayer = LAY_ELEVATOR; dc << XLine(ptBalances[0], ptBalances[1]) << XLine(ptBalances[1], ptBalances[2]) << XLine(ptBalances[2], ptBalances[3]) << XLine(ptBalances[3], ptBalances[0]) << XLine(ptTanks[0], ptTanks[1]) << XLine(ptTanks[1], ptTanks[2]) << XLine(ptTanks[2], ptTanks[3]) << XLine(ptTanks[3], ptTanks[0]) << XLine(ptTanks[0], ptTanks[2]) << XLine(ptTanks[1], ptTanks[3]); } // 获得门在轿厢上的插入点 void GetPntDoorOnTank(const TGGeLine &lnDoorEdge, const TADSGePoint3d *ptTanks, TADSGePoint3d &ptDoorOnTank) { if (IsSameDrt(ads_angle(ptTanks[0], ptTanks[1]), lnDoorEdge.Direction(), _angSnap)) { Midpoint(ptTanks[0], ptTanks[1], ptDoorOnTank); } else { Midpoint(ptTanks[1], ptTanks[2], ptDoorOnTank); } } // End //画电梯 void Elevator() { // 修改描述:原来的轿厢和平衡块是画在楼梯层的,现在改为画在电梯层 // 修改人,修改时间:Zyu modify on 100401 // InitLayer(LAY_STAIR, TRUE); InitLayer(LAY_ELEVATOR, TRUE); CAcModuleResourceOverride vTemp; CElevatorDlg dlg; dlg.Create(dlg.IDD, acedGetAcadFrame()); acedGetAcadDwgView()->SetFocus(); while(1) { XPoint ptCorn1, ptCorn2, ptIn; if (!GetElevtorRect(ptCorn1, ptCorn2)) { // 获得电梯间的边框 break ; } XPoint ptPick; // 门所在的墙体上一点 double dRot; // 墙的旋转角度 Entity entSel; // 选择到的实体 if (!GetPntOnWall(ptPick, dRot, entSel)) { // 获取门所在的墙体上一点ptPickt和这面墙的角度dRot break ; } // 根据墙线的角度,旋转电梯间的对角点ptCorn1,ptCorn2 ads_matrix matRot, matRev; XPoint().GetRotationMatrix(-dRot, matRot); ptCorn1.TransformBy(matRot); ptCorn2.TransformBy(matRot); AT_amatrix(matRot, matRev); XPoly2D poly(1); // 电梯间的边框线 XRectAngle box(ptCorn1, ptCorn2); box.AsPoly2D(poly); // poly.TransUCS(Groups(1), Groups(0)); poly.TransUCS(matRev); poly.Center(ptIn); // 电梯门在矩形的哪一边 int nDoorEdge = GetClosestEdge(poly, ptPick); if (nDoorEdge<0) { adsout << _T("\n请正确点取开电梯门的墙线!"); continue; } int nBalanceEdge = -1; { XPushVar osmode(_T("OSMODE"), OS_NEA); if (ads_getpoint(NULL, _T("\n请点取平衡块的所在的一侧<退出>: "), ptPick) != RTNORM) break; ptPick = Ucs2Wcs(ptPick); nBalanceEdge = GetClosestEdge(poly, ptPick); if (nBalanceEdge<0 || nBalanceEdge==nDoorEdge) { adsout << _T("\n请正确点取平衡块位置!"); continue; } } dlg.UpdateData(TRUE); // 修改描述:根据是否使用"按井道决定轿厢尺寸"一项设置调整相应参数的值 // 修改人,修改时间: Zyu modify on 100401 // Begin double nDoorWidth = dlg.m_dDoorWidth; // double nTankDeep = dlg.m_Room_Deep; // double nTankWidth = dlg.m_dRoomWidth; double nTankDeep = 0; double nTankWidth = 0; int nDeepEdge = 0; XLine lnWidth, lnDeep; if (dlg.IsUseDefault()) { nDeepEdge = DePeriod(4, nBalanceEdge+1); poly.Nth(nBalanceEdge, lnWidth, XArc()); poly.Nth(nDeepEdge, lnDeep, XArc()); if (lnWidth.GetLength() < 500 + _DIST_SNAP || lnDeep.GetLength() < 450 + _DIST_SNAP) { adsout << _T("\n井道尺寸过小无法容纳轿厢和平衡块!"); continue ; } else { nTankDeep = (lnDeep.GetLength() - 450) * 0.8; nTankWidth = lnWidth.GetLength() - 500; } } else { nTankDeep = dlg.m_dRoomDeep; nTankWidth = dlg.m_dRoomWidth; nDeepEdge = DePeriod(4, nDoorEdge+1); poly.Nth(nDoorEdge, lnWidth, XArc()); poly.Nth(nDeepEdge, lnDeep, XArc()); if (nTankDeep>lnDeep.GetLength() || nTankWidth>lnWidth.GetLength()) { // 修改描述:调整提示信息 // 修改人,修改时间:Zyu modify on 100401 // adsout << _T("\n电梯井无法容纳桥箱!") adsout << _T("\n井道尺寸过小无法容纳轿厢和平衡块!") << _T("\n井宽=") << lnWidth.GetLength() << _T("; 井深=") << lnDeep.GetLength() << _T("; 轿箱宽=") << nTankWidth << _T("; 轿箱深=") << nTankDeep; continue; } } int nDirFlag = (nBalanceEdge-nDeepEdge)%2; // 0--宽度方向: 1--深度方向 XLine lnBal, lnBalSides[4]; poly.Nth(nBalanceEdge, lnBal, XArc()); int nSideFlag = lnBal.OnWhichSide(ptIn); double nFactor = nSideFlag==OFFSET_RIGHT? 1.0 : -1.0; if (dlg.IsUseDefault()) { lnBalSides[0] = lnBal.Offset(225*nFactor); lnBalSides[1] = lnBal.Offset((225 + (lnDeep.GetLength() - 450) * 0.1) * nFactor); lnBalSides[2] = lnBal.Offset((225 + (lnDeep.GetLength() - 450) * 0.2) * nFactor); lnBalSides[3] = lnBalSides[2].Offset((nDirFlag ? nTankDeep : nTankWidth) * nFactor); } else { double nBalWidth = nDirFlag? (lnDeep.GetLength()-nTankDeep)/4 : (lnWidth.GetLength()-nTankWidth)/4; lnBalSides[0] = lnBal.Offset(nBalWidth*nFactor); lnBalSides[1] = lnBal.Offset(nBalWidth*nFactor*2); lnBalSides[2] = lnBal.Offset(nBalWidth*nFactor*3); lnBalSides[3] = lnBalSides[2].Offset((nDirFlag? nTankDeep : nTankWidth)*nFactor); } XLine &lnOther = nDirFlag? lnDeep : lnWidth; nSideFlag = lnOther.OnWhichSide(ptIn); nFactor = nSideFlag==OFFSET_RIGHT? 1.0 : -1.0; XLine lnOtherSides[4]; if (dlg.IsUseDefault()) { lnOtherSides[0] = lnOther.Offset((nDirFlag? (lnWidth.GetLength() - 500) / 5 + 250 : (lnDeep.GetLength() - 500) / 5 + 250) * nFactor); lnOtherSides[1] = lnOtherSides[0].Offset((nDirFlag? (lnWidth.GetLength() - 500) * 0.6 : (lnDeep.GetLength() - 500) * 0.6) * nFactor); lnOtherSides[2] = lnOther.Offset(250 * nFactor); lnOtherSides[3] = lnOtherSides[2].Offset((nDirFlag? nTankWidth : nTankDeep)*nFactor); } else { lnOtherSides[0] = lnOther.Offset((nDirFlag? lnWidth.GetLength()/4 : lnDeep.GetLength()/4)*nFactor); lnOtherSides[1] = lnOtherSides[0].Offset((nDirFlag? lnWidth.GetLength()/2 : lnDeep.GetLength()/2)*nFactor); lnOtherSides[2] = lnOther.Offset((nDirFlag? lnWidth.GetLength()-nTankWidth : lnDeep.GetLength()-nTankDeep)*nFactor/2); lnOtherSides[3] = lnOtherSides[2].Offset((nDirFlag? nTankWidth : nTankDeep)*nFactor); } // End for (int i=0; i<4; i++) { // 2010-3-15 17:20 wubo // 移植Geo // lnOtherSides[i].flag=lnBalSides[i].flag=LS_INFINITE; lnOtherSides[i].SetLineFlag(LS_INFINITE); lnBalSides[i].SetLineFlag(LS_INFINITE); } // 根据lnBalSides和lnOtherSides两组线,取得组成平衡块和电梯的点. XPoint ptBalances[4], ptTanks[4]; GetCrossPnts(lnBalSides, lnOtherSides, ptBalances, ptTanks); // 画平衡块和轿厢 DrawBalAndTank(ptBalances, ptTanks); XPoint ptDoorOnTank; // 获得门在轿厢上的插入点 if (dlg.IsUseDefault()) { TGGeLine lnDoorEdge; poly.Nth(nDoorEdge, lnDoorEdge, XArc()); GetPntDoorOnTank(lnDoorEdge, ptTanks, ptDoorOnTank); } else { GetPntDoorOnTank(lnWidth, ptTanks, ptDoorOnTank); } OPENOBJ_BEGIN(entSel, AcDb::kForWrite, TDbWall, pWall1); if (!pWall1) break; XPoint ptDoor; pWall1->ProjectToMe(ptDoorOnTank, ptDoor); // 问题描述:InsertHole的第一个参数使用错误,导致住宅梯、医梯、货梯三种电梯门的中分样式不对 // 修改人,修改时间:Zyu modify on 100323 //if (InsertHole(dlg.m_iType, nDoorWidth, pWall1, ptDoor, ptIn) != RTNORM) { if (InsertHole(dlg.m_iForm, nDoorWidth, pWall1, ptDoor, ptIn) != RTNORM) { adsout << _T("\n不能插入电梯门!"); continue; } OPENOBJ_END(); XPoint ptPick1; Entity entSel1; RBList rbWallFilter(RTDXF0, _T("TCH_WALL,TCH_CURTAIN_WALL"), NULL); // 过滤器 if (entSel1.FilterSelect(_T("\n请点取其他开电梯门的墙线<无>: "), rbWallFilter, ptPick1) != RTNORM) continue; ptPick1 = Ucs2Wcs(ptPick1); // 电梯门在矩形的哪一边 int nDoorEdge1 = GetClosestEdge(poly, ptPick1); if (nDoorEdge1<0 || nDoorEdge1==nDoorEdge || nDoorEdge1==nBalanceEdge) { adsout << _T("\n点取的墙线不合适!"); continue; } poly.Nth(nDoorEdge1, lnWidth, XArc()); // 获得门在轿厢上的插入点 GetPntDoorOnTank(lnWidth, ptTanks, ptDoorOnTank); OPENOBJ_BEGIN(entSel1, AcDb::kForWrite, TDbWall, pWall1); if (!pWall1) break; XPoint ptDoor; pWall1->ProjectToMe(Ucs2Wcs(ptDoorOnTank), ptDoor); // Zyu modify on 100323 // if (InsertHole(dlg.m_iType, nDoorWidth, pWall1, ptDoor, ptIn) != RTNORM) { if (InsertHole(dlg.m_iForm, nDoorWidth, pWall1, ptDoor, ptIn) != RTNORM) { adsout << _T("\n不能插入电梯门!"); continue; } OPENOBJ_END(); } dlg.DestroyWindow(); }