220 lines
5.4 KiB
C++
220 lines
5.4 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();
|
|
} |