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

220 lines
5.3 KiB
C++

#include "stdafx.h"
#include "resource.h"
inline resbuf * GetClosedProfileMask(bool bEntType=false)
{
if(bEntType)
return ads_buildlist(RTDXF0, _T("POLYLINE,LWPOLYLINE,CIRCLE,ATS_SPACE,ATS_SLAB,ATS_COLUMN,ATS_SLOPEROOF,ATS_MOUNTROOF,ATS_CUSPROOF,ATS_DUALROOF,ATS_WALL_PATCH,ATS_CURVEMESH2,ATS_POLYMESH2,ATS_PATH_ARRAY,ATS_APRON"),NULL);
else
return ads_buildlist(-4, _T("<or"),
-4, _T("<and"),
RTDXF0, _T("POLYLINE,LWPOLYLINE"), 70, 1,
-4, _T("and>"),
RTDXF0,
_T("CIRCLE,ATS_SPACE,ATS_SLAB,ATS_COLUMN,ATS_SLOPEROOF,ATS_DUALROOF,ATS_MOUNTROOF,ATS_CUSPROOF,ATS_WALL_PATCH"),
-4, _T("<and"),
RTDXF0, _T("ATS_CURVEMESH2,ATS_POLYMESH2,ATS_PATH_ARRAY,ATS_APRON"), 70, 1,
-4, _T("and>"),
-4, _T("or>"), NULL);
}
BOOL GetOutline(Entity ent1, XPoly2D &poly,AcGeVector3d &normal)
{
XPoly2D poly1(ent1);
AcGeVector3d vt=AcGeVector3d::kZAxis;
if(!poly1)
{
OPENOBJ_BEGIN(ent1, AcDb::kForRead, AcDbEntity, pEnt);
const TEntityBase*pEntBase=TEntityBase::Cast(pEnt);
if(pEntBase!=NULL)
pEntBase->GetPathPoly(poly1,vt);
OPENOBJ_END();
}
if(!poly1 ||!poly1.IsClosed()||poly1.IsSelfIntersect())
{
adsout<<_T("\n选择无效!");
return FALSE;
}
poly=poly1;
normal=vt;
return TRUE;
}
bool SetOutline(Entity ent1, const DList<XPoly2D> &lstDest,const AcGeVector3d &normal)
{
BOOL bDelMe=lstDest.Length()==0;
OPENOBJ_BEGIN(ent1, AcDb::kForWrite, AcDbEntity, pEnt);
if(!pEnt)
return false;
for(int i=0; i<lstDest.Length(); i++)
{
const XPoly2D &rPoly=lstDest[i];
if(pEnt->isA()==AcDbPolyline::desc())
{
AcDbPolyline *pline=AcDbPolyline::cast(pEnt);
ASSERT(pline);
if(i==0)
{
pline->assertWriteEnabled();
PolyConvert(rPoly, *pline);
}
else
{
AcDbPolyline *pNew=(AcDbPolyline *)pline->clone();
PolyConvert(rPoly, *pNew);
AddToCurrentSpace(pNew, Adesk::kTrue);
}
}
else if(pEnt->isA()==AcDbCircle::desc())
{
bDelMe=TRUE;
AcDbPolyline *pNew=new AcDbPolyline;
pNew->setPropertiesFrom(pEnt);
PolyConvert(rPoly,*pNew);
AddToCurrentSpace(pNew, Adesk::kTrue);
}
else
{
AcDbEntity*pNewEnt=(AcDbEntity*)pEnt->clone();
TEntityBase*pEntBase=(TEntityBase*)TEntityBase::Cast(pNewEnt);
if(pEntBase!=NULL)
{
if(pEntBase->SetPathPoly(rPoly,normal)==Acad::eOk)
{
bDelMe=TRUE;
AddToCurrentSpace(pNewEnt, Adesk::kTrue);
}
else
{
delete pNewEnt;
return false;
}
}
else
{
return false;
delete pNewEnt;
}
}
}
OPENOBJ_END();
if(bDelMe)
ent1.Delete();
return true;
}
Adesk::Boolean acedPostCommand(const TCHAR * );
class CBoolEditDlg:public CModelessDialog
{
public:
static int g_iBoolType;
static BOOL g_bDeleteSecond;
public:
CBoolEditDlg():CModelessDialog(IDD_BOOL_EDIT){}
virtual void DoDataExchange(CDataExchange*pDX)
{
CModelessDialog::DoDataExchange(pDX);
DDX_Radio(pDX,IDC_UNION,g_iBoolType);
DDX_Check(pDX,IDC_DELETE,g_bDeleteSecond);
}
DECLARE_MESSAGE_MAP()
afx_msg void OnClose(){acedPostCommand(_T("\33"));}//ok
};
BEGIN_MESSAGE_MAP(CBoolEditDlg,CModelessDialog)
ON_WM_CLOSE()
END_MESSAGE_MAP()
int CBoolEditDlg::g_iBoolType=0;
BOOL CBoolEditDlg::g_bDeleteSecond=TRUE;
void PolyBool()
{
CTemporaryResourceOverride vTemp;
CBoolEditDlg dlg;
dlg.Create(IDD_BOOL_EDIT,acedGetAcadFrame());
acedGetAcadFrame()->SetFocus();
Entity ent1,ent2;
XPoly2D poly1,poly2;
AcGeVector3d vt1,vt2;
RBList mask=GetClosedProfileMask();
PickSet ss1(SS_FREE),ss2(SS_FREE),ss3(SS_FREE);
g_ssPickFirst.BaseFilter(RBList(GetClosedProfileMask(true)));//不能判断是否闭合
if(g_ssPickFirst.Length()==1)
ent1=g_ssPickFirst[0L];
else
SelectEntity(_T("\n选择第一个闭合轮廓对象(pline、圆、平板、柱子、墙体造型、房间、屋顶、散水等):"), ent1,mask);
if(GetOutline(ent1, poly1,vt1)&&
SelectEntities(_T("\n选择其它闭合轮廓对象(pline、圆、平板、柱子、墙体造型、房间、屋顶、散水等):"),ss2,mask)==RTNORM)
{
dlg.UpdateData();
DList<XPoly2D> lstDest,buf1,buf2;
bool bClockwise=poly1.PathArea()>0;
buf1.Append(new XPoly2D(poly1));
long count=ss2.Length();
for(long i=0;i<count;i++)
{
ent2=ss2[i];
if(ent1==ent2)
{
ss3+=ent2;
continue;
}
if(!GetOutline(ent2,poly2,vt2))
{
ss3+=ent2;
continue;
}
if(!vt1.isParallelTo(vt2))
{
ss3+=ent2;
continue;
}
poly2.SetElevation(poly1[0]->z);
buf2.Append(new XPoly2D(poly2));
}
if(dlg.g_iBoolType==0)
Union(buf1,buf2,lstDest);
else if(dlg.g_iBoolType==1)
Intersect(buf1,buf2,lstDest);
else
Subtract(buf1,buf2, lstDest);
//if(lstDest.Length()>0)
{
bool bClockwise=poly1.PathArea()>0;
for(int i=0; i<lstDest.Length(); i++)
{
XPoly2D *pPoly=lstDest[i];
pPoly->Compress();
if(pPoly->PathArea()>0)
{
if(!bClockwise)
pPoly->Reverse();
}
else
{
if(bClockwise)
pPoly->Reverse();
}
}
if(!SetOutline(ent1, lstDest,vt1))
adsout<<_T("\n无法修改第一运算对象轮廓!");
else if(dlg.g_bDeleteSecond)
{
ss2-=ss3;
ss2.Delete();
}
}
}
if(dlg.GetSafeHwnd()!=NULL)
dlg.DestroyWindow();
}