601 lines
21 KiB
C++
601 lines
21 KiB
C++
#include "stdafx.h"
|
|
|
|
// extern GEOAPI XPface * ConstructPolyFace(const AcDbVoidPtrArray &entSet);
|
|
|
|
// 已经坐标变换到polyClip平面上
|
|
BOOL PolyClip3D(XPolygonEx &polySrc, const XPoly2D &polyClip, DList<XPolygonEx> &inSet,
|
|
DList<XPolygonEx> &outSet)
|
|
{
|
|
ASSERT(polySrc.Length()>=3);
|
|
XVector3D vtNorm;
|
|
if (polySrc.GetNormal(vtNorm)!=RTNORM)
|
|
return FALSE;
|
|
((AcGeVector3d &)vtNorm).normalize();
|
|
double nVal=(vtNorm&XVector3D(0,0,1));
|
|
BOOL bVert=(fabs(nVal)<1.0E-6);
|
|
|
|
BOOL nRet=TRUE;
|
|
if (bVert) {
|
|
/*
|
|
int nEdgeNum=0, nInNum=0, nOutNum=0;
|
|
double nElev=polyClip[0].z;
|
|
for(int i=0; i<polySrc.Length(); i++) {
|
|
XPoint ptVert=*polySrc[i];
|
|
ptVert.z = nElev;
|
|
int nFlag=(ptVert&polyClip);
|
|
if (nFlag==PR_INSIDE)
|
|
nInNum++;
|
|
else if (nFlag==PR_OUTSIDE)
|
|
nOutNum++;
|
|
else
|
|
nEdgeNum++;
|
|
}
|
|
if (nInNum==0 && nOutNum>0)
|
|
outSet.Append(new XPolygonEx(polySrc));
|
|
else if (nOutNum==0 && nInNum>0)
|
|
inSet.Append(new XPolygonEx(polySrc));
|
|
else */
|
|
nRet=FALSE; //求解过程比较复杂,暂时放弃
|
|
|
|
} else {
|
|
AcGePlane srcPlane(*polySrc[0], vtNorm);
|
|
AcGePlane tarPlane((AcGePoint3d &)*polyClip[0], AcGeVector3d(0,0,1));
|
|
ASSERT(fabs(polyClip[0].z)<_DIST_SNAP);
|
|
|
|
// 被裁剪面投影到裁剪区域平面内,并设置z=0
|
|
XPoly2D poly2d(1);
|
|
for(int i=0; i<polySrc.Length(); i++) {
|
|
XPoint ptVert=*polySrc[i];
|
|
//投影产生poly2d
|
|
XPoint ptPrj=((AcGePoint3d &)ptVert).orthoProject(tarPlane);
|
|
ptPrj.z=0;
|
|
poly2d.AppendNode(ptPrj);
|
|
}
|
|
|
|
|
|
// 内、外部的区域
|
|
DList<XPoly2D> lstInSide, lstOutSide;
|
|
TchSubExport::Intersect(poly2d, polyClip, lstInSide);
|
|
TchSubExport::Subtract(poly2d, polyClip, lstOutSide);
|
|
for(int m=0; m<2; m++) {
|
|
DList<XPoly2D> &lstRegion=m? lstOutSide : lstInSide;
|
|
DList<XPolygonEx> &lstSet=m? outSet : inSet;
|
|
for(int k=0; k<lstRegion.Length(); k++) {
|
|
XPoly2D &polyReg=*lstRegion[k];
|
|
if (polyReg.PathArea()>1.0E-6)
|
|
polyReg.Reverse();
|
|
XPolygonEx *pNewReg=new XPolygonEx;
|
|
for(int i=0; i<polyReg.Length(); i++) {
|
|
XCurveSegment seg;
|
|
polyReg.Nth(i, seg);
|
|
XPoint ptMid=seg.MidPoint();
|
|
int nHitFlag=poly2d.HitTestOnCurve(ptMid);
|
|
BOOL bVis=(abs(nHitFlag)>0? polySrc.IsVisible(abs(nHitFlag)-1) : TRUE);
|
|
XPoint ptNew=((AcGePoint3d &)seg.StartPoint()).project(srcPlane, AcGeVector3d(0,0,1));
|
|
pNewReg->AppendNode(ptNew, bVis);
|
|
}
|
|
lstSet.Append(pNewReg);
|
|
}
|
|
}
|
|
}
|
|
return nRet;
|
|
}
|
|
|
|
// 坐标变换不正确,应当使用投影的方法
|
|
BOOL PolyClip3DFace(const AcDbPolyline &plane, const AcDbFace &face,
|
|
AcDbVoidPtrArray &inSet, AcDbVoidPtrArray &outSet)
|
|
{
|
|
//extern GEOAPI void Trianglize(const XPolygonEx &poly2d, DList<AcDbFace> &lstFace);
|
|
AcGePoint3d ptArray[4];
|
|
Adesk::Boolean visArray[4];
|
|
|
|
for(int i=0; i<4; i++) {
|
|
VERIFY(face.getVertexAt(i, ptArray[i])==Acad::eOk);
|
|
VERIFY(face.isEdgeVisibleAt(i, visArray[i])==Acad::eOk);
|
|
}
|
|
|
|
|
|
BOOL bTri=FALSE;
|
|
for(i=0; i<4; i++) {
|
|
int j=i+1;
|
|
if (j==4) j=0;
|
|
|
|
if (ptArray[i].distanceTo(ptArray[j])<_DIST_SNAP) {
|
|
switch(j) {
|
|
case 1: //消除第1顶点
|
|
ptArray[1]=ptArray[2];
|
|
ptArray[2]=ptArray[3];
|
|
visArray[0]=visArray[1];
|
|
visArray[1]=visArray[2];
|
|
visArray[2]=visArray[3];
|
|
break;
|
|
case 2: //消除第2顶点
|
|
ptArray[2]=ptArray[3];
|
|
visArray[1]=visArray[2];
|
|
visArray[2]=visArray[3];
|
|
break;
|
|
case 3: //消除第3顶点
|
|
visArray[2]=visArray[3];
|
|
break;
|
|
}
|
|
|
|
bTri=TRUE;
|
|
break;
|
|
}
|
|
}
|
|
XPoly2D polyClip;
|
|
PolyConvert(plane, polyClip);
|
|
XVector3D vtNormal;
|
|
(AcGeVector3d &)vtNormal=plane.normal();
|
|
polyClip.SetElevation(0.0);
|
|
|
|
int nLen=(bTri? 3 : 4);
|
|
XPolygonEx polySrc;
|
|
for(i=0; i<nLen; i++) {
|
|
XPoint pt;
|
|
pt=ptArray[i];
|
|
pt=Wcs2Ecs(pt, vtNormal);
|
|
polySrc.AppendNode(pt, visArray[i]);
|
|
}
|
|
|
|
DList<XPolygonEx> frontSet, backSet;
|
|
BOOL bRet=PolyClip3D(polySrc, polyClip, frontSet, backSet);
|
|
if (!bRet)
|
|
return bRet;
|
|
|
|
for(int m=0; m<2; m++) {
|
|
DList<XPolygonEx> &lstSet=m? backSet : frontSet;
|
|
int nCount=lstSet.Length();
|
|
for(int n=0; n<nCount; n++) {
|
|
XPolygonEx *pRegion=lstSet[n];
|
|
/*
|
|
for(int k=0; k<pRegion->Length(); k++) {
|
|
*(*pRegion)[k]=Ecs2Wcs(*(*pRegion)[k], vtNormal);
|
|
}
|
|
DList<AcDbFace> lstFaces(0);
|
|
Trianglize(*pRegion, lstFaces);
|
|
for(k=0; k<lstFaces.Length(); k++) {
|
|
AcDbFace *pFace=lstFaces[k];
|
|
pFace->setPropertiesFrom(&face);
|
|
if (m==0)
|
|
inSet.append(pFace);
|
|
else
|
|
outSet.append(pFace);
|
|
}
|
|
*/
|
|
DList<XTriangle> lstTris;
|
|
double nElev=(*pRegion)[0]->z;
|
|
pRegion->SetElevation(0.0);
|
|
if (pRegion->Trianglize(lstTris, TRUE)==RTNORM) {
|
|
for(int k=0; k<lstTris.Length(); k++) {
|
|
XTriangle *triangle=lstTris[k];
|
|
Adesk::Boolean bSide1=!(triangle->m_nFlag&SIDE1_INVISIBLE);
|
|
Adesk::Boolean bSide2=!(triangle->m_nFlag&SIDE2_INVISIBLE);
|
|
Adesk::Boolean bSide3=!(triangle->m_nFlag&SIDE3_INVISIBLE);
|
|
triangle->vertex1.z=triangle->vertex2.z=triangle->vertex3.z=nElev;
|
|
XPoint pt1=Ecs2Wcs(triangle->vertex1, vtNormal);
|
|
XPoint pt2=Ecs2Wcs(triangle->vertex2, vtNormal);
|
|
XPoint pt3=Ecs2Wcs(triangle->vertex3, vtNormal);
|
|
AcDbFace *pFace=new AcDbFace(pt1, pt2, pt3, pt1,
|
|
bSide1, bSide2, bSide3);
|
|
pFace->setPropertiesFrom(&face);
|
|
if (m==0)
|
|
inSet.append(pFace);
|
|
else
|
|
outSet.append(pFace);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
// 3DFace的裁剪
|
|
BOOL Clip3DFace(const AcGePlane &plane, const AcGePoint3d *ptArray,
|
|
const Adesk::Boolean *visArray, BOOL bTri,
|
|
AcDbVoidPtrArray &frontSet, AcDbVoidPtrArray &backSet)
|
|
{
|
|
AcGeVector3d vtNormal=plane.normal();
|
|
XPoint *ptArray1=(XPoint *)ptArray;
|
|
XVector3D vtNorm;
|
|
CT_vector_plan3p(ptArray1[0], ptArray1[1], ptArray1[2], vtNorm);
|
|
AcGePlane plan1(ptArray[0], vtNorm);
|
|
AcGeLine3d line;
|
|
if (!plane.intersectWith(plan1, line)) {
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
// 用交线和3DFACE的边求交。
|
|
int nVertice=(bTri? 3 : 4);
|
|
int nIntFlag1=0, nIntFlag2=0; // 在顶点则为负(-idx-1),在边则为正(idx+1)
|
|
AcGePoint3d ptInt1, ptInt2;
|
|
for(int i=0; i<nVertice; i++) {
|
|
int iNext=i+1;
|
|
if (iNext==nVertice)
|
|
iNext=0;
|
|
AcGeLineSeg3d lnEdge(ptArray[i], ptArray[iNext]);
|
|
AcGePoint3d ptInt;
|
|
if (line.intersectWith(lnEdge, ptInt)) {
|
|
if (ptInt==ptArray[iNext]) {
|
|
if (nIntFlag1) {
|
|
nIntFlag2=-iNext-1;
|
|
ptInt2=ptInt;
|
|
break;
|
|
} else {
|
|
nIntFlag1=-iNext-1;
|
|
ptInt1=ptInt;
|
|
}
|
|
} else if (ptInt==ptArray[i]) {
|
|
if (i==0) {
|
|
nIntFlag1=-1;
|
|
ptInt1=ptInt;
|
|
}
|
|
} else {
|
|
if (nIntFlag1) {
|
|
nIntFlag2=i+1;
|
|
ptInt2=ptInt;
|
|
break;
|
|
} else {
|
|
nIntFlag1=i+1;
|
|
ptInt1=ptInt;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
XPolygonEx poly1, poly2;
|
|
if (nIntFlag1 && nIntFlag2 && ptInt1!=ptInt2) {
|
|
// nFlag1~nFlag2, poly1
|
|
for(int n=abs(nIntFlag1)-1; n<=abs(nIntFlag2)-1; n++) {
|
|
if (n==abs(nIntFlag1)-1)
|
|
poly1.AppendNode(ptInt1, visArray[n]);
|
|
else if (n==abs(nIntFlag2)-1 && nIntFlag2<0)
|
|
poly1.AppendNode(ptInt2, TRUE); //裁剪边可见
|
|
else
|
|
poly1.AppendNode(ptArray[n], visArray[n]);
|
|
}
|
|
if (nIntFlag2>0)
|
|
poly1.AppendNode(ptInt2, TRUE);
|
|
|
|
// nFlag2~nFlag1, poly2
|
|
for(n=abs(nIntFlag2)-1; n<=abs(nIntFlag1)-1+nVertice; n++) {
|
|
if (n==abs(nIntFlag2)-1)
|
|
poly2.AppendNode(ptInt2, visArray[DePeriod(nVertice, n)]);
|
|
else if (n==abs(nIntFlag1)-1+nVertice && nIntFlag2<0)
|
|
poly2.AppendNode(ptInt1, TRUE);
|
|
else
|
|
poly2.AppendNode(ptArray[DePeriod(nVertice,n)],
|
|
visArray[DePeriod(nVertice,n)]);
|
|
}
|
|
if (nIntFlag1>0)
|
|
poly2.AppendNode(ptInt1, TRUE);
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
XPoint ptMid;
|
|
Midpoint(ptInt1, ptInt2, ptMid);
|
|
for(int nSide=0; nSide<2; nSide++) {
|
|
XPolygonEx &poly2d=(nSide? poly2 : poly1);
|
|
if (poly2d.Length()>=3) {
|
|
XPoint ptCen1;
|
|
poly2d.Center(ptCen1);
|
|
XVector3D vt1=ptCen1-ptMid;
|
|
XVector3D vt2;
|
|
(AcGeVector3d &)vt2=vtNormal;
|
|
double nVal=(vt1&vt2);
|
|
BOOL bFrontSet=(nVal>0.0);
|
|
if (poly2d.Length()>=5) {
|
|
DList<XTriangle> lstTris;
|
|
if (poly2d.Trianglize(lstTris, TRUE)==RTNORM) {
|
|
for(int n=0; n<lstTris.Length(); n++) {
|
|
XTriangle *triangle=lstTris[n];
|
|
Adesk::Boolean bSide1=!(triangle->m_nFlag&SIDE1_INVISIBLE);
|
|
Adesk::Boolean bSide2=!(triangle->m_nFlag&SIDE2_INVISIBLE);
|
|
Adesk::Boolean bSide3=!(triangle->m_nFlag&SIDE3_INVISIBLE);
|
|
AcDbFace *pFace=new AcDbFace(triangle->vertex1, triangle->vertex2,
|
|
triangle->vertex3, triangle->vertex1, bSide1, bSide2, bSide3);
|
|
if (bFrontSet)
|
|
frontSet.append(pFace);
|
|
else
|
|
backSet.append(pFace);
|
|
}
|
|
}
|
|
} else {
|
|
AcDbFace *pFace=NULL;
|
|
if (poly2d.Length()==3) {
|
|
pFace=new AcDbFace(*poly2d[0], *poly2d[1], *poly2d[2],
|
|
*poly2d[0], poly2d.IsVisible(0),
|
|
poly2d.IsVisible(1), poly2d.IsVisible(2));
|
|
} else {
|
|
pFace=new AcDbFace(*poly2d[0], *poly2d[1], *poly2d[2], *poly2d[3],
|
|
poly2d.IsVisible(0), poly2d.IsVisible(1),
|
|
poly2d.IsVisible(2), poly2d.IsVisible(3));
|
|
}
|
|
if (bFrontSet)
|
|
frontSet.append(pFace);
|
|
else
|
|
backSet.append(pFace);
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
// 用面裁剪3dface
|
|
BOOL Clip3DFace(const AcGePlane &plane, const AcDbFace &face,
|
|
AcDbVoidPtrArray &frontSet, AcDbVoidPtrArray &backSet)
|
|
{
|
|
XPlane planeMe;
|
|
// [2010-3-16 9:34 wubo] 移植到新Geo库
|
|
// plane.getCoefficients(planeMe.a, planeMe.b, planeMe.c, planeMe.d);
|
|
double dParaA = planeMe.GetParaA();
|
|
double dParaB = planeMe.GetParaB();
|
|
double dParaC = planeMe.GetParaC();
|
|
double dParaD = planeMe.GetParaD();
|
|
plane.getCoefficients(dParaA, dParaB, dParaC, dParaD);
|
|
planeMe.SetParaA(dParaA);
|
|
planeMe.SetParaB(dParaB);
|
|
planeMe.SetParaC(dParaC);
|
|
planeMe.SetParaD(dParaD);
|
|
|
|
X3DFace faceMe(face);
|
|
DList<X3DFace> upFaces, downFaces;
|
|
BOOL bOk=faceMe.SectByPlane(planeMe, upFaces, downFaces);
|
|
for(int kk=0; kk<upFaces.Length(); kk++) {
|
|
frontSet.append(upFaces[kk]->AsDbFace());
|
|
}
|
|
for(kk=0; kk<downFaces.Length(); kk++) {
|
|
backSet.append(downFaces[kk]->AsDbFace());
|
|
}
|
|
return bOk;
|
|
|
|
AcGePoint3d ptArray[4];
|
|
Adesk::Boolean visArray[4];
|
|
|
|
for(int i=0; i<4; i++) {
|
|
VERIFY(face.getVertexAt(i, ptArray[i])==Acad::eOk);
|
|
VERIFY(face.isEdgeVisibleAt(i, visArray[i])==Acad::eOk);
|
|
}
|
|
|
|
|
|
BOOL bTri=FALSE;
|
|
for(i=0; i<4; i++) {
|
|
int j=i+1;
|
|
if (j==4) j=0;
|
|
|
|
if (ptArray[i].distanceTo(ptArray[j])<_DIST_SNAP) {
|
|
switch(j) {
|
|
case 1: //消除第1顶点
|
|
ptArray[1]=ptArray[2];
|
|
ptArray[2]=ptArray[3];
|
|
visArray[0]=visArray[1];
|
|
visArray[1]=visArray[2];
|
|
visArray[2]=visArray[3];
|
|
break;
|
|
case 2: //消除第2顶点
|
|
ptArray[2]=ptArray[3];
|
|
visArray[1]=visArray[2];
|
|
visArray[2]=visArray[3];
|
|
break;
|
|
case 3: //消除第3顶点
|
|
visArray[2]=visArray[3];
|
|
break;
|
|
}
|
|
|
|
bTri=TRUE;
|
|
break;
|
|
}
|
|
}
|
|
if (bTri) {
|
|
if ((XPoint(ptArray[2])&XLine(XPoint(ptArray[0]), XPoint(ptArray[1])))!=PR_OUTSIDE)
|
|
return FALSE; //共线
|
|
}
|
|
BOOL bRet=Clip3DFace(plane, ptArray, visArray, bTri, frontSet, backSet);
|
|
if (!bRet) {
|
|
XPoint ptCen;
|
|
ptCen.x=(ptArray[0].x+ptArray[1].x+ptArray[2].x)/3.0;
|
|
ptCen.y=(ptArray[0].y+ptArray[1].y+ptArray[2].y)/3.0;
|
|
ptCen.z=(ptArray[0].z+ptArray[1].z+ptArray[2].z)/3.0;
|
|
// 平行平面
|
|
XPoint pt=ptArray[0].orthoProject(plane);
|
|
XVector3D vt1=ptCen-pt;
|
|
XVector3D vt2;
|
|
AcGeVector3d vtNormal=plane.normal();
|
|
(AcGeVector3d &)vt2=vtNormal;
|
|
double nVal=(vt1&vt2);
|
|
BOOL bFrontSet=(nVal>0.0);
|
|
AcDbFace *pFace=(AcDbFace *)face.clone();
|
|
if (bFrontSet)
|
|
frontSet.append(pFace);
|
|
else
|
|
backSet.append(pFace);
|
|
bRet = TRUE;
|
|
}
|
|
int nCount=frontSet.length();
|
|
for(int n=0; n<nCount; n++) {
|
|
AcDbEntity *pEnt=(AcDbEntity *)frontSet[n];
|
|
pEnt->setPropertiesFrom(&face);
|
|
}
|
|
nCount=backSet.length();
|
|
for(n=0; n<nCount; n++) {
|
|
AcDbEntity *pEnt=(AcDbEntity *)backSet[n];
|
|
pEnt->setPropertiesFrom(&face);
|
|
}
|
|
return bRet;
|
|
}
|
|
|
|
|
|
// Command: 平面切割
|
|
void Clip3D()
|
|
{
|
|
PickSet ss(SS_FREE);
|
|
RBList mask=ads_buildlist(RTDXF0, _T("3DSOLID,REGION,3DBODY,3DFACE,POLYLINE,LINE,ARC,CIRCLE"), NULL);
|
|
if (SelectEntities(_T("\n选择待切割的三维对象:"), ss, mask)!=RTNORM)
|
|
return;
|
|
|
|
XPoint pt1, pt2;
|
|
int nRetCode;
|
|
//INITGET_BEG(0, _T("P"));
|
|
nRetCode=ads_getpoint(NULL, _T("\n切割线第一点<退出>:"), pt1);
|
|
//INITGET_END();
|
|
if (nRetCode!=RTNORM && nRetCode!=RTKWORD)
|
|
return;
|
|
|
|
AcDbPolyline *pClip=NULL;
|
|
AcGePlane plane;
|
|
if (nRetCode==RTKWORD) {
|
|
RBList mask(RTDXF0, _T("LWPOLYLINE"), 70, 1, NULL);
|
|
Entity entPoly;
|
|
if (entPoly.FilterSelect(_T("\n选择作为裁剪边界的封闭多段线<退出>:"), mask)!=RTNORM)
|
|
return;
|
|
OPENOBJ_BEGIN(entPoly, AcDb::kForRead, AcDbPolyline, pLine);
|
|
ASSERT(pLine);
|
|
pClip=(AcDbPolyline*)pLine->clone();
|
|
OPENOBJ_END();
|
|
} else {
|
|
if (XGetPoint(pt1, _T("\n切割线第二点"), pt2)!=RTNORM)
|
|
return;
|
|
XVector3D vt1=pt2-pt1;
|
|
vt1=Ucs2Wcs(vt1, TRUE);
|
|
XVector3D vt0(0,0,1);
|
|
vt0=Ucs2Wcs(vt0, TRUE);
|
|
XVector3D vt2=vt0*vt1;
|
|
plane=AcGePlane((const AcGePoint3d &)Ucs2Wcs(pt1), (const AcGeVector3d &)vt2);
|
|
}
|
|
|
|
|
|
long lCount=ss.Length();
|
|
for(long i=0; i<lCount; i++) {
|
|
Entity ent=ss[i];
|
|
AcDbVoidPtrArray frontSet, backSet;
|
|
OPENOBJ_BEGIN(ent, AcDb::kForRead, AcDbEntity, pEnt);
|
|
ASSERT(pEnt);
|
|
TMasterProperties prop;
|
|
prop.SetFrom(pEnt);
|
|
AcDbVoidPtrArray entSet0;
|
|
if (pEnt->isA()==AcDbFace::desc()) {
|
|
if (pClip)
|
|
PolyClip3DFace(*pClip, *(AcDbFace *)pEnt, frontSet, backSet);
|
|
else
|
|
Clip3DFace(plane, *(AcDbFace *)pEnt, frontSet, backSet);
|
|
} else if (pEnt->isKindOf(AcDbCurve::desc())) {
|
|
double nThickness=0.0;
|
|
if (pEnt->isA()==AcDbLine::desc())
|
|
nThickness=((AcDbLine *)pEnt)->thickness();
|
|
else if (pEnt->isA()==AcDbArc::desc())
|
|
nThickness=((AcDbArc *)pEnt)->thickness();
|
|
else if (pEnt->isA()==AcDbCircle::desc())
|
|
nThickness=((AcDbCircle *)pEnt)->thickness();
|
|
else if (pEnt->isA()==AcDbPolyline::desc())
|
|
nThickness=((AcDbPolyline *)pEnt)->thickness();
|
|
else if (pEnt->isA()==AcDb2dPolyline::desc())
|
|
nThickness=((AcDb2dPolyline *)pEnt)->thickness();
|
|
|
|
if (nThickness>_DIST_SNAP) {
|
|
AcDbVoidPtrArray entSet;
|
|
InitModel(prop, pEnt, NULL, entSet);
|
|
int num=entSet.length();
|
|
for(int n=0; n<num; n++) {
|
|
AcDbEntity *pFace=(AcDbEntity *)entSet[n];
|
|
if (pFace->isA()==AcDbFace::desc()) {
|
|
if (pClip) {
|
|
if (!PolyClip3DFace(*pClip, *(AcDbFace *)pFace, frontSet, backSet)) {
|
|
entSet0.append(pFace->clone());
|
|
}
|
|
} else
|
|
Clip3DFace(plane, *(AcDbFace *)pFace, frontSet, backSet);
|
|
}
|
|
}
|
|
ReleaseEntSet(entSet);
|
|
}
|
|
} else {
|
|
AcDbVoidPtrArray entSet;
|
|
InitModel(prop, pEnt, NULL, entSet);
|
|
int num=entSet.length();
|
|
for(int n=0; n<num; n++) {
|
|
AcDbEntity *pFace=(AcDbEntity *)entSet[n];
|
|
if (pFace->isA()==AcDbFace::desc()) {
|
|
if (pClip) {
|
|
if (!PolyClip3DFace(*pClip, *(AcDbFace *)pFace, frontSet, backSet)) {
|
|
entSet0.append(pFace->clone());
|
|
}
|
|
} else
|
|
Clip3DFace(plane, *(AcDbFace *)pFace, frontSet, backSet);
|
|
}
|
|
}
|
|
ReleaseEntSet(entSet);
|
|
}
|
|
if (frontSet.length()>0 || backSet.length()>0) {
|
|
if (pEnt->upgradeOpen()==Acad::eOk) {
|
|
pEnt->erase();
|
|
pEnt->downgradeOpen();
|
|
|
|
// 不能裁剪的变成单独的PFACE/3DFACE
|
|
for(int nn=0; nn<3; nn++) {
|
|
AcDbVoidPtrArray *pEntSet=NULL;
|
|
if (nn==0)
|
|
pEntSet=&entSet0;
|
|
else if (nn==1)
|
|
pEntSet=&frontSet;
|
|
else
|
|
pEntSet=&backSet;
|
|
AcDbVoidPtrArray &eSet=*pEntSet;
|
|
int num=eSet.length();
|
|
if (num>1) {
|
|
XPface *pFace=ConstructPolyFace(eSet);
|
|
if (pFace) {
|
|
pFace->Make();
|
|
Entity entLast;
|
|
entLast.GetLast();
|
|
OPENOBJ_BEGIN(entLast, AcDb::kForWrite, AcDbEntity, pLast);
|
|
if (pLast)
|
|
pLast->setPropertiesFrom(pEnt);
|
|
OPENOBJ_END();
|
|
delete pFace;
|
|
}
|
|
ReleaseEntSet(eSet);
|
|
} else if (num==1){
|
|
AcDbEntity *pFace=(AcDbFace *)eSet[0];
|
|
pFace->setPropertiesFrom(pEnt);
|
|
AddToCurrentSpace(pFace, Adesk::kTrue);
|
|
}
|
|
}
|
|
} else {
|
|
ReleaseEntSet(frontSet);
|
|
ReleaseEntSet(backSet);
|
|
ReleaseEntSet(entSet0);
|
|
}
|
|
} else {
|
|
ReleaseEntSet(frontSet);
|
|
ReleaseEntSet(backSet);
|
|
ReleaseEntSet(entSet0);
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
|
|
if (pClip)
|
|
delete pClip;
|
|
}
|
|
|
|
// Command: 区域封面
|
|
void Poly2Face()
|
|
{
|
|
Entity entPoly;
|
|
if (SelectEntity(_T("\n选择封闭的多段线<退出>: "), entPoly,
|
|
RBList(RTDXF0, _T("POLYLINE,LWPOLYLINE"), 70, 1, NULL))==RTNORM) {
|
|
XPoly2D poly2d(entPoly);
|
|
XPoly poly1;
|
|
poly2d.MapToPolygon1(poly1, _AS_SYS_UNIT(g_nCirDeviation));
|
|
XPolygonEx polyEx(poly1);
|
|
XTrianglePface lstTris;
|
|
if (polyEx.Trianglize(lstTris, TRUE)==RTNORM) {
|
|
lstTris.MakePolyface();
|
|
adsout << _T("\n成功的转成面!");
|
|
}
|
|
}
|
|
} |