#include "stdafx.h" #include "resource.h" #include "SetWall.h" #include "InsertOpeningDlg.h" // [2010-3-16 10:32 wubo] 移植到新Geo库 // extern GEOAPI Acad::ErrorStatus GetSafeSelection(PickSet &ss, const XPoint &ptLow, const XPoint &ptUp, // DList &lstClass, AcDbObjectId idLayer); extern GEOAPI Acad::ErrorStatus GetSafeSelection(PickSet &ss, BOOL bCrossing, const XPoint &ptLow, const XPoint &ptUp, const AcRxClass *pClass); extern TARCH_IMPEXP BOOL g_bShiftToggle; // [2010-3-16 10:32 wubo] 移植到新Geo库 // extern TARCH_IMPEXP BOOL g_bCtrlToggle; // 绘制点的形状 void DrawOsnapShape(AcGiViewportDraw *pVd, XPoint m_ptLoc, int m_osShape) { XAcGiViewDraw dc(NULL, pVd); AcGePoint2d pixelArea; pVd->viewport().getNumPixelsInUnitSquare(m_ptLoc,pixelArea); double nAperture = 16/pixelArea.asVector().length(); if (nAperture<1.0E-6) return; XRectAngle box(m_ptLoc, nAperture, nAperture); AcDbPolyline pline; pVd->subEntityTraits().setColor(2); double nWidth=1/pixelArea.asVector().length(); pline.setConstantWidth(nWidth); ads_matrix mat; m_ptLoc.GetRotationMatrix(Ucs2Wcs(0.0),mat); //dc.SetColor(6); //用粉红色 switch(m_osShape) { case AcDb::kOsMaskEnd: { pline.addVertexAt(0, box.GetLowLeft().AsAcGePoint2d()); pline.addVertexAt(1, box.GetLowRight().AsAcGePoint2d()); pline.addVertexAt(2, box.GetUpRight().AsAcGePoint2d()); pline.addVertexAt(3, box.GetUpLeft().AsAcGePoint2d()); pline.setClosed(Adesk::kTrue); //pline.viewportDraw(pVd); XPoly2D poly1, poly2, poly; PolyConvert(pline, poly); poly.TransUCS(mat);//add by whl for ucs poly.QuickOffset(-nWidth, poly1); poly.QuickOffset(nWidth, poly2); dc << poly1 << poly2; } break; case AcDb::kOsMaskInt: { pline.setClosed(Adesk::kFalse); pline.addVertexAt(0, box.GetLowLeft().AsAcGePoint2d()); pline.addVertexAt(1, box.GetUpRight().AsAcGePoint2d()); XPoly2D poly1, poly2, poly; PolyConvert(pline, poly); poly.TransUCS(mat);//add by whl for ucs poly.QuickOffset(-nWidth, poly1); poly.QuickOffset(nWidth, poly2); dc << poly1 << poly2; pline.reset(Adesk::kFalse, 0); poly1.Reset(); poly2.Reset(); poly.Reset(); pline.addVertexAt(0, box.GetLowRight().AsAcGePoint2d()); pline.addVertexAt(1, box.GetUpLeft().AsAcGePoint2d()); PolyConvert(pline, poly); poly.TransUCS(mat);//add by whl for ucs poly.QuickOffset(-nWidth, poly1); poly.QuickOffset(nWidth, poly2); dc << poly1 << poly2; } break; case AcDb::kOsMaskNear: { pline.addVertexAt(0, box.GetLowLeft().AsAcGePoint2d()); pline.addVertexAt(1, box.GetLowRight().AsAcGePoint2d()); pline.addVertexAt(2, box.GetUpLeft().AsAcGePoint2d()); pline.addVertexAt(3, box.GetUpRight().AsAcGePoint2d()); pline.setClosed(Adesk::kTrue); XPoly2D poly1, poly2, poly; PolyConvert(pline, poly); poly.TransUCS(mat);//add by whl for ucs poly.QuickOffset(-nWidth, poly1); poly.QuickOffset(nWidth, poly2); dc << poly1 << poly2; } break; case AcDb::kOsMaskPerp: { pline.addVertexAt(0, box.GetUpLeft().AsAcGePoint2d()); pline.addVertexAt(1, box.GetLowLeft().AsAcGePoint2d()); pline.addVertexAt(2, box.GetLowRight().AsAcGePoint2d()); pline.setClosed(Adesk::kFalse); XPoly2D poly1, poly2, poly; PolyConvert(pline, poly); poly.TransUCS(mat);//add by whl for ucs poly.QuickOffset(-nWidth, poly1); poly.QuickOffset(nWidth, poly2); dc << poly1 << poly2; pline.reset(Adesk::kFalse, 0); poly1.Reset(); poly2.Reset(); poly.Reset(); XPoint pt1, pt2; Midpoint(box.GetUpLeft(), box.GetLowLeft(), pt1); Midpoint(box.GetLowRight(), box.GetLowLeft(), pt2); pline.addVertexAt(0, pt1.AsAcGePoint2d()); pline.addVertexAt(1, m_ptLoc.AsAcGePoint2d()); pline.addVertexAt(2, pt2.AsAcGePoint2d()); pline.setClosed(Adesk::kFalse); PolyConvert(pline, poly); poly.TransUCS(mat);//add by whl for ucs poly.QuickOffset(-nWidth, poly1); poly.QuickOffset(nWidth, poly2); dc << poly1 << poly2; } break; } } //////////////////////////////////////////// // 判断给定的点是否在墙体基线上 // -----------------------by gjm---------------------------// /* 画墙时,如果墙起点与终点都在另一个墙A的轮廓线内, 并且新墙标高大于等于A墙标高并且小于A墙的标高+墙高,则为重复墙,不会成功。 以下条件是建立在以上观点上的。 1.终点在墙A的轮廓线内,起点不在,则将新墙线与A墙线取交点,并用交点替换终点 2.起点在墙A的轮廓线内,终点不在,则将新墙线与A墙线取交点,并用交点替换起点 3.弧墙两端点在墙A轮廓线内,而其弧顶点不在,这种情况也要处理,将两端点都替换成墙A基线上的最近点。 */ namespace { // 返回 TRUE 说明对其中一点有过修改。 // 返回 FALSE说明对两点都无修改。即两点都在墙的轮廓线之外 BOOL ModifyPntByWall(TDbWall *pWall, XPoint &ptS, XPoint & ptE) { if (!pWall) return FALSE; TGGePoly2D poly; pWall->GetOutlinePoly(.0, poly, TRUE); int nFlagS = ptS & poly ,nFlagE = ptE & poly; bool bAllIn = nFlagE == PR_OUTSIDE && nFlagS == PR_OUTSIDE; // 如果是直墙,且两端点都在pWall轮廓线内,则直接退出 if (!pWall->IsKindOf(TGGeEntity::eArc)) if (bAllIn) return FALSE; // 求交点 TGGeLine line(ptS, ptE, LS_INFINITE); TADSGePoint3d pt1, pt2; int nCount = pWall->Intersection(line, pt1, pt2); if ((nFlagS == PR_INSIDE) && (nFlagE != PR_INSIDE)) // 起点在内,终点不在 { if (nCount == 1) ptS = pt1; else if (nCount ==2) { double d1 = pt1.Distance2d(ptS); double d2 = pt2.Distance2d(ptS); ptS = d1 < d2 ? pt1 : pt2; } return FALSE; } if ((nFlagS != PR_INSIDE) && (nFlagE == PR_INSIDE)) // 终点在内,起点不在 { if (nCount == 1) ptE = pt1; else if (nCount == 2) { double d1 = pt1.Distance2d(ptE); double d2 = pt2.Distance2d(ptE); ptE = d1 < d2 ? pt1 : pt2; } return TRUE; } if ((nFlagS == PR_INSIDE) && (nFlagE == PR_INSIDE)) // 这种情况只能是弧墙 { if (nCount == 2) { double d1 = pt1.Distance2d(ptE); double d2 = pt2.Distance2d(ptE); ptE = d1 < d2 ? pt1 : pt2; d1 = pt1.Distance2d(ptS); d2 = pt2.Distance2d(ptS); ptS = d1 < d2 ? pt1 : pt2; } return TRUE; } else return FALSE; } } BOOL IsOnWallBase(const XPoint &pt) { XPoint ptOnWall=pt; PickSet ssWall(SS_FREE); if (GetEntByDxf(ssWall, _T("TCH_WALL,TCH_CURTAIN_WALL"),1)==Acad::eOk) { long lCount=ssWall.Length(); for(long i=0L; iGetElevation(); int nPrFlag=ptOnWall&(*pWall); if (nPrFlag==PR_INSIDE || nPrFlag==PR_ONPT1 || nPrFlag==PR_ONPT2) return TRUE; } OPENOBJ_END(); } } return FALSE; } // 转为画墙而生 BOOL IsOnWallBaseForDraw(XPoint &ptEnd, XPoint &ptStart) { PickSet ssWall(SS_FREE); if (GetEntByDxf(ssWall, _T("TCH_WALL,TCH_CURTAIN_WALL"),1)==Acad::eOk) { long lCount=ssWall.Length(); for(long i=0L; iintersectWith(pEnt2, intType, points); OPENOBJ_END(); } OPENOBJ_END(); } int nInters=points.length(); for(int k=0; kgetOsnapPoints(AcDb::kOsModeNear, 0, ptWcs, ptLast, transWcsToDcs, points, AcDbIntArray())==Acad::eOk) { int numPoints=points.length(); for(int k=0; kStartPoint(), pWall->EndPoint()}; ptEnd[0].z=ptEnd[1].z=ptWcs.z; for(int n=0; n<2; n++) { if ((ptEnd[n]&box)!=PR_OUTSIDE) { double nDist=ptEnd[n].Distance(ptWcs); if (bRet) { if (nDistnewIterator(pBlockIterator); ASSERT(es==Acad::eOk && pBlockIterator!=NULL); for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) { AcDbEntity *pEntity=NULL; es = pBlockIterator->getEntity(pEntity, AcDb::kForRead); if (es!=Acad::eOk) continue; ASSERT(pEntity); XDbObject vTemp(pEntity); //不处理不可见的实体 if (pEntity->visibility() == AcDb::kInvisible) { continue; } AcDbCurve *pCurve=AcDbCurve::cast(pEntity); if (!pCurve) continue; if (!!m_lstDxfNameFilter) { const TCHAR *pszDxfName=pEntity->isA()->dxfName(); if (m_lstDxfNameFilter.Index(pszDxfName, 0)<0) continue; } AcDbObjectId idLayer=pEntity->layerId(); OPENOBJ_BEGIN(idLayer, AcDb::kForRead, AcDbLayerTableRecord, pLayer); if (pLayer) { if (pLayer && pLayer->isFrozen() || pLayer->isOff()) continue; } OPENOBJ_END(); if (!!m_lstLayerFilter) { TCHAR *pszLayer=pEntity->layer(); ASSERT(pszLayer); if (m_lstLayerFilter.Index(pszLayer, 0)<0) { delete pszLayer; continue; } delete pszLayer; } XPoint ptCloseToCurve; if (pCurve->getClosestPointTo(ptMid, ptCloseToCurve)==Acad::eOk && (ptCloseToCurve&rect)==PR_INSIDE) { Entity ent; VERIFY(acdbGetAdsName(ent.name, pCurve->objectId())==Acad::eOk); *this += ent; nRet=RTNORM; } } delete pBlockIterator; return nRet; } // nOsShape: 0--没有捕捉; 1--墙基线端点; 2--轴线交点; 3--墙基线最近点; 4--轴线最近点 // 对应: 的捕捉代码 int AsOsnapMask(int nOsShape) { int nRet=0; switch(nOsShape) { case 1: nRet=AcDb::kOsMaskEnd; break; case 2: nRet=AcDb::kOsMaskInt; break; case 3: case 4: nRet=AcDb::kOsMaskNear; break; case 5: case 6: nRet=AcDb::kOsMaskPerp; break; } return nRet; } // 捕捉顺序: 墙基线端点,轴线交点,墙垂足,轴线垂足,墙基线最近点,轴线最近点 // ptWcs -- I/O // 返回: 0--没有捕捉; 1--墙基线端点; 2--轴线交点; 3--墙基线最近点; 4--轴线最近点 // 5--墙垂足; 6--轴线垂足 int AutoSnapWall(XPoint &ptWcs, XPoint *ptBase=NULL) { double nApertureWcs=GetApertureWcs(); if (nApertureWcs<1.0E-6) return 0; int bSnap=0; XPoint vtSnap(nApertureWcs, nApertureWcs); XPoint ptLow=ptWcs-vtSnap; XPoint ptUp = ptWcs+vtSnap; XCurvePickSet ssWall, ssAxis; /* XStringList lstWallFilter, lstAxisFilter, lstAxisLayerFilter; lstWallFilter.Append(strnew(_T("TCH_WALL"))); lstAxisFilter.Append(strnew(_T("LINE"))); lstAxisFilter.Append(strnew(_T("ARC"))); lstAxisFilter.Append(strnew(_T("CIRCLE"))); lstAxisLayerFilter.Append(strnew(LAY_AXIS)); ssWall.SetDxfNameFilter(lstWallFilter); ssAxis.SetDxfNameFilter(lstAxisFilter); ssAxis.SetLayerFilter(lstAxisLayerFilter); BOOL bNearWall = ssWall.GetByCrossing(ptLow, ptUp)==RTNORM; BOOL bNearAxis = ssAxis.GetByCrossing(ptLow, ptUp)==RTNORM; */ BOOL bNearWall = (GetSafeSelectionEx(ssWall, FALSE, ptLow, ptUp, TDbWall::desc())==Acad::eOk); /* PickSet ss1(SS_FREE), ss2(SS_FREE), ss3(SS_FREE); BOOL bNearAxis1=(GetSafeSelection(ss1, FALSE, ptLow, ptUp, AcDbLine::desc())==Acad::eOk); BOOL bNearAxis2=(GetSafeSelection(ss2, FALSE, ptLow, ptUp, AcDbArc::desc())==Acad::eOk); BOOL bNearAxis3=(GetSafeSelection(ss3, FALSE, ptLow, ptUp, AcDbCircle::desc())==Acad::eOk); BOOL bNearAxis=(bNearAxis1 || bNearAxis2 || bNearAxis3); ssAxis += ss1; ssAxis += ss2; ssAxis += ss3; if (bNearAxis) { ssAxis.BaseFilter(RBList(8, LAY_AXIS, NULL)); bNearAxis=(ssAxis.Length()>0); } */ AcDbObjectId idLay=GetLayerIdFromString(LAY_AXIS); // sg modify 120305,由于在ARX2013的开发包中,AcRxClass类的构造函数、析构函数变成了保护成员,因此下面的用法是有错误的,换成其他接口 //DList lstClasses(FALSE); //lstClasses.Append(AcDbLine::desc()); //lstClasses.Append(AcDbArc::desc()); //lstClasses.Append(AcDbCircle::desc()); //BOOL bNearAxis=(GetSafeSelection(ssAxis, ptLow, ptUp, lstClasses, idLay)==Acad::eOk // && ssAxis.Length()>0); CStringArray aryDxfNames; aryDxfNames.Add(_T("Line")); aryDxfNames.Add(_T("Arc")); aryDxfNames.Add(_T("Circle")); BOOL bNearAxis=(GetSafeSelection(ssAxis, ptLow, ptUp, aryDxfNames, idLay)==Acad::eOk && ssAxis.Length()>0); XRectAngle box(ptLow, ptUp); if (bNearWall) if (SnapWallEnd(ssWall, box, ptWcs)) bSnap = 1; if (!bSnap && bNearAxis) if (SnapAxisInt(ssAxis, ptWcs)) bSnap = 2; if (!bSnap && bNearWall) { Entity entNear; XPoint ptCursor=ptWcs; if (SnapNear(ssWall, ptWcs, entNear)) { bSnap = 3; OPENOBJ_BEGIN(entNear, AcDb::kForRead, TDbWall, pWall); if (pWall && ptBase) { if (((*ptBase)&(*pWall))==PR_OUTSIDE) { XPoint ptPrj; pWall->ProjectToMe(*ptBase, ptPrj); double nIntAng=CT_acute_angle(ads_angle(*ptBase, ptPrj)-ads_angle(*ptBase, ptCursor)); if ((ptPrj&(*pWall))==PR_INSIDE && nIntAng<5.0*PI/180.0) { bSnap=5; ptWcs=ptPrj; } } } OPENOBJ_END(); } } if (!bSnap && bNearAxis) { Entity entNear; XPoint ptCursor=ptWcs; if (SnapNear(ssAxis, ptWcs, entNear)) { bSnap = 4; XCurveSegment seg(entNear); if (ptBase) { XPoint ptPrj; if (((*ptBase)&seg)==PR_OUTSIDE) { seg.ProjectToMe(*ptBase, ptPrj); double nIntAng=CT_acute_angle(ads_angle(*ptBase, ptPrj)-ads_angle(*ptBase, ptCursor)); if ((ptPrj&seg)==PR_INSIDE && nIntAng<5.0*PI/180.0) { bSnap=6; ptWcs=ptPrj; } } } } } return bSnap; } // 捕捉唯一的最近墙 // ptWcs(IN) -- 给定的点 // 返回: 捕捉到的墙体 AcDbObjectId SnapOnWall(const XPoint &ptWcs) { AcDbObjectId idRet; XDbBlockTableRec objMSpace; if (!objMSpace) return idRet; AcDbBlockTableRecordIterator* pBlockIterator=NULL; Acad::ErrorStatus es = objMSpace.m_pBlockTableRec->newIterator(pBlockIterator); ASSERT(es==Acad::eOk && pBlockIterator!=NULL); for (pBlockIterator->start(); !pBlockIterator->done(); pBlockIterator->step()) { AcDbEntity *pEntity=NULL; es = pBlockIterator->getEntity(pEntity, AcDb::kForRead); if (es!=Acad::eOk) continue; ASSERT(pEntity); XDbObject vTemp(pEntity); //不处理不可见的实体 if (pEntity->visibility() == AcDb::kInvisible || !pEntity->isKindOf(TDbWall::desc())) { continue; } TDbWall *pWall=(TDbWall*)pEntity; AcDbObjectId idLayer=pWall->layerId(); OPENOBJ_BEGIN(idLayer, AcDb::kForRead, AcDbLayerTableRecord, pLayer); ASSERT(pLayer); if (pLayer->isFrozen() || pLayer->isOff()) continue; OPENOBJ_END(); XPoint ptPrj; if (pWall->ProjectToMe(ptWcs, ptPrj)!=RTNORM) continue; if ((ptPrj&(*pWall))!=PR_INSIDE) continue; double nDist2Wall=pWall->GetDist2Me(ptWcs); if (nDist2Wall > -pWall->GetWidth(0) - _DIST_SNAP*10 && nDist2Wall < pWall->GetWidth(1)+_DIST_SNAP*10) { idRet=pWall->objectId(); break; } } delete pBlockIterator; return idRet; #if 0 // 不知道是否捕捉速度太慢, 光标移动到墙体内时,捕捉光标出现。 PickSet ssWall(SS_FREE); if (GetEntByDxf(ssWall,_T("TCH_WALL,TCH_CURTAIN_WALL"),1)!=Acad::eOk) //if (ssWall.Get(_T("X"), NULL, NULL, RBList(RTDXF0, _T("TCH_WALL"), NULL))!=RTNORM) return AcDbObjectId::kNull; long lCount=ssWall.Length(); for(long i=0; iGetOutlinePoly(ptWcs.z, poly2d); if ((ptWcs&poly2d)!=PR_OUTSIDE) { return pWall->objectId(); } } OPENOBJ_END(); } return AcDbObjectId::kNull; /* AcDbObjectId idRet; double nApertureWcs=GetApertureWcs(); if (nApertureWcs<1.0E-6) return idRet; //int bSnap=0; XPoint vtSnap(nApertureWcs*4, nApertureWcs*4); XPoint ptLow=ptWcs-vtSnap; XPoint ptUp = ptWcs+vtSnap; XCurvePickSet ssWall; XStringList lstWallFilter; lstWallFilter.Append(strnew(_T("TCH_WALL"))); ssWall.SetDxfNameFilter(lstWallFilter); BOOL bNearWall = ssWall.GetByCrossing(ptLow, ptUp)==RTNORM; if (bNearWall && ssWall.Length()==1) { Entity ent=ssWall[0L]; acdbGetObjectId(idRet, ent.name); } return idRet; */ #endif } // 为了绘制Osnap点而构造临时实体 class XDbOsnapPoint: public AcDbEntity { public: XPoint m_ptLoc; int m_osShape; bool m_bRectCursor; XPoint m_ptBase; public: XDbOsnapPoint(): m_osShape(0), m_bRectCursor(false) {} Adesk::Boolean subWorldDraw(AcGiWorldDraw *mode); void subViewportDraw(AcGiViewportDraw *mode); }; Adesk::Boolean XDbOsnapPoint::subWorldDraw(AcGiWorldDraw *mode) { return Adesk::kFalse; } // 由于视窗的实体不能访问, 因此本函数目前没有使用 void XDbOsnapPoint::subViewportDraw(AcGiViewportDraw *mode) { if (m_bRectCursor) { XRectAngle box(Wcs2Ucs(m_ptBase), Wcs2Ucs(m_ptLoc)); XPoly2D poly2d(1); box.AsPoly2D(poly2d); poly2d.TransUCS(Groups(1), Groups(0)); AcDbPolyline pline; PolyConvert(poly2d, pline); pline.viewportDraw(mode); } if (CDrawWallDlg::g_bAutoSnap) DrawOsnapShape(mode, m_ptLoc, m_osShape); } // 拖曳显示点 class XOsPointEdJig : public AcEdJig { public: XOsPointEdJig(); virtual ~XOsPointEdJig(); void doIt(); virtual DragStatus sampler(); virtual Adesk::Boolean update(); virtual AcDbEntity* entity() const; int GetRetCode(int *kwordId=NULL) const; int m_nRetCode; //返回码 const TCHAR *m_pszPrompt; //提示信息 const TCHAR *m_pszKeyword; //关键字 XDbOsnapPoint *m_pDrawEnt; //临时实体 XPoint m_ptFrom, m_ptTo; int m_osShape; int m_nUsageFlag; //0--不带橡皮巾; 1--待橡皮巾; 2--矩形拖曳 }; // 转换成ADS代码 int XOsPointEdJig::GetRetCode(int *kwordId) const { int ret = m_nRetCode; if (ret == AcEdJig::kCancel) ret = RTCAN; else if (ret == AcEdJig::kNull) ret = RTNONE; else if (ret <= 0) ret = RTNORM; else { if (kwordId) *kwordId = ret; ret = RTKWORD; } return ret; } XOsPointEdJig::XOsPointEdJig() :m_pszKeyword(NULL), m_pszPrompt(NULL), m_pDrawEnt(NULL), m_nRetCode(0), m_osShape(0), m_nUsageFlag(0) { } XOsPointEdJig::~XOsPointEdJig() { if (m_pDrawEnt) delete m_pDrawEnt; } // 开始执行拖动 void XOsPointEdJig::doIt() { m_pDrawEnt = new XDbOsnapPoint; m_pDrawEnt->m_osShape=AsOsnapMask(m_osShape); m_pDrawEnt->m_ptLoc = m_ptTo; m_pDrawEnt->m_bRectCursor = (m_nUsageFlag==2); m_pDrawEnt->m_ptBase=m_ptFrom; setDispPrompt(m_pszPrompt); if (m_nUsageFlag==2) setSpecialCursorType(AcEdJig::kNoSpecialCursor); if (m_pszKeyword) { INITGET_BEG(-1, m_pszKeyword); try { m_nRetCode = drag(); } catch(...) { m_nRetCode=AcEdJig::kCancel; } INITGET_END(); } else { try { m_nRetCode = drag(); } catch(...) { m_nRetCode=AcEdJig::kCancel; } } } // 反馈 AcEdJig::DragStatus XOsPointEdJig::sampler() { DragStatus stat; setUserInputControls((UserInputControls) (AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted | AcEdJig::kNoNegativeResponseAccepted | AcEdJig::kNoZeroResponseAccepted)); if (m_pszKeyword) setKeywordList(m_pszKeyword); XPoint ptTemp; XPoint *ptBase=NULL; if (m_nUsageFlag==2) { setSpecialCursorType(AcEdJig::kNoSpecialCursor); stat = acquirePoint(ptTemp, m_ptFrom); ptBase=&m_ptFrom; } else if (m_nUsageFlag==1) { stat = acquirePoint(ptTemp, m_ptFrom); ptBase=&m_ptFrom; } else { stat = acquirePoint(ptTemp); } if (stat == AcEdJig::kNormal) { m_osShape=CDrawWallDlg::g_bAutoSnap? AutoSnapWall(ptTemp, ptBase) : 0; if (ads_distance(ptTemp, m_ptTo)>_DIST_SNAP) { m_ptTo=ptTemp; } else return AcEdJig::kNoChange; } return stat; } // 更新实体数据 Adesk::Boolean XOsPointEdJig::update() { if (!(m_pDrawEnt->m_ptLoc == m_ptTo)) { m_pDrawEnt->m_ptLoc = m_ptTo; m_pDrawEnt->m_osShape = AsOsnapMask(m_osShape); m_pDrawEnt->m_bRectCursor = (m_nUsageFlag==2); m_pDrawEnt->m_ptBase=m_ptFrom; } return Adesk::kTrue; } AcDbEntity* XOsPointEdJig::entity() const { return m_pDrawEnt; } ///////////////////////////////////////////////////// // 为了拖曳墙体和绘制Osnap点而构造临时实体 class TDbWallOsnapPoint: public TDbWall { public: XPoint m_ptLoc; int m_osShape; public: TDbWallOsnapPoint(): m_osShape(0) {} Adesk::Boolean subWorldDraw(AcGiWorldDraw *mode); void subViewportDraw(AcGiViewportDraw *mode); }; Adesk::Boolean TDbWallOsnapPoint::subWorldDraw(AcGiWorldDraw *mode) { return Adesk::kFalse; } void TDbWallOsnapPoint::subViewportDraw(AcGiViewportDraw *mode) { TDbWall::subViewportDraw(mode); if (CDrawWallDlg::g_bAutoSnap) DrawOsnapShape(mode, m_ptLoc, m_osShape); } //////////////////////////////////////// // 拖曳墙体, 并确定半径或者顶点 class XDrawWallEdJig : public TEdJig { public: XDrawWallEdJig(CDrawWallDlg *pDlg); virtual ~XDrawWallEdJig(); void doIt(); virtual DragStatus sampler(); virtual Adesk::Boolean Update(); virtual AcDbEntity* entity() const; #if ADS>15 virtual void CreateGrip(); virtual Acad::ErrorStatus EntityToDim(long iGrip,long iDim); virtual Acad::ErrorStatus DimToEntity(long iGrip,long iDim,double newValue); #endif int GetRetCode(int *kwordId=NULL) const; int m_nRetCode; //返回码 const TCHAR *m_pszPrompt; //提示信息 const TCHAR *m_pszKeyword; //关键字 TDbWallOsnapPoint *m_pDrawEnt; //临时实体 int m_osShape; //捕捉性质 XPoint m_ptStart, m_ptEnd, m_ptAny; double m_nRadius; //控制方案 //int m_bIsDouble; //是否为双线 // 0--已知起点, 待定终点 // 1--已知起点,弧上任意点,待定终点 // 2--已知起点终点, 待定弧上一点 // 3--已知起点终点, 待定半径 int m_nFlag; CDrawWallDlg *m_pDlg; }; /* ========================================================== */ #if ADS>15 void XDrawWallEdJig::CreateGrip() { SetGripNum(2); //直墙 GetGrip(0)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimResultantLength)); GetGrip(0)->AppendDim(new TDbGripAngleDim(AcDbDimData::kDimResultantAngle)); //弧墙 GetGrip(1)->AppendDim(new TDbGripRadiusDim(AcDbDimData::kDimRadius)); GetGrip(1)->AppendDim(new TDbGripAngleDim(AcDbDimData::kDimResultantAngle)); } Acad::ErrorStatus XDrawWallEdJig::EntityToDim(long iGrip,long iDim) { TDbGripDim*pDim=GetGripDim(iGrip,iDim); if (pDim==NULL) return Acad::eInvalidInput; TDbWall*pWall=m_pDrawEnt; double dist=5000; switch(iGrip) { case 0://直墙终点 switch(iDim) { case 0://长度 { TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim; pDistDim->SetData(pWall->EndPoint().AsAcGePoint3d(),pWall->StartPoint().AsAcGePoint3d(),dist); } break; case 1://角度 { TDbGripAngleDim*pAngleDim=(TDbGripAngleDim*)pDim; XPoint ptEnd=pWall->StartPoint()+XPoint(1000,0,0); pAngleDim->SetData(pWall->StartPoint().AsAcGePoint3d(),pWall->EndPoint().AsAcGePoint3d(),ptEnd.AsAcGePoint3d()); } break; default: return Acad::eNotImplementedYet; } break; case 1://中点 switch(iDim) { case 0://半径 { TDbGripRadiusDim*pRadiusDim=(TDbGripRadiusDim*)pDim; pRadiusDim->SetData(pWall->GetArc().GetCenterPt().AsAcGePoint3d(),pWall->MidPoint().AsAcGePoint3d()); } break; case 1://包络角 { TDbGripAngleDim*pAngleDim=(TDbGripAngleDim*)pDim; pAngleDim->SetData(*pWall); } break; default: return Acad::eNotImplementedYet; } break; default: return Acad::eNotImplementedYet; } return Acad::eOk; } Acad::ErrorStatus XDrawWallEdJig::DimToEntity(long iGrip,long iDim,double newValue) { XPoint vt=m_pDrawEnt->EndPoint()-m_pDrawEnt->StartPoint(); vt.Normalize(); switch(iGrip) { case 0://终点 switch(iDim) { case 0://长度 if (newValue>1E-6) { vt*=newValue; m_ptEnd=m_pDrawEnt->EndPoint()=m_pDrawEnt->StartPoint()+vt; } break; case 1://角度 { if (vt.y<0) newValue*=-1; XPoint vt2(m_pDrawEnt->GetLength(),0,0); vt2.Rotate(newValue); m_ptEnd=m_pDrawEnt->EndPoint()=m_pDrawEnt->StartPoint()+vt2; } break; default: return Acad::eNotImplementedYet; } break; case 1://中点 switch(iDim) { case 0://半径 { XCurveSegment line(m_pDrawEnt->StartPoint(),m_pDrawEnt->EndPoint(),0); double len=line.GetLength(); double as=len*0.5/newValue; if (as>1) return Acad::eInvalidInput; newValue=2*asin(as); } case 1://包络角 { m_pDrawEnt->SetBulge(CT_std_angle(newValue)); m_ptAny=m_pDrawEnt->MidPoint(); } break; default: return Acad::eNotImplementedYet; } break; default: return Acad::eNotImplementedYet; } return Acad::eOk; } #endif; // 转换成ADS代码 int XDrawWallEdJig::GetRetCode(int *kwordId) const { int ret = m_nRetCode; if (ret == AcEdJig::kCancel) ret = RTCAN; else if (ret == AcEdJig::kNull) ret = RTNONE; else if (ret <= 0) ret = RTNORM; else { if (kwordId) *kwordId = ret; ret = RTKWORD; } return ret; } XDrawWallEdJig::XDrawWallEdJig(CDrawWallDlg *pDlg) :m_pDlg(pDlg), m_pszKeyword(NULL), m_pszPrompt(NULL), m_pDrawEnt(NULL), m_nRetCode(0), m_osShape(0) { #if ADS>15 CreateGrip(); #endif } XDrawWallEdJig::~XDrawWallEdJig() { if (m_pDrawEnt) delete m_pDrawEnt; } // 开始执行拖动 void XDrawWallEdJig::doIt() { m_pDrawEnt = new TDbWallOsnapPoint; m_pDrawEnt->StartPoint() = m_ptStart; m_pDrawEnt->EndPoint() = m_ptEnd; if (m_pDlg) { m_pDrawEnt->SetWidth(0, m_pDlg->GetLeftWidth()); m_pDrawEnt->SetWidth(1, m_pDlg->GetRightWidth()); } else { m_pDrawEnt->SetWidth(0, g_lWallWidth); m_pDrawEnt->SetWidth(1, g_rWallWidth); } TDbWall::Catalog nCatalog; m_pDrawEnt->setLayer(m_pDrawEnt->GetDefaultLayer()); if (m_pDlg==NULL||m_pDlg->GetUsage(nCatalog)!=TWallData::kVirtual) m_pDrawEnt->SetUsageFlag(TWallData::kEdJig); else m_pDrawEnt->SetUsageFlag(TWallData::kVirtual); // Osnap Point member m_pDrawEnt->m_osShape=AsOsnapMask(m_osShape); if (m_nFlag==0 || m_nFlag==1) m_pDrawEnt->m_ptLoc = m_ptEnd; else if (m_nFlag==2) m_pDrawEnt->m_ptLoc = m_ptAny; setDispPrompt(m_pszPrompt); if (m_pszKeyword) { INITGET_BEG(-1, m_pszKeyword); try { m_nRetCode = drag(); } catch(...) { m_nRetCode=AcEdJig::kCancel; } INITGET_END(); } else { try { m_nRetCode = drag(); } catch(...) { m_nRetCode=AcEdJig::kCancel; } } } extern TARCH_IMPEXP void GetWallLengthModel(DList &lstWidth); extern TARCH_IMPEXP double GetModelNumber(DList &lstModel, double nNearNumber); // 反馈 AcEdJig::DragStatus XDrawWallEdJig::sampler() { DragStatus stat; setUserInputControls((UserInputControls) (AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted | AcEdJig::kNoNegativeResponseAccepted | AcEdJig::kNoZeroResponseAccepted)); if (m_pszKeyword) setKeywordList(m_pszKeyword); XPoint ptTemp; if (m_nFlag==0 || m_nFlag==1 || m_nFlag==2) { stat = acquirePoint(ptTemp, m_ptStart); if (stat == AcEdJig::kNormal) { m_osShape=CDrawWallDlg::g_bAutoSnap? AutoSnapWall(ptTemp, &m_ptStart):0; if (m_nFlag==0 || m_nFlag==1) { //求终点 if (m_pDrawEnt->Is(CURVE_LINE) && m_nFlag==0 && g_bModelNumber && !m_osShape) { //模数打开 double nAng=ads_angle(m_ptStart, ptTemp); double nSize; //=GetModelNumber(lstSize, ); nSize = AS_INT(ads_distance(m_ptStart, ptTemp)/g_nWallStep)*g_nWallStep; if (nSize>0) ads_polar(m_ptStart, nAng, nSize, ptTemp); } if (ads_distance(ptTemp, m_ptEnd)>_DIST_SNAP) m_ptEnd=ptTemp; else return AcEdJig::kNoChange; } else if (m_nFlag==2) { if (ptTemp.Distance(m_ptAny)>_DIST_SNAP) m_ptAny=ptTemp; else return AcEdJig::kNoChange; } } } else if (m_nFlag==3) { //已知起点终点, 待定半径 double nTemp; stat = acquireDist(nTemp, m_ptStart); if (fabs(nTemp-m_nRadius)>_DIST_SNAP) { m_nRadius=nTemp; } else if (stat==AcEdJig::kNormal) { return AcEdJig::kNoChange; } } return stat; } // 更新实体数据 Adesk::Boolean XDrawWallEdJig::Update() { extern TARCH_IMPEXP BOOL g_bRevWallFlag; m_pDrawEnt->m_osShape = AsOsnapMask(m_osShape); if (m_pDlg) { m_pDrawEnt->SetWidth(0, m_pDlg->GetLeftWidth()); m_pDrawEnt->SetWidth(1, m_pDlg->GetRightWidth()); } else { m_pDrawEnt->SetWidth(0, g_lWallWidth); m_pDrawEnt->SetWidth(1, g_rWallWidth); } XCurveSegment seg; if (m_nFlag==0) { if (m_ptStart==m_ptEnd) return Adesk::kFalse; seg=XLine(m_ptStart, m_ptEnd); m_pDrawEnt->m_ptLoc = m_ptEnd; } else if (m_nFlag==1) {//已知起点,弧上任意点,待定终点 if (m_ptEnd==m_ptStart || m_ptEnd==m_ptAny) return Adesk::kFalse; seg=XArc(m_ptStart, m_ptAny, m_ptEnd); m_pDrawEnt->m_ptLoc = m_ptEnd; } else if (m_nFlag==2) { //已知起点终点, 待定弧上一点 if (m_ptAny==m_ptStart || m_ptEnd==m_ptAny || (m_ptAny&XLine(m_ptStart, m_ptEnd))!=PR_OUTSIDE) return Adesk::kFalse; seg=XArc(m_ptStart, m_ptAny, m_ptEnd); if (seg.StartPoint().Distance(m_ptStart)>seg.StartPoint().Distance(m_ptEnd)) { //m_pDrawEnt->SetWidth(0, g_rWallWidth); //m_pDrawEnt->SetWidth(1, g_lWallWidth); g_bRevWallFlag=TRUE; double lWidth=m_pDrawEnt->GetWidth(0); double rWidth=m_pDrawEnt->GetWidth(1); m_pDrawEnt->SetWidth(0, rWidth); m_pDrawEnt->SetWidth(1, lWidth); } else { //m_pDrawEnt->SetWidth(0, g_lWallWidth); //m_pDrawEnt->SetWidth(1, g_rWallWidth); g_bRevWallFlag=FALSE; } m_pDrawEnt->m_ptLoc = m_ptAny; } else if (m_nFlag==3) { double nChordLen=ads_distance(m_ptStart, m_ptEnd); if (nChordLen<2.0*fabs(m_nRadius)-1.0E-6) { double bulge=2.0*asin(nChordLen/2.0/m_nRadius); seg=XDirectionCurve(m_ptStart, m_ptEnd, bulge, LS_FINITE).GetCurve(); if (seg.StartPoint().Distance(m_ptStart)>seg.StartPoint().Distance(m_ptEnd)) { g_bRevWallFlag=TRUE; double lWidth=m_pDrawEnt->GetWidth(0); double rWidth=m_pDrawEnt->GetWidth(1); m_pDrawEnt->SetWidth(0, rWidth); m_pDrawEnt->SetWidth(1, lWidth); } else { //m_pDrawEnt->SetWidth(0, g_lWallWidth); //m_pDrawEnt->SetWidth(1, g_rWallWidth); } } else { return Adesk::kFalse; } } else { return Adesk::kFalse; } *(XCurveSegment *)m_pDrawEnt = seg; return Adesk::kTrue; } AcDbEntity* XDrawWallEdJig::entity() const { return m_pDrawEnt; } // 给定起点, 终点进行弧上一点拖动绘制弧 int DragDrawArc_SEP(CDrawWallDlg *pDlg, const XPoint &ptStart, const XPoint &ptEnd, const TCHAR *prompt, XPoint &ptAny, const TCHAR *kword, int *kwordId) { XDrawWallEdJig jig(pDlg); #if ADS>15 jig.SetCurGrip(1); #endif jig.m_pszKeyword = kword; jig.m_pszPrompt = prompt; jig.m_ptStart = ptStart; jig.m_ptEnd=ptEnd; Midpoint(ptStart, ptEnd, jig.m_ptAny); //jig.m_bIsDouble = bDouble; jig.m_nFlag=2; LAB_REPEAT: jig.doIt(); int nRetCode=jig.GetRetCode(kwordId); if (nRetCode==RTNORM && (jig.m_ptAny&XLine(ptStart, ptEnd))!=PR_OUTSIDE) goto LAB_REPEAT; if (nRetCode==RTNORM) ptAny = jig.m_ptAny; return nRetCode; } // 给定起点, 弧上一点, 进行终点拖动绘制弧 int DragDrawArc_SPE(CDrawWallDlg * pDlg, const XPoint &ptStart, const XPoint &ptAny, const TCHAR *prompt, XPoint &ptEnd, const TCHAR *kword, int *kwordId) { XDrawWallEdJig jig(pDlg); #if ADS>15 jig.SetCurGrip(-1); #endif jig.m_pszKeyword = kword; jig.m_pszPrompt = prompt; jig.m_ptStart = ptStart; jig.m_ptAny=ptAny; //jig.m_bIsDouble = bDouble; jig.m_nFlag=1; jig.doIt(); int nRetCode=jig.GetRetCode(kwordId); if (nRetCode==RTNORM) ptEnd = jig.m_ptEnd; return nRetCode; } // 给定起点, 终点进行拖动半径绘制弧 int DragDrawArc_SER(CDrawWallDlg *pDlg, const XPoint &ptStart, const XPoint &ptEnd, const TCHAR *prompt, double *nRadius, const TCHAR *kword, int *kwordId) { XDrawWallEdJig jig(pDlg); #if ADS>15 jig.SetCurGrip(-1); #endif jig.m_pszKeyword = kword; jig.m_pszPrompt = prompt; jig.m_ptStart = ptStart; jig.m_ptEnd=ptEnd; //jig.m_bIsDouble = bDouble; jig.m_nFlag=3; jig.doIt(); int nRetCode=jig.GetRetCode(kwordId); if (nRetCode==RTNORM) *nRadius = jig.m_nRadius; return nRetCode; } // 给定起点, 终点进行拖动半径绘制弧 int DragDrawLine(CDrawWallDlg *pDlg, XPoint &ptStart, const TCHAR *prompt, XPoint &ptEnd, const TCHAR *kword, int *kwordId, BOOL *bDiscontinue) { XDrawWallEdJig jig(pDlg); jig.m_pszKeyword = kword; jig.m_pszPrompt = prompt; jig.m_ptStart = ptStart; xg_getvar(_T("LASTPOINT"), jig.m_ptEnd); jig.m_ptEnd=Ucs2Wcs(jig.m_ptEnd); //jig.m_bIsDouble = bDouble; jig.m_nFlag=0; jig.doIt(); int nRetCode=jig.GetRetCode(kwordId); if (nRetCode==RTNORM) { ptEnd = jig.m_ptEnd; if (bDiscontinue) *bDiscontinue=IsOnWallBase(ptEnd); } return nRetCode; } ////////////////////////////////////////////////// // 获取输入点, 自动对墙体/轴线进行模糊捕捉 int OsGetPointWall(double *ptFrom, const TCHAR *prompt, XPoint &pt, const TCHAR *kword=NULL, int *kwordId=NULL, BOOL *bDiscontinue=NULL) { XOsPointEdJig jig; jig.m_pszKeyword = kword; jig.m_pszPrompt = prompt; jig.m_ptTo = pt; jig.m_osShape=0; jig.m_nUsageFlag=ptFrom!=NULL; if (ptFrom) jig.m_ptFrom = ptFrom; jig.doIt(); int nKeyword; int & kid=kwordId? *kwordId : nKeyword; int nRetCode=jig.GetRetCode(&kid); if (nRetCode==RTNORM) { pt = jig.m_ptTo; if (bDiscontinue) *bDiscontinue=IsOnWallBase(pt); } return nRetCode; } ////////////////////////////////////////////////// // 获取输入点, 自动对墙体/轴线进行模糊捕捉 int OsGetCornerWall(double *ptFrom, const TCHAR *prompt, XPoint &pt, const TCHAR *kword=NULL, int *kwordId=NULL) { XPushVar vOrthoMode(_T("ORTHOMODE"), 0); ASSERT(ptFrom); XOsPointEdJig jig; jig.m_pszKeyword = kword; jig.m_pszPrompt = prompt; jig.m_ptTo = pt; jig.m_osShape=0; jig.m_nUsageFlag=2; jig.m_ptFrom = ptFrom; jig.doIt(); int nKeyword; int & kid=kwordId? *kwordId : nKeyword; int nRetCode=jig.GetRetCode(&kid); if (nRetCode==RTNORM) pt = jig.m_ptTo; return nRetCode; } //////////////////////////////////////////////////////////////////////////////// // 门窗的绘制 ///////////////////////////////////////////////////// // 为了拖曳门窗和绘制Osnap点而构造临时实体 class TDbOpeningJig:public AcDbEntity { public: TDbOpening *m_pOpening; public: TDbOpeningJig() {m_pOpening=NULL;} ~TDbOpeningJig() { if (m_pOpening!=NULL) delete m_pOpening; } void SetOpening(TDbOpening*pOpening) { if (m_pOpening!=NULL) delete m_pOpening; m_pOpening=(TDbOpening*)pOpening->clone(); m_pOpening->InitHardPointerId(); // add by xly on 1103302设置转角布局 m_pOpening->SetLayoutRotation(Ucs2Wcs(0)); TMasterProperties prop; prop.SetFrom(pOpening); prop.SetTo(this); } Adesk::Boolean subWorldDraw(AcGiWorldDraw *mode); void subViewportDraw(AcGiViewportDraw *mode); void SetParameters(const TDbWall *pWall, const XPoint &ptOnWall, const XPoint &ptQuadrant, UINT nInsMode); }; void TDbOpeningJig::SetParameters(const TDbWall *pWall, const XPoint &ptOnWall, const XPoint &ptQuadrant, UINT nInsMode) { //SHORT nShiftState=GetKeyState(VK_SHIFT); BOOL bShiftPressed = g_bShiftToggle; //(nShiftState&256)!=0; XPoint ptLoc; pWall->GetOpeningLocation(ptOnWall, m_pOpening->GetKind(), m_pOpening->GetWidth(), ptLoc); ptLoc.z = m_pOpening->GetLocation().z; m_pOpening->SetLocation(ptLoc); // add by xly on 110216 8.5需求修改矩形洞,增加是否穿透墙体设置 //m_pOpening->SetThickness(m_pOpening->GetKind()==TOpeningData::OP_HOLE? pWall->GetWidth() : pWall->GetWidth()/2.0); if (m_pOpening->GetKind()==TOpeningData::OP_HOLE) { m_pOpening->SetThickness(m_pOpening->GetThickness()); } else { m_pOpening->SetThickness(pWall->GetWidth()/2.0); } m_pOpening->SetRotation(pWall->Direction(ptOnWall)); if (m_pOpening->isKindOf(TDbGroupOpening::desc())) { ((TDbGroupOpening*)m_pOpening)->Update(false); } ads_real nAng=CT_std_angle(ads_angle(m_pOpening->GetLocation(), ptQuadrant)-m_pOpening->GetRotation()); if (nAng>=0.0 && nAngSetQuadrant(bShiftPressed? 1:0); else m_pOpening->SetQuadrant(bShiftPressed? 2:3); m_pOpening->SetLabelPos(m_pOpening->GetDefaultLabPos()); } Adesk::Boolean TDbOpeningJig::subWorldDraw(AcGiWorldDraw *mode) { if (!m_pOpening->GetWallId()) return Adesk::kTrue; //Draw nothing return Adesk::kFalse;; } void TDbOpeningJig::subViewportDraw(AcGiViewportDraw *mode) { // modify by xly on 110217 增加同时绘制多个门窗时提供预览 //m_pOpening->subViewportDraw(mode); //DrawOsnapShape(mode, m_pOpening->GetLocation(), AcDb::kOsMaskNear); int nNums = CInsertOpeningDlg::g_pCurDlg->GetOpeningNums(); if (CInsertOpeningDlg::g_nInsertMode==7) { nNums = 1; } if (nNums>1) { XPoint ptLoc = m_pOpening->GetLocation(), ptPos; double dWidth = m_pOpening->GetWidth(); double dAngle = m_pOpening->GetRotation(); double dDist(0.0); if (nNums%2 == 0)// 偶数个门 { for (int i=0; iclone(); pOpening->SetLocation(ptPos); pOpening->m_ptLabel=pOpening->GetDefaultLabPos(); pOpening->SetLayoutRotation(Ucs2Wcs(0)); pOpening->subViewportDraw(mode); dAngle = PI+dAngle; } } else// 奇数个门 { m_pOpening->subViewportDraw(mode); for (int i=1; iclone(); pOpening->SetLocation(ptPos); pOpening->m_ptLabel=pOpening->GetDefaultLabPos(); pOpening->SetLayoutRotation(Ucs2Wcs(0)); pOpening->subViewportDraw(mode); dAngle = PI+dAngle; } } DrawOsnapShape(mode, ptLoc, AcDb::kOsMaskNear); } else { m_pOpening->subViewportDraw(mode); DrawOsnapShape(mode, m_pOpening->GetLocation(), AcDb::kOsMaskNear); } } //////////////////////////////////////// // 拖曳墙体, 并确定半径或者顶点 class XDrawOpeningEdJig : public TEdJig //modified by whl { public: XDrawOpeningEdJig(TDbOpening*pOpening); virtual ~XDrawOpeningEdJig(); void doIt(); virtual DragStatus sampler(); virtual Adesk::Boolean Update(); virtual AcDbEntity* entity() const; #if ADS>15 virtual void CreateGrip(); virtual Acad::ErrorStatus EntityToDim(long iGrip,long iDim); virtual Acad::ErrorStatus DimToEntity(long iGrip,long iDim,double newValue); #endif int GetRetCode(int *kwordId=NULL) const; XPoint m_ptCursor, m_ptOnWall; AcDbObjectId m_idWall; int m_nRetCode; //返回码 const TCHAR *m_pszPrompt; //提示信息 const TCHAR *m_pszKeyword; //关键字 TDbOpeningJig *m_pDrawEnt; //临时实体 //CInsertOpeningDlg *m_pDataDlg; replaced by CInsertOpeningDlg::g_pCurDlg }; /* ========================================================== */ #if ADS>15 void XDrawOpeningEdJig::CreateGrip() { SetGripNum(1); GetGrip(0)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength));//前垛距 GetGrip(0)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength));//后垛距 } Acad::ErrorStatus XDrawOpeningEdJig::EntityToDim(long iGrip,long iDim) { TDbOpeningJig *pEnt=m_pDrawEnt; XCurveSegment wall; if (!pEnt->m_pOpening->GetCenterCurve(wall))//中线 return Acad::eInvalidInput; TDbGripDim*pDim=GetGripDim(iGrip,iDim); if (pDim==NULL) return Acad::eInvalidInput; switch(iGrip) { case 0: switch(iDim) { case 0://前垛距 { XCurveSegment seg; TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim; XPoint pt; if (pEnt->m_pOpening->GetNeighbourPoint(pt,true)) { XPoint ptSideStart,ptSideEnd; pEnt->m_pOpening->GetSidePoints(ptSideStart, ptSideEnd); wall.ProjectToMe(pt,pt); wall.ProjectToMe(ptSideStart,ptSideStart); pDistDim->SetData(pt.AsAcGePoint3d(),ptSideStart.AsAcGePoint3d(),1200); } } break; case 1://后垛距 { XCurveSegment seg; TDbGripDistDim*pDistDim=(TDbGripDistDim*)pDim; XPoint pt; if (pEnt->m_pOpening->GetNeighbourPoint(pt,false)) { XPoint ptSideStart,ptSideEnd; pEnt->m_pOpening->GetSidePoints(ptSideStart, ptSideEnd); wall.ProjectToMe(pt,pt); wall.ProjectToMe(ptSideEnd,ptSideEnd); pDistDim->SetData(ptSideEnd.AsAcGePoint3d(),pt.AsAcGePoint3d(),1200); } } break; default: return Acad::eNotImplementedYet; } break; default: return Acad::eNotImplementedYet; } return Acad::eOk; } Acad::ErrorStatus XDrawOpeningEdJig::DimToEntity(long iGrip,long iDim,double newValue) { XCurveSegment wall; m_pDrawEnt->m_pOpening->GetCenterCurve(wall); XPoint vt=wall.EndPoint()-wall.StartPoint(); vt.Normalize(); switch(iGrip) { case 0: switch(iDim) { case 0://后垛距 { XCurveSegment seg; XPoint pt,pt1,pt2; m_pDrawEnt->m_pOpening->GetNeighbourPoint(pt,true); wall.ProjectToMe(pt,pt); m_pDrawEnt->m_pOpening->GetSidePoints(pt1,pt2); double oldValue=pt.Distance2d(pt1.AsAcGePoint3d()); vt*=(newValue-oldValue); m_pDrawEnt->m_pOpening->SetLocation(m_pDrawEnt->m_pOpening->GetLocation()+vt); m_pDrawEnt->m_pOpening->SetLabelPos(m_pDrawEnt->m_pOpening->GetDefaultLabPos());//add by whl on 060301 } break; case 1://后垛距 { XCurveSegment seg; XPoint pt,pt1,pt2; m_pDrawEnt->m_pOpening->GetNeighbourPoint(pt,false); wall.ProjectToMe(pt,pt); m_pDrawEnt->m_pOpening->GetSidePoints(pt1,pt2); double oldValue=pt.Distance2d(pt2.AsAcGePoint3d()); vt*=(oldValue-newValue); m_pDrawEnt->m_pOpening->SetLocation(m_pDrawEnt->m_pOpening->GetLocation()+vt); m_pDrawEnt->m_pOpening->SetLabelPos(m_pDrawEnt->m_pOpening->GetDefaultLabPos());//add by whl on 060301 } break; default: return Acad::eNotImplementedYet; } break; default: return Acad::eNotImplementedYet; } return Acad::eOk; } #endif // 转换成ADS代码 int XDrawOpeningEdJig::GetRetCode(int *kwordId) const { int ret = m_nRetCode; if (ret == AcEdJig::kCancel) ret = RTCAN; else if (ret == AcEdJig::kNull) ret = RTNONE; else if (ret <= 0) ret = RTNORM; else { if (kwordId) *kwordId = ret; ret = RTKWORD; } return ret; } XDrawOpeningEdJig::XDrawOpeningEdJig(TDbOpening*pOpening)//modified by whl :m_pszKeyword(NULL), m_pszPrompt(NULL), m_pDrawEnt(NULL), m_nRetCode(0)//,m_pDataDlg(NULL) { m_pDrawEnt = new TDbOpeningJig; m_pDrawEnt->SetOpening(pOpening); #if ADS>15 CreateGrip(); #endif } XDrawOpeningEdJig::~XDrawOpeningEdJig() { if (m_pDrawEnt) delete m_pDrawEnt; } // 开始执行拖动 void XDrawOpeningEdJig::doIt() { m_pDrawEnt->m_pOpening->setLayer(m_pDrawEnt->m_pOpening->GetDefaultLayer()); setDispPrompt(m_pszPrompt); if (m_pszKeyword) { INITGET_BEG(-1, m_pszKeyword); try { m_nRetCode = drag(); } catch(...) { m_nRetCode=AcEdJig::kCancel; } INITGET_END(); } else { try { m_nRetCode = drag(); } catch(...) { m_nRetCode=AcEdJig::kCancel; } } } // 反馈 AcEdJig::DragStatus XDrawOpeningEdJig::sampler()//modified by whl { double nIncStep=g_nWinStep; DragStatus stat; setUserInputControls((UserInputControls) (AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted | AcEdJig::kNoNegativeResponseAccepted | AcEdJig::kNoZeroResponseAccepted)); if (m_pszKeyword) setKeywordList(m_pszKeyword); XPoint ptTemp; stat = acquirePoint(ptTemp); if (stat == AcEdJig::kNormal) { if (ptTemp.Distance(m_ptCursor)>_DIST_SNAP) { m_ptCursor=ptTemp; m_idWall=SnapOnWall(ptTemp); if (!!m_idWall) { OPENOBJ_BEGIN(m_idWall, AcDb::kForRead, TDbWall, pWall); ASSERT(pWall); if (pWall->Is(CURVE_LINE) && m_pDrawEnt->m_pOpening->GetKind()==TOpeningData::OP_ARCWIN) return AcEdJig::kNoChange; OPENOBJ_END(); } m_ptOnWall=ptTemp; if (!!m_idWall && g_bModelNumber && CInsertOpeningDlg::g_pCurDlg->GetInsertMode()==ID_FREE_INSERT) { OPENOBJ_BEGIN(m_idWall, AcDb::kForRead, TDbWall, pWall); ASSERT(pWall); XPoly2D poly(0); if (pWall->GetKey3Seg(m_ptOnWall, m_pDrawEnt->m_pOpening->GetWidth(), poly)) { ASSERT(poly.TotalSegments()==3); XCurveSegment segFirst, segMid, segLast; poly.Nth(0, segFirst); poly.Nth(1, segMid); poly.Nth(2, segLast); SHORT nControlState=g_bCtrlToggle; //GetKeyState(VK_CONTROL); bool bCtrlPressed = (nControlState&256)!=0; if (!bCtrlPressed) { double nModelFirst=AS_INT(segFirst.GetLength()/nIncStep)*nIncStep; double nDistPos=segMid.GetLength()/2.0 + nModelFirst - segFirst.GetLength(); if (nDistPos>=0 && nDistPos<=segMid.GetLength()) { XPointDir2d ptNewPos; segMid.Polar(nDistPos, ptNewPos); m_ptOnWall=ptNewPos; } } else { double nModelLast=AS_INT(segLast.GetLength()/nIncStep)*nIncStep; double nDistPos=segMid.GetLength()/2.0 + nModelLast - segLast.GetLength(); if (nDistPos>=0 && nDistPos<=segMid.GetLength()) { XPointDir2d ptNewPos; segMid.Polar(nDistPos, ptNewPos, FALSE); m_ptOnWall=ptNewPos; } } } OPENOBJ_END(); } } else { return AcEdJig::kNoChange; } } return stat; } // 更新实体数据 Adesk::Boolean XDrawOpeningEdJig::Update()//modidfied by whl { //add by whl if (CInsertOpeningDlg::g_pCurDlg!=NULL&& CInsertOpeningDlg::g_pCurDlg->IsWindowVisible()) { TDbOpening*pOpening=CInsertOpeningDlg::g_pCurDlg->NewOpening(); m_pDrawEnt->SetOpening(pOpening); delete pOpening; } if (!m_idWall) { m_pDrawEnt->m_pOpening->SetWallId(m_idWall); return Adesk::kTrue; } OPENOBJ_BEGIN(m_idWall, AcDb::kForRead, TDbWall, pWall); if (pWall) { if (m_pDrawEnt->m_pOpening->GetKind()==TOpeningData::OP_ARCWIN) { if (pWall->Is(CURVE_ARC)) m_pDrawEnt->m_pOpening->SetWallId(m_idWall); } else { m_pDrawEnt->m_pOpening->SetWallId(m_idWall); } m_pDrawEnt->SetParameters(pWall, m_ptOnWall, m_ptCursor, CInsertOpeningDlg::g_pCurDlg?CInsertOpeningDlg::g_pCurDlg->GetInsertMode():0); } OPENOBJ_END(); return Adesk::kTrue; } AcDbEntity* XDrawOpeningEdJig::entity() const { return m_pDrawEnt; } AcDbObjectId GetOpeingLocation(const TCHAR *prompt, TDbOpening *&pWin,bool bFreeInsert)//modified by whl { int nOsMode=0; xg_getvar(_T("OSMODE"), &nOsMode); nOsMode |= 0x4000; XPushVar osmode(_T("OSMODE"), nOsMode); AcDbObjectId idWall; XDrawOpeningEdJig jig(pWin); #if ADS>15 if (!bFreeInsert) jig.SetCurGrip(-1); #endif jig.m_pszPrompt = prompt; LAB_REINPUT: jig.doIt(); int kwordId; int nRetCode=jig.GetRetCode(&kwordId); if (nRetCode==RTNORM) { idWall = jig.m_idWall; if (!!idWall) { delete pWin; pWin=jig.m_pDrawEnt->m_pOpening; jig.m_pDrawEnt->m_pOpening=NULL; //成功的添加了门窗, 那么把最近一次的参数写入注册表 CInsertOpeningDlg::g_pCurDlg->UpdateOpening(*pWin, TRUE); CInsertOpeningDlg::g_pCurDlg->WriteParamToRegistry(); CInsertOpeningDlg::g_pCurDlg->SetupLabelList(); } else { goto LAB_REINPUT; } } return idWall; } // add by lgy 20120521,为智能插入门窗jig时的临时实体 class TDbOpeningAptJig: public AcDbEntity { public: // 门窗对象参数 TDbOpening *m_pOpening; // 示意短线所用参数 XCurveSegment m_segWall; double m_dWallWidth; int m_nLineColor; BOOL m_bShow; public: TDbOpeningAptJig() { m_pOpening = NULL; m_bShow = FALSE; m_dWallWidth = 0.0; m_nLineColor = 6; } ~TDbOpeningAptJig() { if (m_pOpening != NULL) { delete m_pOpening; } } void SetOpening(TDbOpening *pOpening) { if (m_pOpening != NULL) { delete m_pOpening; } m_pOpening = (TDbOpening*)pOpening->clone(); m_pOpening->InitHardPointerId(); m_pOpening->SetLayoutRotation(Ucs2Wcs(0)); m_pOpening->setLayer(m_pOpening->GetDefaultLayer()); TMasterProperties prop; prop.SetFrom(pOpening); prop.SetTo(this); } void SetOpeningParameters(const TDbWall *pWall, const XPoint &ptOnWall, const XPoint &ptQuadrant, UINT nInsMode); void SetLineParameters(const AcDbObjectId &wallId, const XCurveSegment &cvSeg, int nColor); public: Adesk::Boolean subWorldDraw(AcGiWorldDraw *mode); void subViewportDraw(AcGiViewportDraw *mode); }; void TDbOpeningAptJig::SetLineParameters(const AcDbObjectId &wallId, const XCurveSegment &cvSeg, int nColor) { m_segWall = cvSeg; m_nLineColor = nColor; OPENOBJ_BEGIN(wallId, AcDb::kForRead, TDbWall, pWall); if (pWall != NULL) { XCurveSegment segGeom; segGeom = pWall->OffsetGeomCenter(LS_INFINITE, TRUE); XPoint ptStart, ptEnd; if (segGeom.ProjectToMe(cvSeg.StartPoint(), ptStart)==RTNORM && segGeom.ProjectToMe(cvSeg.EndPoint(), ptEnd)==RTNORM) m_segWall.SetPoints(ptStart, ptEnd); m_dWallWidth = pWall->GetWidth(4); pWall->close(); } OPENOBJ_END(); } void TDbOpeningAptJig::SetOpeningParameters(const TDbWall *pWall, const XPoint &ptOnWall, const XPoint &ptQuadrant, UINT nInsMode) { BOOL bShiftPressed = g_bShiftToggle; XPoint ptLoc; pWall->GetOpeningLocation(ptOnWall, m_pOpening->GetKind(), m_pOpening->GetWidth(), ptLoc); ptLoc.z = m_pOpening->GetLocation().z; m_pOpening->SetLocation(ptLoc); if (m_pOpening->GetKind() == TOpeningData::OP_HOLE) { m_pOpening->SetThickness(m_pOpening->GetThickness()); } else { m_pOpening->SetThickness(pWall->GetWidth()/2.0); } m_pOpening->SetRotation(pWall->Direction(ptOnWall)); if (m_pOpening->isKindOf(TDbGroupOpening::desc())) { ((TDbGroupOpening*)m_pOpening)->Update(false); } ads_real nAng = CT_std_angle(ads_angle(m_pOpening->GetLocation(), ptQuadrant)-m_pOpening->GetRotation()); if (nAng>=0.0 && nAngSetQuadrant(bShiftPressed? 1:0); } else { m_pOpening->SetQuadrant(bShiftPressed? 2:3); } m_pOpening->SetLabelPos(m_pOpening->GetDefaultLabPos()); } Adesk::Boolean TDbOpeningAptJig::subWorldDraw(AcGiWorldDraw *mode) { if (!m_pOpening->GetWallId()) { return Adesk::kTrue; } if (m_bShow) { double dPLWidth = 0.5 * DocGetPScale(); // 默认50线宽 TADSGePointDir2d ptDir2d; double dLen = m_segWall.GetLength(); m_segWall.Polar(dLen/3, ptDir2d); XPoint ptTmp1, ptTmp2; ptTmp1 = ptDir2d.AsAcGePoint3d(); AcDbPolyline pline1, pline2; ads_polar(ptTmp1, ptDir2d.nDirection+PI/2, m_dWallWidth*1.5, ptTmp2); pline1.addVertexAt(0, ptTmp2.AsAcGePoint2d(), 0, dPLWidth, dPLWidth); ads_polar(ptTmp1, ptDir2d.nDirection-PI/2, m_dWallWidth*1.5, ptTmp2); pline1.addVertexAt(1, ptTmp2.AsAcGePoint2d(), 0, dPLWidth, dPLWidth); m_segWall.Polar(dLen*2/3, ptDir2d); ptTmp1 = ptDir2d.AsAcGePoint3d(); ads_polar(ptTmp1, ptDir2d.nDirection+PI/2, m_dWallWidth*1.5, ptTmp2); pline2.addVertexAt(0, ptTmp2.AsAcGePoint2d(), 0, dPLWidth, dPLWidth); ads_polar(ptTmp1, ptDir2d.nDirection-PI/2, m_dWallWidth*1.5, ptTmp2); pline2.addVertexAt(1, ptTmp2.AsAcGePoint2d(), 0, dPLWidth, dPLWidth); int nColor = colorIndex(); // 门窗的颜色 mode->subEntityTraits().setColor(m_nLineColor); mode->geometry().pline(pline1); mode->geometry().pline(pline2); mode->subEntityTraits().setColor(nColor); } return Adesk::kFalse;; } void TDbOpeningAptJig::subViewportDraw(AcGiViewportDraw *mode) { int nNums = CInsertOpeningDlg::g_pCurDlg->GetOpeningNums(); if (nNums>1) { XPoint ptLoc = m_pOpening->GetLocation(), ptPos; double dWidth = m_pOpening->GetWidth(); double dAngle = m_pOpening->GetRotation(); double dDist(0.0); if (nNums%2 == 0) // 偶数个门 { for (int i=0; iclone(); pOpening->SetLocation(ptPos); pOpening->m_ptLabel = pOpening->GetDefaultLabPos(); pOpening->SetLayoutRotation(Ucs2Wcs(0)); pOpening->subViewportDraw(mode); dAngle = PI + dAngle; } } else // 奇数个门 { m_pOpening->subViewportDraw(mode); for (int i=1; iclone(); pOpening->SetLocation(ptPos); pOpening->m_ptLabel = pOpening->GetDefaultLabPos(); pOpening->SetLayoutRotation(Ucs2Wcs(0)); pOpening->subViewportDraw(mode); dAngle = PI + dAngle; } } DrawOsnapShape(mode, ptLoc, AcDb::kOsMaskNear); } else { m_pOpening->subViewportDraw(mode); DrawOsnapShape(mode, m_pOpening->GetLocation(), AcDb::kOsMaskNear); } } // add by lgy 20120612,智能插入门窗时由于jig时无法获取墙线两侧的轴线, // 此函数根据点,求两侧的轴线 // ptPick:拾取点, cvBase:基线, cvSeg:所求线段 //void GetSubSegmentByPoint(XPoint ptPick, XCurveSegment cvBase, XCurveSegment &cvSeg) //{ // XDbBlockTableRec objMSpace; // if (!objMSpace) // return; // // AcDbBlockTableRecordIterator *pIterator = NULL; // Acad::ErrorStatus es = objMSpace.m_pBlockTableRec->newIterator(pIterator); // if (es!=Acad::eOk || pIterator==NULL) // return; // // double dDist = cvBase.PathDistance(ptPick), // dDistLeft(0.0), // dDistRight = cvBase.GetLength(); // XPoint ptTempS, ptTempE, ptInt1, ptInt2, ptInters, ptStart, ptEnd; // // for (pIterator->start(); !pIterator->done(); pIterator->step()) // { // AcDbEntity *pEnt = NULL; // es = pIterator->getEntity(pEnt, AcDb::kForRead); // if (es!=Acad::eOk || pEnt==NULL) // continue; // // if (pEnt->visibility()==AcDb::kInvisible || _tcsicmp(pEnt->layer(), LAY_AXIS)!=0 || !pEnt->isKindOf(AcDbLine::desc())) // continue; // // AcDbLine *pLine = AcDbLine::cast(pEnt); // pLine->getStartPoint(ptTempS); // pLine->getEndPoint(ptTempE); // pLine->close(); // // XCurveSegment segTemp(ptTempS, ptTempE, 0); // segTemp.SetElevation(0.0); // // int nRet = cvBase.Intersection(segTemp, ptInt1, ptInt2); // if (nRet < 1) // continue; // else if (nRet == 1) // ptInters = ptInt1; // else // ptInters = TGGeLine(ptInt1, ptInt2).NearPoint(ptPick); // // double dDist0 = cvBase.PathDistance(ptInters); // if (dDist0 < dDist + _DIST_SNAP) // { // if (dDist0 > dDistLeft - _DIST_SNAP) // { // ptStart = ptInters; // dDistLeft = dDist0; // } // } // else // { // if (dDist0 < dDistRight + _DIST_SNAP) // { // ptEnd = ptInters; // dDistRight = dDist0; // } // } // } // delete pIterator; // // XCurveSegment cvTemp(ptStart, ptEnd, cvBase.GetBulge()); // cvSeg = cvTemp; //} BOOL GetSubSegmentByPoint2(AcDbObjectId wallId, DList &lstIds, XPoint ptPick, XCurveSegment cvBase, XCurveSegment &cvSeg, XPoint &ptS, XPoint &ptE) { BOOL bRet(FALSE); XPoint ptStart, ptEnd; long lLen = lstIds.Length(); for (long l=0; lgetStartPoint(ptTempS); pLine->getEndPoint(ptTempE); segAxis.SetPoints(ptTempS, ptTempE); } else { AcDbArc *pArc = AcDbArc::cast(pEntity); if (pArc != NULL) { pArc->center(); TADSGePoint3d ptCen; (AcGePoint3d &)ptCen = pArc->center(); TVector3D vtNormal; (AcGeVector3d &)vtNormal = pArc->normal(); ptCen = TchPrivate::Wcs2Ecs(ptCen, vtNormal); TGGeArc arc(ptCen, pArc->radius(), pArc->startAngle(), pArc->endAngle()); ads_polar(arc.GetCenterPt(), arc.GetStarAngle(), arc.GetRadius(), segAxis.StartPoint()); ads_polar(arc.GetCenterPt(), arc.GetEndAngle(), arc.GetRadius(), segAxis.EndPoint()); segAxis.SetBulge(arc.Bulge()); } } pEntity->close(); } OPENOBJ_END(); segAxis.SetElevation(0.0); segAxis.SetLineFlag(LS_FINITE); int nRet = cvBase.Intersection(segAxis, ptInt1, ptInt2); if (nRet < 1) continue; else if (nRet == 1) ptInters = ptInt1; else ptInters = TGGeLine(ptInt1, ptInt2).NearPoint(ptPick); double dDist0 = cvBase.PathDistance(ptInters); if (dDist0 < dDist + _DIST_SNAP) { if (dDist0 > dDistLeft - _DIST_SNAP) { ptStart = ptInters; dDistLeft = dDist0; bSAxisOk = true; } } else { if (dDist0 < dDistRight + _DIST_SNAP) { ptEnd = ptInters; dDistRight = dDist0; bEAxisOk = true; } } } if (!bEAxisOk || !bSAxisOk) // 两边可能就没有轴线,或者只有1根,总之,只要一边的轴线不OK,那么就使用墙线做为SEG { ptStart = ptS; ptEnd = ptE; } bRet = TRUE; break; } XCurveSegment cvTemp(ptStart, ptEnd, cvBase.GetBulge()); cvSeg = cvTemp; return bRet; } // add by lgy 20120521 根据jig时的墙的ID和拾取点,得到当前智能分割线 // add by lgy 20120518 根据墙体id,拾取点,智能插入门窗方式,获取门窗应该插入的位置 // [wallId]:墙体ID, [ptPick]:拾取点, [cvSeg]:智能插入分割线1, [bAptType]:智能插入方式 BOOL GetAptitudeLocalPt(AcDbObjectId wallId, XPoint ptPick, XCurveSegment &cvSeg, int nAptType, DList &lstIds) { PickSet ss; XPoly2D poly; XCurveSegment cvSegBase; TDPtrList openingList; OPENOBJ_BEGIN(wallId, AcDb::kForRead, TDbWall, pWall); if (pWall == NULL) return FALSE; if (nAptType == 1) // 轴线定距 { XCurveSegment cvLongBaseLine = pWall->GetLongBaseLine(); cvLongBaseLine.SetElevation(0.0); cvLongBaseLine.SetLineFlag(LS_FINITE); // 不再采用全图搜索的方法,效率差,而且试用起来总有问题 if (!GetSubSegmentByPoint2(wallId, lstIds, ptPick, cvLongBaseLine, cvSegBase, pWall->StartPoint(), pWall->EndPoint()) || cvSegBase.GetLength()<_DIST_SNAP) { pWall->close(); return FALSE; } // add by lgy 20120614 轴线定距插入时无法将门窗插入到墙上,关闭墙实体后可以插入,具体原因不清楚 pWall->close(); } else // 墙线定距 { if (!pWall->GetSubSegmentByPierAt(ptPick, cvSegBase)) { pWall->close(); return FALSE; } const TDPtrList &openingList = pWall->GetOpeningIdList(); ss.Free(); for (int j = 0; j < openingList.Length(); j ++) ss += openingList[j]; } OPENOBJ_END(); if (nAptType == 1) { cvSeg = cvSegBase; return TRUE; } XPoint ptTemp; ads_polar(ptPick, cvSegBase.Direction(ptPick) + PI/2, 1000, ptTemp); XCurveSegment segAppeak(ptPick, ptTemp, 0); XPoint ptNear1 = cvSegBase.StartPoint(), ptNear2 = cvSegBase.EndPoint(); // 保存离拾取点最近的两个点 int nSide = segAppeak.OnWhichSide(ptNear1); for (long i = 0; i < ss.Length(); i++) { Entity ent = ss[i]; XPoint pt1, pt2; OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbOpening, pOpening); if (pOpening == NULL) continue; pOpening->GetSidePoints(pt1, pt2); XPoint ptTemp1; cvSegBase.ProjectToMe(pt1, ptTemp1); pt1 = ptTemp1; cvSegBase.ProjectToMe(pt2, ptTemp1); pt2 = ptTemp1; if (segAppeak.OnWhichSide(pt1) == nSide) // 在拾取点的左边 { if (ptNear1.Distance2d(ptPick) > pt2.Distance2d(ptPick)) ptNear1 = pt2; } else { if (ptNear2.Distance2d(ptPick) > pt1.Distance2d(ptPick)) ptNear2 = pt1; } OPENOBJ_END(); } ss.Free(); cvSeg = XCurveSegment(ptNear1, ptNear2, cvSegBase.GetBulge()); return TRUE; } // add by lgy 20120521 为智能插入门窗添加jig类 // 没有使用原本的类的原因是智能插入门窗时需要显示两段分割线 class XDrawAptOpeningEdJig : public TEdJig { public: XDrawAptOpeningEdJig(TDbOpening *pOpening, DList &lstIds); virtual ~XDrawAptOpeningEdJig(); public: void doIt(); virtual DragStatus sampler(); virtual Adesk::Boolean Update(); virtual AcDbEntity *entity() const; int GetRetCode(int *kwordId = NULL) const; public: XPoint m_ptOnWall; AcDbObjectId m_idWall; XCurveSegment m_cvSeg; // 智能分割的线段 DList m_lstIds; // 提前搜索出来墙和轴网的关系,防止在JIG过程中有对象打开,无法通过SSGET获得轴网 XPoint m_ptCursor; int m_nRetCode; // 返回码 const TCHAR* m_pszPrompt; // 提示信息 const TCHAR* m_pszKeyword; // 关键字 int m_nAptType; // 智能插入门窗方式 public: TDbOpeningAptJig *m_pDrawEnt; // 临时实体 }; XDrawAptOpeningEdJig::XDrawAptOpeningEdJig(TDbOpening *pOpening, DList &lstIds) : m_pszKeyword(NULL), m_pszPrompt(NULL), m_pDrawEnt(NULL), m_nRetCode(0) { m_pDrawEnt = new TDbOpeningAptJig; m_pDrawEnt->SetOpening(pOpening); // 提前搜索出来墙和轴网的关系,防止在JIG过程中有对象打开,无法通过SSGET获得轴网 m_lstIds.Reset(); int nLength = lstIds.Length(); for (int i=0; i _DIST_SNAP) { m_ptCursor = ptTemp; m_idWall = SnapOnWall(ptTemp); // 判断点在墙上的id if (!!m_idWall) { OPENOBJ_BEGIN(m_idWall, AcDb::kForRead, TDbWall, pWall); if (pWall == NULL) { return AcEdJig::kNoChange; } if (pWall->Is(CURVE_LINE) && m_pDrawEnt->m_pOpening->GetKind()==TOpeningData::OP_ARCWIN) { pWall->close(); return AcEdJig::kNoChange; } OPENOBJ_END(); if (GetAptitudeLocalPt(m_idWall, m_ptCursor, m_cvSeg, m_nAptType, m_lstIds)) { m_pDrawEnt->m_bShow = TRUE; m_pDrawEnt->SetLineParameters(m_idWall, m_cvSeg, (m_nAptType==0)?6:4); // 更新线的参数 } } m_ptOnWall = ptTemp; } else { m_pDrawEnt->m_bShow = FALSE; return AcEdJig::kNoChange; } } return stat; } // 更新实体数据 Adesk::Boolean XDrawAptOpeningEdJig::Update() { if (CInsertOpeningDlg::g_pCurDlg!=NULL && CInsertOpeningDlg::g_pCurDlg->IsWindowVisible()) { TDbOpening *pOpening = CInsertOpeningDlg::g_pCurDlg->NewOpening(); m_pDrawEnt->SetOpening(pOpening); delete pOpening; } if (!m_idWall) { m_pDrawEnt->m_pOpening->SetWallId(m_idWall); return Adesk::kTrue; } OPENOBJ_BEGIN(m_idWall, AcDb::kForRead, TDbWall, pWall); if (pWall) { if (m_pDrawEnt->m_pOpening->GetKind() == TOpeningData::OP_ARCWIN) { if (pWall->Is(CURVE_ARC)) { m_pDrawEnt->m_pOpening->SetWallId(m_idWall); } } else { m_pDrawEnt->m_pOpening->SetWallId(m_idWall); } m_pDrawEnt->SetOpeningParameters(pWall, m_ptOnWall, m_ptCursor, CInsertOpeningDlg::g_pCurDlg?CInsertOpeningDlg::g_pCurDlg->GetInsertMode():0); } OPENOBJ_END(); return Adesk::kTrue; } AcDbEntity* XDrawAptOpeningEdJig::entity() const { return m_pDrawEnt; } //add by lgy 20120517 智能插入门窗 AcDbObjectId GetOpeingLocationApt(const TCHAR *prompt, TDbOpening *&pWin, XPoint &ptPick, XCurveSegment &cvSeg, int &nRetCode, int nAptType, DList &lstIds) { int nOsMode = 0; xg_getvar(_T("OSMODE"), &nOsMode); nOsMode |= 0x4000; XPushVar osmode(_T("OSMODE"), nOsMode); XDrawAptOpeningEdJig jig(pWin, lstIds); jig.m_pszPrompt = prompt; jig.m_pszKeyword = _T("Q"); jig.m_nAptType = nAptType; jig.doIt(); ptPick = jig.m_ptCursor; cvSeg = jig.m_cvSeg; int kwordId; AcDbObjectId idWall; nRetCode = jig.GetRetCode(&kwordId); if (nRetCode == RTNORM) { idWall = jig.m_idWall; if (!!idWall) { delete pWin; pWin = jig.m_pDrawEnt->m_pOpening; jig.m_pDrawEnt->m_pOpening = NULL; // 成功的添加了门窗,那么把最近一次的参数写入注册表 CInsertOpeningDlg::g_pCurDlg->UpdateOpening(*pWin, TRUE); CInsertOpeningDlg::g_pCurDlg->WriteParamToRegistry(); CInsertOpeningDlg::g_pCurDlg->SetupLabelList(); } } return idWall; }