#include "StdAfx.h" #include "dbmain.h" #include "EditSymbCutDlg.h" // 出头长度 extern double g_nRuptureExDist = 3.0*DocGetPScale(); // sg add 090512,设置折断线两端伸出连接区间的距离 extern TARCH_IMPEXP double g_dRuptureLenLimit; // 折断线连接区间长度界限值 extern TARCH_IMPEXP double g_dMoreRuptureLimit; // 大于界限值时,出头距离 extern TARCH_IMPEXP double g_dLessRuptureLimit; // 小于界限值时,出头距离 class TDbSymbCut; static BOOL bSecond = TRUE; // [11/16/2007 nsh] class SymbCutJig : public AcEdJig { public: SymbCutJig(const XPoint&); int DoIt(); virtual DragStatus sampler(); virtual Adesk::Boolean update(); virtual AcDbEntity* entity() const; public: TDbSymbCut* m_pSymbCut; protected: int GetRetCode(int nRetCode, int *kwordId=NULL) const; public: XPoint pt0; XPoint pt1; XPoint pt2; XPoint pt3; XPoint pt4; int m_nRupNum; XDcClip::ClipType m_ClipType; int mPromptCounter; // add by lgy 20120511,是否是双折断线 BOOL m_bIsTwo; }; /////////////////////////////////////////////////////////// SymbCutJig::SymbCutJig(const XPoint& pt) { pt0 = pt; pt1 = pt; pt3 = pt4 = pt2 = pt; m_nRupNum = 1; mPromptCounter = 0; m_ClipType = XDcClip::kClipOut; m_pSymbCut = new TDbSymbCut; m_bIsTwo = FALSE; // add by lgy 20120511,是否是双折断线,默认为不是 } int SymbCutJig::GetRetCode(int nRetCode, int *kwordId) const { int ret =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-1; ret = RTKWORD; } return ret; } int SymbCutJig::DoIt() { bSecond = TRUE;// [11/16/2007 nsh] AcEdJig::DragStatus stat; int iKey; while(true) { //modify by lgy 20120511 绘制的可能是单折断线,也可能是双折断线 //adsout << _T("\n点取折断线终点或 [改折断数目,当前=")<:"); if (!m_bIsTwo) { // sg modify 120614,根据测试反馈,修改提示语 //adsout << _T("\n点取折断线终点或 [改折断数目,当前=")<:"); adsout << _T("\n点取折断线终点或 [改折断数目(N),当前=")<:"); } else { //adsout << _T("\n点取第一折断线终点或 [改折断数目,当前=")<:"); adsout << _T("\n点取第一折断线终点或 [改折断数目(N),当前=")<:"); } INITGET_BEG(-1, _T("N")) try { stat = drag(); } catch(...) { stat=AcEdJig::kCancel; } INITGET_END() int nCode = GetRetCode(stat,&iKey); if (nCode == RTKWORD) { adsout << _T("\n折断数目<") << m_nRupNum << _T(">:"); ads_initget(RSG_NONEG, NULL); ads_getint(_T(""), &m_nRupNum); } else if (nCode != RTNORM) return RTCAN; else // 取点 break; } mPromptCounter++; // now == 1 // add by lgy 20120511 判断当前是否是双折断线 if (m_bIsTwo) { adsout<<_T("\n点取第二折断线位置<退出>:"); m_ClipType = XDcClip::kClipIn; try { stat = drag(); } catch (...) { stat = AcEdJig::kCancel; } if (stat == AcEdJig::kNormal) { return RTNORM; } else if (stat == AcEdJig::kCancel) { return RTCAN; } else { return RTNONE; } } while(true) { if (m_ClipType == XDcClip::kClipIn) adsout<<_T("\n当前切除内部,请选择切除范围或 [改为切除外部(Q)]<不切割>:"); else adsout<<_T("\n当前切除外部,请选择保留范围或 [改为切除内部(Q)]<不切割>:"); INITGET_BEG(-1, _T("Q")) try { stat = drag(); } catch(...) { stat = AcEdJig::kCancel; } INITGET_END() int nCode = GetRetCode(stat,&iKey); if (nCode == RTKWORD) { if (m_ClipType == XDcClip::kClipIn) m_ClipType = XDcClip::kClipOut; else m_ClipType = XDcClip::kClipIn; } else if (nCode == RTNONE) { bSecond = FALSE;// [11/16/2007 nsh] return RTNONE; } else if (nCode != RTNORM) return RTCAN; else // 取点 break; } return RTNORM; } AcEdJig::DragStatus SymbCutJig::sampler() { DragStatus stat; setUserInputControls((UserInputControls) (AcEdJig::kAccept3dCoordinates | AcEdJig::kNullResponseAccepted)); if (mPromptCounter == 0) { setKeywordList(_T("N")); static XPoint PointTemp1; stat=acquirePoint(pt1,pt0); //pt1=Wcs2Ucs(pt1); //pt0=Wcs2Ucs(pt0); //int mode=0; //xg_getvar(_T("ORTHOMODE"),&mode); //if(mode==1)// //{ // AcGeVector3d Vec=pt1-pt0; // AcGeVector3d vecUnitX = AcGeVector3d(1,0,0);//acdbHostApplicationServices()->workingDatabase()->ucsxdir(); // AcGeVector3d vecUnitY = AcGeVector3d(0,1,0);//acdbHostApplicationServices()->workingDatabase()->ucsydir(); // double Angx=Vec.angleTo(vecUnitX); // double Angy=Vec.angleTo(vecUnitY); // double dLength=Vec.length(); // // if((Angx>3*PI/4)&&(Angx<=PI)) // { // pt1.y=pt0.y; // pt1.x=pt0.x-dLength; // pt1.z=pt0.z; // } // else if((Angx>=0)&&(Angx=0)&&(Angy<=PI/4)) // { // pt1.y=pt0.y+dLength; // pt1.x=pt0.x; // pt1.z=pt0.z; // } // else // { // pt1.y=pt0.y-dLength; // pt1.x=pt0.x; // pt1.z=pt0.z; // } // // } // // //} //pt1=Ucs2Wcs(pt1); //pt0=Ucs2Wcs(pt0); if (PointTemp1!=pt1) PointTemp1=pt1; else if (stat == AcEdJig::kNormal) return AcEdJig::kNoChange; } else if (mPromptCounter == 1) { setKeywordList(_T("Q")); static XPoint PointTemp2; stat = acquirePoint(pt2); if (PointTemp2 != pt2) PointTemp2 = pt2; else if (stat == AcEdJig::kNormal) return AcEdJig::kNoChange; } return stat; } Adesk::Boolean SymbCutJig::update() { switch (mPromptCounter) { case 0: { XCurveSegment aLine(pt0,pt1,LS_INFINITE); aLine.SetElevation(0); double dist=1000; int side=0; XCurveSegment aLine1=aLine.Offset(side,dist,LS_INFINITE); pt3=aLine1.EndPoint(); pt4=aLine1.StartPoint(); break; } case 1: { XCurveSegment aLine(pt0,pt1,LS_INFINITE); aLine.SetElevation(0); pt2.z=0; double dist=pt2.Distance(&aLine); int side=aLine.OnWhichSide(pt2); XCurveSegment aLine1=aLine.Offset(side,dist,LS_INFINITE); pt3=aLine1.EndPoint(); pt4=aLine1.StartPoint(); break; } } XPoly2D aPoly; aPoly.AppendNode(pt0); aPoly.AppendNode(pt1); aPoly.AppendNode(pt3); aPoly.AppendNode(pt4); m_pSymbCut->SetOutline(aPoly); m_pSymbCut->SetEdgeType(0,m_nRupNum); //add by lgy 20120511 双折断线 if (m_bIsTwo) { m_pSymbCut->SetEdgeType(2,m_nRupNum); } m_pSymbCut->SetClipType(m_ClipType); // delete by xly on 100915 实体图层设置放在AddToSpace中 //m_pSymbCut->setLayer(InitLayer(LAY_OTHER_DIM)); return Adesk::kTrue; } AcDbEntity* SymbCutJig::entity() const { return m_pSymbCut; } ////////////////////////////////////////////////////////// //TDbSymbCut对象编辑 int EditSymbCut(AcDbObjectId id) { // 加折断:取边上点,然后尝试构造新边,新边折断数为1; // 去折断:取边,设折断数为0, // 改折断数:取边,然后输入折断数 // 改切割类型 XPushVar vVar(_T("OSMODE"),512); extern TARCH_IMPEXP BOOL g_bGetExtents; XPushMemVar vTemp1(TchGeLib::g_bGetExtents,TRUE); // add by whl on 070522 OPENOBJ_BEGIN(id, AcDb::kForRead, TDbSymbCut, pSymbCut); if (!pSymbCut) return RTERROR; CTemporaryResourceOverride vTemp; CEditSymbCutDlg dlg(pSymbCut); dlg.DoModal(); OPENOBJ_END(); return RTNORM; } // modify by xly on 101028 在EditSymbolAnnotate.cpp中已经包含同样功能的代码,调用即可 extern AcDbObjectId AddToSpace(Adesk::Boolean bClosed, TDbEntity *pEntSymb) ; //add by lgy 20120511 打断封闭区域经过的所有实体 void BreakEnt2Segment(XPoly2D poly) { PickSet entSet(SS_FREE); XPoint ptLow, ptUp; poly.GetExtend(ptLow, ptUp); // sg modify 120614,解决过滤表书写错误的问题,同时增加本来需求希望支持的块的切除 //Acad::ErrorStatus es = GetSafeSelection(entSet, TRUE, ptLow, ptUp, _T("LINE ARC LWPOLYLINE")); Acad::ErrorStatus es = GetSafeSelection(entSet, TRUE, ptLow, ptUp, _T("LINE,ARC,POLYLINE,LWPOLYLINE,INSERT,AEC_BLOCK_INSERT")); if (es != Acad::eOk) { return; } // sg modify 120614,不需要自己写算法,准确性不高还不支持块,底层函数即可 TchExport2::ClipEntitiesByPoly(poly, entSet); ////求得折断线的两条边 //XCurveSegment seg1,seg2; //poly.Nth(0, seg1); //poly.Nth(2, seg2); //for (long i = 0; i < entSet.Length(); i++) //{ // AcGePoint3dArray ptTrimArray; //保存trim要用到的所有点 // Entity ent = entSet[i]; // XPoly2D polySet(ent); //将实体转换成为poly // // //逐个取polySet中的seg判断其是否与seg1, seg2相交,记录交点 // for (int j = 0; j < polySet.TotalSegments(); j++) // { // XCurveSegment segTemp; // polySet.Nth(j, segTemp); // // XPoint pt1, pt2, pt3, pt4; // int nNum1 = 0, nNum2 = 0; // nNum1 = segTemp.Intersection(seg1, pt1, pt2); // nNum2 = segTemp.Intersection(seg2, pt3, pt4); // if (nNum1 == 2) //弧线被双折断线中seg1切割有两个交点时 // { // XCurveSegment segArc(pt1, pt2, segTemp.GetBulge()); // XPoint ptMid, ptMidProj = segArc.MidPoint(); // segTemp.ProjectToMe(ptMidProj, ptMid); // ptTrimArray.append(ptMid); // } // else if (nNum2 == 2) //弧线被双折断线中seg2切割有两个交点时 // { // XCurveSegment segArc(pt1, pt2, segTemp.GetBulge()); // XPoint ptMid, ptMidProj = segArc.MidPoint(); // segTemp.ProjectToMe(ptMidProj, ptMid); // ptTrimArray.append(ptMid); // } // else if (nNum1 == 1) //跟seg1只有一个交点 // { // if (nNum2 == 1) //跟seg2有一个交点 // { // XCurveSegment seg(pt3, pt1, segTemp.GetBulge()); // XPoint ptMid, ptMidProj = seg.MidPoint(); // segTemp.ProjectToMe(ptMidProj, ptMid); // ptTrimArray.append(ptMid); // } // else //跟seg2没有交点 // { // XPoint ptEnd = segTemp.EndPoint(); // if ((ptEnd&poly) != PR_OUTSIDE)//框选中了终点 // { // XCurveSegment seg(pt1, ptEnd, segTemp.GetBulge()); // XPoint ptMid, ptMidProj = seg.MidPoint(); // segTemp.ProjectToMe(ptMidProj, ptMid); // ptTrimArray.append(ptMid); // } // else //框选中了起点 // { // XCurveSegment seg(pt1, segTemp.StartPoint(), segTemp.GetBulge()); // XPoint ptMid, ptMidProj = seg.MidPoint(); // segTemp.ProjectToMe(ptMidProj, ptMid); // ptTrimArray.append(ptMid); // } // } // } // else if (nNum2 == 1) //跟seg1只有一个交点 // { // if (nNum1 == 1) //跟seg2有一个交点 // { // XCurveSegment seg(pt1, pt3, segTemp.GetBulge()); // XPoint ptMid, ptMidProj = seg.MidPoint(); // segTemp.ProjectToMe(ptMidProj, ptMid); // ptTrimArray.append(ptMid); // } // else //跟seg2没有交点 // { // XPoint ptEnd = segTemp.EndPoint(); // if ((ptEnd&poly) != PR_OUTSIDE)//框选中了终点 // { // XCurveSegment seg(pt1, ptEnd, segTemp.GetBulge()); // XPoint ptMid, ptMidProj = seg.MidPoint(); // segTemp.ProjectToMe(ptMidProj, ptMid); // ptTrimArray.append(ptMid); // } // else //框选中了起点 // { // XCurveSegment seg(pt1, segTemp.StartPoint(), segTemp.GetBulge()); // XPoint ptMid, ptMidProj = seg.MidPoint(); // segTemp.ProjectToMe(ptMidProj, ptMid); // ptTrimArray.append(ptMid); // } // } // } // } // poly.Make(); // Entity lastent; // ads_entlast(lastent); //获得最后添加到模型空间的实体 // // //for循环打断实体 // for (int n = 0; n < ptTrimArray.length(); n++) // { // PickSet entSS; // XPoint ptMidd = ptTrimArray[n]; // entSS.Get(ptMidd, NULL); // if (entSS.Length() > 0) // { // ent = entSS[0L]; // ads_command(RTSTR,_T(".TRIM"),RTENAME,lastent.name,RTSTR,_T(""),RTLB,RTENAME,ent.name,RT3DPOINT,&ptMidd,RTLE,RTSTR,_T(""),RTNONE); // } // } // lastent.Erase(); //} } // 临时命令,7.5、8.0中的命令 void SymbCut() { XPoint pt0; int nRet = 0; //modify by lgy 20120511 添加绘制双折断线功能 //INITGET_BEG(0,_T("S")); //nRet = ads_getpoint(NULL, _T("\n点取折断线起点或 [选多段线(S)]<退出>: "), pt0); //INITGET_END(); static BOOL bIsTwo = FALSE; //表示当前是否是要绘制双折断线,默认是单折断线 while (nRet!=RTNORM && nRet!=RTNONE && nRet!=RTCAN) { if (!bIsTwo) //绘制单折断线 { INITGET_BEG(0, _T("S Q")); nRet = ads_getpoint(NULL, _T("\n点取折断线起点或 [选多段线(S)\\绘双折断线(Q),当前:绘单折断线]<退出>:"), pt0); INITGET_END(); if (nRet == RTKWORD) { TCHAR szKey[132]; acedGetInput(szKey); if (szKey[0] == _T('s') || szKey[0] == _T('S')) { break; } else { bIsTwo = TRUE; } } } else //绘制双折断线 { INITGET_BEG(0, _T("S Q")); nRet = ads_getpoint(NULL, _T("\n点取第一折断线起点或 [选多段线(S)\\绘单折断线(Q),当前:绘双折断线]<退出>: "), pt0); INITGET_END(); if (nRet == RTKWORD) { TCHAR szKey[132]; acedGetInput(szKey); if (szKey[0] == _T('s') || szKey[0] == _T('S')) { break; } else { bIsTwo = FALSE; } } } } if (nRet == RTKWORD) { Entity ent; if (SelectEntity(_T("\n选择闭合多段线:"), ent, RBList(RTDXF0,_T("LWPOLYLINE,POLYLINE"), 70, 1, NULL)) != RTNORM) return; TDbSymbCut *pCut = new TDbSymbCut; pCut->SetOutline(XPoly2D(ent)); // modify by xly on 100915 实体是否设置在默认层 // AcDbObjectId id = pCut->AddToCSpace(Adesk::kFalse); AcDbObjectId id = AddToSpace(Adesk::kFalse,pCut); pCut->downgradeOpen(); pCut->draw(); pCut->close(); ent.Erase(); acdbGetAdsName(ent.name, id); acedRedraw(ent.name, 0); EditSymbCut(id); } else if (nRet == RTNORM) { pt0 = Ucs2Wcs(pt0); SymbCutJig jig(pt0); jig.m_bIsTwo = bIsTwo; // add by lgy 20120511 设置是否是单折断线还是双折断线 int nCode = jig.DoIt(); // add by lgy 20120514 保存添加到模型空间中的折断线的ID AcDbObjectId idRupture; // modify by xly on 100915 实体是否设置在默认层 /*if (nCode == RTNORM) jig.m_pSymbCut->AddToCSpace(Adesk::kTrue);*/ if (nCode == RTNORM) { //modify by lgy 20120514 保存添加到模型空间中的实体ID //AddToSpace(Adesk::kTrue, jig.m_pSymbCut); idRupture = AddToSpace(Adesk::kTrue, jig.m_pSymbCut); } else if (nCode == RTNONE) { // [11/16/2007 nsh] //---------------------------begin------------------------- { // 这个地方添加用户是否开延伸线和延伸的长度 if (!bSecond) { XPoint ptA = jig.pt0; // 初始化默认值的大小 XPoint ptB = jig.pt1; // sg modify 090512,根据连接区间的距离,确定折断线两端伸出长度 // ads_polar(jig.pt0, ads_angle(jig.pt1, jig.pt0), g_nRuptureExDist, ptA); // ads_polar(jig.pt1, ads_angle(jig.pt0, jig.pt1), g_nRuptureExDist, ptB); double dDist = ptA.Distance(ptB); if (dDist > g_dRuptureLenLimit - _DIST_SNAP) // 大于界限值时 { ads_polar(ptA, ads_angle(ptB, ptA), g_dMoreRuptureLimit*DocGetPScale(), ptA); ads_polar(ptB, ads_angle(ptA, ptB), g_dMoreRuptureLimit*DocGetPScale(), ptB); } else // 小于界限值时 { ads_polar(ptA, ads_angle(ptB, ptA), g_dLessRuptureLimit*DocGetPScale(), ptA); ads_polar(ptB, ads_angle(ptA, ptB), g_dLessRuptureLimit*DocGetPScale(), ptB); } TDbSymbRupture *pRupture = new TDbSymbRupture; pRupture->SetStartPoint(ptA); pRupture->SetEndPoint(ptB); pRupture->SetRuptureNum(jig.m_nRupNum); // modify by xly 101110设置打断线的图层设置,支持默认图层和当前图层 //pRupture->AddToCSpace(Adesk::kTrue); AddToSpace(Adesk::kTrue, pRupture); delete jig.m_pSymbCut; return; } } //-----------------------------end------------------------- TDbSymbRupture *pRupture = new TDbSymbRupture; pRupture->SetStartPoint(jig.pt0); pRupture->SetEndPoint(jig.pt1); pRupture->SetRuptureNum(jig.m_nRupNum); // modify by xly 101110设置打断线的图层设置,支持默认图层和当前图层 //pRupture->AddToCSpace(Adesk::kTrue); AddToSpace(Adesk::kTrue, pRupture); delete jig.m_pSymbCut; } else delete jig.m_pSymbCut; if (jig.m_ClipType == XDcClip::kClipIn) // sg add 120614,只有切除内部的时候,才对内部的CAD线进行处理 { // add by lgy 20120514 打断直线,弧线,多段线等 XPoly2D poly; OPENOBJ_BEGIN(idRupture, AcDb::kForRead, TDbSymbCut, pRupture); if (pRupture != NULL) { poly = pRupture->GetOutline(); } OPENOBJ_END(); if (poly.TotalSegments() > 2) { BreakEnt2Segment(poly); } } } }