#include "stdafx.h" #include "TDbColumn.h" #include "TDbWallPatch.h" inline CString DoubleToString(double dValue, int nPreci) { CString csRet; CString csFormat; csFormat.Format(_T("%%.%df"), nPreci); csRet.Format(csFormat, dValue); return csRet; } const Adesk::UInt8 TDbApron::g_nVersion = 1; ACRX_DXF_DEFINE_MEMBERS(ATSApron, ATSPolyCurveEnt, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_APRON, "ATS_APRON图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(TDbApron); ////////////////////////////////////////////////////////////////////// TDbApron::TDbApron() { m_dInHeight = _AS_SYS_UNIT(20); m_dOutHeight = _AS_SYS_UNIT(10); m_nFlag = 0; } TDbApron::~TDbApron() { ReleaseEntSet(m_entSet); // sg add 090521,释放掉外边界点 } ////////////////////////////////////////////////////////////////////// void TDbApron::SetInHeight(double dHeight) { assertWriteEnabled(); m_dInHeight = dHeight; } double TDbApron::GetInHeight() const { assertReadEnabled(); return m_dInHeight; } void TDbApron::SetOutHeight(double dHeight) { assertWriteEnabled(); m_dOutHeight = dHeight; } double TDbApron::GetOutHeight() const { assertReadEnabled(); return m_dOutHeight; } void TDbApron::SetDistArray(const Array &aryDist) { assertWriteEnabled(); m_aryDist = aryDist; } void TDbApron::GetDistArray(Array &aryDist) const { assertReadEnabled(); aryDist = m_aryDist; } ////////////////////////////////////////////////////////////////////// int TDbApron::GetDistNum() const { return m_aryDist.GetLength(); } void TDbApron::SetAllDists(double dDist, long lLength) { assertWriteEnabled(); if (GetDistNum() != 0) { m_aryDist.Clear(); // 首先清空 } if (lLength == -1) // 使用路径的段数 { lLength = m_polyBase.TotalSegments(); } m_aryDist.Realloc(lLength); m_aryDist.SetAll(dDist); } BOOL TDbApron::SetDistAt(long lIndex, double dDist) { assertWriteEnabled(); int nLength = GetDistNum(); if (lIndex<0 || lIndex>nLength-1) { return FALSE; } m_aryDist.SetAt(lIndex, dDist); return TRUE; } double TDbApron::GetDistAt(long lIndex) const { int nLength = GetDistNum(); if (lIndex<0 || lIndex>nLength-1) { return -1; } return m_aryDist.GetAt(lIndex); } BOOL TDbApron::InsertDistAt(long lIndex, double dDist) { if (lIndex < 0) { return FALSE; } int nLength = GetDistNum(); if (lIndex >= nLength) // 超过数组长度,不考虑位置,在最后添加 { m_aryDist.AddTail(dDist); } else // 在指定位置插入宽度值 { m_aryDist.Insert(lIndex, dDist); } int nSegNum = m_polyBase.TotalSegments(); if (nSegNum==3 && nLength==1 && m_polyBase.IsClosed()) { m_aryDist.AddTail(dDist); // 注:此情况下,需要增加两段 } return TRUE; } BOOL TDbApron::RemoveDistAt(long lIndex) { int nLength = GetDistNum(); if (lIndex<0 || lIndex>=nLength) { return FALSE; } m_aryDist.Del(lIndex); int nSegNum = m_polyBase.TotalSegments(); if (nSegNum==1 && nLength==3) { m_aryDist.DelTail(); // 注:此情况下,需要删除两段 } return TRUE; } ////////////////////////////////////////////////////////////////////// void TDbApron::Get2DInPoly(XPoly2D &poly2d) const { assertReadEnabled(); poly2d = m_polyBase; poly2d.SetElevation(0); } // aryIndex:polyBase的各顶点对应poly2d的顶点编号 // aryShow:polyBase的各线段对应poly2d的线段编号 BOOL TDbApron::Get2DOutPoly(XPoly2D &poly2d, Array &aryIndex, Array &aryShow) const { assertReadEnabled(); XPoly2D polyBase; // 内侧路径点 Get2DInPoly(polyBase); int nDistNum = GetDistNum(), // “宽度”数组数量 nSegNum = polyBase.TotalSegments(); // “段”数 if (nDistNum!=nSegNum || !IsValid()) return FALSE; double dDist = m_aryDist.GetAt(0); polyBase.QuickOffset(dDist, poly2d); // 首先快速生成一个外侧路径poly2d int nTmp = poly2d.TotalSegments(); if (nTmp != nSegNum) // sg add 090522,当内侧路径有重合时,快速生成的路径数量和原来不一致,导致致命错误 return FALSE; aryIndex.Realloc(polyBase.Length()); // sg add 081013,与内侧顶点对应的外侧顶点编号 aryIndex.SetAll(0); aryShow.Realloc(nDistNum); // 与内侧段对应的外侧段编号 aryShow.SetAll(0); // 以polyBase中的“段”为单位进行循环,对poly2d、aryIndex、aryShow进行修改 for (int i=0, j=0; i=0 && nPrev _DIST_SNAP) // 两个偏移后的点不重合,需要加点 { if (i == 0) // sg add 090602,解决首顶点处宽度不一致时,产生错误的情况 *poly2d[j] = pt2; poly2d.SetBulge(j, 0); // 与新增加的点,直线连接 poly2d.InsertNodeAt(++j, pt1, cvBase.GetBulge()); } if (fabs(cvBase.GetBulge())<1.0E-5 && fabs(cvPrev.GetBulge())<1.0E-5) // 两直线 { if (m_aryDist.GetAt(i) > m_aryDist.GetAt(nPrev) + 1.0E-5) { nIndex++; // pt1离cvBase.StartPoint()较远 } } else // 有弧线 { BOOL bSwap(FALSE); // 标记是否有弧段反向 XPoint ptArcStart, ptArcEnd; if (fabs(cvBase.GetBulge()) > 1.0E-5) // 当前段是弧段 { XArc arc = cvBase.GetArc(); arc.GetStartPoint(ptArcStart); arc.GetEndPoint(ptArcEnd); bSwap = ptArcStart.Distance(cvPrev.EndPoint()) > _DIST_SNAP; // 弧段反向 } if (!bSwap && fabs(cvPrev.GetBulge())>1.0E-5) // 前一段是弧段 { XArc arc = cvPrev.GetArc(); arc.GetStartPoint(ptArcStart); arc.GetEndPoint(ptArcEnd); bSwap = ptArcEnd.Distance(cvBase.StartPoint()) > _DIST_SNAP; } if (bSwap) // 有弧线产生了反向 { nIndex = -1; // 不绘制“转角线” } else if (m_aryDist.GetAt(i) > m_aryDist.GetAt(nPrev) + 1.0E-5) // pt1较远 { nIndex++; XDirectionCurve(pt1, cvBase.StartPoint()).Intersection(cvPrevOffset, ptArcStart, ptArcEnd); // 求交点 *poly2d[j-1] = XLine(ptArcStart, ptArcEnd).NearPoint(cvOffset.StartPoint()); } else // pt2较远 { XDirectionCurve(pt2, cvBase.StartPoint()).Intersection(cvOffset, ptArcStart, ptArcEnd); // 求交点 ptStart = XLine(ptArcStart, ptArcEnd).NearPoint(cvOffset.StartPoint()); } } } } else // 不封闭路径时的第1段 { ptStart = cvOffset.StartPoint(); } if (nNext>=0 && nNext 1.0E-5) // 当前段是弧段,需要修改起点的Bulge { XPoint ptMid = cvOffset.MidPoint(); // sg add 091029,解决弧段较小时,出现的反向错误 XArc arcTmp = cvOffset.GetArc(); XPoint ptTmpCen = arcTmp.GetCenterPt(); XLine lineTmp(ptTmpCen, ptMid, LS_FINITE); int nSide1 = lineTmp.OnWhichSide(ptStart), nSide2 = lineTmp.OnWhichSide(ptEnd); BOOL bSame = nSide1==nSide2; XArc arc(ptStart, ptMid, ptEnd); // if (!!arc) // 新弧有效 // sg modify 091029,解决弧段较小时,出现的反向错误 if (!bSame && !!arc) // 新弧有效 { XPoint ptArcStart, ptArcEnd; arc.GetStartPoint(ptArcStart); arc.GetEndPoint(ptArcEnd); dBulge = arc.Bulge(); if (ptArcStart.Distance(ptStart) > _DIST_SNAP) // 判断是否自动修改了弧的起点、终点 { dBulge *= -1; } } } aryShow.SetAt(i, j); // sg add 081013 aryIndex.SetAt(i, nIndex); *poly2d[j] = ptStart; poly2d.SetBulge(j, dBulge); if (j < poly2d.Length() - 1) { *poly2d[j+1] = ptEnd; } } poly2d.SetElevation(0); return TRUE; } BOOL TDbApron::Get2DRegion(XPoly2D &poly2d) const { AcGeVector3d vt = m_vtNormal; if ((vt==AcGeVector3d(0,0,1)) && !m_polyBase.IsClosed()) { XPoly2D poly1, poly2; Get2DInPoly(poly1); Array aryIndex, aryShow; if (!Get2DOutPoly(poly2, aryIndex, aryShow)) return FALSE; poly2.Reverse(); aryIndex.Reverse(); aryShow.Reverse(); int nLength = poly2.Length(); for (int i=0; iz; // 统一标高 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()); 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()); polyPath.SetBulge(nPos, seg1.GetBulge()); polyPath.InsertNodeAt(nPos+1, ptAdd, seg2.GetBulge()); } m_polyBase = polyPath; return TRUE; } ptAdd.z = 0; ptOnCurve.z = 0; if (nPos>0 && ptOnCurve!=ptAdd) // 命中顶点 { nPos--; // 获取顶点的索引号 ptAdd.z = polyPath[nPos]->z; // 统一标高 int nPrev = nPos - 1, // 前一点 nNext = nPos + 1; // 后一点 int nLength = polyPath.Length(); if (polyPath.IsClosed()) // 封闭路径,周期查找 { nPrev = DePeriod(nLength, nPrev); nNext = DePeriod(nLength, nNext); } BOOL bAddAfter(TRUE); // 标志是否将新点放在最近点之后 if (nPrev<0 || nPrev>=nLength) // 最近点为首顶点,且路径不闭合 { bAddAfter = FALSE; } else if (nNext>=0 && nNext dDistNew + _DIST_SNAP) // 新点距离连线近 { bAddAfter = FALSE; } else // 新点距离连线远 { seg.SetPoints(*poly2d[nPos], *poly2d[nNext]); int nRet = seg.OnWhichSide(ptOnCurve); bAddAfter = nRet!=2; // 注:防止新点、最近点和下一点共线 } } if (bAddAfter) // 放到最近点之后,否则放在最近点之前 { nPos++; } polyPath.InsertNodeAt(nPos, ptAdd); m_polyBase = polyPath; return TRUE; } return FALSE; } Acad::ErrorStatus TDbApron::SetPathPoly(const XPoly2D &polyPath, const AcGeVector3d&normal) { Acad::ErrorStatus es = TDbPolyCurveEnt::SetPathPoly(polyPath, normal); XPoly2D poly2d; Get2DInPoly(poly2d); int nSegNum = poly2d.TotalSegments(), nDistNum = GetDistNum(); while (nSegNum > nDistNum) { InsertDistAt(nDistNum, _AS_SYS_UNIT(600)); nDistNum++; } while (nSegNum < nDistNum) { RemoveDistAt(nDistNum-1); nDistNum--; } return es; } ////////////////////////////////////////////////////////////////////// double TDbApron::GetPathLength() const { return m_polyBase.Distance3d(); } double TDbApron::GetShapePerimeter(long lIndex) const { XPoly2D poly2d; if (GetShapePoly(lIndex, poly2d)) // 获取指定段的截面 { return poly2d.Distance2d(); } return 0.0; } double TDbApron::GetShapeArea(long lIndex) const { XPoly2D poly2d; if (!GetShapePoly(lIndex, poly2d)) // 获取指定段的截面 { return 0.0; } if (!poly2d.IsClosed()) // 不闭合,不考虑面积 { return 0.0; } return poly2d.Area(); } double TDbApron::GetSideArea() const { double dArea(0.0); int nLength = GetDistNum(); // 段数 for (int i=0; i1 && m_aryDist.GetLength()>0); return bRet; } bool TDbApron::IsClipMe(const TEntityBase* pEnt)const { if (TEntityBase::IsClipMe(pEnt)) { return true; } //if (pEnt->GetMe()->isKindOf(TDbColumn::desc())|| // 柱子 // pEnt->GetMe()->isKindOf(TDbWallPatch::desc())) // 墙体附件 //{ // return true; //} // sg modify 110504,根据8.5测试反馈,修改为内凹墙体造型不遮挡散水 if (pEnt->GetMe()->isKindOf(TDbColumn::desc())) // 柱子 { return true; } if (pEnt->GetMe()->isKindOf(TDbWallPatch::desc())) // 墙体附件 { TDbWallPatch *pWallPatch = TDbWallPatch::cast(pEnt->GetMe()); if (pWallPatch != NULL) { if (pWallPatch->GetUsageFlag() == TDbWallPatch::kConcave) // 内凹墙体造型不遮挡散水 { return false; } return true; } } TDbWall *pWall = TDbWall::cast(pEnt->GetMe()); if (pWall != NULL) { if (pWall->HasOpeningOutWall()) return true; } else { TDbOpening *pOpen = TDbOpening::cast(pEnt->GetMe()); if (pOpen != NULL) { // 未处理组合门窗... if (pOpen->GetKind() == TOpeningData::OP_PROWIN) // 窗 { return true; } } else { TDbCornerWin* pCornerWin = TDbCornerWin::cast(pEnt->GetMe()); if (pCornerWin!=NULL && pCornerWin->IsProtrude()) // 角窗 { return true; } else { TDbBalcony *pBalcony = TDbBalcony::cast(pEnt->GetMe()); if (pBalcony != NULL) // 阳台 { return true; } else { TDbAscent *pAscent = TDbAscent::cast(pEnt->GetMe()); if (pAscent != NULL) // 坡道 { return true; } else { TDbStep *pStep = TDbStep::cast(pEnt->GetMe()); if (pStep != NULL) // 台阶 { return true; } } } } } } return false; } ////////////////////////////////////////////////////////////////////// void TDbApron::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag) { assertWriteEnabled(); TDbPolyCurveEnt::CopyPropertiesFrom(pSrcEntity, gMatchFlag); TDbApron *pSrc = TDbApron::cast(pSrcEntity); if (pSrc != NULL) { m_dInHeight = pSrc->m_dInHeight; m_dOutHeight = pSrc->m_dOutHeight; m_nFlag = pSrc->m_nFlag; Array aryDist; pSrc->GetDistArray(aryDist); SetDistArray(aryDist); XPoly2D poly2D; AcGeVector3d vec = pSrc->GetNormal(); double dElev = pSrc->GetElevationAt(0); pSrc->GetPathPoly(poly2D, vec); poly2D.SetElevation(dElev); SetPathPoly(poly2D, vec); } } Acad::ErrorStatus TDbApron::subGetClassID(CLSID* pClsid) const { return Acad::eOk; } ////////////////////////////////////////////////////////////////////// // 从DWG读入数据: Acad::ErrorStatus TDbApron::dwgInFields(AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbPolyCurveEnt::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_dInHeight); pFiler->readItem(&m_dOutHeight); if (m_aryDist.GetLength() != 0) { m_aryDist.Clear(); } Adesk::UInt16 nTemp = 0; pFiler->readItem(&nTemp); for (Adesk::UInt16 i=0; ireadItem(&dNum); m_aryDist.AddTail(dNum); } pFiler->readItem(&m_nFlag); return pFiler->filerStatus(); } Acad::ErrorStatus TDbApron::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = TDbPolyCurveEnt::dwgOutFields(pFiler); if (es != Acad::eOk) { return es; } pFiler->writeItem(g_nVersion); pFiler->writeItem(m_dInHeight); pFiler->writeItem(m_dOutHeight); Adesk::UInt16 nCount = (Adesk::UInt16)m_aryDist.GetLength(); pFiler->writeItem(nCount); for (Adesk::UInt16 i=0; iwriteItem(dNum); } pFiler->writeItem(m_nFlag); return pFiler->filerStatus(); } Acad::ErrorStatus TDbApron::dxfInFields (AcDbDxfFiler* pFiler) { Acad::ErrorStatus es = TDbPolyCurveEnt::dxfInFields(pFiler); if (es != Acad::eOk) { return es; } if (!pFiler->atSubclassData(_T("TDbApron"))) { return Acad::eBadDxfSequence; } resbuf rb; Adesk::UInt32 nFlag = 0; Array aryDist; double dInHeight(0), dOutHeight(0); while ((es==Acad::eOk) && ((es=pFiler->readResBuf(&rb))==Acad::eOk)) { switch(rb.restype) { case AcDb::kDxfAngle: dInHeight = rb.resval.rreal; break; case AcDb::kDxfAngle+1: dOutHeight = rb.resval.rreal; break; case AcDb::kDxfAngle+2: aryDist.AddTail(rb.resval.rreal); break; case AcDb::kDxfInt32: nFlag = rb.resval.rlong; break; default: pFiler->pushBackItem(); es = Acad::eEndOfFile; break; } } if (es != Acad::eEndOfFile) { return Acad::eInvalidResBuf; } long lCount = aryDist.GetLength(); if (lCount < 1) { pFiler->setError(_T("\nError DXF group code: 11, 51")); return Acad::eMissingDxfField; } m_dInHeight = dInHeight; m_dOutHeight = dOutHeight; if (m_aryDist.GetLength() != 0) { m_aryDist.Clear(); } for (long i=0; ifilerStatus(); } Acad::ErrorStatus TDbApron::dxfOutFields(AcDbDxfFiler* pFiler) const { Acad::ErrorStatus es = TDbPolyCurveEnt::dxfOutFields(pFiler); assert(es == Acad::eOk); es = pFiler->writeItem(AcDb::kDxfSubclass, _T("TDbApron")); assert(es == Acad::eOk); pFiler->writeDouble(AcDb::kDxfAngle, m_dInHeight); pFiler->writeDouble(AcDb::kDxfAngle+1, m_dOutHeight); long lCount = m_aryDist.GetLength(); for (long i=0; iwriteDouble(AcDb::kDxfAngle+2, dNum); } pFiler->writeInt32(AcDb::kDxfInt32, m_nFlag); return es; } ////////////////////////////////////////////////////////////////////// Acad::ErrorStatus TDbApron::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); TDbPolyCurveEnt::subTransformBy(xform); if (IsMirrorMatrix(xform)) { m_polyBase.Reverse(); m_aryDist.Reverse(); return Acad::eOk; } return Acad::eOk; } // sg modify 090521 Acad::ErrorStatus TDbApron::subGetOsnapPoints(AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const { assertReadEnabled(); int nCount = m_entSet.length(); for (int i=0; igetOsnapPoints(osnapMode, gsSelectionMark, pickPoint, lastPoint, viewXform, snapPoints, geomIds); } return Acad::eOk; } Acad::ErrorStatus TDbApron::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { TDbPolyCurveEnt::subGetGripPoints(gripPoints, osnapModes, geomIds); XPoly2D poly2D; // 外侧线 Array aryIndex, aryShow; if (!Get2DOutPoly(poly2D, aryIndex, aryShow)) return Acad::eOk; double dElev = GetElevationAt(0); // 获取路径标高 poly2D.SetElevation(dElev); int nLength = aryShow.GetLength(); for (long i=0; i aryIndex, aryShow; if (!Get2DOutPoly(poly2d, aryIndex, aryShow)) return Acad::eOk; poly2d.SetElevation(dElev); for (int i=0; i=0 && nIndex _DIST_SNAP) // 自动交换了起点、终点 { vecMove = XVector3D(ptMid - arc.GetCenterPt()).AsAcGeVector3d(); } else // 未交换起点、终点 { vecMove = XVector3D(arc.GetCenterPt() - ptMid).AsAcGeVector3d(); } } vecMove.normalize(); double dNewDist = vtOffset.AsAcGeVector3d().dotProduct(vecMove), // 拖拽宽度 dOldDist = GetDistAt(nIndex); // 旧宽度 double dDist = dOldDist - dNewDist; // 新宽度 //if (dDist < _DIST_SNAP) // 只允许往外侧拖拽 if (dOldDist*dDist < _DIST_SNAP) // sg add 110126,解决8.5版本支持宽度为负数的情况,只允许往外侧拖拽 { dDist = 0.0; } SetDistAt(nIndex, dDist); } } return Acad::eOk; } ////////////////////////////////////////////////////////////////////// Acad::ErrorStatus TDbApron::DownGradeSave(int nDrawMode, AcDbVoidPtrArray &entSet, BOOL *bErase) // sg add 081021 { Acad::ErrorStatus es = Acad::eOk; if (g_nSaveTArchVer >= GetFirstVersion()) // 导出为T8格式 { if (bErase) { *bErase = FALSE; } es = TDbPolyCurveEnt::DownGradeSave(nDrawMode, entSet, bErase); } else if (g_nSaveTArchVer == 7) // 导出为T7格式 { Array aryTmp = m_aryDist; double dDist = m_aryDist.GetAt(0); aryTmp.SetAll(dDist); int nLen1 = aryTmp.GetLength(), nLen2 = m_aryDist.GetLength(); BOOL bFlag = nLen1 == nLen2; // 首先判断长度是否相等 if (bFlag) { for (int i=0; i 1.0E-5) { bFlag = FALSE; // 再判断内容是否一致 break; } } } if (bFlag) // 一样,存为“路径曲面”对象 { XPoly2D polyShape; GetShapePoly(0, polyShape); TDbCurveMesh2 *pMesh = new TDbCurveMesh2; pMesh->CopyPropertiesFrom(this, 0); pMesh->SetPathPoly(m_polyBase, GetNormal()); pMesh->SetShapePoly(polyShape); pMesh->SetShapeBase(XPoint()); pMesh->SetHas2D(TRUE); pMesh->SetHasDivide2D(TRUE); pMesh->SetHas3D(TRUE); pMesh->setLayer(layerId()); pMesh->setColorIndex(colorIndex()); entSet.append(pMesh); if (bErase) { *bErase = TRUE; } } else // 不一样,炸开 { XExplodeStream dc(entSet); if (!OnExplodeOrDraw(dc)) // sg add 090303,解决导出后,无遮挡关系的BUG return es; dc.SetPropertiesFrom(this); if (nDrawMode == DRAW_2D) es = ExplodeOrDraw2d(dc); else es = ExplodeOrDraw3d(dc); if (bErase) *bErase = TRUE; } } else // 导出为T3、T5、T6格式,炸开 { XExplodeStream dc(entSet); if (!OnExplodeOrDraw(dc)) // sg add 090303,解决导出后,无遮挡关系的BUG return es; dc.SetPropertiesFrom(this); if (nDrawMode == DRAW_2D) es = ExplodeOrDraw2d(dc); else es = ExplodeOrDraw3d(dc); if (bErase) *bErase = TRUE; } return es; } // 绘制2D的显示,注:目前只考虑是散水对象 Acad::ErrorStatus TDbApron::ExplodeOrDraw2d(XExplodeDraw &dc) const { assertReadEnabled(); if (!IsValid()) // sg add 090601,只有一个点时,不绘制 return Acad::eNotApplicable; // add by whl on 090324,捕捉时加速 // sg modify 090521,解决加速后,散水外侧路径线,无捕捉问题 if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0 || g_bOsnapExpl) { ReleaseEntSet(m_entSet); // sg modify 090521 XPushMemVar bExpl(g_bOsnapExpl, FALSE); XPushMemVar bFull(XExplodeStream::m_bFullExplode, TRUE); // AcDbVoidPtrArray entSet; // sg delete 090521 // XExplodeStream dcExp(entSet); XExplodeStream dcExp(m_entSet); dcExp.SetPropertiesFrom(this); //add by xlc on 100430 解决散水移动时速度慢的问题 if (dc.IsDragging()) { dcExp.SetIsDragging(Adesk::kTrue); } if (_tcscmp(dc.Desc(), XAcGiViewDraw::Descriptor())==0) // add by whl on 090427 OnExplodeOrDraw(dcExp); // add by whl on 090423 ExplodeOrDraw2d(dcExp); int nGsMarker = 1; INT_PTR nQuickMarker = GetQuickMarker(); // int nCount = entSet.length(); // sg modify 090521 int nCount = m_entSet.length(); for (int i=0; i aryIndex, aryShow; if (!Get2DOutPoly(polyOut, aryIndex, aryShow)) return Acad::eOk; int nLength = aryShow.GetLength(); if (nLength == polyIn.TotalSegments()) { for (long i=0; i lstPolys; DList lstColVis; XPoly2D polyIn2d, polyOut2d; Array aryIndex, aryShow; Get2DInPoly(polyIn2d); if (!Get2DOutPoly(polyOut2d, aryIndex, aryShow)) return Acad::eOk; lstPolys.Append(new XPoly2D(polyIn2d)); // 路径曲线,基线 lstColVis.Append(new Adesk::UInt8(TRUE)); lstPolys.Append(new XPoly2D(polyOut2d)); // 外侧线 lstColVis.Append(new Adesk::UInt8(TRUE)); XPoly2D polyIn3d = polyIn2d, polyOut3d = polyOut2d; polyIn3d.SetElevation(m_dInHeight); polyOut3d.SetElevation(m_dOutHeight); lstPolys.Append(new XPoly2D(polyOut3d)); lstColVis.Append(new Adesk::UInt8(TRUE)); lstPolys.Append(new XPoly2D(polyIn3d)); lstColVis.Append(new Adesk::UInt8(TRUE)); lstPolys.Append(new XPoly2D(polyIn2d)); // 注:截面曲线为封闭曲线 lstColVis.Append(new Adesk::UInt8(TRUE)); double dElev = GetElevationAt(0); // 散水各点标高一致 int nPolyNum = lstPolys.Length(); // 截面点数量=5 for (int i=0; iz += dElev; // 调整标高 } } int nTotalSeg = m_polyBase.TotalSegments(); // 路径段数 for (int n=0; n lstCurves; // 构成每“段”的五条边 for (int j=0; jNth(nNum, *pCurve); lstCurves.Append(pCurve); } int nDiv = 30; XDirectionCurve mSeg; polyIn2d.Nth(n, mSeg); if (mSeg.Is(CURVE_ARC)) // 将弧线分成若干段直线 { nDiv = TchExport::GetCirDivNum(mSeg.GetArc().GetRadius(), _AS_SYS_UNIT(TchGeLib::g_nCirDeviation)); } int nStep = AS_INT(fabs(mSeg.GetBulge())/PI/2.0*nDiv); if (nStep <= 0) { nStep = 1; } int nCol = lstCurves.Length(), // =5 nRow = nStep + 1; XPoint *ptArray = new XPoint[nCol*nRow]; for (int col=0; col()); } if (n==nTotalSeg-1 && !polyIn2d.IsClosed()) { XPoly2D polyTemp2(1); for (col=0; col()); } delete []pVisArray; delete []ptArray; } return Acad::eOk; } ////////////////////////////////////////////////////////////////////// void TDbApron::GetTips(DList &lstInfo) const { lstInfo.Append(new TObjInfoUnit(_T("对象类型"), _T("散水"))); lstInfo.Append(new TObjInfoUnit(_T("路径长度"), Dist2Str(GetPathLength()))); lstInfo.Append(new TObjInfoUnit(_T("侧面面积"), XString(_T("%.2f"), _AS_SQMETER(GetSideArea())))); lstInfo.Append(new TObjInfoUnit(_T("体积"), XString(_T("%.3f"), _AS_CUMETER(GetVolume())))); } // 取得夹点说明 Acad::ErrorStatus TDbApron::GetGripText(int idx, CString &cs) const { Acad::ErrorStatus es = TDbPolyCurveEnt::GetGripText(idx, cs); if (es == Acad::eOk) { return es; } int nVertexCount = m_polyBase.Length(), nTotalEdge = m_polyBase.TotalSegments(); int nIndex = idx - nVertexCount - nTotalEdge; if (nIndex>=0 && nIndexSetAllDists(_AS_SYS_UNIT(600)); // 保证数组长度与新实体中的路径段数一致 XPoly2D polyOld2D, poly2D; Get2DInPoly(polyOld2D); // 获取当前的POLY pNewApron->Get2DInPoly(poly2D); // 获取操作后新产生的POLY int nSegCount = poly2D.TotalSegments(); for (long j=0; jSetDistAt(j, dDist); } } } // TRIM调用 Acad::ErrorStatus TDbApron::getSplitCurves(const AcGeDoubleArray& params, AcDbVoidPtrArray& curveSegments) const { assertReadEnabled(); Acad::ErrorStatus es = TDbPolyCurveEnt::getSplitCurves(params, curveSegments); int nLength = curveSegments.length(); for (long i=0; im_polyBase.SetFlag(0); // 强制修改为不闭合 ModifyAllDistByOld(pApron); } return es; } // BREAK调用 Acad::ErrorStatus TDbApron::getSplitCurves(const AcGePoint3dArray& points, AcDbVoidPtrArray& curveSegments) const { assertReadEnabled(); Acad::ErrorStatus es = TDbPolyCurveEnt::getSplitCurves(points, curveSegments); int nLength = curveSegments.length(); for (long i=0; im_polyBase.SetFlag(0); // 强制修改为不闭合 ModifyAllDistByOld(pApron); } return es; } // OFFSET调用 Acad::ErrorStatus TDbApron::getOffsetCurves(double offsetDist, AcDbVoidPtrArray& offsetCurves) const { XPoly2D polyOld2D; AcDbPolyline pline; Get2DInPoly(polyOld2D); PolyConvert(polyOld2D, pline); // 转化成CAD中的PLINE线 AcDbVoidPtrArray entSet; Acad::ErrorStatus es = pline.getOffsetCurves(offsetDist, entSet); if (es == Acad::eOk) { int nCount = entSet.length(); double dElev = GetElevationAt(0); for (int n=0; nisKindOf(AcDbPolyline::desc())) { XPoly2D poly2D; AcDbPolyline *pCurve = AcDbPolyline::cast(pEnt); PolyConvert(*pCurve, poly2D); // 再转化为XPoly2D poly2D.SetElevation(dElev); // 修改标高 TDbApron *pClone = new TDbApron; pClone->setPropertiesFrom(this); if (pClone->SetPathPoly(poly2D, GetNormal()) == Acad::eOk) { offsetCurves.append(pClone); } else { delete pClone; } } } } ReleaseEntSet(entSet); return es; } #if ADS>14 Acad::ErrorStatus TDbApron::getOffsetCurvesGivenPlaneNormal(const AcGeVector3d& normal, double offsetDist, AcDbVoidPtrArray& offsetCurves) const { // 注:散水对象为2D实体,忽略normal return getOffsetCurves(offsetDist, offsetCurves); } #endif ////////////////////////////////////////////////////////////////////// #if ADS>15 void TDbApron::CreateGrip() { TDbPolyCurveEnt::CreateGrip(); // 由基类添加 int nSegNum = m_polyBase.TotalSegments(), // 段的数量 nVertexNum = m_polyBase.Length(); // 点的数量 long lFirset = nSegNum + nVertexNum; // 起始编号 XPoly2D poly2D; // 外侧线 Array aryIndex, aryShow; if (!Get2DOutPoly(poly2D, aryIndex, aryShow)) return; if (aryShow.GetLength() != nSegNum) { return; } for (int i=0; iAppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength)); // 宽度 GetGrip(iSeg)->AppendDim(new TDbGripDistDim(AcDbDimData::kDimDeltaLength, false)); // 偏移量 } } Acad::ErrorStatus TDbApron::EntityToDim(long iGrip, long iDim, const AcDbEntity *pEnt) { TDbGripDim *pDim = GetGripDim(iGrip, iDim); if (pDim == NULL) { return Acad::eInvalidInput; } TDbApron *pApron = TDbApron::cast(pEnt); if (pApron == NULL) { // return Acad::eInvalidInput; pApron = this; // sg modify 080916,动态输入打开,查看夹点时,也显示标注 } int nSegNum = m_polyBase.TotalSegments(), // 段的数量 nVertexNum = m_polyBase.Length(); // 点的数量 long lFirset = nSegNum + nVertexNum; // 起始编号 if (lFirset > iGrip) // 与基类处理相同 { XPoly2D polyPath; AcGeVector3d normal; pApron->GetPathPoly(polyPath, normal); return ::EntityToDim(this, polyPath, iGrip, iDim, 0); } XPoly2D polyIn2D, polyOut2D; Array aryIndex, aryShow; Get2DInPoly(polyIn2D); if (!Get2DOutPoly(polyOut2D, aryIndex, aryShow)) return Acad::eOk; XDirectionCurve cvIn, cvOut; long lSegNum = iGrip - lFirset; int nNum = aryShow.GetAt(lSegNum); polyIn2D.Nth(lSegNum, cvIn); polyOut2D.Nth(nNum, cvOut); ASSERT(!!cvIn || !!cvOut); XPoint ptMidOut = cvOut.MidPoint(), ptNew, ptMidIn; cvIn.ProjectToMe(ptMidOut, ptMidIn); double dAngle = ads_angle(XPoint(), XVector3D(ptMidOut-ptMidIn)), dDist = pApron->GetDistAt(lSegNum); ads_polar(ptMidIn, dAngle, dDist, ptNew); switch(iDim) { case 0: // 宽度 { TDbGripDistDim *pDistDim = (TDbGripDistDim*)pDim; pDistDim->SetData(ptMidIn, ptNew, _AS_SYS_UNIT(800)); } break; case 1: // 位置偏移 { TDbGripDistDim *pDistDim = (TDbGripDistDim*)pDim; pDistDim->SetData(ptMidOut, ptNew, _AS_SYS_UNIT(-800)); } break; default: return Acad::eNotImplementedYet; } return Acad::eOk; } Acad::ErrorStatus TDbApron::DimToEntity(long iGrip, long iDim, double newValue, const AcGeVector3d& offset) { assertWriteEnabled(); int nSegNum = m_polyBase.TotalSegments(), // 段的数量 nVertexNum = m_polyBase.Length(); // 点的数量 long lFirset = nSegNum + nVertexNum; // 起始编号 if (lFirset > iGrip) // 与基类处理相同 { TDbApron apron; apron.CopyPropertiesFrom(this, 0); Acad::ErrorStatus es = ::DimToEntity(this, m_polyBase, iGrip, iDim, newValue, offset, 0); if ((es==Acad::eOk) && !IsValid()) { CopyPropertiesFrom(&apron, 0); return Acad::eInvalidInput; } return es; } double dNewDist(newValue); long lSegNum = iGrip - lFirset; switch(iDim) { case 1: // 位置偏移 { XPoly2D polyIn2D, polyOut2D; Array aryIndex, aryShow; Get2DInPoly(polyIn2D); if (!Get2DOutPoly(polyOut2D, aryIndex, aryShow)) return Acad::eOk; XDirectionCurve cvIn, cvOut; int nNum = aryShow.GetAt(lSegNum); polyIn2D.Nth(lSegNum, cvIn); polyOut2D.Nth(nNum, cvOut); ASSERT(!!cvIn || !!cvOut); XPoint ptMidIn, ptMidOut = cvOut.MidPoint(); cvIn.ProjectToMe(ptMidOut, ptMidIn); AcGePoint3d ptNew = GetGripPoint(iGrip) + offset; // 输入时,点的位置 AcGeVector3d vtOld = ptMidOut.AsAcGePoint3d() - ptMidIn.AsAcGePoint3d(), vtNew = ptNew - ptMidOut.AsAcGePoint3d(); if (fabs(vtNew.angleTo(vtOld)) < 1.0E-5) // 同向拖拽 { dNewDist += GetDistAt(lSegNum); } else // 反向拖拽 { dNewDist = GetDistAt(lSegNum) - dNewDist; if (dNewDist < -1.0E-5) // 宽度小于0,自动修正 { dNewDist = 0; } } } case 0: // 宽度 SetDistAt(lSegNum, dNewDist); break; default: return Acad::eNotImplementedYet; } return Acad::eOk; } #endif CString TDbApron::GetXml( const AcGeMatrix3d& mat ) const { XPoly2D polyIn, polyOut; Get2DInPoly(polyIn); // 内侧线 Array aryIndex, aryShow; if (!Get2DOutPoly(polyOut, aryIndex, aryShow)) // 外侧线 { return CString(); } polyIn.TransformBy(mat); polyOut.TransformBy(mat); TXmlTree xmlTree; POSITION posRoot = xmlTree.Insert(_T("ATS_APRON"), NULL, NULL); { xmlTree.SetAttribute(posRoot, _T("name"), _T("散水")); xmlTree.SetAttribute(posRoot, _T("comment"), _T("上华对象名称")); } int nPre = 3; // 精度 POSITION posIn = xmlTree.Insert(_T("PolyIn"), posRoot, NULL); { xmlTree.SetAttribute(posIn, _T("name"), _T("内侧线")); POSITION posTemp = NULL; int nLen = polyIn.Length(); CString sPt, sX, sY, sZ; XPoint ptTemp; for (int i = 0; i < nLen; ++i) { ptTemp = *polyIn[i]; sPt.Format(_T("Point_%d"), i + 1); posTemp = xmlTree.Insert(sPt, posIn, posTemp); { sPt.Format(_T("第%d点"), i + 1); xmlTree.SetAttribute(posTemp, _T("name"), sPt); sX = DoubleToString(ptTemp.x, nPre); sY = DoubleToString(ptTemp.y, nPre); sZ = DoubleToString(ptTemp.z, nPre); sPt.Format(_T("%s,%s,%s"), sX, sY, sZ); xmlTree.SetItemText(posTemp, sPt); } sPt.Format(_T("Ang_%d"), i + 1); posTemp = xmlTree.Insert(sPt, posIn, posTemp); { sPt.Format(_T("圆心角%d"), i + 1); xmlTree.SetAttribute(posTemp, _T("name"), sPt); sPt = DoubleToString(polyIn.GetBulge(i), nPre); xmlTree.SetItemText(posTemp, sPt); } } } POSITION posOut = xmlTree.Insert(_T("PolyOut"), posRoot, posIn); { xmlTree.SetAttribute(posOut, _T("name"), _T("外侧线")); POSITION posTemp = NULL; int nLen = polyOut.Length(); CString sPt, sX, sY, sZ; XPoint ptTemp; for (int i = 0; i < nLen; ++i) { ptTemp = *polyOut[i]; sPt.Format(_T("Point_%d"), i + 1); posTemp = xmlTree.Insert(sPt, posOut, posTemp); { sPt.Format(_T("第%d点"), i + 1); xmlTree.SetAttribute(posTemp, _T("name"), sPt); sX = DoubleToString(ptTemp.x, nPre); sY = DoubleToString(ptTemp.y, nPre); sZ = DoubleToString(ptTemp.z, nPre); sPt.Format(_T("%s,%s,%s"), sX, sY, sZ); xmlTree.SetItemText(posTemp, sPt); } sPt.Format(_T("Ang_%d"), i + 1); posTemp = xmlTree.Insert(sPt, posOut, posTemp); { sPt.Format(_T("圆心角%d"), i + 1); xmlTree.SetAttribute(posTemp, _T("name"), sPt); sPt = DoubleToString(polyIn.GetBulge(i), nPre); xmlTree.SetItemText(posTemp, sPt); } } } POSITION posInHeight = xmlTree.Insert(_T("InHeight"), posRoot, posOut); { xmlTree.SetAttribute(posInHeight, _T("name"), _T("截面内侧高度")); CString sTemp = DoubleToString(m_dInHeight, nPre); xmlTree.SetItemText(posInHeight, sTemp); } POSITION posOutHeight = xmlTree.Insert(_T("OutHeight"), posRoot, posInHeight); { xmlTree.SetAttribute(posOutHeight, _T("name"), _T("截面外侧高度")); CString sTemp = DoubleToString(m_dInHeight, nPre); xmlTree.SetItemText(posOutHeight, sTemp); } POSITION posItemId = xmlTree.Insert(_T("Object_ID"), posRoot, posOutHeight); { xmlTree.SetAttribute(posItemId, _T("name"), _T("ID")); xmlTree.SetAttribute(posItemId, _T("comment"), _T("散水ID")); CString sText; sText.Format(_T("%ld"), objectId().asOldId()); xmlTree.SetItemText(posItemId, sText); } CString sXml = xmlTree.GetXml(); int nIdex = -1; nIdex = sXml.Find(_T("")); if (nIdex != -1) { CString sTemp = TDbPolyCurveEnt::GetXml(mat); sXml.Insert(nIdex, sTemp); } return sXml; } void InitDbApron(BOOL bTrue) { if (bTrue) { TDbApron::rxInit(); acrxBuildClassHierarchy(); TDbApron::InitMatchProtocol(TRUE); } else { TDbApron::InitMatchProtocol(FALSE); deleteAcRxClass(TDbApron::desc()); } }