398 lines
5.8 KiB
C++
398 lines
5.8 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, SH Software Co. Ltd.
|
|
// = FileName : XPoly 类
|
|
// = Version : ver2.0
|
|
// = Author : zjq
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: XPoly 定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "XPoly.h"
|
|
#include "XLine.h"
|
|
|
|
#include "XCell.h"
|
|
#include "XTrianglePface.h"
|
|
#include "XGlobalFunc.h"
|
|
#include "XPolygonEx.h"
|
|
#include "XGlobalCurveFunc.h"
|
|
#include "XCurveInline.h"
|
|
|
|
XPoly::XPoly()
|
|
{
|
|
}
|
|
|
|
XPoly::XPoly(resbuf *pts)
|
|
{
|
|
Groups *ptList = (Groups *)pts;
|
|
for (Groups *pt = ptList; pt != NULL; pt = pt->next)
|
|
{
|
|
if (pt->type != RT3DPOINT && pt->type != RTPOINT)
|
|
{
|
|
Reset();
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
Point tmp = pt->point;
|
|
tmp.z = 0.0;
|
|
Append(new XPoint(tmp));
|
|
}
|
|
}
|
|
}
|
|
|
|
XPoly::XPoly(const Entity &ent)
|
|
{
|
|
Entity entPLine = ent;
|
|
XPoint pt;
|
|
if (entPLine.Is(_T("POLYLINE")))
|
|
{
|
|
Entity subEnt = entPLine;
|
|
while (TRUE)
|
|
{
|
|
Entity sub_ent;
|
|
if (ads_entnext(subEnt, sub_ent) != RTNORM)
|
|
{
|
|
break;
|
|
}
|
|
|
|
subEnt = sub_ent;
|
|
subEnt.FreeGroups();
|
|
if (subEnt.Is(_T("SEQEND")))
|
|
{
|
|
break;
|
|
}
|
|
|
|
int nflg = 0;
|
|
if (subEnt.GetData(70, &nflg) == RTNORM && nflg == 128)
|
|
{
|
|
break;
|
|
}
|
|
|
|
subEnt.GetData(10, pt);
|
|
Append(new XPoint(pt));
|
|
}
|
|
}
|
|
else if (entPLine.Is(_T("LWPOLYLINE")))
|
|
{
|
|
ads_real dElevation = 0.0;
|
|
entPLine.GetData(38, &dElevation);
|
|
|
|
resbuf *ebuf = entPLine;
|
|
while(ebuf)
|
|
{
|
|
resbuf *rb1 = AT_get_resbuf(ebuf, 10);
|
|
if (rb1)
|
|
{
|
|
pt = rb1->resval.rpoint;
|
|
pt.z = dElevation;
|
|
Append(new XPoint(pt));
|
|
ebuf = rb1->rbnext;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
XPoly::XPoly(const XPoly &src)
|
|
{
|
|
*this = src;
|
|
}
|
|
|
|
XPoly::~XPoly()
|
|
{
|
|
|
|
}
|
|
|
|
void XPoly::CopyFrom(const XEntity* pSrc)
|
|
{
|
|
if (this != pSrc && pSrc->IsKindOf(XEntity::ePoly2D))
|
|
{
|
|
copyFrom(*((XPoly* )pSrc));
|
|
}
|
|
}
|
|
|
|
void XPoly::Center(ads_point ptcen)
|
|
{
|
|
Center(ptcen);
|
|
}
|
|
|
|
int XPoly::IsRectAngle(ads_point ptcen, ads_real *pdwidth, ads_real *pdheight)
|
|
{
|
|
if (Length() != 4)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
XLine line[4];
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
NthLine(i, line[i]);
|
|
}
|
|
|
|
if (CT_IsOrthDrt(line[0].Direction(), line[1].Direction(), _angSnap)
|
|
&& CT_IsOrthDrt(line[2].Direction(), line[3].Direction(), _angSnap)
|
|
&& CT_IsSameDrt(line[0].Direction(), line[2].Direction(), _angSnap))
|
|
{
|
|
if (CT_RealEqual(line[0].GetLength(),line[2].GetLength(),_DIST_SNAP) &&
|
|
CT_RealEqual(line[1].GetLength(), line[3].GetLength(),_DIST_SNAP))
|
|
{
|
|
if (CT_IsSameDrt(line[0].Direction(), 0, _angSnap))
|
|
{
|
|
XLine ln(*(*this)[0], *(*this)[2]);
|
|
if (ptcen)
|
|
{
|
|
*(XPoint*)ptcen = ln.MidPoint();
|
|
}
|
|
|
|
if (pdwidth)
|
|
{
|
|
*pdwidth = line[0].GetLength();
|
|
}
|
|
|
|
if (pdheight)
|
|
{
|
|
*pdheight = line[1].GetLength();
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
else if (CT_IsSameDrt(line[1].Direction(), 0, _angSnap))
|
|
{
|
|
XLine ln(*(*this)[0], *(*this)[2]);
|
|
if (ptcen)
|
|
{
|
|
*(XPoint*)ptcen = ln.MidPoint();
|
|
}
|
|
|
|
if (pdwidth)
|
|
{
|
|
*pdwidth = line[1].GetLength();
|
|
}
|
|
|
|
if (pdheight)
|
|
{
|
|
*pdheight = line[0].GetLength();
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int XPoly::NthLine(int nIndex, XLine& res)
|
|
{
|
|
int nlen = Length();
|
|
if (nIndex >= nlen || nIndex < 0)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
|
|
XPoint *pt1 = (*this)[nIndex];
|
|
XPoint *pt2;
|
|
if (nIndex == nlen - 1)
|
|
{
|
|
pt2 = (*this)[0];
|
|
}
|
|
else
|
|
{
|
|
pt2 = (*this)[nIndex + 1];
|
|
}
|
|
|
|
if (!pt1 || !pt2)
|
|
{
|
|
return RTERROR;
|
|
}
|
|
res.SetPoints(*pt1, *pt2);
|
|
|
|
return RTNORM;
|
|
}
|
|
|
|
ads_real XPoly::PathArea()
|
|
{
|
|
XLine line;
|
|
ads_real dresult = 0.0;
|
|
|
|
int nsegments = Length();
|
|
for (int i = 0; i < nsegments; i++)
|
|
{
|
|
if (NthLine(i, line) != RTNORM)
|
|
{
|
|
break;
|
|
}
|
|
|
|
dresult += line.PathArea();
|
|
}
|
|
|
|
return dresult;
|
|
}
|
|
|
|
int XPoly::IsPoint()
|
|
{
|
|
int nlen = Length();
|
|
if (!nlen)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
XPoint bp = *(*this)[0];
|
|
for (int i = 0; i < nlen; i++)
|
|
{
|
|
if (!(bp == *(*this)[i]))
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int XPoly::IsLinear()
|
|
{
|
|
XLine xline;
|
|
int i = 0;
|
|
while(1)
|
|
{
|
|
if (NthLine(i, xline) != RTNORM)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (xline.GetLength() > _DIST_SNAP)
|
|
{
|
|
break;
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
int nlen = Length();
|
|
for (i = 0; i < nlen; i++)
|
|
{
|
|
XPoint &pt = *(*this)[i];
|
|
if ((pt & xline) == PR_OUTSIDE)
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
resbuf* XPoly::Polygon()
|
|
{
|
|
return ResbufList(0);
|
|
}
|
|
|
|
resbuf* XPoly::Fence()
|
|
{
|
|
return ResbufList(1);
|
|
}
|
|
|
|
resbuf* XPoly::ResbufList(int nIsClosed)
|
|
{
|
|
int nlen = Length();
|
|
if (nIsClosed)
|
|
{
|
|
nlen++;
|
|
}
|
|
|
|
Groups *lastrb = NULL, *result = NULL;
|
|
for (int i = 0; i < nlen; i++)
|
|
{
|
|
int ncur;
|
|
if (nIsClosed && i == nlen - 1)
|
|
{
|
|
ncur = 0;
|
|
}
|
|
else
|
|
{
|
|
ncur = i;
|
|
}
|
|
|
|
Groups *rb = new Groups(*(*this)[ncur]);
|
|
rb->next = NULL;
|
|
if (lastrb)
|
|
{
|
|
lastrb->next = rb;
|
|
lastrb = rb;
|
|
}
|
|
else
|
|
{
|
|
lastrb = result = rb;
|
|
}
|
|
}
|
|
|
|
return (resbuf *)result;
|
|
}
|
|
|
|
ads_real XPoly::Area()
|
|
{
|
|
return fabs(PathArea());
|
|
}
|
|
|
|
ShapeType XPoly::GetShapeType() const
|
|
{
|
|
return SHAPE_POLY;
|
|
}
|
|
|
|
XPoly& XPoly::operator = (const XPoly &src)
|
|
{
|
|
(XPointList &)*this = src;
|
|
return *this;
|
|
//Reset();
|
|
//if (this != &src)
|
|
//{
|
|
// CopyFrom(&src);
|
|
//}
|
|
//return *this;
|
|
}
|
|
|
|
int XPoly::operator !()
|
|
{
|
|
return (Length() < 3 ? 1 : 0);
|
|
}
|
|
|
|
int XPoly::CreatePface(const TCHAR *szlay/* = NULL*/)
|
|
{
|
|
XPolygonEx polyEx(*this);
|
|
XTrianglePface lstTris;
|
|
|
|
if (polyEx.Trianglize(lstTris, TRUE) == RTNORM)
|
|
{
|
|
return lstTris.MakePolyface(szlay);
|
|
}
|
|
return RTERROR;
|
|
}
|
|
|
|
int XPoly::GetExtend(XPoint &ptlow, XPoint &ptup) const
|
|
{
|
|
return XPointList::GetExtend(ptlow, ptup);
|
|
}
|
|
|
|
bool XPoly::IsKindOf(XEntity::TEntityId entType) const
|
|
{
|
|
switch(entType)
|
|
{
|
|
case XEntity::eEntity:
|
|
case XEntity::eCurve:
|
|
case XEntity::eShape:
|
|
case XEntity::ePoly:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
XEntity::TEntityId XPoly::Type() const
|
|
{
|
|
return XEntity::ePoly;
|
|
}
|