Files
envi-code/SourceCode/Code2026/AdsXRx/XPoly3D.cpp
T
2026-09-28 15:28:50 +08:00

379 lines
6.7 KiB
C++

//-----------------------------------------------------------------------------+
// Copyright (C), 1998-2007, SH Software Co. Ltd.
// = FileName : XPoly3D Ŕŕ
// = Version : ver2.0
// = Author : zjq
// = CreateDate : 2002-09-09
// = Description: XPoly3D ŔඨŇĺ
// = Maintainers:
//
//-----------------------------------------------------------------------------+
#include "StdAfx.h"
#include "XPoly3D.h"
#include "XDbObject.h"
#include "XGlobalFunc.h"
XPoly3D::XPoly3D(int nFlag)
:XPoly2D(nFlag)
{
}
XPoly3D::XPoly3D(const XPoly2D& poly)
:XPoly2D(poly)
{
}
XPoly3D::XPoly3D(const Entity & e)
: XPoly2D(e)
{
Entity entPLine = e;
AcGeVector3d vt(0,0,1);
if (entPLine.Is(_T("LWPOLYLINE")))
{
entPLine.GetData(210, &vt);
}
else if (entPLine.Is(_T("CIRCLE")))
{
XDbObject obj(entPLine,AcDb::kForRead);
AcDbCircle *pCircle = (AcDbCircle *)obj.m_pObject;
vt = pCircle->normal();
}
else if (entPLine.Is(_T("ARC")))
{
XDbObject obj(entPLine,AcDb::kForRead);
AcDbArc *pArc = (AcDbArc*) obj.m_pObject;
vt = pArc->normal();
}
else
{
return;
}
*this = PlaneToWcs(vt);// wulw;
// AcGeMatrix3d mat;
// mat.setToPlaneToWorld(vt);
// TransformBy(mat);
}
XPoly3D::~XPoly3D()
{
}
bool XPoly3D::IsPlanear() const
{
if (Length() < 2)
{
return true;
}
AcGePlane plane((*this)[0].AsAcGePoint3d(),GetNormal(false));
for (long i = 1; i < Length(); i++)
{
if (!plane.isOn((*this)[i].AsAcGePoint3d()))
{
return false;
}
}
return true;
}
AcGeVector3d XPoly3D::GetNormal(bool bCheckConcave)const
{
AcGeVector3d vt0,vt1;
bool bFindVt0 = false,bFindVt1 = false;
for (long i = 0; i < Length(); i++)
{
AcGeVector3d vt = ((*this)[(i+1) % Length()] - (*this)[i]).AsAcGeVector3d();
if (!vt.isZeroLength())
{
if (bFindVt0)
{
if (!vt.isParallelTo(vt0))
{
vt1 = vt;
bFindVt1 = true;
break;
}
}
else
{
vt0 = vt;
bFindVt0 = true;
}
}
}
AcGeVector3d vtRes;
if (bFindVt0 && bFindVt1)
{
vtRes = vt0.crossProduct(vt1).normal();
}
else if (bFindVt0 && !vt0.isPerpendicularTo(AcGeVector3d::kZAxis))
{
vtRes = vt0.perpVector().normal();
}
else
{
vtRes = AcGeVector3d::kZAxis;
}
if (bCheckConcave && TotalSegments() > 3)
{
AcGeMatrix3d mat;
mat.setToWorldToPlane(vtRes);
XPoly3D temp = (*this);
temp.TransformBy(mat);
temp.SetElevation(0);
if (temp.PathArea() > 0)
{
vtRes *= -1;
}
}
return vtRes;
}
XPoly2D XPoly3D::WcsToPlane() const
{
AcGeVector3d vtNormal = GetNormal(true);
AcGeMatrix3d mat;
mat.setToWorldToPlane(vtNormal);
XPoly2D polyTemp = *this;
polyTemp.TransformBy(mat);
return polyTemp;
}
XPoly2D XPoly3D::WcsToPlane(const AcGeVector3d& vtNormal) const
{
AcGeMatrix3d mat;
mat.setToWorldToPlane(vtNormal);
XPoly2D polyTemp = *this;
polyTemp.TransformBy(mat);
return polyTemp;
}
AcDbCurve* XPoly3D::AsAcDbCurve() const
{
if (IsPlanear())
{
AcGeVector3d vtNormal = GetNormal(true);
AcGeMatrix3d mat;
mat.setToWorldToPlane(vtNormal);
XPoly2D polyTemp = *this;
polyTemp.TransformBy(mat);
AcDbCurve* pCurve = polyTemp.AsAcDbCurve();
if (pCurve != NULL)
{
AcDbPolyline* pPline = (AcDbPolyline*)pCurve;
pPline->setNormal(vtNormal);
}
return pCurve;
}
else
{
AcDb3dPolyline* pPLine = new AcDb3dPolyline;
AcGePoint3d pt;
for (long i = 0; i < Length(); i++)
{
pPLine->appendVertex(new AcDb3dPolylineVertex((*this)[i].AsAcGePoint3d()));
}
if(IsClosed())
{
pPLine->makeClosed();
}
else
{
pPLine->makeOpen();
}
return pPLine;
}
return NULL;
}
bool XPoly3D::SetAcDbCurve(AcDbCurve*pCurve)
{
bool bRet = false;
if (pCurve->isKindOf(AcDbPolyline::desc()))
{
AcDbPolyline*pPLine = (AcDbPolyline*)pCurve;
if (XPoly2D::SetAcDbCurve(pPLine))
{
AcGeMatrix3d mat;
mat.setToPlaneToWorld(pPLine->normal());
TransformBy(mat);
}
}
else if (pCurve->isKindOf(AcDb3dPolyline::desc()))
{
AcDb3dPolyline* pPLine = (AcDb3dPolyline*)pCurve->clone();
AcDbObjectId id = AddToModelSpace(pPLine,Adesk::kFalse);
if (!id.isNull())
{
AcDbObjectIterator* pIter = pPLine->vertexIterator();
if (pIter != NULL)
{
Reset();
for (pIter->start(); !pIter->done(); pIter->step())
{
AcDbObjectId vertId = pIter->objectId();
AcDb3dPolylineVertex*pVertex = NULL;
acdbOpenObject(pVertex, vertId, AcDb::kForRead);
if (pVertex != NULL)
{
AppendNode(pVertex->position());
pVertex->close();
}
}
delete pIter;
bRet = true;
}
if (pPLine->isClosed())
{
SetFlag(1);
}
else
{
SetFlag(0);
}
pPLine->erase();
pPLine->close();
}
else
{
delete pPLine;
}
}
return bRet;
}
// XPoly3D::XPoly3D(int nFlag)
// {
// if (m_pEntityImp != NULL)
// {
// delete m_pEntityImp;
// m_pEntityImp = NULL;
// }
// m_pEntityImp = new XPoly3D((XPointList*)this, nFlag);
// }
//
// XPoly3D::XPoly3D(const XPoly2D& poly)
// {
// if (m_pEntityImp != NULL)
// {
// delete m_pEntityImp;
// m_pEntityImp = NULL;
// }
// //XPoly3D& ppoly3d = (XPoly3D& )poly;
// XPoly3D* pImp = (XPoly3D*)poly.GetEntityImp();
// if (pImp != NULL)
// {
// m_pEntityImp = new XPoly3D((XPointList*)this, *pImp);
// }
// }
//
// XPoly3D::XPoly3D(const Entity & e)
// {
// if (m_pEntityImp != NULL)
// {
// delete m_pEntityImp;
// m_pEntityImp = NULL;
// }
// m_pEntityImp = new XPoly3D((XPointList*)this, e);
//
// }
//
// XPoly3D::~XPoly3D()
// {
//
// }
//
// bool XPoly3D::IsPlanear()const
// {
// ASSERT(m_pEntityImp != NULL);
// return ((XPoly3D*)m_pEntityImp)->IsPlanear(this);
//
// }
//
// AcGeVector3d XPoly3D::GetNormal(bool bCheckConcave)const
// {
// ASSERT(m_pEntityImp != NULL);
// return ((XPoly3D*)m_pEntityImp)->GetNormal(this, bCheckConcave);
// }
//
// XPoly2D XPoly3D::WcsToPlane()const
// {
// ASSERT(m_pEntityImp != NULL);
// XPoly3D poly3d = *this;
// ((XPoly3D*)poly3d.m_pEntityImp)->WcsToPlane(this);
// return poly3d;
// }
//
// XPoly2D XPoly3D::WcsToPlane(const AcGeVector3d& vtNormal)const
// {
// ASSERT(m_pEntityImp != NULL);
// XPoly3D poly3d = *this;
// ((XPoly3D*)poly3d.m_pEntityImp)->WcsToPlane(vtNormal);
// return poly3d;
// }
//
// AcDbCurve* XPoly3D::AsAcDbCurve()const
// {
// ASSERT(m_pEntityImp != NULL);
// return ((XPoly3D*)m_pEntityImp)->AsAcDbCurve(this);
// }
//
// bool XPoly3D::SetAcDbCurve(AcDbCurve*pCurve)
// {
// ASSERT(m_pEntityImp != NULL);
// return ((XPoly3D*)m_pEntityImp)->SetAcDbCurve(pCurve);
// }
bool XPoly3D::IsKindOf(XEntity::TEntityId entType) const
{
switch(entType)
{
case XEntity::eEntity:
case XEntity::eCurve:
case XEntity::ePoly2D:
case XEntity::ePoly3D:
return true;
}
return false;
}
XEntity::TEntityId XPoly3D::Type() const
{
return XEntity::ePoly3D;
}