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

381 lines
11 KiB
C++

#include "stdafx.h"
class TRegionEdJig : public TSymbEdJig {
public:
enum RegionOper {kNone=0, kThick=1,};
protected:
RegionOper m_nOperCode;
XPoly2D m_polyOut;
DList<XPoly2D> m_lstPolyIns;
// I/O
AcDbHatch *m_pDrawEnt;
public:
TRegionEdJig(const XRegion &extRegion, const DList<XRegion> &lstAllRegion);
~TRegionEdJig() {
if (m_pDrawEnt) delete m_pDrawEnt;
}
//DragStatus GetPoint(XPoint &pt);
protected:
virtual Adesk::Boolean update();
virtual AcDbEntity* entity() const {
return m_pDrawEnt;
}
public:
void SetOperCode(TRegionEdJig::RegionOper opCode) {
m_nOperCode=opCode;
}
const XPoly2D *GetHitRegion(XPoint pt) const;
};
TRegionEdJig::TRegionEdJig(const XRegion &extRegion, const DList<XRegion> &lstAllRegion)
:m_pDrawEnt(NULL)
{
m_ptResult=GetCursorWcs();
m_ptResult.z=0;
m_polyOut.SetFlag(1);
extRegion.CenterPoly2D(m_polyOut);
m_polyOut.SetElevation(0.0);
m_polyOut.Compress();
for(int i=0; i<lstAllRegion.Length(); i++) {
const XRegion &reg=lstAllRegion[i];
if (&reg==&extRegion)
continue;
XPoly2D *pNew=new XPoly2D(1);
reg.CenterPoly2D(*pNew);
pNew->SetElevation(0.0);
pNew->Compress();
m_lstPolyIns.Append(pNew);
if (!m_pDrawEnt && (m_ptResult&(*pNew))==PR_INSIDE) {
m_pDrawEnt=NewHatchFromPoly2D(*pNew);
}
}
if (!m_pDrawEnt)
m_pDrawEnt=NewHatchFromPoly2D(m_polyOut);
}
//AcEdJig::DragStatus TComposingEdJig::GetPoint(XPoint &pt)
//{
// XPoint ptBase=m_nOperCode==kTextLine? m_pDrawEnt->GetTurnPoint() : m_pDrawEnt->GetStartPoint();
// return acquirePoint(pt, ptBase);
//}
const XPoly2D *TRegionEdJig::GetHitRegion(XPoint pt) const
{
pt.z=0;
for(int i=0; i<m_lstPolyIns.Length(); i++) {
const XPoly2D &rPoly=m_lstPolyIns[i];
if ((pt&rPoly)==PR_INSIDE)
return &rPoly;
}
return &m_polyOut;
}
// 更新实体数据
Adesk::Boolean TRegionEdJig::update()
{
AcDbHatch *pHatch=NewHatchFromPoly2D(*GetHitRegion(m_ptResult));
if (pHatch) {
CopyObject(*pHatch, *m_pDrawEnt);
delete pHatch;
return Adesk::kTrue;
}
return Adesk::kFalse;
}
/////////////////////////////////////////////////////////////
// Command: 二维裁剪
void Clip2D()
{
RBList mask=ads_buildlist(RTDXF0, _T("LINE,ARC,CIRCLE,POLYLINE,LWPOLYLINE,INSERT,TCH_BLOCK_INSERT"), NULL);
PickSet ss(SS_FREE), ssIn(SS_FREE|SS_CREATE), ssOut(SS_FREE|SS_CREATE);
//g_ssPickFirst.Free();
int nRet=SelectEntities(_T("\n请选择被裁剪的对象:"),ss, mask);
if (nRet!=RTNORM)
return;
XPoly2D poly(1);
if (GetClipBoundary1(poly)!=RTNORM)
return;
XPoly poly1;
poly.MapToPolygon(poly1);
// UCS to WCS
poly.TransUCS(Groups(1), Groups(0));
ClipEntitiesByPoly(poly, ss);
}
//////////////////////////////////
// Command: 由图块产生外轮廓线, 只是显示
void GenBoundaryFromInsert2D()
{
Entity ent;
if (SelectEntity(_T("\n请选择二维的图块<退出>: "), ent, RBList(RTDXF0, _T("INSERT"), NULL))==RTNORM) {
XPoly2D polyBoundary(1);
if (GetBoundaryFromInsert2D(ent, polyBoundary)==RTNORM) {
XScreenDc dc;
dc.SetColor(1);
XPoly2D polyTemp(polyBoundary);
polyTemp.TransUCS(Groups(0), Groups(1));
dc << polyTemp;
if (YesNoQuestion(_T("\n是否生成pline"))==Q_YES) {
polyBoundary.Make();
}
}
}
}
///////////////////////////////////////////
// Command: 由二维实体生成轮廓线, 产生pline
// bOnElev--TRUE, 用于生成立面轮廓(不封闭)
// FALSE, 封闭轮廓
void SearchOutlineArg(BOOL bOnElev)
{
XPushMemVar<BOOL> vTemp(g_bEchoSearch, TRUE);
XPushPrec var(_AS_SYS_UNIT(0.1), 1.0E-5);
PickSet ss(SS_FREE);
if (SelectEntities(_T("\n选择二维对象:"), ss,
RBList(RTDXF0, _T("LINE,ARC,CIRCLE,INSERT,TCH_BLOCK_INSERT,TCH_MVINSERT,POLYLINE,LWPOLYLINE"), NULL))==RTNORM) {
DList<XCurveSegment> lstSegs;
long lCount=ss.Length();
for(long i=0L; i<lCount; i++) {
Entity ent=ss[i];
if (ent.Is(_T("INSERT")) || ent.Is(_T("TCH_BLOCK_INSERT")) || ent.Is(_T("TCH_MVINSERT"))) {
GetCurveFromInsert2D(ent, lstSegs);
} else if (ent.Is(_T("POLYLINE")) || ent.Is(_T("LWPOLYLINE"))) {
XPoly2D poly2D(ent);
if (!!poly2D) {
XCurveSegment seg;
for(int n=0; n<poly2D.TotalSegments(); n++) {
poly2D.Nth(n, seg);
if (!!seg && seg.GetLength()>_DIST_SNAP)
lstSegs.Append(new XCurveSegment(seg));
}
}
} else {
XCurveSegment *pSeg=new XCurveSegment(ent);
if (!(*pSeg) || pSeg->GetLength()<_DIST_SNAP) {
delete pSeg;
} else {
lstSegs.Append(pSeg);
}
}
}
for(i=0; i<lstSegs.Length(); i++) {
XCurveSegment &seg=*lstSegs[i];
seg.SetElevation(0.0);
}
XPoly2D polyOut(1);
// add these lines on 2003/12/28
RemoveDupCurves(lstSegs);
_IntersectCurves(lstSegs,_DIST_SNAP); //为支持圆
XSearchRegionFromCurve aSearch;
try {
aSearch.InitStart(lstSegs);
} catch(...) {
adsout << /*UMSG*/_T("\n发生例外情况!");
return;
}
XRegion *pExt=aSearch.SearchRegions();
if (pExt) {
pExt->CenterPoly2D(polyOut);
polyOut.Compress();
} else {
adsout << _T("\n对不起, 找不出轮廓线!");
return;
}
//if (GetExternalBoundaryFromCurves(lstSegs, polyOut)==RTNORM) {
// polyOut.Compress();
if (polyOut.PathArea()>0.0)
polyOut.Reverse();
if (bOnElev) {
XPoint ptLow, ptUp;
polyOut.GetExtend(ptLow, ptUp);
double yMin=ptLow.y;
DList<int> lstIdx;
for(int k=0; k<polyOut.Length(); k++) {
double y=polyOut[k]->y;
if (fabs(y-yMin)<_DIST_SNAP)
lstIdx.Append(new int(k));
}
if (lstIdx.Length()==2 &&
(*lstIdx[0] - *lstIdx[1])==-1) {
XPoint pt1=*polyOut[*lstIdx[0]];
XPoint pt2=*polyOut[*lstIdx[1]];
XPoly2D poly1, poly2;
if (SplitPoly2D(polyOut, pt1, pt2, poly1, poly2)==RTNORM) {
polyOut=poly2;
}
}
}
if (bOnElev) {
XScreenDc dc(1, 3);
XPoly2D polyTemp(polyOut);
polyTemp.TransUCS(Groups(0), Groups(1));
dc << polyTemp;
static double nThick=0.0;
int nRetCode=RTNORM;
ads_initget(RSG_NONEG|RSG_NOZERO, NULL);
adsout << _T("\n请输入轮廓线宽度(按模型空间的尺寸)<") << nThick << _T(">: ");
nRetCode=ads_getreal(_T(""), &nThick);
if (nRetCode==RTNORM || nRetCode==RTNONE) {
AcDbPolyline *pline=new AcDbPolyline;
PolyConvert(polyOut, *pline);
pline->setConstantWidth(nThick);
AddToModelSpace(pline, Adesk::kTrue);
adsout << _T("\n成功的生成了轮廓线!");
}
} else {
XPushVar<int> vFillMode(_T("FILLMODE"), 1);
XPushVar<int> vOsMode(_T("OSMODE"),0);//add by whl on 060305
TRegionEdJig jig(*pExt, aSearch.m_regions);
jig.SetPrompt(_T("\n点取要生成的轮廓(提示:点取外部生成外轮廓; PLINEWID 系统变量设置pline宽度)<退出>:"));
while(jig.DoIt()==RTNORM) {
const XPoly2D *pRegion=jig.GetHitRegion(jig.GetPickPoint());
AcDbPolyline *pline=new AcDbPolyline;
PolyConvert(*pRegion, *pline);
double nThick=0.0;
xg_getvar(_T("PLINEWID"), &nThick);
pline->setConstantWidth(nThick);
AcDbObjectId id=AddToModelSpace(pline, Adesk::kTrue);
if (id.isValid()) {
adsout << _T("\n成功生成轮廓,接着点取生成其他轮廓!");
} else {
delete pline;
}
}
/*
INITGET_BEG(RSG_NONEG|RSG_NOZERO, _T("S"));
adsout << _T("\n请输入轮廓线宽度(按模型空间的尺寸)或 {选择内轮廓[S]}<") << nThick << _T(">: ");
nRetCode=ads_getreal(_T(""), &nThick);
INITGET_END();
if (nRetCode==RTNORM || nRetCode==RTNONE) {
AcDbPolyline *pline=new AcDbPolyline;
PolyConvert(polyOut, *pline);
pline->setConstantWidth(nThick);
AddToModelSpace(pline, Adesk::kTrue);
adsout << _T("\n成功的生成了轮廓线!");
} else if (nRetCode==RTKWORD) {
}*/
}
}
}
void SearchOutline()
{
SearchOutlineArg(FALSE);
}
void ElevOutline()
{
SearchOutlineArg(TRUE);
}
///////////////////////////////////////////
// Command: 由二维实体生成轮廓线, 产生pline
void GenBoundary()
{
XPushMemVar<BOOL> vTemp(g_bEchoSearch, TRUE);
PickSet ss(SS_FREE);
if (SelectEntities(_T("\n选择二维对象:"), ss,
RBList(RTDXF0, _T("LINE,ARC,CIRCLE,INSERT,TCH_BLOCK_INSERT,TCH_MVINSERT,POLYLINE,LWPOLYLINE"), NULL))==RTNORM) {
DList<XCurveSegment> lstSegs;
long lCount=ss.Length();
for(long i=0L; i<lCount; i++) {
Entity ent=ss[i];
if (ent.Is(_T("INSERT")) || ent.Is(_T("TCH_BLOCK_INSERT")) || ent.Is(_T("TCH_MVINSERT"))) {
GetCurveFromInsert2D(ent, lstSegs);
} else if (ent.Is(_T("POLYLINE")) || ent.Is(_T("LWPOLYLINE"))) {
XPoly2D poly2D(ent);
if (!!poly2D) {
XCurveSegment seg;
for(int n=0; n<poly2D.TotalSegments(); n++) {
poly2D.Nth(n, seg);
if (!!seg && seg.GetLength()>_DIST_SNAP)
lstSegs.Append(new XCurveSegment(seg));
}
}
} else {
XCurveSegment *pSeg=new XCurveSegment(ent);
if (!(*pSeg) || pSeg->GetLength()<_DIST_SNAP) {
delete pSeg;
} else {
lstSegs.Append(pSeg);
}
}
}
DList<XPoly2D> lstPolyBoundary(1);
if (GetExternalBoundaryFromCurves(lstSegs, lstPolyBoundary)==RTNORM && lstPolyBoundary.Length()) {
for(int k=0; k<lstPolyBoundary.Length(); k++) {
XPoly2D &polyBoundary=*lstPolyBoundary[k];
XScreenDc dc;
dc.SetColor(1);
XPoly2D polyTemp(polyBoundary);
polyTemp.TransUCS(Groups(0), Groups(1));
dc << polyTemp;
static int nAnswer=Q_YES;
nAnswer=YesNoQuestion(_T("\n是否生成pline"), nAnswer);
if (nAnswer==Q_YES) {
polyBoundary.Make();
} else if (nAnswer==RTCAN) {
break;
}
}
}
}
}
///////////////////////////////////////////
// Command: 矩形裁剪
// 条件: 必须在WCS下
void RectClip()
{
// AsureWCS();
XPoint ptCorner1, ptCorner2;
if (XGetPoint(NULL, _T("\n第一个角点"), ptCorner1)!=RTNORM)
return ;
if (XGetCorner(ptCorner1, _T("\n第二个角点: "), ptCorner2)!=RTNORM)
return ;
if (ptCorner1==ptCorner2)
return ;
XRectAngle box(ptCorner1, ptCorner2);
XPoly2D poly(1);
poly.AppendNode(box.lowLeft);
poly.AppendNode(XPoint(box.upRight.x, box.lowLeft.y, box.lowLeft.z));
poly.AppendNode(box.upRight);
poly.AppendNode(XPoint(box.lowLeft.x, box.upRight.y, box.lowLeft.z));
XScreenDc dc;
dc.m_nDrawMode = 1;
//dc << box;
XPoly2D polyTemp(1);
box.AsPoly2D(polyTemp);
polyTemp.TransUCS(Groups(0), Groups(1));
dc << polyTemp;
RBList mask=ads_buildlist(RTDXF0, _T("LINE,ARC,CIRCLE,POLYLINE,LWPOLYLINE,INSERT,TCH_BLOCK_INSERT"), NULL);
PickSet ss(SS_FREE);
//adsout << _T("\n请选择被裁剪的对象!");
g_ssPickFirst.Free();
if (SelectEntities(_T("\n选择被裁减的对象:"), ss, mask)!=RTNORM)
return;
ClipEntitiesByPoly(poly, ss);
}