#include "stdafx.h" #include "ImpHvacOffset.h" #include "AuxTools.h" #include "AecDbEntityBase.h" using namespace AecEqui; extern void GetEndPointIndex(const AcGePoint3dArray &ptArr, int &nIndex1, int &nIndex2, AcGeVector3d* pRangeDir = NULL); // 获取标准基准投影面,2D相关绘制不在此面上的点都投影到此面上 AcGePlane GetStdPrjPlan( const AcGePoint3d &ptOnPlan ) { AcGeVector3d vtZAxis(TAuxTools::GetUcsZvt()); AcGePlane planStd(ptOnPlan, vtZAxis); AcGePoint3d ptPrj = AcGePoint3d::kOrigin.orthoProject(planStd); planStd.set(ptPrj, vtZAxis); return planStd; } // 辅助添加点函数,减少程序行数 int AutoAppendPt( AecComplexCurve &cplCurve, AecCurveElement &cplEle, const AcGePoint3d &ptS, const AcGePoint3d &ptMid, const AcGePoint3d &ptE ) { cplEle.ptGe[0] = ptS; cplEle.ptGe[1] = ptMid; cplEle.ptGe[2] = ptE; return cplCurve.append(cplEle); } ImpHvacOffset::ImpHvacOffset() { m_pXDataMap = NULL; m_pOwnerEnt = NULL; } ImpHvacOffset::~ImpHvacOffset() { } void ImpHvacOffset::list() const { ASSERT(NULL != m_pXDataMap); // 管件类型 acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t\t\t 暖通:乙字弯")); // 截面类型 ESection eSectType = eRect; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); switch (eSectType) { case eRect: acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t\t\t 截面:矩形")); break; case eCircle: acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t\t\t 截面:圆形")); break; case eOblate: acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t\t\t 截面:扁圆形")); break; } // 圆型截面显示直径 if ( eCircle == eSectType) { double dDiameter = 0.0; m_pXDataMap->GetAt(HOFF_Diameter, dDiameter); acutPrintf(_T("\n\t\t\t\t\t\t\t\t\t直径:%.2f"), dDiameter); } // 非圆型截面显示宽度和厚度 else { double dStartWidth = 0.0, dEndWidth = 0.0, dThick = 0.0; m_pXDataMap->GetAt(HOFF_StartWidth, dStartWidth); m_pXDataMap->GetAt(HOFF_EndWidth, dEndWidth); m_pXDataMap->GetAt(HOFF_Thick, dThick); acutPrintf(_T("\n\t\t\t\t\t\t\t\t始端宽度:%.2f 末端宽度:%.2f 厚度:%.2f"), dStartWidth, dEndWidth, dThick); } // 起点 AcGePoint3d pt; m_pXDataMap->GetAt(HOFF_StartPoint, pt); acutPrintf(_T("\n\t\t\t\t\t\t\t\t自 点,X=%.4f\t Y=%.4f\t Z=%.4f"), pt.x, pt.y, pt.z); // 终点 m_pXDataMap->GetAt(HOFF_EndPoint, pt); acutPrintf(_T("\n\t\t\t\t\t\t\t\t到 点,X=%.4f\t Y=%.4f\t Z=%.4f"), pt.x, pt.y, pt.z); } AecEqui::Position ImpHvacOffset::ExplainGripIndex( int nIndex ) const { AecEqui::Position ePos = AecEqui::eStart; switch(nIndex) { case 0: ePos = AecEqui::eStart; break; case 1: ePos = AecEqui::eEnd; break; case 2: ePos = AecEqui::eCommand0; break; case 3: ePos = AecEqui::eCommand1; break; default: break; } return ePos; } Acad::ErrorStatus ImpHvacOffset::transformBy( const AcGeMatrix3d& xform ) { if (NULL == m_pXDataMap) return Acad::eNotApplicable; // 变换点位置 AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); ptStart.transformBy(xform); ptEnd.transformBy(xform); // 变换向量 AcGeVector3d vtSta(StartVect()), vtEnd(EndVect()); vtSta.transformBy(xform); vtEnd.transformBy(xform); vtSta.normalize(); vtEnd.normalize(); // 更新点 m_pXDataMap->SetAt(HOFF_StartPoint, ptStart); m_pXDataMap->SetAt(HOFF_EndPoint, ptEnd); // 更新向量 m_pXDataMap->SetAt(HOFF_StartDir, vtSta); m_pXDataMap->SetAt(HOFF_EndDir, vtEnd); // 设置尺寸 double dScale = xform.scale(); double dStaWidth(0.0), dEndWidth(0.), dHeigh(0.0); m_pXDataMap->GetAt(HOFF_StartWidth, dStaWidth); m_pXDataMap->GetAt(HOFF_EndWidth, dEndWidth); m_pXDataMap->GetAt(HOFF_Thick, dHeigh); dStaWidth *= dScale; dEndWidth *= dScale; dHeigh *= dScale; m_pXDataMap->SetAt(HOFF_StartWidth, dStaWidth); m_pXDataMap->SetAt(HOFF_EndWidth, dEndWidth); m_pXDataMap->SetAt(HOFF_Thick, dHeigh); return Acad::eOk; } AcGeVector3d ImpHvacOffset::StartVect() const { ASSERT(NULL != m_pXDataMap); AcGeVector3d vtSta(AcGeVector3d::kIdentity); if (NULL != m_pXDataMap) m_pXDataMap->GetAt(HOFF_StartDir, vtSta); return vtSta; } AcGeVector3d ImpHvacOffset::EndVect() const { ASSERT(NULL != m_pXDataMap); AcGeVector3d vtEnd(AcGeVector3d::kIdentity); if (NULL != m_pXDataMap) m_pXDataMap->GetAt(HOFF_EndDir, vtEnd); return vtEnd; } AcGeVector3d ImpHvacOffset::normal() const { ASSERT(NULL != m_pXDataMap); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtEnd(EndVect()); AcGeVector3d vtDirect = ptEnd- ptStart; AcGeVector3d vtNormal = vtDirect.crossProduct(vtEnd); vtNormal.normalize(); return vtNormal; } BOOL ImpHvacOffset::IsHorzAlignment() const { ASSERT(NULL != m_pXDataMap); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtUserZAxis = TAuxTools::GetUcsZvt(); AcGeVector3d vtSub = ptEnd - ptStart; return vtSub.isPerpendicularTo(vtUserZAxis); } BOOL ImpHvacOffset::IsSideVertAlignment() const { ASSERT(NULL != m_pXDataMap); AcGeVector3d vtUserZAxis = TAuxTools::GetUcsZvt(); return StartVect().isParallelTo(vtUserZAxis); } BOOL ImpHvacOffset::IsFaceVertAlignment() const { ASSERT(NULL != m_pXDataMap); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtSub = ptEnd - ptStart; AcGeVector3d vtSta; m_pXDataMap->GetAt(HOFF_StartDir, vtSta); AcGeVector3d vtUserZAxis = TAuxTools::GetUcsZvt(); AcGeVector3d vtSubPrj = vtSub.orthoProject(TAuxTools::GetUcsZvt()); AcGeVector3d vtStaPrj = vtSta.orthoProject(TAuxTools::GetUcsZvt()); return vtSubPrj.isParallelTo(vtStaPrj); } BOOL ImpHvacOffset::IsSingleLine() const { ASSERT(NULL != m_pXDataMap); BOOL bSingleLine = FALSE; m_pXDataMap->GetAt(HVAC_IsSingleLine, (int&)bSingleLine); return bSingleLine; } BOOL ImpHvacOffset::IsBaseLine() const { ASSERT(NULL != m_pXDataMap); BOOL bBaseLine = FALSE; m_pXDataMap->GetAt(HVAC_HasBaseLine, (int&)bBaseLine); return bBaseLine; } Acad::ErrorStatus ImpHvacOffset::Draw3d( AcGiDraw &mode ) const { if (NULL == m_pXDataMap) return Acad::eNotImplementedYet; if (!IsCanDraw()) return Acad::eNotImplementedYet; AecHvac::HvacOffsetType eType =AecHvac::eArcuateLink; ESection eSectType = eRect; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); if (eType ==AecHvac::eArcuateLink) { if (eSectType == eRect) return DrawRectArcuate3d(mode); else if (eSectType ==eCircle) return DrawCircleArcuate3d(mode); } else if (eType ==AecHvac::eLinearLink) { if (eSectType == eRect) return DrawRectLinear3d(mode); else if (eSectType ==eCircle) return DrawCircleLinear3d(mode); } return Acad::eNotImplementedYet; } BOOL ImpHvacOffset::DrawMesh(AcGiDraw &mode,const Adesk::UInt32 rows,const Adesk::UInt32 columns,const AcGePoint3d* pVertexList) const { AcGePoint3dArray vertexArray; AcArray faceArray; int nV0 = 0,nV1 = 0,nV2 = 0; int nV3= 0; int nFaceIndex = 0; AcGePoint3d ptFace[4]; for (int i = 0;i < rows - 1;i++) { for (int j = 0;j < columns - 1;j++) { nV0 = i * columns + j; nV1 = nV0 + 1; //第二行,第一个 nV2 = (i + 1) * columns + j; nV3 = nV2 + 1; //三角:nV0-nV1-nV2 faceArray.append(3); faceArray.append(nV0);//v0 faceArray.append(nV1);//v1 faceArray.append(nV2);//v2 ptFace[0] = pVertexList[nV0]; ptFace[1] = pVertexList[nV1]; ptFace[2] = pVertexList[nV2]; ptFace[3] = ptFace[0]; //mode.DrawFace(ptFace); //三角:nV2-nV1-nV3 faceArray.append(3); faceArray.append(nV2);//v2 faceArray.append(nV1);//v1 faceArray.append(nV3);//v3 ptFace[0] = pVertexList[nV2]; ptFace[1] = pVertexList[nV1]; ptFace[2] = pVertexList[nV3]; ptFace[3] = ptFace[0]; //mode.DrawFace(ptFace); } } if (!faceArray.isEmpty()) { int nIndex = 0; for (int i = 0;i < rows;i++) { for (int j = 0;j < columns;j++) { nIndex = i * columns + j; vertexArray.append(pVertexList[nIndex]); } } AcDbSubDMesh* pSubMesh = new AcDbSubDMesh; if ( Acad::eOk == pSubMesh->setSubDMesh(vertexArray,faceArray,0) ) { mode.DrawEntity(pSubMesh); m_ar3DDrableBufPtrs_.append(pSubMesh); //有时候失败? /*Acad::ErrorStatus es; AcDb3dSolid* pSolid = new AcDb3dSolid; if ( Acad::eOk == (es = pSubMesh->convertToSolid(false,false,pSolid) ) ) { mode.DrawEntity(pSolid); } delete pSubMesh; */ return TRUE; } delete pSubMesh; } mode.DrawMeshS (rows,columns,pVertexList,false); return FALSE; } BOOL ImpHvacOffset::DrawShell(AcGiDraw &mode,const Adesk::UInt32 nbVertex,const AcGePoint3d* pVertexList,const Adesk::UInt32 faceListSize,const Adesk::Int32* pFaceList) const { AcGePoint3dArray vertexArray; AcArray faceArray; for(int i = 0;i < nbVertex;i++) { vertexArray.append(pVertexList[i]); } for (int j = 0;j < faceListSize;j++) { faceArray.append(pFaceList[j]); } AcDbSubDMesh* pSubMesh = new AcDbSubDMesh; if ( Acad::eOk == pSubMesh->setSubDMesh(vertexArray,faceArray,0) ) { mode.DrawEntity(pSubMesh); m_ar3DDrableBufPtrs_.append(pSubMesh); //有时候失败? /*Acad::ErrorStatus es; AcDb3dSolid* pSolid = new AcDb3dSolid; if ( Acad::eOk == (es = pSubMesh->convertToSolid(false,false,pSolid) ) ) { mode.DrawEntity(pSolid); } delete pSubMesh; */ return TRUE; } delete pSubMesh; mode.DrawShell (nbVertex,pVertexList,faceListSize,pFaceList); return FALSE; } void ImpHvacOffset::Move3DBuffer(AcDbVoidPtrArray& ar3DBuffer) const { if (!m_ar3DDrableBufPtrs_.isEmpty()) { ar3DBuffer.append(m_ar3DDrableBufPtrs_); m_ar3DDrableBufPtrs_.removeAll(); } } bool ImpHvacOffset::Has3DBuffer() const { return !m_ar3DDrableBufPtrs_.isEmpty(); } Acad::ErrorStatus ImpHvacOffset::Draw2d( AcGiDraw &mode ) const { if (NULL == m_pXDataMap) return Acad::eNotImplementedYet; AecComplexCurve cplCurve; MakeCurves(cplCurve); AecComplexCurveDraw edage; edage.SetEdage(cplCurve); AcDbObjectId idReal = m_idDoubleLayer; AcDbObjectId idDash = m_idDashLayer; AcDbObjectId idCent = m_idCenterLayer; edage.Draw2d(mode,idReal,idDash,idCent,NULL,FALSE,FALSE); AecComplexCurve cplCen; GetCurvesInSide(cplCen); edage.SetEdage(cplCen); edage.Draw2d(mode,idReal,idDash,idCent,NULL,FALSE,FALSE); return Acad::eOk; } BOOL ImpHvacOffset::MakeCurves( AecComplexCurve& compCurve ) const { if (NULL == m_pXDataMap) return FALSE; if (!IsSingleLine() && !IsCanDraw()) return FALSE; if (IsHorzAlignment()) { AecHvac::HvacOffsetType eType =AecHvac::eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); if (eType ==AecHvac::eArcuateLink) return MakeHorizArcuate2DCurves(compCurve, 0); else if (eType ==AecHvac::eLinearLink) return MakeHorizLinear2DCurves(compCurve, 0); } else if (IsSideVertAlignment()) { ESection eSectType = eRect; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); if (eSectType == eRect) return MakeSideVertRect2DCurves(compCurve, 0); else if (eSectType ==eCircle) return MakeSideVertCircle2DCurves(compCurve, 0); } else if (IsFaceVertAlignment()) { return MakeFaceVert2DCurves(compCurve, 0); } return FALSE; } BOOL ImpHvacOffset::GetCurvesInSide( AecComplexCurve& compCurve ) const { if (NULL == m_pXDataMap) return FALSE; if (!IsSingleLine() && !IsCanDraw()) return FALSE; if (IsHorzAlignment()) { AecHvac::HvacOffsetType eType = AecHvac::eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); if (eType == AecHvac::eArcuateLink) return MakeHorizArcuate2DCurves(compCurve, 1); else if (eType == AecHvac::eLinearLink) return MakeHorizLinear2DCurves(compCurve, 1); } else if (IsSideVertAlignment()) { ESection eSectType = eRect; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); if (eSectType == eRect) return MakeSideVertRect2DCurves(compCurve, 1); else if (eSectType == eCircle) return MakeSideVertCircle2DCurves(compCurve, 1); } else if (IsFaceVertAlignment()) { return MakeFaceVert2DCurves(compCurve, 1); } return FALSE; } Acad::ErrorStatus ImpHvacOffset::DrawRectArcuate3d( AcGiDraw &mode ) const { AcGePoint3dArray ptLeftArr, ptRightArr; GetAllMinAnglePt(ptLeftArr, ptRightArr); if (ptLeftArr.length() != ptRightArr.length() || 7 > ptLeftArr.length()) return Acad::eNotImplementedYet; double dHalfThick(0.0); m_pXDataMap->GetAt(HOFF_Thick, dHalfThick); dHalfThick *= 0.5; AcGeVector3d vtNormal = normal(); AcGeVector3d vtOff = dHalfThick * vtNormal; AcGePoint3dArray ptMeshArr; int i(0); for (i = 0; i < ptLeftArr.length(); i++) { ptMeshArr.append(ptLeftArr[i] + vtOff); ptMeshArr.append(ptRightArr[i] + vtOff); ptMeshArr.append(ptRightArr[i] - vtOff); ptMeshArr.append(ptLeftArr[i] - vtOff); ptMeshArr.append(ptLeftArr[i] + vtOff); } DrawMesh(mode,ptLeftArr.length(), 5, ptMeshArr.asArrayPtr()); return Acad::eOk; } Acad::ErrorStatus ImpHvacOffset::DrawRectLinear3d( AcGiDraw &mode ) const { AcGePoint3dArray ptUpArr, ptDownArr; if (!GetTwoSideKeyPoints(ptUpArr, ptDownArr)) return Acad::eNotImplementedYet; if (8 != ptDownArr.length() || 8 != ptUpArr.length()) return Acad::eNotImplementedYet; AcGePoint3dArray ptMeshArr; ptMeshArr.append(ptUpArr[1]); ptMeshArr.append(ptUpArr[0]); ptMeshArr.append(ptDownArr[0]); ptMeshArr.append(ptDownArr[1]); ptMeshArr.append(ptUpArr[1]); ptMeshArr.append(ptUpArr[2]); ptMeshArr.append(ptUpArr[7]); ptMeshArr.append(ptDownArr[7]); ptMeshArr.append(ptDownArr[2]); ptMeshArr.append(ptUpArr[2]); ptMeshArr.append(ptUpArr[3]); ptMeshArr.append(ptUpArr[6]); ptMeshArr.append(ptDownArr[6]); ptMeshArr.append(ptDownArr[3]); ptMeshArr.append(ptUpArr[3]); ptMeshArr.append(ptUpArr[4]); ptMeshArr.append(ptUpArr[5]); ptMeshArr.append(ptDownArr[5]); ptMeshArr.append(ptDownArr[4]); ptMeshArr.append(ptUpArr[4]); DrawMesh(mode,4, 5, ptMeshArr.asArrayPtr()); return Acad::eOk; } // 先找出左右两侧弧所有最小分度角点,然后循环求出每段圆中各分度角点 Acad::ErrorStatus ImpHvacOffset::DrawCircleArcuate3d( AcGiDraw &mode ) const { AcGePoint3dArray ptLeftArr, ptRightArr; GetAllMinAnglePt(ptLeftArr, ptRightArr); if (ptLeftArr.length() != ptRightArr.length() || 7 > ptLeftArr.length()) return Acad::eNotImplementedYet; double dMinAngle(TAuxTools::GetMinDiffAngle()); double dCircleMinAngle(0.0); int nCirclePart = (int)(PI*2 / dMinAngle) + 1; dCircleMinAngle = PI*2 / nCirclePart; // 每段圆左/右侧点,循环点, 每段圆心点 AcGePoint3d ptLeft, ptRight, ptNow, ptCenter; // 每段相切、垂直向量, 法向 AcGeVector3d vtTangEvery, vtPerlEvery, vtNormal(normal()); AcGePoint3dArray ptArrMesh; int i(0), j(0); for (i = 0; i < ptLeftArr.length(); i++) { vtPerlEvery = ptLeftArr[i] - ptRightArr[i]; vtTangEvery = vtPerlEvery.crossProduct(vtNormal); ptCenter = TAuxTools::Mid(ptLeftArr[i], ptRightArr[i]); ptNow = ptLeftArr[i]; for (j = 0; j < nCirclePart; j++) { ptArrMesh.append(ptNow); ptNow.rotateBy(dCircleMinAngle, vtTangEvery, ptCenter); } ptArrMesh.append(ptLeftArr[i]); } DrawMesh(mode,ptLeftArr.length(), nCirclePart + 1, ptArrMesh.asArrayPtr()); return Acad::eOk; } Acad::ErrorStatus ImpHvacOffset::DrawCircleLinear3d( AcGiDraw &mode ) const { double dRadius(0.0), dPluse(0.0); m_pXDataMap->GetAt(HOFF_Diameter, dRadius); dRadius *= 0.5; m_pXDataMap->GetAt(HVAC_PlusEdge, dPluse); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtStart(StartVect()); AcGeVector3d vtDirect = (ptEnd + dPluse * vtStart) - (ptStart - dPluse * vtStart); AcGeVector3d vtNormal = normal(); double dMinAngle(TAuxTools::GetMinDiffAngle()); int nPart = (int)(PI*2 / dMinAngle) + 1; dMinAngle = PI*2 / nPart; AcGePoint3dArray ptMeshArr; AcGePoint3d ptStartFirst = ptStart + dRadius * vtNormal; AcGePoint3d ptStartNow = ptStartFirst; AcGePoint3d ptNext; int i(0); for (i = 0; i < nPart + 1; i++) { ptMeshArr.append(ptStartNow); ptNext = ptStartNow - dPluse * vtStart; ptMeshArr.append(ptNext); ptNext += vtDirect; ptMeshArr.append(ptNext); ptNext -= dPluse * vtStart; ptMeshArr.append(ptNext); ptStartNow.rotateBy(dMinAngle, vtStart, ptStart); } DrawMesh(mode,nPart + 1, 4, ptMeshArr.asArrayPtr()); return Acad::eOk; } // 按两个弯头连接,有变径时在起始端半部变 BOOL ImpHvacOffset::MakeHorizArcuate2DCurves( AecComplexCurve& cplCurve, const int &nOutOrIn ) const { AecCurveElement tCurveEle; memset(&tCurveEle, 0, sizeof(AecCurveElement)); tCurveEle.bHided = FALSE; tCurveEle.dWidth = 0.0; tCurveEle.gsMark = 0; double dEdgeWidth(GetEdgeLineWidth()); if (IsSingleLine() || (IsBaseLine() && nOutOrIn == 1)) { AcGePoint3dArray ptBaseArr; if (!GetArcBaseKeyPt(ptBaseArr) || ptBaseArr.length() != 7) return FALSE; if (IsSingleLine()) tCurveEle.dWidth = dEdgeWidth; else { tCurveEle.dWidth = GetCentLineWidth(); tCurveEle.idSubLay = GetBaseLayerId(); } AutoAppendPt(cplCurve, tCurveEle, ptBaseArr[0], ptBaseArr[1], ptBaseArr[1]); AutoAppendPt(cplCurve, tCurveEle, ptBaseArr[1], ptBaseArr[2], ptBaseArr[3]); AutoAppendPt(cplCurve, tCurveEle, ptBaseArr[3], ptBaseArr[4], ptBaseArr[5]); AutoAppendPt(cplCurve, tCurveEle, ptBaseArr[5], ptBaseArr[6], ptBaseArr[6]); } else if (nOutOrIn == 0) { AcGePoint3dArray ptLeftArr, ptRightArr; if (!GetArcTwoSideKeyPt(ptLeftArr, ptRightArr)) return FALSE; if (7 != ptLeftArr.length() || 7 != ptRightArr.length()) return FALSE; tCurveEle.dWidth = dEdgeWidth; AutoAppendPt(cplCurve, tCurveEle, ptLeftArr[0], ptLeftArr[1], ptLeftArr[1]); AutoAppendPt(cplCurve, tCurveEle, ptLeftArr[1], ptLeftArr[2], ptLeftArr[3]); AutoAppendPt(cplCurve, tCurveEle, ptLeftArr[3], ptLeftArr[4], ptLeftArr[5]); AutoAppendPt(cplCurve, tCurveEle, ptLeftArr[5], ptLeftArr[6], ptLeftArr[6]); AutoAppendPt(cplCurve, tCurveEle, ptRightArr[0], ptRightArr[1], ptRightArr[1]); AutoAppendPt(cplCurve, tCurveEle, ptRightArr[1], ptRightArr[2], ptRightArr[3]); AutoAppendPt(cplCurve, tCurveEle, ptRightArr[3], ptRightArr[4], ptRightArr[5]); AutoAppendPt(cplCurve, tCurveEle, ptRightArr[5], ptRightArr[6], ptRightArr[6]); tCurveEle.dWidth = GetEndLineWidth(); m_pXDataMap->GetAt(HVAC_EndLayer, tCurveEle.idSubLay); AutoAppendPt(cplCurve, tCurveEle, ptLeftArr[0], ptRightArr[0], ptRightArr[0]); AutoAppendPt(cplCurve, tCurveEle, ptLeftArr[6], ptRightArr[6], ptRightArr[6]); } return TRUE; } BOOL ImpHvacOffset::MakeHorizLinear2DCurves( AecComplexCurve& cplCurve, const int &nOutOrIn ) const { AecCurveElement tCurveEle; memset(&tCurveEle, 0, sizeof(AecCurveElement)); tCurveEle.bHided = FALSE; tCurveEle.dWidth = 0.0; tCurveEle.gsMark = 0; double dEdgeWidth(GetEdgeLineWidth()); if (IsSingleLine() || (IsBaseLine() && nOutOrIn == 1)) { AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); double dPlus(0.0); m_pXDataMap->GetAt(HVAC_PlusEdge, dPlus); AcGeVector3d vtSta(StartVect()), vtEnd(EndVect()); AcGePoint3d ptStaPlus = ptStart - dPlus * vtSta; AcGePoint3d ptEndPlus = ptEnd - dPlus * vtEnd; if (IsSingleLine()) tCurveEle.dWidth = dEdgeWidth; else { tCurveEle.dWidth = GetCentLineWidth(); tCurveEle.idSubLay = GetBaseLayerId(); } AutoAppendPt(cplCurve, tCurveEle, ptStart, ptStaPlus, ptStaPlus); AutoAppendPt(cplCurve, tCurveEle, ptStaPlus, ptEndPlus, ptEndPlus); AutoAppendPt(cplCurve, tCurveEle, ptEndPlus, ptEnd, ptEnd); return TRUE; } else if (nOutOrIn == 0) { AcGePoint3dArray ptArr; GetMidKeyPoints(ptArr); int i(0); for (i = 0; i < ptArr.length() - 1; i++) { if (i == 0 || i == 4) { tCurveEle.dWidth = GetEndLineWidth(); m_pXDataMap->GetAt(HVAC_EndLayer, tCurveEle.idSubLay); } else { tCurveEle.dWidth = dEdgeWidth; tCurveEle.idSubLay.setNull(); } AutoAppendPt(cplCurve, tCurveEle, ptArr[i], ptArr[i+1], ptArr[i+1]); } AutoAppendPt(cplCurve, tCurveEle, ptArr[i], ptArr[0], ptArr[0]); } return TRUE; } BOOL ImpHvacOffset::MakeSideVertRect2DCurves( AecComplexCurve& cplCurve, const int &nOutOrIn ) const { AecCurveElement tCurveEle; memset(&tCurveEle, 0, sizeof(AecCurveElement)); tCurveEle.bHided = FALSE; tCurveEle.dWidth = 0.0; tCurveEle.gsMark = 0; AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGePlane planStd = GetStdPrjPlan(ptMid); double dEdgeWidth(GetEdgeLineWidth()), dCentWidth(GetCentLineWidth()); if (IsSingleLine()) { tCurveEle.dWidth = dEdgeWidth; tCurveEle.idSubLay = m_idCenterLayer; AutoAppendPt(cplCurve, tCurveEle, ptStart.orthoProject(planStd), ptEnd.orthoProject(planStd), ptEnd.orthoProject(planStd)); return TRUE; } AcGePoint3dArray ptUpArr, ptDownArr; GetTwoSideKeyPoints(ptUpArr, ptDownArr); if (8 != ptUpArr.length() || 8 != ptDownArr.length()) return FALSE; int nEnd1(0), nEnd2(0); GetEndPointIndex(ptUpArr, nEnd1, nEnd2); if(nOutOrIn == 1) { tCurveEle.dWidth = dEdgeWidth; int i(0); for (i = 0; i < ptUpArr.length(); i++) { if (i == nEnd1 || i == nEnd2) continue; AutoAppendPt(cplCurve, tCurveEle, ptDownArr[i].orthoProject(planStd), ptUpArr[i].orthoProject(planStd), ptUpArr[i].orthoProject(planStd)); } if (IsBaseLine()) { tCurveEle.dWidth = dCentWidth; tCurveEle.idSubLay = m_idCenterLayer; AutoAppendPt(cplCurve, tCurveEle, ptStart.orthoProject(planStd), ptEnd.orthoProject(planStd), ptEnd.orthoProject(planStd)); } } else if (nOutOrIn == 0) { tCurveEle.dWidth = dEdgeWidth; // 端点两边 AutoAppendPt(cplCurve, tCurveEle, ptDownArr[nEnd1].orthoProject(planStd), ptUpArr[nEnd1].orthoProject(planStd), ptUpArr[nEnd1].orthoProject(planStd)); AutoAppendPt(cplCurve, tCurveEle, ptDownArr[nEnd2].orthoProject(planStd), ptUpArr[nEnd2].orthoProject(planStd), ptUpArr[nEnd2].orthoProject(planStd)); // 侧部两边 AutoAppendPt(cplCurve, tCurveEle, ptDownArr[nEnd1].orthoProject(planStd), ptDownArr[nEnd2].orthoProject(planStd), ptDownArr[nEnd2].orthoProject(planStd)); AutoAppendPt(cplCurve, tCurveEle, ptUpArr[nEnd1].orthoProject(planStd), ptUpArr[nEnd2].orthoProject(planStd), ptUpArr[nEnd2].orthoProject(planStd)); } return Acad::eOk; } BOOL ImpHvacOffset::MakeSideVertCircle2DCurves( AecComplexCurve& cplCurve, const int &nOutOrIn ) const { AecCurveElement tCurveEle; memset(&tCurveEle, 0, sizeof(AecCurveElement)); tCurveEle.bHided = FALSE; tCurveEle.dWidth = 0.0; tCurveEle.gsMark = 0; AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); double dRadius(0.0); m_pXDataMap->GetAt(HOFF_Diameter, dRadius); dRadius *= 0.5; AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGePlane planStd = GetStdPrjPlan(ptMid); ptStart = ptStart.orthoProject(planStd); ptEnd = ptEnd.orthoProject(planStd); double dEdgeWidth(GetEdgeLineWidth()), dCentWidth(GetCentLineWidth()); if (IsSingleLine()) { tCurveEle.dWidth = dEdgeWidth; AutoAppendPt(cplCurve, tCurveEle, ptStart, ptEnd, ptEnd); return TRUE; } AcGeVector3d vtNormal = normal(); AcGeVector3d vtDirect = ptEnd - ptStart; vtDirect.normalize(); AcGePoint3d ptStartCirSta, ptStartCirMid, ptStartCirEnd; // 起始半圆各点 AcGePoint3d ptEndCirSta, ptEndCirMid, ptEndCirEnd; // 末半圆各点 ptStartCirSta = ptStart + dRadius * vtNormal; ptStartCirEnd = ptStart - dRadius * vtNormal; ptEndCirSta = ptEnd + dRadius * vtNormal; ptEndCirEnd = ptEnd - dRadius * vtNormal; if(nOutOrIn == 1) { tCurveEle.dWidth = dEdgeWidth; // 起始端半圆 ptStartCirMid = ptStart + dRadius * vtDirect; AutoAppendPt(cplCurve, tCurveEle, ptStartCirSta, ptStartCirMid, ptStartCirEnd); // 末端半圆 ptEndCirMid = ptEnd - dRadius * vtDirect; AutoAppendPt(cplCurve, tCurveEle, ptEndCirSta, ptEndCirMid, ptEndCirEnd); if (IsBaseLine()) { tCurveEle.dWidth = dCentWidth; tCurveEle.idSubLay = GetBaseLayerId(); AutoAppendPt(cplCurve, tCurveEle, ptStart, ptEnd, ptEnd); } } else if (nOutOrIn == 0) { tCurveEle.dWidth = dEdgeWidth; // 两边 AutoAppendPt(cplCurve, tCurveEle, ptStartCirSta, ptEndCirSta, ptEndCirSta); AutoAppendPt(cplCurve, tCurveEle, ptStartCirEnd, ptEndCirEnd, ptEndCirEnd); // 两半圆 ptStartCirMid = ptStart - dRadius * vtDirect; AutoAppendPt(cplCurve, tCurveEle, ptStartCirSta, ptStartCirMid, ptStartCirEnd); ptEndCirMid = ptEnd + dRadius * vtDirect; AutoAppendPt(cplCurve, tCurveEle, ptEndCirSta, ptEndCirMid, ptEndCirEnd); } return TRUE; } BOOL ImpHvacOffset::MakeFaceVert2DCurves( AecComplexCurve& cplCurve, const int &nOutOrIn ) const { AecCurveElement tCurveEle; memset(&tCurveEle, 0, sizeof(AecCurveElement)); tCurveEle.bHided = FALSE; tCurveEle.dWidth = 0.0; tCurveEle.gsMark = 0; AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGePoint3d ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGePlane planStd = GetStdPrjPlan(ptMid); AcGePoint3dArray ptUpArr, ptDownArr; GetTwoSideKeyPoints(ptUpArr, ptDownArr); if (8 != ptUpArr.length() || 8 != ptDownArr.length()) return FALSE; double dEdgeWidth(GetEdgeLineWidth()), dCentWidth(GetCentLineWidth()); if (IsSingleLine()) { tCurveEle.dWidth = dEdgeWidth; tCurveEle.idSubLay = m_idCenterLayer; AutoAppendPt(cplCurve, tCurveEle, ptStart.orthoProject(planStd), ptEnd.orthoProject(planStd), ptEnd.orthoProject(planStd)); return Acad::eOk; } if (nOutOrIn == 1) { if (IsBaseLine()) { tCurveEle.dWidth = dCentWidth; tCurveEle.idSubLay = m_idCenterLayer; AutoAppendPt(cplCurve, tCurveEle, ptStart.orthoProject(planStd), ptEnd.orthoProject(planStd), ptEnd.orthoProject(planStd)); } } else if (nOutOrIn == 0) { tCurveEle.dWidth = dEdgeWidth; AutoAppendPt(cplCurve, tCurveEle, ptUpArr[1].orthoProject(planStd), ptUpArr[4].orthoProject(planStd), ptUpArr[4].orthoProject(planStd)); AutoAppendPt(cplCurve, tCurveEle, ptDownArr[4].orthoProject(planStd), ptDownArr[1].orthoProject(planStd), ptDownArr[1].orthoProject(planStd)); tCurveEle.dWidth = GetEndLineWidth(); m_pXDataMap->GetAt(HVAC_EndLayer, tCurveEle.idSubLay); AutoAppendPt(cplCurve, tCurveEle, ptDownArr[1].orthoProject(planStd), ptUpArr[1].orthoProject(planStd), ptUpArr[1].orthoProject(planStd)); AutoAppendPt(cplCurve, tCurveEle, ptUpArr[4].orthoProject(planStd), ptDownArr[4].orthoProject(planStd), ptDownArr[4].orthoProject(planStd)); // 中间加箭头标示,上升(下降)摇手弯,及气流方向 // 长度为乙子弯长度1/2,三条线均分宽度 // 箭头7.5度 /* 0━━━━━━1 高标高 \ \ Start \ 4 End \ \ \ \ 2━━━━━━━━3 低标高 */ int nDrawMode(0); m_pXDataMap->GetAt(HOFF_VertDrawStyle, nDrawMode); if (1 == nDrawMode) { int nFlowDir(0); m_pXDataMap->GetAt(HVAC_FlowDirect, nFlowDir); AcGePoint3d ptArrorArr[5], ptRectArr[4]; ptRectArr[0] = ptDownArr[1].orthoProject(planStd); ptRectArr[1] = ptUpArr[1].orthoProject(planStd); ptRectArr[2] = ptUpArr[4].orthoProject(planStd); ptRectArr[3] = ptDownArr[4].orthoProject(planStd); double dLen = ptRectArr[0].distanceTo(ptRectArr[3]); double dWidth = ptRectArr[0].distanceTo(ptRectArr[1]); AcGeVector3d vtLen, vtWidth; vtLen = (ptRectArr[3] - ptRectArr[0]).normalize(); vtWidth = (ptRectArr[1] - ptRectArr[0]).normalize(); AcGeVector3d vtHook = vtWidth; double dHookOff = dLen/12 * tan(7.5/180.0*PI); if (dHookOff > dWidth/3) dHookOff = dWidth/3; if (nFlowDir == 0) // 起始点流向终点 { // 注:乙字弯的流向在外部没有使用,所以暂未考虑逆向的画法 AcGeVector3d vecTmp = ptEnd - ptStart; if(vecTmp.angleTo(TAuxTools::GetUcsXvt()) - PI * 0.5 < 1E-6) { ptArrorArr[0] = ptRectArr[0] + vtWidth * dWidth/3 + vtLen * dLen/4; ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; ptArrorArr[3] = ptRectArr[2] - vtWidth * dWidth/3 - vtLen * dLen/4; ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; ptArrorArr[4] = ptArrorArr[3] - vtLen * dLen/12; // 纠正末尾钩子方向 AcGeVector3d vtDirect = ptArrorArr[3] - ptArrorArr[0]; vtDirect.rotateBy(PI*0.5, TAuxTools::GetUcsZvt()); if (vtHook.angleTo(vtDirect) > PI*0.5) vtHook *= -1; ptArrorArr[4] += vtHook * dHookOff; } else { ptArrorArr[0] = ptRectArr[1] - vtWidth * dWidth/3 + vtLen * dLen/4; ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; ptArrorArr[3] = ptRectArr[3] + vtWidth * dWidth/3 - vtLen * dLen/4; ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; ptArrorArr[4] = ptArrorArr[3] - vtLen * dLen/12; AcGeVector3d vtDirect = ptArrorArr[3] - ptArrorArr[0]; vtDirect.rotateBy(PI*0.5, TAuxTools::GetUcsZvt()); if (vtHook.angleTo(vtDirect) < PI*0.5) vtHook *= -1; ptArrorArr[4] += vtHook * dHookOff; } } else { vtLen *= -1; ptArrorArr[0] = ptRectArr[3] + vtWidth * dWidth/3 + vtLen * dLen/4; ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; ptArrorArr[3] = ptRectArr[1] - vtWidth * dWidth/3 - vtLen * dLen/4; ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; ptArrorArr[4] = ptArrorArr[3] - vtLen * dLen/12; AcGeVector3d vtDirect = ptArrorArr[3] - ptArrorArr[0]; vtDirect.rotateBy(PI*0.5, TAuxTools::GetUcsZvt()); if (vtHook.angleTo(vtDirect) > PI*0.5) vtHook *= -1; ptArrorArr[4] += vtHook * dHookOff; } tCurveEle.dWidth = dEdgeWidth; tCurveEle.idSubLay.setNull(); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[0], ptArrorArr[1], ptArrorArr[1]); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[1], ptArrorArr[2], ptArrorArr[2]); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[2], ptArrorArr[3], ptArrorArr[3]); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[3], ptArrorArr[4], ptArrorArr[4]); } else if (2 == nDrawMode) { int nFlowDir(0); m_pXDataMap->GetAt(HVAC_FlowDirect, nFlowDir); AcGePoint3d ptArrorArr[5], ptRectArr[4]; ptRectArr[0] = ptDownArr[1].orthoProject(planStd); ptRectArr[1] = ptUpArr[1].orthoProject(planStd); ptRectArr[2] = ptUpArr[4].orthoProject(planStd); ptRectArr[3] = ptDownArr[4].orthoProject(planStd); double dLen = ptRectArr[0].distanceTo(ptRectArr[3]); double dWidth = ptRectArr[0].distanceTo(ptRectArr[1]); AcGeVector3d vtLen, vtWidth; vtLen = (ptRectArr[3] - ptRectArr[0]).normalize(); vtWidth = (ptRectArr[1] - ptRectArr[0]).normalize(); AcGeVector3d vtHook = vtWidth; double dHookOff = dLen/12 * tan(7.5/180.0*PI); if (dHookOff > dWidth/3) dHookOff = dWidth/3; if (nFlowDir == 0) // 起始点流向终点 { // 注:乙字弯的流向在外部没有使用,所以暂未考虑逆向的画法 AcGeVector3d vecTmp = ptEnd - ptStart; if(vecTmp.angleTo(TAuxTools::GetUcsXvt()) - PI * 0.5 < 1E-6) { ptArrorArr[0] = ptRectArr[0] + vtWidth * dWidth/3 + vtLen * dLen/4; ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; ptArrorArr[3] = ptRectArr[2] - vtWidth * dWidth/3 - vtLen * dLen/4; ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; } else { ptArrorArr[0] = ptRectArr[1] - vtWidth * dWidth/3 + vtLen * dLen/4; ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; ptArrorArr[3] = ptRectArr[3] + vtWidth * dWidth/3 - vtLen * dLen/4; ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; } } else { vtLen *= -1; ptArrorArr[0] = ptRectArr[3] + vtWidth * dWidth/3 + vtLen * dLen/4; ptArrorArr[1] = ptArrorArr[0] + vtLen * dLen/6; ptArrorArr[3] = ptRectArr[1] - vtWidth * dWidth/3 - vtLen * dLen/4; ptArrorArr[2] = ptArrorArr[3] - vtLen * dLen/6; } tCurveEle.dWidth = dEdgeWidth; tCurveEle.idSubLay.setNull(); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[0], ptArrorArr[1], ptArrorArr[1]); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[1], ptArrorArr[2], ptArrorArr[2]); AutoAppendPt(cplCurve, tCurveEle, ptArrorArr[2], ptArrorArr[3], ptArrorArr[3]); } } return Acad::eOk; } /* 0━7 ┃ \ ┃ \ S ┃ \ ┃ \ ┃ \ 1━2 6━ 5 \ ┃ \ ┃ \ ┃ \ ┃ E \ ┃ 3━4 */ void ImpHvacOffset::GetMidKeyPoints( AcGePoint3dArray &ptArr, BOOL bSingleLine /*= FALSE*/ ) const { ASSERT(NULL != m_pXDataMap); AcGePoint3d ptS, ptE; m_pXDataMap->GetAt(HOFF_StartPoint, ptS); m_pXDataMap->GetAt(HOFF_EndPoint, ptE); AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); AcGeVector3d vtStaSide(vtStart), vtEndSide(vtEnd); AcGeVector3d vtPerl = normal(); vtStaSide.rotateBy(PI*0.5, vtPerl); vtEndSide.rotateBy(PI*0.5, vtPerl); double dStaWidth(0.0), dEndWidth(0.0), dHeigh(0.0), dPluse(0); m_pXDataMap->GetAt(HOFF_Thick, dHeigh); m_pXDataMap->GetAt(HVAC_PlusEdge, dPluse); if (bSingleLine) { m_pXDataMap->GetAt(KEY_HIDEWIDTH, dStaWidth); // 遮挡宽度 dEndWidth = dStaWidth; } else { m_pXDataMap->GetAt(HOFF_StartWidth, dStaWidth); m_pXDataMap->GetAt(HOFF_EndWidth, dEndWidth); ESection eSectType = eRect; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); if (eSectType ==eCircle) dEndWidth = dStaWidth; } AcGePoint3d ptTempArr[8]; ptTempArr[0] = ptS - dStaWidth * 0.5 * vtStaSide; ptTempArr[1] = ptTempArr[0] + dStaWidth * vtStaSide; ptTempArr[4] = ptE - dEndWidth * 0.5 * vtEndSide; ptTempArr[5] = ptTempArr[4] + dEndWidth * vtEndSide; ptTempArr[2] = ptTempArr[1] - dPluse * vtStart; ptTempArr[7] = ptTempArr[0] - dPluse * vtStart; ptTempArr[3] = ptTempArr[4] - dPluse * vtEnd; ptTempArr[6] = ptTempArr[5] - dPluse * vtEnd; int i(0); for (i = 0; i < 8; i++) { ptArr.append(ptTempArr[i]); } } BOOL ImpHvacOffset::GetTwoSideKeyPoints( AcGePoint3dArray &ptUpArr, AcGePoint3dArray &ptDownArr, BOOL bSingleLine /*= FALSE*/ ) const { GetMidKeyPoints(ptUpArr, bSingleLine); if (ptUpArr.length() < 1) return FALSE; AcGeVector3d vtPerl = normal(); double dThick(0.0); m_pXDataMap->GetAt(HOFF_Thick, dThick); ESection eSect = eRect; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSect); if (eSect ==eCircle) m_pXDataMap->GetAt(HOFF_Diameter, dThick); AcGeVector3d vtOffSet = dThick * vtPerl * 0.5; int i(0); for (i = 0; i < ptUpArr.length(); i++) { ptDownArr.append(ptUpArr[i] - vtOffSet); ptUpArr[i] += vtOffSet; } return TRUE; } BOOL ImpHvacOffset::GetArcBaseKeyPt( AcGePoint3dArray &ptKeyArr ) const { AcGePoint3d ptStart, ptEnd, ptMid; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); ptMid = TAuxTools::Mid(ptStart, ptEnd); AcGeVector3d vtUserZAixs = normal(); AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); double dPluse(0.0); m_pXDataMap->GetAt(HVAC_PlusEdge, dPluse); AcGePoint3d ptStartArc = ptStart - dPluse * vtStart; // 起始端弧开始点 AcGePoint3d ptEndArc = ptEnd - dPluse * vtEnd; //末端弧开始点 // 起始端弧 AcGeVector3d vtStartPer(vtStart); vtStartPer.rotateBy(PI * 0.5, vtUserZAixs); AcGeLine3d lineStaPer(ptStartArc, ptStartArc + 100 * vtStartPer); AcGePoint3d ptStaMid = TAuxTools::Mid(ptStartArc, ptMid); AcGeVector3d vtMidPer = ptEndArc - ptStartArc; vtMidPer.rotateBy(PI * 0.5, vtUserZAixs); vtMidPer.normalize(); AcGeLine3d lineStartMidPer(ptStaMid, ptStaMid + 100 * vtMidPer); AcGePoint3d ptStaCenter; // 起始端弧圆心 if (lineStaPer.intersectWith(lineStartMidPer, ptStaCenter) != Adesk::kTrue) return FALSE; AcGeVector3d vtStartArc = ptStaMid - ptStaCenter; if (vtStartArc.angleTo(vtStart) < PI * 0.5) vtStartArc *= -1; vtStartArc.normalize(); double dStartRadius = ptStartArc.distanceTo(ptStaCenter); AcGePoint3d ptStarArcMid = ptStaCenter + dStartRadius * vtStartArc; // 起始端弧中点 // 末端弧 AcGeVector3d vtEndPer(vtEnd); vtEndPer.rotateBy(PI * 0.5, vtUserZAixs); AcGeLine3d lineEndPer(ptEndArc, ptEndArc + 100 * vtEndPer); AcGePoint3d ptEndMid = TAuxTools::Mid(ptEndArc, ptMid); AcGeLine3d lineEndMidPer(ptEndMid, ptEndMid + 100 * vtMidPer); AcGePoint3d ptEndCenter; // 末端弧圆心 if (lineEndPer.intersectWith(lineEndMidPer, ptEndCenter) != Adesk::kTrue) return FALSE; AcGeVector3d vtEndArc = ptEndMid - ptEndCenter; if (vtEndArc.angleTo(vtEnd) < PI * 0.5) vtEndArc *= -1; vtEndArc.normalize(); double dEndRadius = ptEndArc.distanceTo(ptEndCenter); AcGePoint3d ptEndArcMid = ptEndCenter + dEndRadius * vtEndArc; // 末端弧中点 ptKeyArr.append(ptStart); ptKeyArr.append(ptStartArc); ptKeyArr.append(ptStarArcMid); ptKeyArr.append(ptMid); ptKeyArr.append(ptEndArcMid); ptKeyArr.append(ptEndArc); ptKeyArr.append(ptEnd); return TRUE; } BOOL ImpHvacOffset::GetArcTwoSideKeyPt( AcGePoint3dArray &ptArrLeft, AcGePoint3dArray &ptArrRight, BOOL bSingleLine /*= FALSE*/ ) const { AcGePoint3dArray ptBaseArr; if (!GetArcBaseKeyPt(ptBaseArr)) return FALSE; AcGePoint3d ptStart, ptEnd, ptMid; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); ptMid = TAuxTools::Mid(ptStart, ptEnd); double dHalfStartWidth(0.0), dHalfEndWidth(0.0); if (bSingleLine) { m_pXDataMap->GetAt(KEY_HIDEWIDTH, dHalfStartWidth); // 遮挡宽度 dHalfEndWidth = dHalfStartWidth; } else { m_pXDataMap->GetAt(HOFF_StartWidth, dHalfStartWidth); m_pXDataMap->GetAt(HOFF_EndWidth, dHalfEndWidth); ESection eSectType = eRect; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); if (eSectType ==eCircle) m_pXDataMap->GetAt(HOFF_Diameter, dHalfEndWidth); } dHalfStartWidth *= 0.5; dHalfEndWidth *= 0.5; AcGeVector3d vtUserZAixs = normal(); AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); AcGeVector3d vtMidPer = ptEnd - ptStart; vtMidPer.rotateBy(PI * 0.5, vtUserZAixs); vtMidPer.normalize(); AcGeVector3d vtStartPer(vtStart), vtEndPer(vtEnd); vtStartPer.rotateBy(PI * 0.5, vtUserZAixs); vtEndPer.rotateBy(PI * 0.5, vtUserZAixs); // 左边(从起始端法向方向 往末端法向看) double dEverWidth = (dHalfStartWidth + dHalfEndWidth) * 0.5; AcGeCircArc3d arc(ptBaseArr[1], ptBaseArr[2], ptBaseArr[3]); AcGePoint3d ptCenter = arc.center(); AcGeVector3d vtMid = ptMid - ptCenter; vtMid.normalize(); AcGeVector3d vtStartMid = ptBaseArr[2] - ptCenter; // 起始端弧中点到圆心的向量 vtStartMid.normalize(); if (vtStartMid.angleTo(vtStartPer) > PI * 0.5) { vtStartMid *= -1; vtMid *= -1; } ptArrLeft.append(ptStart - dHalfStartWidth * vtStartPer); ptArrLeft.append(ptBaseArr[1] - dHalfStartWidth * vtStartPer); ptArrLeft.append(ptBaseArr[2] - dEverWidth * vtStartMid); ptArrLeft.append(ptMid - dHalfEndWidth * vtMid); arc.set(ptBaseArr[3], ptBaseArr[4], ptBaseArr[5]); ptCenter = arc.center(); AcGeVector3d vtEndMid = ptBaseArr[4] - ptCenter; // 末端弧中点到圆心的向量 vtEndMid.normalize(); if (vtEndMid.angleTo(vtEndPer) > PI * 0.5) { vtEndMid *= -1; } ptArrLeft.append(ptBaseArr[4] + dHalfEndWidth * vtEndMid); ptArrLeft.append(ptBaseArr[5] + dHalfEndWidth * vtEndPer); ptArrLeft.append(ptEnd + dHalfEndWidth * vtEndPer); // 右边 vtStartMid *= -1; vtMid *= -1; vtEndMid *= -1; ptArrRight.append(ptStart + dHalfStartWidth * vtStartPer); ptArrRight.append(ptBaseArr[1] + dHalfStartWidth * vtStartPer); ptArrRight.append(ptBaseArr[2] - dEverWidth * vtStartMid); ptArrRight.append(ptMid - dHalfEndWidth * vtMid); ptArrRight.append(ptBaseArr[4] + dHalfEndWidth * vtEndMid); ptArrRight.append(ptBaseArr[5] - dHalfEndWidth * vtEndPer); ptArrRight.append(ptEnd - dHalfEndWidth * vtEndPer); return TRUE; } void ImpHvacOffset::GetAllMinAnglePt( AcGePoint3dArray &ptArrLeftPart, AcGePoint3dArray &ptArrRightPart, BOOL bSingleLine /*= FALSE*/ ) const { AcGePoint3dArray ptLeftArr, ptRightArr; if (!GetArcTwoSideKeyPt(ptLeftArr, ptRightArr, bSingleLine)) return; if (7 != ptLeftArr.length() || 7 != ptRightArr.length()) return; AcGeVector3d vtNormal = normal(); double dMinAngle(TAuxTools::GetMinDiffAngle()); // 首端法兰边直部分 ptArrLeftPart.append(ptLeftArr[0]); ptArrLeftPart.append(ptLeftArr[1]); ptArrRightPart.append(ptRightArr[0]); ptArrRightPart.append(ptRightArr[1]); // 起始端左侧 AcGeCircArc3d arcStartLeft(ptLeftArr[1], ptLeftArr[2], ptLeftArr[3]); AcGePoint3d ptStaLeftCent = arcStartLeft.center(); double dStaLeftAngle = arcStartLeft.endAng() - arcStartLeft.startAng(); int nStartLeftPartNum = int(dStaLeftAngle / dMinAngle) + 1; // 起始端右侧 AcGeCircArc3d arcStartRight(ptRightArr[1], ptRightArr[2], ptRightArr[3]); AcGePoint3d ptStaRightCent = arcStartRight.center(); double dStaRightAngle = arcStartRight.endAng() - arcStartRight.startAng(); int nStartRightPartNum = int(dStaRightAngle / dMinAngle) + 1; // 按最大数目划分 int nStartMaxNum = nStartLeftPartNum > nStartRightPartNum ? nStartLeftPartNum : nStartRightPartNum; double dStartLeftMinAngle = dStaLeftAngle / nStartMaxNum; DOUBLE dStartRightMinAngle = dStaRightAngle / nStartMaxNum; AcGePoint3d ptLeftNow, ptRightNow; ptLeftNow = ptLeftArr[1]; ptRightNow = ptRightArr[1]; int i(0); for (i = 0; i < nStartMaxNum - 1; i++) { ptLeftNow.rotateBy(dStartLeftMinAngle, -vtNormal, ptStaLeftCent); ptRightNow.rotateBy(dStartRightMinAngle, -vtNormal, ptStaRightCent); ptArrLeftPart.append(ptLeftNow); ptArrRightPart.append(ptRightNow); } ptArrLeftPart.append(ptLeftArr[3]); ptArrRightPart.append(ptRightArr[3]); // 末端左侧 AcGeCircArc3d arcEndLeft(ptLeftArr[3], ptLeftArr[4], ptLeftArr[5]); AcGePoint3d ptEndLeftCent = arcEndLeft.center(); double dEndLeftAngle = arcEndLeft.endAng() - arcEndLeft.startAng(); int nEndLeftPartNum = int(dEndLeftAngle / dMinAngle) + 1; double dEndLeftMinAngle = dEndLeftAngle / nEndLeftPartNum; // 末端右侧 AcGeCircArc3d arcEndRight(ptRightArr[3], ptRightArr[4], ptRightArr[5]); AcGePoint3d ptEndRightCent = arcEndRight.center(); double dEndRightAngle = arcEndRight.endAng() - arcEndRight.startAng(); int nEndRightPartNum = int(dEndRightAngle / dMinAngle) + 1; double dEndRightMinAngle = dEndRightAngle / nEndRightPartNum; // 按最大数目划分 int nEndMaxNum = nEndLeftPartNum > nEndRightPartNum ? nEndLeftPartNum : nEndRightPartNum; dEndLeftMinAngle = dEndLeftAngle / nEndMaxNum; dEndRightMinAngle = dEndRightAngle / nEndMaxNum; ptLeftNow = ptLeftArr[3]; ptRightNow = ptRightArr[3]; for (i = 0; i < nEndMaxNum - 1; i++) { ptLeftNow.rotateBy(dEndLeftMinAngle, vtNormal, ptEndLeftCent); ptRightNow.rotateBy(dEndRightMinAngle, vtNormal, ptEndRightCent); ptArrLeftPart.append(ptLeftNow); ptArrRightPart.append(ptRightNow); } // 末端法兰部分 ptArrLeftPart.append(ptLeftArr[5]); ptArrLeftPart.append(ptLeftArr[6]); ptArrRightPart.append(ptRightArr[5]); ptArrRightPart.append(ptRightArr[6]); } BOOL ImpHvacOffset::IsCanDraw() const { if (NULL == m_pXDataMap) return FALSE; // 增加控制形态判断。2010.04.08 if (!IsHorzAlignment() && !IsSideVertAlignment() && !IsFaceVertAlignment()) return FALSE; AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); if (ptStart.distanceTo(ptEnd) < 1e-3) return FALSE; // 首尾法向量必须不同向平行 AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); if (!vtStart.isParallelTo(vtEnd) || vtStart.isCodirectionalTo(vtEnd)) return FALSE; // 首尾点方向与首尾法向量判断 AcGeVector3d vtDirect = ptEnd - ptStart; double dMaxAngle(PI * 0.5 - 0.1), dMinAngle(1e-3); if (vtDirect.angleTo(vtEnd) > dMaxAngle || vtDirect.angleTo(vtEnd) < dMinAngle) return FALSE; AecHvac::HvacOffsetType eType =AecHvac::eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); if (eType ==AecHvac::eArcuateLink) { AcGePoint3dArray ptLeftArr, ptRightArr; if (!GetArcTwoSideKeyPt(ptLeftArr, ptRightArr)) return FALSE; double dSmallDist = ptLeftArr[3].distanceTo(ptStart); double dBigDist = ptLeftArr[4].distanceTo(ptStart); if (dBigDist < dSmallDist) return FALSE; // 因为起始端有可能有变径,右侧也判断一下 dSmallDist = ptRightArr[1].distanceTo(ptStart); dBigDist = ptRightArr[2].distanceTo(ptStart); if (dBigDist < dSmallDist) return FALSE; } return TRUE; } AcDbObjectId ImpHvacOffset::GetBaseLayerId() const { return m_idDoubleLayer; } double ImpHvacOffset::GetEdgeLineWidth() const { ASSERT(NULL != m_pXDataMap); double dWidth(0.0); m_pXDataMap->GetAt(HVAC_EdgeWidth, dWidth); return dWidth; } double ImpHvacOffset::GetCentLineWidth() const { ASSERT(NULL != m_pXDataMap); double dWidth(0.0); m_pXDataMap->GetAt(HVAC_CentWidth, dWidth); return dWidth; } double ImpHvacOffset::GetEndLineWidth() const { ASSERT(NULL != m_pXDataMap); double dWidth(0.0); m_pXDataMap->GetAt(HVAC_EndWidth, dWidth); return dWidth; } double ImpHvacOffset::GetAngle() const { ASSERT(NULL != m_pXDataMap); // 基本参数 AecHvac::HvacOffsetType eType = AecHvac::eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); double dFlangPlus(0.0); m_pXDataMap->GetAt(HVAC_PlusEdge, dFlangPlus); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtStart, vtEnd, vtOffSet; m_pXDataMap->GetAt(HOFF_StartDir, vtStart); m_pXDataMap->GetAt(HOFF_EndDir, vtEnd); // 先反求角度,再根据角度求末点,角度不变 AcGePoint3d ptArcStart = ptStart - vtStart * dFlangPlus; AcGePoint3d ptArcEnd = ptEnd - vtEnd * dFlangPlus; double dAngle = (ptArcEnd - ptArcStart).angleTo(vtEnd); if (dAngle > PI*0.5) dAngle = PI - dAngle; if (AecHvac::eArcuateLink == eType) { dAngle = PI*0.5 - dAngle; dAngle = PI - dAngle * 2; } return dAngle; } AcGePoint3d ImpHvacOffset::GetEndPointByAngle() { ASSERT(NULL != m_pXDataMap); // 基本参数 AecHvac::HvacOffsetType eType = AecHvac::eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); double dAngle(0.0), dFlangPlus(0.0); m_pXDataMap->GetAt(HVAC_PlusEdge, dFlangPlus); m_pXDataMap->GetAt(HOFF_Angle, dAngle); AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); AcGeVector3d vtStart, vtOffSet; m_pXDataMap->GetAt(HOFF_StartDir, vtStart); vtOffSet = ptEnd - ptStart; vtOffSet = vtOffSet.orthoProject(vtStart); // 求末点 double dPerlDist = vtOffSet.length(); // 向下偏移的距离 double dHorizLen(0.0); // 水平偏移距离 if (AecHvac::eArcuateLink == eType) // 双弧Angle:表示弯头角度 dHorizLen = dPerlDist / tan(dAngle * 0.5); // 水平偏移距离 else if (AecHvac::eLinearLink == eType) // 角接时,dAngle:表示倾斜角度 dHorizLen = dPerlDist / tan(dAngle); AcGePoint3d ptArcSta = ptStart - dFlangPlus * vtStart;// 弧开始点 ptEnd = ptArcSta + vtOffSet - (dHorizLen + dFlangPlus) * vtStart; return ptEnd; } AcGePoint3d ImpHvacOffset::GetEndPtByLength() { ASSERT(NULL != m_pXDataMap); // 基本参数 AecHvac::HvacOffsetType eType = AecHvac::eArcuateLink; m_pXDataMap->GetAt(HOFF_Type, (int&)eType); double dLength(0.0), dOffset(0.0), dFlangPlus(0.0); m_pXDataMap->GetAt(HVAC_PlusEdge, dFlangPlus); m_pXDataMap->GetAt(HOFF_Length, dLength); m_pXDataMap->GetAt(HOFF_Offset, dOffset); double dOffsetArcLength = dLength - 2 * dFlangPlus; if (dOffsetArcLength > 0.1) { double dAngle = atan(dOffset / dOffsetArcLength); if (AecHvac::eArcuateLink == eType) dAngle *= 2; m_pXDataMap->SetAt(HOFF_Angle, dAngle); return GetEndPointByAngle(); } return AcGePoint3d::kOrigin; } BOOL ImpHvacOffset::GetInterfaceSizeData(int nIndex, AecInterface& inf) const { if(NULL == m_pXDataMap) return FALSE; // 获取截面类型 ESection eSectType = eRect; m_pXDataMap->GetAt(HVAC_SectType, (int&)eSectType); // 获取接口截面、宽度、厚度数据key值 LPCTSTR pszWidthKey, pszThickKey; switch (nIndex) { case 0: pszWidthKey = ((eCircle == eSectType) ? HOFF_Diameter : HOFF_StartWidth); pszThickKey = HOFF_Thick; break; case 1: pszWidthKey = ((eCircle == eSectType) ? HOFF_Diameter : HOFF_EndWidth); pszThickKey = HOFF_Thick; break; default: return FALSE; } // 获取尺寸 double dWidth = 0.0, dThick = 0.0; m_pXDataMap->GetAt(pszWidthKey, dWidth); m_pXDataMap->GetAt(pszThickKey, dThick); // 设置接口数据 inf.nSectType = eSectType; inf.dSize1 = dWidth; inf.dSize2 = dThick; return TRUE; } bool ImpHvacOffset::GetInterface(AcArray& arInfs) const { if (NULL == m_pXDataMap) return FALSE; // 获取各点位置 AcGePoint3d ptStart, ptEnd; m_pXDataMap->GetAt(HOFF_StartPoint, ptStart); m_pXDataMap->GetAt(HOFF_EndPoint, ptEnd); // 求各端方向 AcGeVector3d vtStart(StartVect()), vtEnd(EndVect()); AecInterface inf; for (int nIndex = 0;nIndex < 2;nIndex++) { switch(nIndex) { case 0: { inf.vtDir = vtStart; inf.ptPos = ptStart; inf.idOwner = m_pOwnerEnt->objectId(); GetInterfaceSizeData(nIndex, inf); break; } case 1: { inf.vtDir = vtEnd; inf.ptPos = ptEnd; inf.idOwner = m_pOwnerEnt->objectId(); GetInterfaceSizeData(nIndex, inf); break; } } arInfs.append(inf); } return true; }