//------------------------------------------------------------------------+ // Copyright (C), 1998-2012, Beijing Tangent Software Co. Ltd. // = FileName : TDbStruBarBase类 // = Version : ver1.0 // = Author : zyc // = CreateDate : 2012-11-02 // = Description: 条形基础平面图类定义 // = Maintainers: // //------------------------------------------------------------------------+ #include "stdafx.h" #ifdef TASD #include "TDbStruBarBase.h" #include "TAsdKeyDefine.h" #include "TConfigInfo.h" #include "TBaseWallIntegrateTool.h" extern void AddMsg(const TAssocMsg& assocMsg); extern bool g_bModifyAgain; const Adesk::UInt8 TDbStruBarBase::g_nVersion = 1; ACRX_DXF_DEFINE_MEMBERS(ATSStruBarBase, ATSBaseWall, AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent, 1, ATS_STRUBARBASE, "ATS_STRUBARBASE图形无法解析, 请下载上华软件|网址: www.shanghuasoft.com"); IMPLEMENT_TENTBASE(TDbStruBarBase); TDbStruBarBase::TDbStruBarBase() { SetAt(KEY_WEIGHT, 1); SetAt(KEY_H, 1000); SetAt(KEY_BULGE, 0.0); } TDbStruBarBase::~TDbStruBarBase() { } Acad::ErrorStatus TDbStruBarBase::dwgInFields (AcDbDwgFiler* pFiler) { assertWriteEnabled(); Acad::ErrorStatus es = TDbBaseWall::dwgInFields(pFiler); if (es != Acad::eOk) { return es; } Adesk::UInt8 nVer; pFiler->readItem(&nVer); if (nVer > g_nVersion) { return Acad::eMakeMeProxy; } return pFiler->filerStatus(); } Acad::ErrorStatus TDbStruBarBase::dwgOutFields(AcDbDwgFiler* pFiler) const { assertReadEnabled(); Acad::ErrorStatus es = TDbBaseWall::dwgOutFields(pFiler); if (es != Acad::eOk) { return es; } pFiler->writeItem(g_nVersion); return pFiler->filerStatus(); } Acad::ErrorStatus TDbStruBarBase::subGetOsnapPoints(AcDb::OsnapMode osnapMode, INT_PTR gsSelectionMark, const AcGePoint3d& pickPoint, const AcGePoint3d& lastPoint, const AcGeMatrix3d& viewXform, AcGePoint3dArray& snapPoints, AcDbIntArray& geomIds) const { assertReadEnabled(); return TDbBaseWall::subGetOsnapPoints(osnapMode, gsSelectionMark, pickPoint, lastPoint, viewXform, snapPoints, geomIds); } Acad::ErrorStatus TDbStruBarBase::subTransformBy(const AcGeMatrix3d& xform) { assertWriteEnabled(); Acad::ErrorStatus es = TDbBaseWall::subTransformBy(xform); // 拖拽结束时发送消息 if (objectId() && g_bMonitorDbAction) { TAssocMsg msg; msg.SetMethod(TAssocMsg::kTransform); msg.SetMatrix(xform); msg.SetAssocId(objectId()); AddMsg(msg); } return es; } Acad::ErrorStatus TDbStruBarBase::subGetGripPoints(AcGePoint3dArray& gripPoints, AcDbIntArray& osnapModes, AcDbIntArray& geomIds) const { assertReadEnabled(); AcGePoint3d ptStart, ptEnd, ptMid; GetAt(KEY_START, ptStart); GetAt(KEY_END, ptEnd); double dBulge = 0.0; GetAt(KEY_BULGE, dBulge); if (fabs(dBulge) < g_fZero) // 直线 { Midpoint(ptStart, ptEnd, ptMid); } else // 弧线 { TGGeArc arc(ptStart, ptEnd, dBulge); ptMid = arc.MidPoint().AsAcGePoint3d(); } gripPoints.append(ptStart); gripPoints.append(ptEnd); gripPoints.append(ptMid); return Acad::eOk; } Acad::ErrorStatus TDbStruBarBase::subGetStretchPoints(AcGePoint3dArray& stretchPoints) const { assertReadEnabled(); AcDbIntArray osnapModes; AcDbIntArray geomIds; return subGetGripPoints(stretchPoints, osnapModes, geomIds); } // 独立移动 void TDbStruBarBase::SingleMove(const AcDbIntArray& indices, const AcGeVector3d& offset) { double dBulge = 0.0; AcGePoint3d ptStart, ptEnd; GetAt(KEY_START, ptStart); GetAt(KEY_END, ptEnd); GetAt(KEY_BULGE, dBulge); int nIndex = indices[0]; AcGeVector3d vtOffset = offset; vtOffset.z = 0; switch (nIndex) { case 0: // 起点 ptStart += vtOffset; SetAt(KEY_START, ptStart); break; case 1: // 终点 ptEnd += vtOffset; SetAt(KEY_END, ptEnd); break; case 2: // 中点 default: if (fabs(dBulge) < g_fZero) // 直线 { ptStart += vtOffset; ptEnd += vtOffset; SetAt(KEY_START, ptStart); SetAt(KEY_END, ptEnd); } else // 弧线 { TADSGePoint3d ptMid; TGGeArc arc(ptStart, ptEnd, dBulge); ptMid = arc.MidPoint(); ptMid += vtOffset; TGGeArc arcNew(ptStart, ptMid, ptEnd); // 移动后的新弧 TADSGePoint3d ptS, ptE; arcNew.GetStartPoint(ptS); arcNew.GetEndPoint(ptE); SetAt(KEY_START, ptS.AsAcGePoint3d()); SetAt(KEY_END, ptE.AsAcGePoint3d()); SetAt(KEY_BULGE, (double)arcNew.Bulge()); } break; } } // 关联移动 void TDbStruBarBase::AssociateMove(const AcDbIntArray& indices, const AcGeVector3d& offset) { double dBulge; AcGePoint3d ptStart, ptEnd; GetAt(KEY_START, ptStart); GetAt(KEY_END, ptEnd); GetAt(KEY_BULGE, dBulge); // 是否是直线 bool bIsStraight = false; if (fabs(dBulge) < g_fZero) { bIsStraight = true; } AcGeVector3d vtOffset = offset; vtOffset.z = 0.0; int nIndex = indices[0]; switch (nIndex) { case 0: // 起点 if (bIsStraight) { TGGeLine line(asDblArray(ptStart), asDblArray(ptEnd)); TADSGePoint3d ptMoved(ptStart); ptMoved += vtOffset; ptMoved.Project(&line, ptMoved); SetAt(KEY_START, ptMoved.AsAcGePoint3d()); } else { TADSGePoint3d ptMid; TGGeArc arc(ptStart, ptEnd, dBulge); ptMid = arc.MidPoint(); TADSGePoint3d ptCenter; arc.Center(ptCenter); TGGeCircle circle(ptCenter, arc.GetRadius()); ptStart += vtOffset; TADSGePoint3d ptTemp; TADSGePoint3d(ptStart).Project(&circle, ptTemp); ptStart = ptTemp.AsAcGePoint3d(); arc.Set(ptStart, ptMid, ptEnd); SetAt(KEY_START, ptStart); SetAt(KEY_BULGE, arc.Bulge()); } break; case 1: // 终点 if (bIsStraight) { TGGeLine line(asDblArray(ptStart), asDblArray(ptEnd)); TADSGePoint3d ptMoved(ptEnd); ptMoved += vtOffset; ptMoved.Project(&line, ptMoved); SetAt(KEY_END, ptMoved.AsAcGePoint3d()); } else { TADSGePoint3d ptMid; TGGeArc arc(ptStart, ptEnd, dBulge); ptMid = arc.MidPoint(); TADSGePoint3d ptCenter; arc.Center(ptCenter); TGGeCircle circle(ptCenter, arc.GetRadius()); ptEnd += vtOffset; TADSGePoint3d ptTemp; TADSGePoint3d(ptEnd).Project(&circle, ptTemp); ptEnd = ptTemp.AsAcGePoint3d(); arc.Set(ptStart, ptMid, ptEnd); SetAt(KEY_END, ptEnd); SetAt(KEY_BULGE, arc.Bulge()); } break; case 2: // 中点 default: if (bIsStraight) { TGGeLine line(asDblArray(ptStart), asDblArray(ptEnd)); TADSGePoint3d pt = ptStart + vtOffset, pt2; pt.Project(&line, pt2); vtOffset = pt - pt2; ptStart += vtOffset; ptEnd += vtOffset; SetAt(KEY_START, ptStart); SetAt(KEY_END, ptEnd); // 拖拽结束时发送消息 if (objectId()) { TAssocMsg msg; msg.SetMethod(TAssocMsg::kMovegrippoint); msg.SetTarget(line.MidPoint()); msg.SetOffset(vtOffset); msg.SetAssocId(objectId()); AddMsg(msg); } } else //弧线 改变半径 { TADSGePoint3d ptMid; TGGeArc arc(ptStart, ptEnd, dBulge); ptMid = arc.MidPoint(); TADSGePoint3d ptCenter; arc.Center(ptCenter); TGGeLine line(ptCenter, ptMid); ptMid += vtOffset; ptMid.Project(&line, ptMid); if (ptMid.Distance(ptCenter) > _DIST_SNAP) { AcGeVector3d vt1 = ptStart - ptCenter.AsAcGePoint3d(), vt2 = ptEnd - ptCenter.AsAcGePoint3d(); double dAngle = vt1.angleTo(vt2, AcGeVector3d::kZAxis); vt1 = ptMid - ptCenter; ptStart = ptCenter + vt1.rotateBy(-dAngle * 0.5, AcGeVector3d::kZAxis); ptEnd = ptCenter + vt1.rotateBy(dAngle, AcGeVector3d::kZAxis); arc.Set(ptStart, ptMid, ptEnd); SetAt(KEY_START, ptStart); SetAt(KEY_END, ptEnd); SetAt(KEY_BULGE, arc.Bulge()); } } break; } } Acad::ErrorStatus TDbStruBarBase::subMoveGripPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { if (GetCtrlToggle()) { SingleMove(indices, offset); // 单独移动 } else { AssociateMove(indices, offset); } return Acad::eOk; } Acad::ErrorStatus TDbStruBarBase::subMoveStretchPointsAt(const AcDbIntArray& indices, const AcGeVector3d& offset) { assertWriteEnabled(); return subMoveGripPointsAt(indices, offset); } Acad::ErrorStatus TDbStruBarBase::subGetClassID(CLSID* pClsid) const { #if (ADS >= 17) assertReadEnabled(); #endif return Acad::eOk; } Acad::ErrorStatus TDbStruBarBase::subDeepClone(AcDbObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary) const { assertReadEnabled(); return TDbBaseWall::subDeepClone(pOwner, pClonedObject, idMap, isPrimary); } Acad::ErrorStatus TDbStruBarBase::subWblockClone(AcRxObject* pOwner, AcDbObject*& pClonedObject, AcDbIdMapping& idMap, Adesk::Boolean isPrimary) const { assertReadEnabled(); return TDbBaseWall::subWblockClone(pOwner, pClonedObject, idMap, isPrimary); } Acad::ErrorStatus TDbStruBarBase::subIntersectWith(const AcDbEntity* ent, AcDb::Intersect intType, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { assertReadEnabled(); return TDbBaseWall::subIntersectWith(ent, intType, points, thisGsMarker, otherGsMarker); } Acad::ErrorStatus TDbStruBarBase::subIntersectWith(const AcDbEntity* ent, AcDb::Intersect intType, const AcGePlane& projPlane, AcGePoint3dArray& points, INT_PTR thisGsMarker, INT_PTR otherGsMarker) const { assertReadEnabled(); return TDbBaseWall::subIntersectWith(ent, intType, projPlane, points, thisGsMarker, otherGsMarker); } // TEntityBase // 夹点提示 Acad::ErrorStatus TDbStruBarBase::GetGripText(int i, CString &cs) const { bool bIsArc = true; double dBulge = 0.0; GetAt(KEY_BULGE, dBulge); if (fabs(dBulge) < g_fZero) // 直线 { bIsArc = false; } Acad::ErrorStatus es=Acad::eOk; if (GetCtrlToggle()) // 单独移动 { switch(i) { case 0: case 1: cs=_T("改变位置"); break; case 2: if (bIsArc) { cs=_T("改变位置"); } else { cs=_T("独立平行移动"); } break; default: es=Acad::eInvalidInput; break; } } else { switch(i) { case 0: case 1: if (bIsArc) { cs=_T("沿弧伸缩"); } else { cs=_T("沿条基方向拉伸缩短"); } break; case 2: if (bIsArc) { cs=_T("改变半径"); } else { cs=_T("关联平行移动"); } break; default: es=Acad::eInvalidInput; break; } } return es; } Acad::ErrorStatus TDbStruBarBase::ExplodeOrDraw3d(TGGiExplodeDrawBase &dc) const { assertReadEnabled(); return Acad::eOk; } // 基础平行时,获得封口线,poly的0索引点与左条形基础线起点或终点重合 void TDbStruBarBase::GetSideLine2d(bool bStart, const AcDbObjectId &idWall, const TBaseWallLine &wallLine, TGGeVisibilityPoly2D &poly) const { poly.Reset(); TDbStruBarBase *pWall = NULL; acdbOpenObject(pWall, idWall, AcDb::kForRead); if (pWall != NULL) { TBaseWallLine bwlThat; pWall->GetThisBaseWallLine(bwlThat); int nThatWeight = 0; pWall->GetAt(KEY_WEIGHT, nThatWeight); pWall->close(); // 判断基础融合方式 TADSGePoint3d ptThat1,ptThat2; TBaseWallLine bwlThis; GetThisBaseWallLine(bwlThis); int nType = TBaseWallIntegrateTool::IsIntegrateAtTail(bwlThat, bwlThis); if (nType == 1) // 起始端相交 { TGGeVisibilityPoly2D leftThat = bwlThat.GetLeftLine(); TGGeVisibilityPoly2D rightThat = bwlThat.GetRightLine(); ptThat1 = *leftThat[0]; ptThat2 = *rightThat[0]; } else if (nType == 2) // 终止端相交 { TGGeVisibilityPoly2D leftThat = bwlThat.GetLeftLine(); TGGeVisibilityPoly2D rightThat = bwlThat.GetRightLine(); ptThat1 = *leftThat[leftThat.Length() - 1]; ptThat2 = *rightThat[leftThat.Length() - 1]; } else { return; } if (!!ptThat1 && !!ptThat2) { TADSGePoint3d ptThis1,ptThis2; TGGeVisibilityPoly2D leftThis = bwlThis.GetLeftLine(); TGGeVisibilityPoly2D rightThis = bwlThis.GetRightLine(); if (bStart) { ptThis1 = *leftThis[0]; ptThis2 = *rightThis[0]; } else { ptThis1 = *leftThis[leftThis.Length() - 1]; ptThis2 = *rightThis[rightThis.Length() - 1]; } AcGeVector3d vtThat = ptThat1 - ptThat2; AcGeVector3d vtThis = ptThis1 - ptThis2; int nThisWeight = 0; GetAt(KEY_WEIGHT, nThisWeight); if (vtThis.isParallelTo(vtThat)) // 端点连线平行 { if (nThisWeight < nThatWeight) // 比较优先级 { poly.AppendNode(ptThis1); poly.AppendNode(ptThis2); } else { bool bSuperposition = (ptThat1.Distance(ptThis1) < _DIST_SNAP && ptThat2.Distance(ptThis2) < _DIST_SNAP) || (ptThat1.Distance(ptThis2) < _DIST_SNAP && ptThat2.Distance(ptThis1) < _DIST_SNAP); // 融合端点两两重合 if (!bSuperposition) { // 将that的融合端点投影到this融合端点连线的直线上 std::vector vecPt; vecPt.push_back(ptThis1); vecPt.push_back(ptThis2); TADSGePoint3d pt; TGGeLine line(ptThis1, ptThis2); ptThat1.Project(&line, pt); vecPt.push_back(pt); ptThat2.Project(&line, pt); vecPt.push_back(pt); // 求两点间的距离 std::map > mapData; std::vector vecTemp; std::vector::iterator it1, it2; for (it1 = vecPt.begin(); it1 != vecPt.end(); it1++) { it2 = it1; ++it2; for (; it2 != vecPt.end(); it2++) { vecTemp.clear(); vecTemp.push_back(*it1); vecTemp.push_back(*it2); mapData.insert(std::make_pair((*it1).Distance(*it2), vecTemp)); } } // 获取距离最远的点 std::map >::iterator it; it = mapData.end(); --it; vecTemp.clear(); vecTemp.push_back((*it).second[0]); vecTemp.push_back((*it).second[1]); // 从vecPt中删除最远的两点 for (it1 = vecTemp.begin(); it1 != vecTemp.end(); it1++) { for (it2 = vecPt.begin(); it2 != vecPt.end(); it2++) { if ((*it1).Distance(*it2) < _DIST_SNAP) { vecPt.erase(it2); break;; } } } // this的融合端点是否与最远点重合 if (ptThis1.Distance(vecTemp[0]) < _DIST_SNAP || ptThis1.Distance(vecTemp[1]) < _DIST_SNAP) { double dDist1 = ptThis1.Distance(vecPt[0]); double dDist2 = ptThis1.Distance(vecPt[1]); if (dDist1 < dDist2) { poly.AppendNode(ptThis1); poly.AppendNode(vecPt[0], 0.0, AcDb::kInvisible); } else { poly.AppendNode(ptThis1); poly.AppendNode(vecPt[1], 0.0, AcDb::kInvisible); } } if (ptThis2.Distance(vecTemp[0]) < _DIST_SNAP || ptThis2.Distance(vecTemp[1]) < _DIST_SNAP) { double dDist1 = ptThis2.Distance(vecPt[0]); double dDist2 = ptThis2.Distance(vecPt[1]); if (dDist1 < dDist2) { poly.AppendNode(vecPt[0]); poly.AppendNode(ptThis2); } else { poly.AppendNode(vecPt[1]); poly.AppendNode(ptThis2); } } if (poly.Length() == 0) { poly.AppendNode(ptThis1, 0.0, AcDb::kInvisible); poly.AppendNode(ptThis2, 0.0, AcDb::kInvisible); } } } } else if (nThatWeight != nThisWeight) // 优先级不同 { TGGeVisibilityPoly2D left = wallLine.GetLeftLine(); TGGeVisibilityPoly2D right = wallLine.GetRightLine(); if (bStart) { poly.AppendNode(*left[0]); poly.AppendNode(*right[0]); } else { poly.AppendNode(*left[left.Length() - 1]); poly.AppendNode(*right[right.Length() - 1]); } } } } } // 融合后生成的TGGeVisibilityPoly2D void TDbStruBarBase::GetIntegratedPoly2d(TGGeVisibilityPoly2D &poly) const { // 双线绘制样式 TBaseWallLine bwlThis; GetThisBaseWallLine(bwlThis); // 融合基础 TDPtrList arBaseWallLinesS, arBaseWallLinesM, arBaseWallLinesE; GetAssocBaseWallLine(arBaseWallLinesS, arBaseWallLinesM, arBaseWallLinesE); // 起点融合 TBaseWallIntegrateTool::IntegrateAtTail(true, bwlThis, arBaseWallLinesS); // 终点融合 TBaseWallIntegrateTool::IntegrateAtTail(false, bwlThis, arBaseWallLinesE); // 基础内融合 int i; for (i = 0; i < arBaseWallLinesM.Length(); i++) { TBaseWallIntegrateTool::Integrate(bwlThis,*arBaseWallLinesM[i]); } // 生成poly2d // 添加左线 TGGeVisibilityPoly2D left, right; left = bwlThis.GetLeftLine(); right = bwlThis.GetRightLine(); for (i = 0; i < left.Length(); i++) { poly.AppendNode(*left[i], *(left.m_ardbulges[i]), left.GetVisibleAt(i)); } // 添加终点封口线 int nLen = arBaseWallLinesE.Length(); if (nLen == 0) // 终点封口 { if (!(left.GetVisibleAt(left.Length() - 2) == AcDb::kInvisible && right.GetVisibleAt(right.Length() - 2) == AcDb::kInvisible)) { poly.AppendNode(*left[left.Length() - 1]); poly.AppendNode(*right[right.Length() - 1]); } } else if (nLen == 1) // 处理终点处有一个融合基础时,基础端点两点连线平行的情况 { AcDbObjectId id; GetWallId(false, id); TGGeVisibilityPoly2D polyNew; GetSideLine2d(false, id, bwlThis, polyNew); polyNew.Compress(); for (int i = 0; i < polyNew.Length(); i++) { poly.AppendNode(*polyNew[i], *(polyNew.m_ardbulges[i]), polyNew.GetVisibleAt(i)); } if (polyNew.Length() == 0) { poly.InsertNodeAt(*left[left.Length() - 1], AcDb::kInvisible); // 改变点的可见性 } } else { poly.InsertNodeAt(*left[left.Length() - 1], AcDb::kInvisible); // 改变点的可见性 } // 添加右线 right.Reverse(); for (i = 0; i < right.Length(); i++) { poly.AppendNode(*right[i], *(right.m_ardbulges[i]), right.GetVisibleAt(i)); } // 添加起点封口线 nLen = arBaseWallLinesS.Length(); if (nLen == 0) // 起点封口 { if (!(left.GetVisibleAt(0) == AcDb::kInvisible && right.GetVisibleAt(0) == AcDb::kInvisible)) { poly.AppendNode(*right[right.Length() - 1]); // right 已逆转方向 poly.AppendNode(*left[0]); } } else if (nLen == 1) // 处理起点处有一个融合基础时,基础端点两点连线平行的情况 { AcDbObjectId id; GetWallId(true, id); TGGeVisibilityPoly2D polyNew; GetSideLine2d(true, id, bwlThis, polyNew); polyNew.Compress(); polyNew.Reverse(); for (int i = 0; i < polyNew.Length(); i++) { poly.AppendNode(*polyNew[i], *(polyNew.m_ardbulges[i]), polyNew.GetVisibleAt(i)); } if (polyNew.Length() == 0) { poly.InsertNodeAt(*right[right.Length() - 1], AcDb::kInvisible); // 改变点的可见性 } } else { poly.InsertNodeAt(*right[right.Length() - 1], AcDb::kInvisible); // 改变点的可见性 } poly.SetClosed(); } // 绘制加粗的线 Acad::ErrorStatus TDbStruBarBase::DrawWeightLine2d(TGGiExplodeDrawBase &dc) const { // 获取融合后的poly2d TGGeVisibilityPoly2D poly; GetIntegratedPoly2d(poly); poly.Compress(); DrawWeightLine2d(dc, poly, true); return Acad::eOk; } Acad::ErrorStatus TDbStruBarBase::DrawWeightLine2d(TGGiExplodeDrawBase &dc, TGGeVisibilityPoly2D &poly, bool bVal) const { int nNum = 1; if (!bVal) { nNum = -1; } double dLineWidth = DocGetConWallLWeight()*GetPScale(); TGGePoly2D polyDest; if (poly.PathArea() > 0) // 顺时针 { poly.Offset(dLineWidth * nNum, polyDest); } else { poly.Offset(dLineWidth * (-1) * nNum, polyDest); } if (poly.Length() != polyDest.Length()) { return Acad::eInvalidInput; } TGGePoly2D poly2dNew; for (int i = 0; i < poly.Length() - 1; i++) { if (poly.GetVisibleAt(i) == AcDb::kInvisible) { continue; } poly2dNew.Reset(); poly2dNew.AppendNode(*poly[i], *(poly.m_ardbulges[i])); poly2dNew.AppendNode(*poly[i+1]); poly2dNew.AppendNode(*polyDest[i+1], *(polyDest.m_ardbulges[i]) * (-1)); poly2dNew.AppendNode(*polyDest[i]); poly2dNew.SetClosed(); dc << TGGeSolid(poly2dNew); } if (poly.GetVisibleAt(poly.Length() - 1) == AcDb::kVisible) { poly2dNew.Reset(); poly2dNew.AppendNode(*poly[poly.Length() - 1], *(poly.m_ardbulges[poly.Length() - 1])); poly2dNew.AppendNode(*poly[0]); poly2dNew.AppendNode(*polyDest[0], *(polyDest.m_ardbulges[polyDest.Length() - 1]) * (-1)); poly2dNew.AppendNode(*polyDest[polyDest.Length() - 1]); poly2dNew.SetClosed(); dc << TGGeSolid(poly2dNew); } return Acad::eOk; } Acad::ErrorStatus TDbStruBarBase::ExplodeOrDraw2d(TGGiExplodeDrawBase &dc) const { assertReadEnabled(); // 加粗 if (DocGetIsLineWeight() && DocGetWallIsLW()) { DrawWeightLine2d(dc); } // 绘制线 TBaseWallLine bwlThis; GetThisBaseWallLine(bwlThis); TDPtrList arBaseWallLinesStart, arBaseWallLinesMid, arBaseWallLinesEnd; GetAssocBaseWallLine(arBaseWallLinesStart, arBaseWallLinesMid, arBaseWallLinesEnd); TBaseWallIntegrateTool::IntegrateAtTail(true, bwlThis, arBaseWallLinesStart); TBaseWallIntegrateTool::IntegrateAtTail(false, bwlThis, arBaseWallLinesEnd); int i; for (i=0; i Wcs2Ucs(ptEnd) + g_fZero) { vtDir = ptStart - ptEnd; } dAngle = TADSGePoint3d(vtDir).AsAcGeVector2d().angle(); // 文本的旋转角度 vtDir.rotateBy(PI / 2.0, AcGeVector3d(0, 0, 1)); // 文本的偏移方向 vtDir.normalize(); if (abs(dBulge) < g_fZero) { // 条基为直线 Midpoint(ptStart, ptEnd, ptMidPt); } else { // 条基为弧 TGGeArc arc(ptStart, ptEnd, dBulge); ptMidPt = arc.MidPoint(); } // 文本位置 ptTextPos = ptMidPt + vtDir * (dWidth / 2.0 + dTextHeight * DocGetPScale() / 3.0); text.SetText(sNumber); text.SetAlignment(TGGiExplodeDrawBase::kBottomCenter); text.SetHeight(dTextHeight); text.setPropertiesFrom(this); text.SetRotation(dAngle); text.SetStyleId(GetTextStyleId(_T("Standard"))); text.SetLocation(ptTextPos); dc.DrawEntity(text); } return Acad::eOk; } // 绘制端点的封口线 Acad::ErrorStatus TDbStruBarBase::DrawSideLine2d(bool bStart, const AcDbObjectId &idWall, const TBaseWallLine &wallLine, TGGiExplodeDrawBase &dc) const { TDbStruBarBase *pWall = NULL; acdbOpenObject(pWall, idWall, AcDb::kForRead); if (pWall != NULL) { TBaseWallLine bwlThat; pWall->GetThisBaseWallLine(bwlThat); int nThatWeight = 0; pWall->GetAt(KEY_WEIGHT, nThatWeight); pWall->close(); // 判断基础线融合方式 TADSGePoint3d ptThat1,ptThat2; TBaseWallLine bwlThis; GetThisBaseWallLine(bwlThis); int nType = TBaseWallIntegrateTool::IsIntegrateAtTail(bwlThat, bwlThis); if (nType == 1) // 起始端相交 { TGGeVisibilityPoly2D leftThat = bwlThat.GetLeftLine(); TGGeVisibilityPoly2D rightThat = bwlThat.GetRightLine(); ptThat1 = *leftThat[0]; ptThat2 = *rightThat[0]; } else if (nType == 2) // 终止端相交 { TGGeVisibilityPoly2D leftThat = bwlThat.GetLeftLine(); TGGeVisibilityPoly2D rightThat = bwlThat.GetRightLine(); ptThat1 = *leftThat[leftThat.Length() - 1]; ptThat2 = *rightThat[leftThat.Length() - 1]; } else { return Acad::eOk; } if (!!ptThat1 && !!ptThat2) { TADSGePoint3d ptThis1,ptThis2; TGGeVisibilityPoly2D leftThis = bwlThis.GetLeftLine(); TGGeVisibilityPoly2D rightThis = bwlThis.GetRightLine(); if (bStart) { ptThis1 = *leftThis[0]; ptThis2 = *rightThis[0]; } else { ptThis1 = *leftThis[leftThis.Length() - 1]; ptThis2 = *rightThis[rightThis.Length() - 1]; } AcGeVector3d vtThat = ptThat1 - ptThat2; AcGeVector3d vtThis = ptThis1 - ptThis2; int nThisWeight = 0; GetAt(KEY_WEIGHT, nThisWeight); if (vtThis.isParallelTo(vtThat)) // 端点连线平行 { if (nThisWeight < nThatWeight) // 比较优先级 { dc << TGGeLine(ptThis1, ptThis2); } else { bool bSuperposition = (ptThat1.Distance(ptThis1) < _DIST_SNAP && ptThat2.Distance(ptThis2) < _DIST_SNAP) || (ptThat1.Distance(ptThis2) < _DIST_SNAP && ptThat2.Distance(ptThis1) < _DIST_SNAP); // 融合端点两两重合 if (!bSuperposition) { // 将that的融合端点投影到this融合端点连线的直线上 std::vector vecPt; vecPt.push_back(ptThis1); vecPt.push_back(ptThis2); TADSGePoint3d pt; TGGeLine line(ptThis1, ptThis2); ptThat1.Project(&line, pt); vecPt.push_back(pt); ptThat2.Project(&line, pt); vecPt.push_back(pt); // 求两点间的距离 std::map > mapData; std::vector vecTemp; std::vector::iterator it1, it2; for (it1 = vecPt.begin(); it1 != vecPt.end(); it1++) { it2 = it1; ++it2; for (; it2 != vecPt.end(); it2++) { vecTemp.clear(); vecTemp.push_back(*it1); vecTemp.push_back(*it2); mapData.insert(std::make_pair((*it1).Distance(*it2), vecTemp)); } } // 获取距离最远的点 std::map >::iterator it; it = mapData.end(); --it; vecTemp.clear(); vecTemp.push_back((*it).second[0]); vecTemp.push_back((*it).second[1]); // 从vecPt中删除最远的两点 for (it1 = vecTemp.begin(); it1 != vecTemp.end(); it1++) { for (it2 = vecPt.begin(); it2 != vecPt.end(); it2++) { if ((*it1).Distance(*it2) < _DIST_SNAP) { vecPt.erase(it2); break;; } } } // this的融合端点是否与最远点重合 if (ptThis1.Distance(vecTemp[0]) < _DIST_SNAP || ptThis1.Distance(vecTemp[1]) < _DIST_SNAP) { double dDist1 = ptThis1.Distance(vecPt[0]); double dDist2 = ptThis1.Distance(vecPt[1]); if (dDist1 < dDist2) { dc << TGGeLine(ptThis1, vecPt[0]); } else { dc << TGGeLine(ptThis1, vecPt[1]); } } if (ptThis2.Distance(vecTemp[0]) < _DIST_SNAP || ptThis2.Distance(vecTemp[1]) < _DIST_SNAP) { double dDist1 = ptThis2.Distance(vecPt[0]); double dDist2 = ptThis2.Distance(vecPt[1]); if (dDist1 < dDist2) { dc << TGGeLine(ptThis2, vecPt[0]); } else { dc << TGGeLine(ptThis2, vecPt[1]); } } } } } else if (nThatWeight != nThisWeight) // 优先级不同 { TGGeVisibilityPoly2D left = wallLine.GetLeftLine(); TGGeVisibilityPoly2D right = wallLine.GetRightLine(); if (bStart) { dc << TGGeLine(*left[0], *right[0]); } else { dc << TGGeLine(*left[left.Length() - 1], *right[right.Length() - 1]); } } } } return Acad::eOk; } Acad::ErrorStatus TDbStruBarBase::GetExtents2d(TADSGePoint3d &ptLow, TADSGePoint3d &ptUp) const { TGGePoly2D poly2d; GetPoly2D(poly2d); poly2d.GetExtend(ptLow, ptUp); ptLow.z = 0.0; ptUp.z = 0.0; return Acad::eOk; } Acad::ErrorStatus TDbStruBarBase::GetExtents(TADSGePoint3d &ptLow, TADSGePoint3d &ptUp) const { GetExtents2d(ptLow, ptUp); double dH = 0.0; GetAt(KEY_H, dH); AcGePoint3d ptStart; GetAt(KEY_START, ptStart); ptLow.z = ptStart.z - dH; ptUp.z = ptStart.z; return Acad::eOk; } //取动态属性显示数据 void TDbStruBarBase::GetTips(TDPtrList &lstInfo) const { } const TCHAR *TDbStruBarBase::GetDefaultLayer() const { return LAY_S_BASE_STRIP_LINE; } BOOL TDbStruBarBase::IsValid() const { assertReadEnabled(); AcGePoint3d ptStart, ptEnd; double dBulge; int iWeight; double dWidth, dHeight; if (GetAt(KEY_START, ptStart) && GetAt(KEY_END, ptEnd) && GetAt(KEY_BULGE, dBulge) && GetAt(KEY_WEIGHT, iWeight) && GetAt(KEY_W, dWidth) && GetAt(KEY_H, dHeight)) { return TRUE; } return FALSE; } // 支持夹点ctrl功能切换 int TDbStruBarBase::GetCtrlToggleIndex()const { return 11; } void TDbStruBarBase::CopyPropertiesFrom(AcDbEntity *pSrcEntity, unsigned gMatchFlag) { assertWriteEnabled(); TDbBaseWall::CopyPropertiesFrom(pSrcEntity, gMatchFlag); TDbStruBarBase* pEnt = TDbStruBarBase::cast(pSrcEntity); if (pEnt != NULL) { AcGePoint3d ptStart, ptEnd; double dBulge; GetAt(KEY_START, ptStart); GetAt(KEY_END, ptEnd); GetAt(KEY_BULGE, dBulge); GetSpecialtyData()->Empty(); *GetSpecialtyData() = *pEnt->GetSpecialtyData(); SetAt(KEY_START, ptStart); SetAt(KEY_END, ptEnd); SetAt(KEY_BULGE, dBulge); } } TEntityBase::DrawType TDbStruBarBase::GetDrawType() const { assertReadEnabled(); return TEntityBase::k2DOnly; } bool TDbStruBarBase::GetStandardFaceBody(AcDbVoidPtrArray& arFacePtrs) const { return false; } bool TDbStruBarBase::GetSafeProtectedSpace(AcDbVoidPtrArray& arFacePtrs) const { return false; } bool TDbStruBarBase::GetSection(const AcDbFace &face, const AcGeVector3d &vtPlaneSecDir, std::vector §ionRecords, AcDbVoidPtrArray &arFillPtrs) const { return false; } CString TDbStruBarBase::GetXml(const AcGeMatrix3d& mat) const { return _T(""); } // 对象修改发出关联更改消息 void TDbStruBarBase::PostAssocMsg(TAssocMsg assocMsg)const { } // 对象接收到更改消息 void TDbStruBarBase::ReceiveAssocMsg(TAssocMsg assocMsg) { assertWriteEnabled(); TDbBaseWall::ReceiveAssocMsg(assocMsg); } // 建立关联关系 void TDbStruBarBase::MakeAssocRelation(AcDbObjectIdArray& ids) { assertWriteEnabled(); if(ids.length() < 1) { return; } TPickEntSet ss(SS_FREE); ads_name eName; for (int i = 0; i < ids.length(); i++) { if (acdbGetAdsName(eName, ids[i]) == Acad::eOk) { ss += ids[i]; } } TGGePoly2D poly; //基础闭合平面 GetPoly2D(poly); double dWidth = 0; //基础平面宽 GetTotalWidth(dWidth); TGGeCurveSegment cvCL = GetCenterLine(); cvCL.SetLineFlag(LS_INFINITE); double dElevS = cvCL.StartPoint().z; double dElevE = cvCL.EndPoint().z; bool bModFlg = false; //记录基础的中心线是否调整 double dGap(0); AcDbObjectId idObj = AcDbObjectId::kNull; TEntitySet ent; for (long j = 0; j < ss.Length(); j++) { ent = ss[j]; if (ent.Is(_T("ATS_STRUBARBASE"))) { OPENOBJ_BEGIN(ent, AcDb::kForRead, TDbStruBarBase, pEnt); if (!pEnt) { continue; } TGGePoly2D polyDest; pEnt->GetPoly2D(polyDest); double dWidthDest(0); pEnt->GetTotalWidth(dWidthDest); bool bRet = TBaseWallIntegrateTool::GetMinGap(poly, polyDest, dGap); //间隙小于基础宽一半时,当作关联处理 if(bRet && (dGap < dWidth*0.5 || dGap < dWidthDest*0.5)) { if (cvCL.Is(CURVE_LINE)) { //建立关联时对基础的中心线进行校验,相交 TGGeCurveSegment cvCLDest = pEnt->GetCenterLine(); cvCLDest.SetLineFlag(LS_INFINITE); TADSGePoint3d ptInter1,ptInter2; int nNum = cvCL.Intersection(cvCLDest,ptInter1,ptInter2); if (nNum != 0) // 有交点 { //两个交点时取离cvCL中点近的 if (nNum == 2) { TADSGePoint3d ptMid = cvCL.MidPoint(); ptInter1 = TGGeLine(ptInter1, ptInter2).NearPoint(ptMid); } bool bModBreak = false; int nHitFlag = cvCL.HitTest2d(ptInter1); if (nHitFlag == 6) //起始侧延长线 { bModFlg = true; bModBreak = true; cvCL.SetStartPoint(ptInter1); } else if (nHitFlag == 7) //终止侧延长线 { bModFlg = true; bModBreak = true; cvCL.SetEndPoint(ptInter1); } //add by xlc on 120417 基础自动打断 if (g_bAutoBreak) { if (bModBreak) { Acad::ErrorStatus es = upgradeOpen(); if ((es == Acad::eOk || es == Acad::eWasOpenForWrite)) { AcGePoint3d pt = cvCL.StartPoint(); pt.z = dElevS; SetAt(KEY_START, pt); pt = cvCL.EndPoint(); pt.z = dElevE; SetAt(KEY_END, pt); if (es == Acad::eOk) { downgradeOpen(); } } } bool bBreak = false; if(nHitFlag == 5) //交点在线内时对自己进行打断 { if(BreakAt(ptInter1,NULL)) { bModFlg = false; bBreak = true; } } bool bModifyOld = g_bModifyAgain; pEnt->BreakAt(ptInter1, NULL); g_bModifyAgain = bModifyOld; if (bBreak) { break; } } } } idObj = pEnt->objectId(); } else { continue; } OPENOBJ_END(); if (!m_arAssocBWallIds.contains(idObj)) { m_arAssocBWallIds.append(idObj); } } } // 修改条形基础的端点 if (bModFlg) { Acad::ErrorStatus es = upgradeOpen(); if ((es == Acad::eOk || es == Acad::eWasOpenForWrite)) { AcGePoint3d pt = cvCL.StartPoint(); pt.z = dElevS; SetAt(KEY_START, pt); pt = cvCL.EndPoint(); pt.z = dElevE; SetAt(KEY_END, pt); if (es == Acad::eOk) { downgradeOpen(); } } } } // 移除关联关系 void TDbStruBarBase::RemoveAssocRelation(AcDbObjectId& id) { m_arAssocBWallIds.remove(id); } // 获得条形基础总宽度 void TDbStruBarBase::GetTotalWidth(double &dWidth)const { dWidth = 0; GetAt(KEY_W, dWidth); } // 获得条形基础总高度 void TDbStruBarBase::GetTotalHeight(double &dHeight)const { dHeight = 0; GetAt(KEY_H, dHeight); } // 基础外围poly2d void TDbStruBarBase::GetPoly2D(TGGePoly2D &poly2d) const { TBaseWallLine wallLine; GetThisBaseWallLine(wallLine); TGGeVisibilityPoly2D left, right; left = wallLine.GetLeftLine(); right = wallLine.GetRightLine(); AcDbPolyline* pLwPoly = new AcDbPolyline(); double dBuge = 0.0; int nIndex = 0; int i; for (i = 0; i < left.Length(); i++) { dBuge = tan(*(left.m_ardbulges[i]) / 4.0); pLwPoly->addVertexAt(nIndex, (*left[i]).AsAcGePoint2d(), dBuge); ++nIndex; } for (i=left.Length()-1; i >= 0; i--) { if (i > 0) { dBuge = tan(*(right.m_ardbulges[i-1]) / 4.0) * (-1); } else { dBuge = 0.0; } pLwPoly->addVertexAt(nIndex, (*right[i]).AsAcGePoint2d(), dBuge); ++nIndex; } pLwPoly->setClosed(Adesk::kTrue); poly2d.SetAcDbCurve(pLwPoly); delete pLwPoly; } BOOL TDbStruBarBase::CanMerge(AcDbObjectId idWall) { return TRUE; } int TDbStruBarBase::GetFirstVersion()const { return 10; } bool TDbStruBarBase::IsModelEntity() const { return true; } void InitDbStruBarBase(BOOL bInit) { if (bInit) { TDbStruBarBase::rxInit(); acrxBuildClassHierarchy(); TDbStruBarBase::InitMatchProtocol(TRUE); } else { TDbStruBarBase::InitMatchProtocol(FALSE); deleteAcRxClass(TDbStruBarBase::desc()); } } #endif