//-------------------------------------------------------------------------------------------------------+ // Copyright (C), 1998-2007, SH Software Co. Ltd. // = FileName : AecDbPolyCurveEnt.cpp // = Version : ver2.0 // = Author : zjq // = CreateDate : 2002-09-09 // = Description: 路径曲线类的定义 // = Maintainers: // //-------------------------------------------------------------------------------------------------------+ #include "StdAfx.h" #include "AecDbPolyCurveEnt.h" #include "XArc.h" #include "XDbObject.h" #include "XArchMatchProp.h" #include "XGlobalFunc.h" #include "XGlobalCurveFunc.h" #include "XPrivateGlobalFunc.h" #include "XDirectionCurve.h" ACRX_DXF_DEFINE_MEMBERS(AecDbPolyCurveEnt,AecCurveEntity, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, AEC_DBPOLY_CURVE,"AEC_KERNAL|缺乏解释器图形看不见, 请下载插件"); IMPLEMENT_TENTBASE(AecDbPolyCurveEnt); const Adesk::UInt8 AecDbPolyCurveEnt::g_nVersion = 0; AecDbPolyCurveEnt::AecDbPolyCurveEnt() : m_vtNormal(0,0,1) { } AecDbPolyCurveEnt::~AecDbPolyCurveEnt() { } double AecDbPolyCurveEnt::GetElevationAt(int idx) const { return m_polyBase[idx].z; } double AecDbPolyCurveEnt::GetSweepAngleAt(int idx) const { return m_polyBase.GetBulge(idx); } AcGeVector3d AecDbPolyCurveEnt::GetNormal()const { assertReadEnabled(); return m_vtNormal; } void AecDbPolyCurveEnt::SetSweepAngleAt(int idx,double da) { assertWriteEnabled(); m_polyBase.SetBulge(idx, da); } void AecDbPolyCurveEnt::SetElevationAt(int idx,double de) { assertWriteEnabled(); m_polyBase[idx]->z = de; } void AecDbPolyCurveEnt::SetNormal(AcGeVector3d vt) { assertWriteEnabled(); m_vtNormal = vt; } int AecDbPolyCurveEnt::GetFirstVersion()const { return 7; } void AecDbPolyCurveEnt::GetTips(DList &lstInfo) const { } Acad::ErrorStatus AecDbPolyCurveEnt::GetPathPoly(XPoly2D &polyPath,AcGeVector3d&normal)const { assertReadEnabled(); polyPath = m_polyBase; normal = m_vtNormal; return Acad::eOk; } Acad::ErrorStatus AecDbPolyCurveEnt::SetPathPoly(const XPoly2D &polyPath,const AcGeVector3d&normal) { assertWriteEnabled(); m_polyBase = polyPath; m_vtNormal = normal; return Acad::eOk; } BOOL AecDbPolyCurveEnt::IsValid() const { BOOL bRet = AecCurveEntity::IsValid(); if (!bRet) { return bRet; } bRet = (m_polyBase.Length() > 1); return bRet; } // 提供对格式刷的支持 void AecDbPolyCurveEnt::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag) { assertWriteEnabled(); AecCurveEntity::CopyPropertiesFrom(pSrcEntity, gMatchFlag); AecDbPolyCurveEnt *pSrc = AecDbPolyCurveEnt::cast(pSrcEntity); if (pSrc) { } } Acad::ErrorStatus AecDbPolyCurveEnt::dwgInFields (AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = AecCurveEntity::dwgInFields(pFiler); if (es != Acad::eOk) { return es; } Adesk::UInt8 nVer; pFiler->readItem(&nVer); if (nVer > g_nVersion) { return Acad::eMakeMeProxy; } pFiler->readItem(&m_idBind); m_polyBase.Reset(); Adesk::UInt16 m_nCount = 0; pFiler->readItem(&m_nCount); for (Adesk::UInt16 i = 0; i < m_nCount; i++) { AcGePoint3d pt; double nBulge = 0.0; pFiler->readItem(&pt); pFiler->readItem(&nBulge); m_polyBase.AppendNode(XPoint(pt), nBulge); } int nFlag = m_polyBase.GetFlag(); pFiler->readItem(&nFlag); m_polyBase.SetFlag(nFlag); pFiler->readItem(&m_vtNormal); return pFiler->filerStatus(); } Acad::ErrorStatus AecDbPolyCurveEnt::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = AecCurveEntity::dwgOutFields(pFiler); if (es != Acad::eOk) { return es; } pFiler->writeItem(g_nVersion); pFiler->writeItem(m_idBind); Adesk::UInt16 nCount = m_polyBase.Length(); pFiler->writeItem(nCount); for (Adesk::UInt16 i = 0; i < nCount; i++) { pFiler->writeItem((AcGePoint3d &)m_polyBase[i]); pFiler->writeItem(m_polyBase.GetBulge(i)); } //modify by zjq on 100413 pFiler->writeItem(m_polyBase.GetFlag()); pFiler->writeItem(m_vtNormal); return pFiler->filerStatus(); } Acad::ErrorStatus AecDbPolyCurveEnt::dxfInFields (AcDbDxfFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = AecCurveEntity::dxfInFields(pFiler); if (es != Acad::eOk) { return es; } if (!pFiler->atSubclassData(_T("AecDbPolyCurveEnt"))) { return Acad::eBadDxfSequence; } resbuf rb; DList pts; DList bulges; int flag = -1; XPoint vt(0,0,1); while ((es == Acad::eOk) && ((es = pFiler->readResBuf(&rb)) == Acad::eOk)) { switch (rb.restype) { case AcDb::kDxfXCoord: pts.Append(new XPoint(rb.resval.rpoint)); break; case AcDb::kDxfAngle: bulges.Append(new double(rb.resval.rreal)); break; case AcDb::kDxfNormalX: vt = rb.resval.rpoint; break; case AcDb::kDxfInt16: flag = rb.resval.rint; break; default: // 未识别组抛出,让子类读 pFiler->pushBackItem(); es = Acad::eEndOfFile; break; } } if (flag == -1) { return Acad::eMissingDxfField; } if(pts.Length() < 2 || pts.Length() != bulges.Length()) { pFiler->setError(_T("\nError DXF group code: 10, 50")); return Acad::eMissingDxfField; } m_polyBase.Reset(); m_polyBase.SetFlag(flag); for (int i = 0; i < pts.Length(); i++) { m_polyBase.AppendNode(*pts[i], *bulges[i]); } m_vtNormal = vt; return pFiler->filerStatus(); } Acad::ErrorStatus AecDbPolyCurveEnt::dxfOutFields(AcDbDxfFiler* pFiler) const { assertReadEnabled(); AecCurveEntity::dxfOutFields(pFiler); pFiler->writeItem(AcDb::kDxfSubclass,_T("AecDbPolyCurveEnt")); for (int i = 0; i < m_polyBase.Length(); i++) { pFiler->writePoint3d(AcDb::kDxfXCoord, m_polyBase[i]); pFiler->writeDouble(AcDb::kDxfAngle, m_polyBase.GetBulge(i)); } pFiler->writeItem(AcDb::kDxfInt16,(Adesk::Int16)m_polyBase.GetFlag()); pFiler->writeVector3d(AcDb::kDxfNormalX, m_vtNormal); return pFiler->filerStatus(); } #if (ADS > 15 && ADS < 18) Acad::ErrorStatus AecDbPolyCurveEnt::subGetOsnapPoints(AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const { assertReadEnabled(); if (g_bSnapCurveBase && osnapMode == AcDb::kOsModeEnd) { for (long i = 0; i < m_polyBase.Length(); i++) { AcGePoint3d pt = Ecs2Wcs(m_polyBase[i], m_vtNormal).AsAcGePoint3d(); snapPoints.append(pt); } return Acad::eOk; } return AecCurveEntity::subGetOsnapPoints(osnapMode,gsSelectionMark, pickPoint, lastPoint,viewXform,snapPoints,geomIds); } Acad::ErrorStatus AecDbPolyCurveEnt::subGetOsnapPoints(AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds, const AcGeMatrix3d& insertionMat) const { #if ARX<16 return Acad::eNotImplemented; #else return subGetOsnapPoints(osnapMode,gsSelectionMark, pickPoint, lastPoint,viewXform,snapPoints,geomIds); #endif } #endif Acad::ErrorStatus AecDbPolyCurveEnt::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { assertReadEnabled(); if (!IsBind())//绑定后没有夹点 { AcGeVector3d v(GetNormal()); XExport2::GetGripPoints(m_polyBase,v,gripPoints); } return Acad::eOk; } Acad::ErrorStatus AecDbPolyCurveEnt::subGetStretchPoints(AcGePoint3dArray &stretchPoints) const { assertReadEnabled(); if (!IsBind()) { return AecCurveEntity::subGetStretchPoints(stretchPoints); } return Acad::eOk; } // 功能: 夹点操作 Acad::ErrorStatus AecDbPolyCurveEnt::subMoveGripPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); AcGeVector3d v(GetNormal()); return XExport2::MoveGripPointsAt(m_polyBase,v,indices,offset); } Adesk::Boolean AecDbPolyCurveEnt::subWorldDraw(AcGiWorldDraw* pWd) { if (isA() == AecDbPolyCurveEnt::desc()) { AcDbCurve *pCurve = GetBaseCurve(); if (pCurve != NULL) { pCurve->setDatabaseDefaults(); pWd->geometry().draw(pCurve); delete pCurve; return Adesk::kTrue; } } return AecCurveEntity::subWorldDraw(pWd); } Acad::ErrorStatus AecDbPolyCurveEnt::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); 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); } 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 AecDbPolyCurveEnt::GetGripText(int idx, CString &cs) const { assertReadEnabled(); return XExport2::GetGripText(m_polyBase,idx,cs); } AcDbCurve* AecDbPolyCurveEnt::GetBaseCurve()const { assertReadEnabled(); AcDbCurve* pCurve = m_polyBase.AsAcDbCurve(); if (pCurve != NULL) { AcGeMatrix3d mat; mat.setToPlaneToWorld(GetNormal()); pCurve->transformBy(mat); } return pCurve; } Acad::ErrorStatus AecDbPolyCurveEnt::SetBaseCurve(AcDbCurve*pCurve) { assertWriteEnabled(); AcGeMatrix3d mat; mat.setToWorldToPlane(GetNormal()); AcDbCurve *pCurve1 = (AcDbCurve*)pCurve->clone(); pCurve1->transformBy(mat); if (m_polyBase.SetAcDbCurve(pCurve1)) { delete pCurve1; return Acad::eOk; } else { delete pCurve1; return Acad::eNotImplementedYet; } } #if ARX > 17 void AecDbPolyCurveEnt::CreateGrip() { if (IsBind()) { return; } AecCurveEntity::CreateGrip(); ::CreateGrip(this,m_polyBase,0); } Acad::ErrorStatus AecDbPolyCurveEnt::EntityToDim(long iGrip,long iDim,const AcDbEntity*pEnt) { AEntityBase *pCurve = AecDbPolyCurveEnt::cast(pEnt); if (pCurve == NULL) { pCurve=this; } XPoly2D polyPath; AcGeVector3d normal; pCurve->GetPathPoly(polyPath,normal); return ::EntityToDim(this,polyPath,iGrip,iDim,0); } Acad::ErrorStatus AecDbPolyCurveEnt::DimToEntity(long iGrip,long iDim,double newValue,const AcGeVector3d& offset) { assertWriteEnabled(); AecDbPolyCurveEnt curve; curve.CopyPropertiesFrom(this,0); Acad::ErrorStatus es = XExport2::DimToEntity(this,m_polyBase,iGrip,iDim,newValue,offset,0); if (es == Acad::eOk && !IsValid()) { CopyPropertiesFrom(&curve,0); return Acad::eInvalidInput; } return es; } #endif Acad::ErrorStatus AecDbPolyCurveEnt::subDeepClone(AcDbObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary) const { Acad::ErrorStatus es = AecCurveEntity::subDeepClone(pOwner, pClonedObject, idMap, isPrimary); if (es != Acad::eOk || !m_idBind) { return es; } AecDbPolyCurveEnt *pClonedEnvelop = AecDbPolyCurveEnt::cast(pClonedObject); ASSERT(pClonedEnvelop); pClonedEnvelop->m_idBind = AcDbObjectId::kNull; return Acad::eOk; } // INSERT实体要被删除/恢复 void AecDbPolyCurveEnt::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; VERIFY(downgradeToNotify(wasWritable) == Acad::eOk); } } // 绊定的实体发生变化 void AecDbPolyCurveEnt::modified(const AcDbObject* pDbObj) { if (pDbObj->objectId() == m_idBind && !isWriteEnabled() && isNotifyEnabled()) { const AEntityBase *pMaster = AEntityBase::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 AecDbPolyCurveEnt::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 AecDbPolyCurveEnt::SetBindObject(const AcDbObjectId &id) { assertWriteEnabled(); OPENOBJ_BEGIN(id, AcDb::kForWrite, AcDbEntity, pEnt); const AEntityBase *pMaster = AEntityBase::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; } AcDbObjectId AecDbPolyCurveEnt::GetBindObjectId() const { assertReadEnabled(); return m_idBind; } BOOL AecDbPolyCurveEnt::IsBind() const { assertReadEnabled(); return (!!m_idBind); } BOOL AecDbPolyCurveEnt::GetClosestPoint2d(const XPoint &ptTest, XPoint &ptOnCurve) const { assertReadEnabled(); AcDbPolyline pline; XPoly2D poly2d = m_polyBase; poly2d.SetElevation(0.0); PolyConvert(poly2d, pline); XPoint pt2d = ptTest; pt2d.z = 0; return (pline.getClosestPointTo(pt2d, ptOnCurve) == Acad::eOk); } BOOL AecDbPolyCurveEnt::AddVertex(const XPoint &ptAdd) { assertWriteEnabled(); XPoly2D polyPath = m_polyBase; 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()); } m_polyBase = polyPath; return TRUE; } else if (nPos > 0 && ptOnCurve != ptAdd) { nPos--; if (nPos == 0) { polyPath[nPos]; polyPath.InsertNodeAt(nPos, ptAdd); } else { polyPath.AppendNode(ptAdd); } m_polyBase = polyPath; return TRUE; } } return FALSE; } BOOL AecDbPolyCurveEnt::RemoveVertexAt(int nPos) { assertWriteEnabled(); m_polyBase.Remove(nPos); m_polyBase.RemoveBugle(nPos); if (m_polyBase.Length() < 3) { m_polyBase.SetFlag(0); } return TRUE; } // >0 命中顶点; <0 命中边; 0--没有命中 // abs(nRet)-1 为命中目标序号 int AecDbPolyCurveEnt::HitTestOnBase2d(const XPoint &ptTest, double nTol) const { assertReadEnabled(); XPoint pt2d = ptTest; pt2d.z = 0; return m_polyBase.HitTestOnCurve(pt2d, nTol); } void AecDbPolyCurveEnt::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)); } void InitDbPolyCurveEnt(BOOL bTrue) { if (bTrue) { AecDbPolyCurveEnt::rxInit(); acrxBuildClassHierarchy(); AecDbPolyCurveEnt::InitMatchProtocol(TRUE); } else { AecDbPolyCurveEnt::InitMatchProtocol(FALSE); deleteAcRxClass(AecDbPolyCurveEnt::desc()); } }