Files
envi-code/SourceCode/Code2026/tg_shs/shs_annotate/symbcutedit.cpp
T
2026-09-28 15:28:50 +08:00

658 lines
16 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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点取折断线终点或 [改折断数目,当前=")<<m_nRupNum<<_T("(N)]<退出>:");
if (!m_bIsTwo)
{
// sg modify 120614,根据测试反馈,修改提示语
//adsout << _T("\n点取折断线终点或 [改折断数目,当前=")<<m_nRupNum<<_T("(N)]<退出>:");
adsout << _T("\n点取折断线终点或 [改折断数目(N),当前=")<<m_nRupNum<<_T("]<退出>:");
}
else
{
//adsout << _T("\n点取第一折断线终点或 [改折断数目,当前=")<<m_nRupNum<<_T("(N)]<退出>:");
adsout << _T("\n点取第一折断线终点或 [改折断数目(N),当前=")<<m_nRupNum<<_T("]<退出>:");
}
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<PI/4))
// {
// pt1.y=pt0.y;
// pt1.x=pt0.x+dLength;
// pt1.z=pt0.z;
// }
// else
// {
// if((Angy>=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<int> vVar(_T("OSMODE"),512);
extern TARCH_IMPEXP BOOL g_bGetExtents;
XPushMemVar<BOOL> 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);
}
}
}
}