718 lines
21 KiB
C++
718 lines
21 KiB
C++
#include "stdafx.h"
|
|
|
|
ACRX_NO_CONS_DEFINE_MEMBERS(ATSPolyPathEnt, ATSEntity);
|
|
const Adesk::UInt8 TDbPolyPathEnt::g_nVersion = 2;
|
|
|
|
TDbPolyPathEnt::TDbPolyPathEnt()
|
|
{
|
|
}
|
|
|
|
|
|
TDbPolyPathEnt::~TDbPolyPathEnt()
|
|
{
|
|
}
|
|
|
|
BOOL TDbPolyPathEnt::IsValid() const
|
|
{
|
|
BOOL bRet=TDbEntity::IsValid();
|
|
if(!bRet)
|
|
return bRet;
|
|
XPoly2D polyPath;
|
|
AcGeVector3d normal;
|
|
GetPathPoly(polyPath,normal);
|
|
bRet=(polyPath.Length()>1);
|
|
return bRet;
|
|
}
|
|
|
|
// 提供对格式刷的支持
|
|
void TDbPolyPathEnt::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag)
|
|
{
|
|
assertWriteEnabled();
|
|
TDbEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag);
|
|
TDbPolyPathEnt *pSrc=TDbPolyPathEnt::cast(pSrcEntity);
|
|
if(pSrc) {
|
|
}
|
|
}
|
|
|
|
Acad::ErrorStatus
|
|
TDbPolyPathEnt::dwgInFields (AcDbDwgFiler* pFiler)
|
|
{
|
|
assertWriteEnabled();
|
|
Acad::ErrorStatus es = TDbEntity::dwgInFields(pFiler);
|
|
if(es != Acad::eOk) return es;
|
|
Adesk::UInt8 nVer;
|
|
pFiler->readItem(&nVer);
|
|
if(nVer>g_nVersion) {// Version is too new
|
|
return Acad::eMakeMeProxy;
|
|
}
|
|
pFiler->readItem(&m_idBind);
|
|
return pFiler->filerStatus();
|
|
}
|
|
|
|
Acad::ErrorStatus
|
|
TDbPolyPathEnt::dwgOutFields(AcDbDwgFiler* pFiler) const
|
|
{
|
|
assertReadEnabled();
|
|
Acad::ErrorStatus es = TDbEntity::dwgOutFields(pFiler);
|
|
if(es != Acad::eOk) return es;
|
|
|
|
pFiler->writeItem(g_nVersion);
|
|
pFiler->writeItem(m_idBind);
|
|
return pFiler->filerStatus();
|
|
}
|
|
|
|
Acad::ErrorStatus TDbPolyPathEnt::dxfInFields (AcDbDxfFiler* pFiler)
|
|
{
|
|
assertWriteEnabled();
|
|
Acad::ErrorStatus es= TDbEntity::dxfInFields(pFiler);
|
|
if(es!=Acad::eOk)
|
|
return es;
|
|
|
|
if (!pFiler->atSubclassData(_T("TDbPolyPathEnt"))) {
|
|
return Acad::eBadDxfSequence;
|
|
}
|
|
|
|
return pFiler->filerStatus();
|
|
|
|
// 不读入任何数据
|
|
}
|
|
|
|
Acad::ErrorStatus TDbPolyPathEnt::dxfOutFields(AcDbDxfFiler* pFiler) const
|
|
{
|
|
assertReadEnabled();
|
|
Acad::ErrorStatus es;
|
|
|
|
es = TDbEntity::dxfOutFields(pFiler);
|
|
assert(es == Acad::eOk);
|
|
|
|
es = pFiler->writeItem(AcDb::kDxfSubclass,_T("TDbPolyPathEnt"));
|
|
assert(es == Acad::eOk);
|
|
|
|
|
|
return es;
|
|
}
|
|
|
|
// -----------------------------------------------------------------------
|
|
|
|
|
|
Acad::ErrorStatus
|
|
TDbPolyPathEnt::subGetOsnapPoints(
|
|
AcDb::OsnapMode osnapMode,
|
|
INT_PTR gsSelectionMark,
|
|
const AcGePoint3d& ptPick,
|
|
const AcGePoint3d& lastPoint,
|
|
const AcGeMatrix3d& viewXform,
|
|
AcGePoint3dArray& snapPoints,
|
|
AcDbIntArray& geomIds) const
|
|
{
|
|
assertReadEnabled();
|
|
if(osnapMode==AcDb::kOsModeNode) {
|
|
XVector3D vtNormal=GetNormal();
|
|
XPoly2D polyPath;
|
|
AcGeVector3d normal;
|
|
GetPathPoly(polyPath,normal);
|
|
for(int i=0; i<polyPath.Length(); i++) {
|
|
snapPoints.append(Ecs2Wcs(*polyPath[i], vtNormal).AsAcGePoint3d());
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
return TDbEntity::subGetOsnapPoints(osnapMode, gsSelectionMark,
|
|
ptPick, lastPoint, viewXform, snapPoints, geomIds);
|
|
}
|
|
|
|
// Overriden functions for edit
|
|
// to do:
|
|
// 对于自定义柱子,应当允许通过夹点改变边界
|
|
Acad::ErrorStatus TDbPolyPathEnt::subGetGripPoints(AcGePoint3dArray& gripPoints,
|
|
AcDbIntArray& osnapModes,
|
|
AcDbIntArray& geomIds) const
|
|
{
|
|
assertReadEnabled();
|
|
AcGeVector3d vtNormal;
|
|
XPoly2D polyPath;
|
|
GetPathPoly(polyPath,vtNormal);
|
|
if(!IsBind()) {
|
|
int nVertexCount=polyPath.Length();
|
|
for(int i=0; i<nVertexCount; i++) {
|
|
XPoint ptWcs=Ecs2Wcs(*polyPath[i], vtNormal);
|
|
gripPoints.append(ptWcs);
|
|
}
|
|
//边上的夹点
|
|
int nEdgeNum=polyPath.TotalSegments();
|
|
for(i=0; i<nEdgeNum; i++) {
|
|
XCurveSegment seg;
|
|
polyPath.Nth(i, seg);
|
|
XPoint ptMid=Ecs2Wcs(seg.MidPoint(), vtNormal);
|
|
gripPoints.append(ptMid);
|
|
}
|
|
}
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
// stretch points is diffrent from grep points, with no midpoint included
|
|
Acad::ErrorStatus TDbPolyPathEnt::subGetStretchPoints(AcGePoint3dArray & stretchPoints) const
|
|
{
|
|
assertReadEnabled();
|
|
if(!IsBind()) {
|
|
AcGeVector3d vtNormal;
|
|
XPoly2D polyPath;
|
|
GetPathPoly(polyPath,vtNormal);
|
|
|
|
int nVertexCount=polyPath.Length();
|
|
for(int i=0; i<nVertexCount; i++) {
|
|
XPoint ptWcs=Ecs2Wcs(*polyPath[i], vtNormal);
|
|
stretchPoints.append(ptWcs);
|
|
}
|
|
}
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
void
|
|
TDbPolyPathEnt::GetLocalMatrix(const AcGeMatrix3d& xform, ads_matrix &mat) const
|
|
{
|
|
assertReadEnabled();
|
|
XVector3D vtNormal=GetNormal();
|
|
double nElev=0.0;
|
|
AcGeMatrix2d xform2d(xform.convertToLocal(vtNormal,nElev));
|
|
ads_matrix mat0={{xform2d(0,0), xform2d(0,1), 0, xform2d(0,2)},
|
|
{xform2d(1,0), xform2d(1,1), 0, xform2d(1,2)},
|
|
{0,0,1, nElev},
|
|
{0,0,0,1}};
|
|
memcpy(mat, mat0, sizeof(ads_matrix));
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////
|
|
// Active when being rotated, scaled, moved, etc.
|
|
Acad::ErrorStatus TDbPolyPathEnt::subTransformBy(const AcGeMatrix3d& xform)
|
|
{
|
|
assertWriteEnabled();
|
|
TDbEntity::subTransformBy(xform);
|
|
if(!IsBind()) {
|
|
AcGeVector3d vtNormal;
|
|
XPoly2D polyPath;
|
|
GetPathPoly(polyPath,vtNormal);
|
|
|
|
ads_matrix mat;
|
|
GetLocalMatrix(xform, mat);
|
|
double nElev=0.0;
|
|
AcGeMatrix2d xform2d(xform.convertToLocal(vtNormal,nElev));
|
|
((AcGeVector3d &)vtNormal).normalize();
|
|
for(int i=0; i<polyPath.Length(); i++)
|
|
polyPath[i]->TransformBy(mat);
|
|
|
|
// Modify on 2002/1/30 纠正弧段转角错误
|
|
if(IsMirrorMatrix(mat))
|
|
{
|
|
for(int m=0; m<polyPath.Length(); m++)
|
|
{
|
|
polyPath.SetBulge(m, -polyPath.GetBulge(m));
|
|
}
|
|
}
|
|
|
|
SetPathPoly(polyPath,vtNormal);
|
|
}
|
|
return Acad::eOk;
|
|
}
|
|
|
|
///////////////////////////////////////////
|
|
// 功能: 夹点操作
|
|
Acad::ErrorStatus TDbPolyPathEnt::subMoveGripPointsAt(
|
|
const AcDbIntArray& indices,
|
|
const AcGeVector3d& offset)
|
|
{
|
|
assertWriteEnabled();
|
|
if(IsBind())
|
|
return Acad::eOk;
|
|
|
|
XVector3D vtNormal;
|
|
XPoly2D polyPath;
|
|
GetPathPoly(polyPath,vtNormal);
|
|
|
|
int nVertexCount=polyPath.Length();
|
|
|
|
XPoint vtOffset=Wcs2Ecs(*(XPoint *)&offset, vtNormal);
|
|
for (int i = 0; i < indices.length(); i++) {
|
|
int idx = indices[i];
|
|
if(idx<nVertexCount) { // Move vertex
|
|
*polyPath[idx] += vtOffset;
|
|
} else { // Move Edge or Shape
|
|
XPoly2D poly2d(polyPath);
|
|
poly2d.SetElevation(0.0);
|
|
|
|
int nEdgeIndex=idx-nVertexCount;
|
|
int nTotalEdge=poly2d.TotalSegments();
|
|
if(nEdgeIndex<nTotalEdge) { //移动边
|
|
XDirectionCurve cv;
|
|
poly2d.Nth(nEdgeIndex, cv);
|
|
ASSERT(!!cv);
|
|
if(cv.Is(CURVE_LINE)) { // Move
|
|
XLine ln=cv.GetLine();
|
|
ln.StartPoint() += vtOffset;
|
|
ln.EndPoint() += vtOffset;
|
|
ln.SetLineFlag(LS_INFINITE);
|
|
XDirectionCurve prevSeg, nextSeg;
|
|
int nPrev=nEdgeIndex-1, nNext=nEdgeIndex+1;
|
|
if(poly2d.IsClosed()) {
|
|
nPrev=DePeriod(nTotalEdge, nPrev);
|
|
nNext=DePeriod(nTotalEdge, nNext);
|
|
}
|
|
|
|
XPoint ptStart, ptEnd;
|
|
BOOL bUpdateIt=TRUE;
|
|
//更新起点
|
|
if(nPrev>=0 && nPrev<nTotalEdge) {
|
|
poly2d.Nth(nPrev, prevSeg);
|
|
prevSeg.SetLineFlag(LS_INFINITE);
|
|
XPoint ptInt[2];
|
|
int nIntNum=prevSeg.Intersection(ln, ptInt[0], ptInt[1]);
|
|
if(nIntNum==1) ptStart=ptInt[0];
|
|
else if(nIntNum==2) {
|
|
ptStart=XLine(ptInt[0], ptInt[1]).NearPoint(ln.StartPoint());
|
|
} else bUpdateIt=FALSE;
|
|
} else {
|
|
ptStart = *poly2d[nEdgeIndex] + vtOffset;
|
|
}
|
|
|
|
// 更新下一点
|
|
if(nNext>=0 && nNext<nTotalEdge) {
|
|
poly2d.Nth(nNext, nextSeg);
|
|
nextSeg.SetLineFlag(LS_INFINITE);
|
|
XPoint ptInt[2];
|
|
int nIntNum=nextSeg.Intersection(ln, ptInt[0], ptInt[1]);
|
|
if(nIntNum==1) ptEnd=ptInt[0];
|
|
else if(nIntNum==2) {
|
|
ptEnd=XLine(ptInt[0], ptInt[1]).NearPoint(ln.EndPoint());
|
|
} else bUpdateIt=FALSE;
|
|
} else {
|
|
ptEnd = *poly2d[nEdgeIndex+1] + vtOffset;
|
|
}
|
|
|
|
if(bUpdateIt) {
|
|
double nPrevBulge=0.0, nNextBulge=0.0;
|
|
if(fabs(prevSeg.GetBulge())>1.0E-5) {
|
|
XArc prevArc=prevSeg.GetArc();
|
|
double nAngBeg=ads_angle(prevArc.GetCenterPt(), prevSeg.StartPoint());
|
|
double nAngEnd=ads_angle(prevArc.GetCenterPt(), ptStart);
|
|
if(prevSeg.IsMinusArc()) {
|
|
nPrevBulge=-CT_std_angle(nAngBeg-nAngEnd);
|
|
} else {
|
|
nPrevBulge=CT_std_angle(nAngEnd-nAngBeg);
|
|
}
|
|
}
|
|
if(fabs(nextSeg.GetBulge())>1.0E-5) {
|
|
XArc nextArc=nextSeg.GetArc();
|
|
double nAngBeg=ads_angle(nextArc.GetCenterPt(), ptEnd);
|
|
double nAngEnd=ads_angle(nextArc.GetCenterPt(), nextSeg.EndPoint());
|
|
if(nextSeg.IsMinusArc()) {
|
|
nNextBulge=-CT_std_angle(nAngBeg-nAngEnd);
|
|
} else {
|
|
nNextBulge=CT_std_angle(nAngEnd-nAngBeg);
|
|
}
|
|
}
|
|
|
|
*poly2d[nEdgeIndex] = ptStart;
|
|
if(nNext>=0 && nNext<poly2d.Length())
|
|
{
|
|
*poly2d[nNext] = ptEnd;
|
|
poly2d.SetBulge(nNext, nNextBulge);
|
|
}
|
|
if(nPrev>=0 && nPrev<poly2d.Length())
|
|
{
|
|
poly2d.SetBulge(nPrev, nPrevBulge);
|
|
}
|
|
|
|
}
|
|
|
|
} else { // Change Arc Segment--bulge
|
|
XPoint ptMid=cv.MidPoint();
|
|
XPoint ptMidNew= ptMid + vtOffset;
|
|
XArc arNew(cv.StartPoint(), ptMidNew, cv.EndPoint());
|
|
if(!!arNew) { //新的弧有效
|
|
XCurveSegment cvLine(cv.StartPoint(), cv.EndPoint(), 0.0);
|
|
int nSideOld=cvLine.OnWhichSide(ptMid);
|
|
int nSideNew=cvLine.OnWhichSide(ptMidNew);
|
|
double nSignal=cv.GetBulge()/fabs(cv.GetBulge());
|
|
if(nSideOld==nSideNew)
|
|
{
|
|
poly2d.SetBulge(nEdgeIndex, nSignal*arNew.Bulge());
|
|
}
|
|
else
|
|
{
|
|
poly2d.SetBulge(nEdgeIndex, -nSignal*arNew.Bulge());
|
|
}
|
|
}
|
|
}
|
|
|
|
for(int n=0; n<poly2d.Length(); n++) {
|
|
poly2d[n]->z = polyPath[n]->z;
|
|
}
|
|
polyPath = poly2d;
|
|
}
|
|
}
|
|
}
|
|
SetPathPoly(polyPath,vtNormal);
|
|
return Acad::eOk;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////
|
|
// 功能: 夹点操作
|
|
Acad::ErrorStatus TDbPolyPathEnt::subMoveStretchPointsAt(
|
|
const AcDbIntArray& indices,
|
|
const AcGeVector3d& offset)
|
|
{
|
|
assertWriteEnabled();
|
|
if(IsBind())
|
|
return Acad::eOk;
|
|
AcGeVector3d vtNormal;
|
|
XPoly2D polyPath;
|
|
GetPathPoly(polyPath,vtNormal);
|
|
|
|
int nVertexCount=polyPath.Length();
|
|
|
|
XPoint vtOffset=Wcs2Ecs(*(XPoint *)&offset, vtNormal);
|
|
for (int i = 0; i < indices.length(); i++) {
|
|
int idx = indices[i];
|
|
if(idx<nVertexCount) // Move vertex
|
|
*polyPath[idx] += vtOffset;
|
|
}
|
|
SetPathPoly(polyPath,vtNormal);
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
|
|
|
|
|
|
// 取得夹点说明
|
|
Acad::ErrorStatus TDbPolyPathEnt::GetGripText(int idx, CString &cs) const
|
|
{
|
|
assertReadEnabled();
|
|
Acad::ErrorStatus es=Acad::eNotApplicable;
|
|
if(IsBind())
|
|
return Acad::eNotApplicable;
|
|
|
|
XPoly2D polyPath;
|
|
AcGeVector3d normal;
|
|
GetPathPoly(polyPath,normal);
|
|
int nVertexCount=polyPath.Length();
|
|
if(idx<nVertexCount) { // Move vertex
|
|
cs.Format(_T("移动第%d个顶点"), idx+1);
|
|
es = Acad::eOk;
|
|
} else { // Move Edge or Shape
|
|
int nEdgeIndex=idx-nVertexCount;
|
|
int nTotalEdge=polyPath.TotalSegments();
|
|
if(nEdgeIndex<nTotalEdge) { //移动边
|
|
cs.Format(_T("移动第%d条边"), nEdgeIndex+1);
|
|
es = Acad::eOk;
|
|
}
|
|
}
|
|
|
|
return es;
|
|
}
|
|
|
|
|
|
|
|
|
|
Acad::ErrorStatus
|
|
TDbPolyPathEnt::subDeepClone(AcDbObject* pOwner,
|
|
AcDbObject*& pClonedObject,
|
|
AcDbIdMapping& idMap,
|
|
Adesk::Boolean isPrimary) const
|
|
{
|
|
Acad::ErrorStatus es=TDbEntity::subDeepClone(pOwner, pClonedObject, idMap, isPrimary);
|
|
if(es!=Acad::eOk || !m_idBind)
|
|
return es;
|
|
|
|
TDbPolyPathEnt *pClonedEnvelop = TDbPolyPathEnt::cast(pClonedObject);
|
|
ASSERT(pClonedEnvelop);
|
|
pClonedEnvelop->m_idBind = AcDbObjectId::kNull;
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
|
|
|
|
/* ----------------------------------------------------------------------- */
|
|
//////////////////////////////////////////////////////////////////////
|
|
// derived from AcDbObject, Reactor的唤醒函数
|
|
|
|
// INSERT实体要被删除/恢复
|
|
void TDbPolyPathEnt::erased(const AcDbObject* pDbObj, Adesk::Boolean erasing)
|
|
{
|
|
if(pDbObj->objectId()==m_idBind && !isWriteEnabled() && isNotifyEnabled()) {
|
|
Adesk::Boolean wasWritable;
|
|
VERIFY(upgradeFromNotify(wasWritable)==Acad::eOk);
|
|
assertWriteEnabled();
|
|
m_idBind=NULL;
|
|
//erase(erasing);
|
|
//UnBind();
|
|
VERIFY(downgradeToNotify(wasWritable)==Acad::eOk);
|
|
}
|
|
}
|
|
|
|
// 绊定的实体发生变化
|
|
void TDbPolyPathEnt::modified(const AcDbObject* pDbObj)
|
|
{
|
|
if(pDbObj->objectId()==m_idBind && !isWriteEnabled() && isNotifyEnabled()) {
|
|
const TEntityBase *pMaster = TEntityBase::Cast(pDbObj);
|
|
if(pMaster) {
|
|
Adesk::Boolean wasWritable;
|
|
VERIFY(upgradeFromNotify(wasWritable)==Acad::eOk);
|
|
assertWriteEnabled();
|
|
XPoly2D polyPath;
|
|
AcGeVector3d normal;
|
|
pMaster->GetBindPath(polyPath,normal);
|
|
SetPathPoly(polyPath,normal);
|
|
VERIFY(downgradeToNotify(wasWritable)==Acad::eOk);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
TDbPolyPathEnt::UnBind()
|
|
{
|
|
assertWriteEnabled();
|
|
AcDbObjectId id=objectId();
|
|
if(!!m_idBind) {
|
|
OPENOBJ_BEGIN(m_idBind, AcDb::kForWrite, AcDbEntity, pEnt);
|
|
if(pEnt) {
|
|
if(!!id)
|
|
pEnt->removePersistentReactor(id);
|
|
m_idBind=AcDbObjectId::kNull;
|
|
}
|
|
OPENOBJ_END();
|
|
}
|
|
}
|
|
|
|
// 把当前目标绊定到一个对象上
|
|
// 注意: 目前仅用坡屋顶来绊定
|
|
Acad::ErrorStatus
|
|
TDbPolyPathEnt::SetBindObject(const AcDbObjectId &id)
|
|
{
|
|
assertWriteEnabled();
|
|
|
|
OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbEntity, pEnt);
|
|
|
|
const TEntityBase *pMaster = TEntityBase::Cast(pEnt);
|
|
if(pEnt==NULL || !objectId())
|
|
return Acad::eInvalidInput;
|
|
|
|
XPoly2D polyPath;
|
|
AcGeVector3d normal;
|
|
pMaster->GetBindPath(polyPath,normal);
|
|
SetPathPoly(polyPath,normal);
|
|
m_idBind = id;
|
|
pEnt->addPersistentReactor(objectId());
|
|
OPENOBJ_END();
|
|
|
|
return Acad::eOk;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
XVector3D
|
|
TDbPolyPathEnt::GetNormal() const
|
|
{
|
|
return XVector3D(0,0,1);
|
|
}
|
|
|
|
|
|
AcDbObjectId
|
|
TDbPolyPathEnt::GetBindObjectId() const
|
|
{
|
|
assertReadEnabled();
|
|
return m_idBind;
|
|
}
|
|
|
|
BOOL
|
|
TDbPolyPathEnt::IsBind() const
|
|
{
|
|
assertReadEnabled();
|
|
return (!!m_idBind);
|
|
}
|
|
|
|
|
|
void
|
|
TDbPolyPathEnt::SetNormal(const XVector3D &vtNormal)
|
|
{
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
TDbPolyPathEnt::SetElevationAt(int idx, double nElev)
|
|
{
|
|
assertWriteEnabled();
|
|
XPoly2D polyPath;
|
|
AcGeVector3d normal;
|
|
GetPathPoly(polyPath,normal);
|
|
ASSERT(idx>=0 && idx<polyPath.Length());
|
|
polyPath[idx]->z=nElev;
|
|
SetPathPoly(polyPath,normal);
|
|
}
|
|
|
|
void
|
|
TDbPolyPathEnt::SetSweepAngleAt(int idx, double nAng)
|
|
{
|
|
assertWriteEnabled();
|
|
XPoly2D polyPath;
|
|
AcGeVector3d normal;
|
|
GetPathPoly(polyPath,normal);
|
|
ASSERT(idx>=0 && idx<polyPath.Length());
|
|
polyPath.SetBulge(idx, nAng);
|
|
SetPathPoly(polyPath,normal);
|
|
}
|
|
|
|
double
|
|
TDbPolyPathEnt::GetElevationAt(int idx) const
|
|
{
|
|
assertReadEnabled();
|
|
XPoly2D polyPath;
|
|
AcGeVector3d normal;
|
|
GetPathPoly(polyPath,normal);
|
|
ASSERT(idx>=0 && idx<polyPath.Length());
|
|
return polyPath[idx]->z;
|
|
}
|
|
|
|
double
|
|
TDbPolyPathEnt::GetSweepAngleAt(int idx) const
|
|
{
|
|
assertReadEnabled();
|
|
XPoly2D polyPath;
|
|
AcGeVector3d normal;
|
|
GetPathPoly(polyPath,normal);
|
|
ASSERT(idx>=0 && idx<polyPath.Length());
|
|
return polyPath.GetBulge(idx);
|
|
}
|
|
|
|
BOOL
|
|
TDbPolyPathEnt::GetClosestPoint2d(const XPoint &ptTest, XPoint &ptOnCurve) const
|
|
{
|
|
assertReadEnabled();
|
|
AcDbPolyline pline;
|
|
XPoly2D poly2d;
|
|
AcGeVector3d normal;
|
|
GetPathPoly(poly2d,normal);
|
|
poly2d.SetElevation(0.0);
|
|
PolyConvert(poly2d, pline);
|
|
XPoint pt2d=ptTest;
|
|
pt2d.z=0;
|
|
return (pline.getClosestPointTo(pt2d, ptOnCurve)==Acad::eOk);
|
|
}
|
|
|
|
|
|
BOOL
|
|
TDbPolyPathEnt::AddVertex(const XPoint &ptAdd)
|
|
{
|
|
assertWriteEnabled();
|
|
XPoly2D polyPath;
|
|
AcGeVector3d normal;
|
|
GetPathPoly(polyPath,normal);
|
|
XPoint ptOnCurve;
|
|
if(GetClosestPoint2d(ptAdd, ptOnCurve)) {
|
|
int nPos=HitTestOnBase2d(ptOnCurve);
|
|
if(nPos<0) {
|
|
nPos = abs(nPos);
|
|
nPos--;
|
|
XPoly2D poly2d(polyPath);
|
|
poly2d.SetElevation(0.0);
|
|
|
|
XDirectionCurve seg;
|
|
poly2d.Nth(nPos, seg);
|
|
if(seg.IsMinusArc()) {
|
|
XArc ar1=seg.GetArc(), ar2=seg.GetArc();
|
|
ar1.SetAngleByPoints(seg.EndPoint(), ptOnCurve);
|
|
ar2.SetAngleByPoints(ptOnCurve, seg.StartPoint());
|
|
ptOnCurve.z = polyPath[nPos]->z;
|
|
polyPath.SetBulge(nPos, - ar2.Bulge());
|
|
polyPath.InsertNodeAt(nPos+1, ptAdd, ar1.Bulge());
|
|
} else {
|
|
XCurveSegment seg1=seg, seg2=seg;
|
|
seg1.SetPoints(seg.StartPoint(), ptOnCurve);
|
|
seg2.SetPoints(ptOnCurve, seg.EndPoint());
|
|
ptOnCurve.z = polyPath[nPos]->z;
|
|
polyPath.SetBulge(nPos, seg1.GetBulge());
|
|
polyPath.InsertNodeAt(nPos+1, ptAdd, seg2.GetBulge());
|
|
}
|
|
SetPathPoly(polyPath,normal);
|
|
return TRUE;
|
|
} else if(nPos>0 && ptOnCurve!=ptAdd){
|
|
nPos--;
|
|
if(nPos==0) {
|
|
polyPath[nPos];
|
|
polyPath.InsertNodeAt(nPos, ptAdd);
|
|
} else {
|
|
polyPath.AppendNode(ptAdd);
|
|
}
|
|
SetPathPoly(polyPath,normal);
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
BOOL
|
|
TDbPolyPathEnt::RemoveVertexAt(int nPos)
|
|
{
|
|
assertWriteEnabled();
|
|
XPoly2D polyPath;
|
|
AcGeVector3d normal;
|
|
GetPathPoly(polyPath,normal);
|
|
ASSERT(nPos>=0 && nPos<polyPath.Length());
|
|
polyPath.Remove(nPos);
|
|
polyPath.RemoveBugle(nPos);
|
|
SetPathPoly(polyPath,normal);
|
|
return TRUE;
|
|
}
|
|
|
|
// >0 命中顶点; <0 命中边; 0--没有命中
|
|
// abs(nRet)-1 为命中目标序号
|
|
int
|
|
TDbPolyPathEnt::HitTestOnBase2d(const XPoint &ptTest, double nTol) const
|
|
{
|
|
assertReadEnabled();
|
|
XPoly2D polyPath;
|
|
AcGeVector3d normal;
|
|
GetPathPoly(polyPath,normal);
|
|
XPoint pt2d=ptTest;
|
|
pt2d.z=0;
|
|
/*
|
|
for(int i=0; i<polyPath.Length(); i++) {
|
|
if(pt2d.Distance2d(*polyPath[i])<nTol)
|
|
return (i+1);
|
|
}
|
|
XPushPrec vTemp(nTol, _angSnap);
|
|
int nEdgeNum=polyPath.TotalSegments();
|
|
for(i=0; i<nEdgeNum; i++) {
|
|
XCurveSegment seg;
|
|
polyPath.Nth(i, seg);
|
|
seg.SetElevation(0.0);
|
|
if((pt2d&seg)==PR_INSIDE)
|
|
return (-i-1);
|
|
}
|
|
return 0;
|
|
*/
|
|
return polyPath.HitTestOnCurve(pt2d, nTol);
|
|
}
|
|
|
|
|
|
|
|
void InitDbPolyPathEnt(BOOL bTrue)
|
|
{
|
|
if(bTrue) {
|
|
TDbPolyPathEnt::rxInit();
|
|
//TDbPolyPathEnt::SetEditMethod(EditPolyPathEnt0);
|
|
} else {
|
|
deleteAcRxClass(TDbPolyPathEnt::desc());
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|