#include "stdafx.h" #include "TAuxTools.h" #include "math.h" #include "TImpSpecFitting.h" #include "TImpSpecEquipment.h" using namespace std; #define ZERO_AIR 1.0e-6 // 取得接口记录指针 外部使用 DLLIMPEXP TDbInterfaceRecord* GetInterfacePtr() { return TAuxTools::GetIntfPtrFromDB(); } // 写入暖通动态扩展数据到图纸中 DLLIMPEXP void SetTHvacParamToDwg(LPCTSTR pszKey = NULL) { if(NULL == pszKey) { BOOL bShowCover = FALSE; // 显示遮挡 GetGlobalContext()->GetAt(KEY_HIDEDRAW, bShowCover); TAuxTools::SetTHvacDataToDwg(KEY_HIDEDRAW, bShowCover); double dHideWidth = 0; // 打断间隙 GetGlobalContext()->GetAt(HVAC_HIDEEXTENT, dHideWidth); TAuxTools::SetTHvacDataToDwg(HVAC_HIDEEXTENT, dHideWidth); BOOL bShowWidth = FALSE; // 是否加粗 GetGlobalContext()->GetAt(HVAC_SHOWWIDTH, bShowWidth); TAuxTools::SetTHvacDataToDwg(HVAC_SHOWWIDTH, bShowWidth); double dBrWidth = 0; // 水管风管打断间隙 GetGlobalContext()->GetAt(HVAC_PIPEHIDEWIDTH, dBrWidth); TAuxTools::SetTHvacDataToDwg(HVAC_PIPEHIDEWIDTH, dBrWidth); BOOL bPipeDuctBreak = FALSE; // 风管与水管打断 GetGlobalContext()->GetAt(HVAC_PIPEDUCTBREAK, bPipeDuctBreak); TAuxTools::SetTHvacDataToDwg(HVAC_PIPEDUCTBREAK, bPipeDuctBreak); } else { if(0 == _tcscmp(pszKey, KEY_HIDEDRAW) || 0 == _tcscmp(pszKey, HVAC_SHOWWIDTH) || 0 == _tcscmp(pszKey, HVAC_PIPEDUCTBREAK)) { BOOL bValue = FALSE; if(GetGlobalContext()->GetAt(pszKey, bValue)) { TAuxTools::SetTHvacDataToDwg(pszKey, bValue); } } else if(0 == _tcscmp(pszKey, HVAC_HIDEEXTENT) || 0 == _tcscmp(pszKey, HVAC_PIPEHIDEWIDTH)) { double dValue = 0; if(GetGlobalContext()->GetAt(pszKey, dValue)) { TAuxTools::SetTHvacDataToDwg(pszKey, dValue); } } } } // 从图纸中读取暖通风管遮挡参数 DLLIMPEXP void GetTHvacParamFromDwg() { BOOL bShowCover = FALSE; // 显示遮挡 if(TAuxTools::GetTHvacDataFromDwg(KEY_HIDEDRAW, bShowCover)) { GetGlobalContext()->SetAt(KEY_HIDEDRAW, bShowCover); } double dHideWidth = 0; // 打断间隙 if(TAuxTools::GetTHvacDataFromDwg(HVAC_HIDEEXTENT, dHideWidth)) { // add by hh 2011-10-11 支持遮挡宽度随比例变化 if(10 < dHideWidth) { // 兼容旧版图纸,宽度大于10时,认为是旧版数据,转换为新版的 dHideWidth /= DocGetPScale(); TAuxTools::SetTHvacDataToDwg(HVAC_HIDEEXTENT, dHideWidth); } GetGlobalContext()->SetAt(HVAC_HIDEEXTENT, dHideWidth); } BOOL bShowWidth = FALSE; // 是否加粗 if(TAuxTools::GetTHvacDataFromDwg(HVAC_SHOWWIDTH, bShowWidth)) { GetGlobalContext()->SetAt(HVAC_SHOWWIDTH, bShowWidth); } // add by hh 2011-01-05 兼容8.2版图纸 else { AcDbBlockTable* pBlockTable = NULL; AcDbBlockTableRecord* pTableRecord = NULL; if(acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead) != Acad::eOk) return; pBlockTable->close(); if(pBlockTable->getAt(ACDB_MODEL_SPACE, pTableRecord, AcDb::kForRead) != Acad::eOk) return; pTableRecord->close(); bShowWidth = (BOOL)_ttoi(TAuxTools::ReadXdata(pTableRecord->id(), HVAC_SHOWWIDTH)); GetGlobalContext()->SetAt(HVAC_SHOWWIDTH, bShowWidth); // 将是否加粗标识写入动态扩展数据中 转换为8.5版图纸 //bsl 2011.10.26 增加暖通判断 // change by hh 2013-03-25 暖通标准版ID从6改成15 // if (g_nProductId == 6 || g_nProductId == 5) if (g_nProductId == 15 || g_nProductId == 5) TAuxTools::SetTHvacDataToDwg(HVAC_SHOWWIDTH, bShowWidth); } double dBrWidth = 0; // 水管风管打断间隙 if(TAuxTools::GetTHvacDataFromDwg(HVAC_PIPEHIDEWIDTH, dBrWidth)) { GetGlobalContext()->SetAt(HVAC_PIPEHIDEWIDTH, dBrWidth); } BOOL bPipeDuctBreak = FALSE; // 风管与水管打断 if(TAuxTools::GetTHvacDataFromDwg(HVAC_PIPEDUCTBREAK, bPipeDuctBreak)) { GetGlobalContext()->SetAt(HVAC_PIPEDUCTBREAK, bPipeDuctBreak); } } AcGePoint3d TAuxTools::Mid(AcGePoint3d ptGe1, AcGePoint3d ptGe2) { return AcGePoint3d((ptGe1.x + ptGe2.x) / 2.0,(ptGe1.y + ptGe2.y) / 2.0,(ptGe1.z + ptGe2.z) / 2.0); } /* 两圆相交法求椭圆法点图 O2 D | | A--O1--------O-----------B | F | C */ // int TAuxTools::GetEllipseFromCircle( AcGePoint3d ptCenter, double dDia, AcGeVector3d vtOrigNormal, // AcGeVector3d vtNewNormal, AcDbPolyline &polyLine, AcGeVector3d vtGet) // { // vtOrigNormal.normalize(); // vtNewNormal.normalize(); // // double dRadius = dDia * 0.5; // AcGePlane planStd; // 椭圆投影所在标准面 // planStd.set(ptCenter, vtNewNormal); // AcGePoint3d ptPrj = AcGePoint3d::kOrigin.orthoProject(planStd); // planStd.set(ptPrj, vtNewNormal); // double dEle = ptPrj.asVector().length(); // if (!ptPrj.asVector().isCodirectionalTo(planStd.normal())) // { // dEle *= -1.0; // } // if (vtNewNormal.isParallelTo(vtOrigNormal)) // 平行,还是圆 // { // AcGePoint3d ptStart, ptEnd; // if (vtGet.length() < 1e-6) // 整个圆 // { // AcGeVector3d vtPerl = vtOrigNormal.perpVector(); // // ptStart = ptCenter + dRadius * vtPerl; // ptEnd = ptCenter - dRadius * vtPerl; // polyLine.addVertexAt(0, ptStart.convert2d(planStd), 1.0); // polyLine.addVertexAt(1, ptEnd.convert2d(planStd), 1.0); // polyLine.setClosed(Adesk::kTrue); // } // else // 半个圆 // { // AcGeVector3d vtPerl = vtGet.orthoProject(vtNewNormal); // vtPerl.rotateBy(-PI / 2, vtNewNormal); // vtPerl.normalize(); // // ptStart = ptCenter + dRadius * vtPerl; // ptEnd = ptCenter - dRadius * vtPerl; // polyLine.addVertexAt(0, ptStart.convert2d(planStd), 1); // polyLine.addVertexAt(1, ptEnd.convert2d(planStd), 0); // } // // polyLine.setElevation(dEle); // polyLine.setNormal(vtNewNormal); // return 0; // } // else if (vtNewNormal.isPerpendicularTo(vtOrigNormal)) // 垂直情况, 为直线 // { // AcGeVector3d vtCrossPerl = vtOrigNormal.crossProduct(vtNewNormal); // AcGePoint3d ptStart, ptEnd; // ptStart = ptCenter + dRadius * vtCrossPerl; // ptEnd = ptCenter - dRadius * vtCrossPerl; // polyLine.addVertexAt(0, ptStart.convert2d(planStd)); // polyLine.addVertexAt(1, ptEnd.convert2d(planStd)); // polyLine.setElevation(dEle); // polyLine.setNormal(vtNewNormal); // return 1; // } // else // 普通投影为椭圆情况 // { // // 长/短轴向量 // AcGeVector3d vtLong = vtOrigNormal.crossProduct(vtNewNormal); // vtLong.normalize(); // AcGeVector3d vtShort = vtLong; // vtShort.rotateBy(PI * 0.5, vtOrigNormal); // // // 把向量投影到所给面上 // vtLong = vtLong.orthoProject(vtNewNormal); // vtShort = vtShort.orthoProject(vtNewNormal); // // AcGePoint3d ptO = ptCenter.orthoProject(planStd); // 中心点 // AcGePoint3d ptA = ptO + dDia * 0.5 * vtLong; // A // AcGePoint3d ptB = ptA - dDia * vtLong; // B // AcGePoint3d ptC = ptO + dDia * 0.5 * vtShort; // C // AcGePoint3d ptD = ptC - dDia * vtShort; // D // // double CF = dDia / 2 - ptC.distanceTo(ptD) / 2; // AcGeVector3d vtCF = ptA - ptC; // vtCF.normalize(); // AcGePoint3d ptF = ptC + CF * vtCF; // // AcGeLine3d lineAB(ptA, ptB); // AcGeLine3d lineCD(ptC, ptD); // AcGeLine3d lineAF(ptA, ptF); // // // 求线AF的中垂线 // AcGeVector3d vtAFPerl = ptF - ptA; // vtAFPerl.rotateBy(PI * 0.5, vtNewNormal); // AcGePoint3d ptAFMid = Mid(ptA, ptF); // AcGeLine3d lineAFPerl(ptAFMid, ptAFMid + 100 * vtAFPerl); // // AcGePoint3d ptO1, ptO2; // 两个辅助圆圆心O1 O2 // lineAFPerl.intersectWith(lineAB, ptO1); // lineAFPerl.intersectWith(lineCD, ptO2); // // double dRad1 = ptO1.distanceTo(ptA); // 两圆对应半径 // double dRad2 = ptO2.distanceTo(ptC); // // // 构造两个圆,求交点,为两弧邻接点 // AcGeCircArc3d cir1(ptO1, vtNewNormal, dRad1); // AcGeCircArc3d cir2(ptO2, vtNewNormal, dRad2); // AcGePoint3d ptCross, ptCross2; // int nSucsId(0); // cir1.intersectWith(cir2, nSucsId, ptCross, AcGePoint3d()); // // if (nSucsId < 1) // return -1; // // // 镜像后得到其他3个邻接点 // AcGePoint3d ptCrossLongMir(ptCross), ptCrossShortMir(ptCross), ptCrossInclinMir; // AcGePlane planAB(ptO, ptC - ptD); // AcGePlane planCD(ptO, ptA - ptB); // ptCrossLongMir.mirror(planAB); // ptCrossShortMir.mirror(planCD); // ptCrossInclinMir = ptCrossShortMir; // ptCrossInclinMir.mirror(planAB); // // // 求两种弧bulge值 // AcGePoint3d ptMidCorss1 = Mid(ptCross, ptCrossLongMir); // AcGePoint3d ptMidCorss2 = Mid(ptCross, ptCrossShortMir); // double dBulge1 = ptMidCorss1.distanceTo(ptA) / ptMidCorss1.distanceTo(ptCross); // double dBulge2 = ptMidCorss2.distanceTo(ptC) / ptMidCorss2.distanceTo(ptCross); // // // 矫正Bulge正负值 // AcGeVector3d vtClockSta = ptCrossShortMir - ptCross; // AcGeVector3d vtClockEnd = ptCrossLongMir - ptCross; // AcGeVector3d vtClockPerl = vtClockSta.crossProduct(vtClockEnd); // if (!vtClockPerl.isCodirectionalTo(vtNewNormal)) // { // dBulge1 *= -1; // dBulge2 *= -1; // } // // if (vtGet.length() < 1e-6) // { // polyLine.addVertexAt(0, ptCross.convert2d(planStd), dBulge2); // polyLine.addVertexAt(1, ptCrossShortMir.convert2d(planStd), dBulge1); // polyLine.addVertexAt(2, ptCrossInclinMir.convert2d(planStd), dBulge2); // polyLine.addVertexAt(3, ptCrossLongMir.convert2d(planStd), dBulge1); // polyLine.setClosed(Adesk::kTrue); // } // else // { // vtGet = vtGet.orthoProject(vtNewNormal); // if (vtGet.angleTo(vtShort) < PI*0.5) // C 端部分 // { // polyLine.addVertexAt(0, ptA.convert2d(planStd), dBulge1*0.5); // polyLine.addVertexAt(1, ptCross.convert2d(planStd), dBulge2); // polyLine.addVertexAt(2, ptCrossShortMir.convert2d(planStd), dBulge1*0.5); // polyLine.addVertexAt(3, ptB.convert2d(planStd)); // } // else // D 端部分 // { // polyLine.addVertexAt(0, ptB.convert2d(planStd), dBulge1*0.5); // polyLine.addVertexAt(1, ptCrossInclinMir.convert2d(planStd), dBulge2); // polyLine.addVertexAt(2, ptCrossLongMir.convert2d(planStd), dBulge1*0.5); // polyLine.addVertexAt(3, ptA.convert2d(planStd)); // } // } // } // // polyLine.setElevation(dEle); // polyLine.setNormal(vtNewNormal); // // return 2; // } int TAuxTools::GetEllipseFromCircle( AcGePoint3d ptCenter, double dDia, AcGeVector3d vtOrigNormal, AcGeVector3d vtNewNormal, AcDbPolyline &polyLine, AcGeVector3d vtGet) { vtOrigNormal.normalize(); vtNewNormal.normalize(); double dRadius = dDia * 0.5; AcGePlane planStd; // 椭圆投影所在标准面 planStd.set(ptCenter, vtNewNormal); AcGePoint3d ptPrj = AcGePoint3d::kOrigin.orthoProject(planStd); planStd.set(ptPrj, vtNewNormal); double dEle = ptPrj.asVector().length(); if (!ptPrj.asVector().isCodirectionalTo(planStd.normal())) { dEle *= -1.0; } if (vtNewNormal.isParallelTo(vtOrigNormal)) // 平行,还是圆 { AcGePoint3d ptStart, ptEnd; if (vtGet.length() < 1e-6) // 整个圆 { AcGeVector3d vtPerl = vtOrigNormal.perpVector(); ptStart = ptCenter + dRadius * vtPerl; ptEnd = ptCenter - dRadius * vtPerl; polyLine.addVertexAt(0, ptStart.convert2d(planStd), 1.0); polyLine.addVertexAt(1, ptEnd.convert2d(planStd), 1.0); polyLine.setClosed(Adesk::kTrue); } else // 半个圆 { AcGeVector3d vtPerl = vtGet.orthoProject(vtNewNormal); vtPerl.rotateBy(-PI / 2, vtNewNormal); vtPerl.normalize(); ptStart = ptCenter + dRadius * vtPerl; ptEnd = ptCenter - dRadius * vtPerl; polyLine.addVertexAt(0, ptStart.convert2d(planStd), 1); polyLine.addVertexAt(1, ptEnd.convert2d(planStd), 0); } polyLine.setElevation(dEle); polyLine.setNormal(vtNewNormal); return 0; } else if (vtNewNormal.isPerpendicularTo(vtOrigNormal)) // 垂直情况, 为直线 { AcGeVector3d vtCrossPerl = vtOrigNormal.crossProduct(vtNewNormal); AcGePoint3d ptStart, ptEnd; ptStart = ptCenter + dRadius * vtCrossPerl; ptEnd = ptCenter - dRadius * vtCrossPerl; polyLine.addVertexAt(0, ptStart.convert2d(planStd)); polyLine.addVertexAt(1, ptEnd.convert2d(planStd)); polyLine.setElevation(dEle); polyLine.setNormal(vtNewNormal); return 1; } else // 普通投影为椭圆情况 { // 长/短轴向量 AcGeVector3d vtLong = vtOrigNormal.crossProduct(vtNewNormal); vtLong.normalize(); AcGeVector3d vtShort = vtLong; vtShort.rotateBy(PI * 0.5, vtOrigNormal); AcGeVector3d vtPerp = vtOrigNormal.crossProduct(vtNewNormal); vtPerp.normalize(); double dMinAngle = GetMinDiffAngle(); // dMinAngle *= 0.5; int nPart = (int)(PI / dMinAngle) +1; dMinAngle = PI / nPart; AcGePoint3d ptNow; AcGePoint3dArray arptsEdge; if (vtGet.length() < 1e-6) { ptNow = ptCenter + vtPerp * dDia * 0.5; for(int i = 0; i <= nPart*2; i++) { polyLine.addVertexAt(i, ptNow.convert2d(planStd)); ptNow.rotateBy(dMinAngle, vtOrigNormal, ptCenter); } } else { vtGet = vtGet.orthoProject(vtNewNormal); if (vtGet.angleTo(vtShort) < PI*0.5) // C 端部分 { ptNow = ptCenter + vtPerp * dDia * 0.5; for(int i = 0; i <= nPart; i++) { polyLine.addVertexAt(i, ptNow.convert2d(planStd)); ptNow.rotateBy(dMinAngle, vtOrigNormal, ptCenter); } } else // D 端部分 { ptNow = ptCenter - vtPerp * dDia * 0.5; for(int i = 0; i <= nPart; i++) { polyLine.addVertexAt(i, ptNow.convert2d(planStd)); ptNow.rotateBy(dMinAngle, vtOrigNormal, ptCenter); } } } } polyLine.setElevation(dEle); polyLine.setNormal(vtNewNormal); return 2; } void TAuxTools::GetArcPoint(AcDbPolyline &polyLine, AcGePoint3dArray &ptArcArr) { // if (polyLine.numVerts() != 4) // return; // double dBugle(0.0); polyLine.getBulgeAt(0, dBugle); if (EQUAL_ZERO(dBugle - 1.0))// Polyline线是半个圆,或者圆 { double dPar1, dPar2; AcGePoint3d pt0, pt1, pt2, pt3, ptMid; polyLine.getPointAt(0, pt0); polyLine.getPointAt(1, pt1); polyLine.getPointAt(2, pt2); polyLine.getPointAt(3, pt3); polyLine.getParamAtPoint(pt0, dPar1); polyLine.getParamAtPoint(pt1, dPar2); polyLine.getPointAtParam((dPar1 + dPar2)*0.5, ptMid); ptArcArr.append(pt0); ptArcArr.append(ptMid); ptArcArr.append(pt1); polyLine.getParamAtPoint(pt1, dPar1); polyLine.getParamAtPoint(pt2, dPar2); polyLine.getPointAtParam((dPar1 + dPar2)*0.5, ptMid); ptArcArr.append(ptMid); ptArcArr.append(pt2); polyLine.getParamAtPoint(pt2, dPar1); polyLine.getParamAtPoint(pt3, dPar2); polyLine.getPointAtParam((dPar1 + dPar2)*0.5, ptMid); ptArcArr.append(ptMid); ptArcArr.append(pt3); if (polyLine.isClosed()) { polyLine.getParamAtPoint(pt3, dPar1); polyLine.getEndParam(dPar2); polyLine.getPointAtParam((dPar1 + dPar2)*0.5, ptMid); ptArcArr.append(ptMid); ptArcArr.append(pt0); } } else { AcGePoint3d pt1; for(int i = 0; i < polyLine.numVerts(); i++) { polyLine.getPointAt(i, pt1); ptArcArr.append(pt1); } } } int TAuxTools::GetEllipsePtsFromCircle(AcGePoint3dArray& arPtsOnCurve, AcGePoint3d ptCenter, double dDia, AcGeVector3d vtOrigNormal, AcGeVector3d vtNewNormal, AcDbPolyline &polyLine, AcGeVector3d vtGet/* = AcGeVector3d::kIdentity*/) { int iRes = TAuxTools::GetEllipseFromCircle(ptCenter, dDia, vtOrigNormal, vtNewNormal, polyLine, vtGet); if (iRes != -1) { AcGePoint3d ptTemp, ptTemp1, ptTemp2; double dPam1, dPam2; AcGeVector3d vtDir; AcGePlane plan; switch (iRes) { default: case 2:// 投影为椭圆 TAuxTools::GetArcPoint(polyLine, arPtsOnCurve); break; case 1:// 投影为直线 polyLine.getPointAt(0, ptTemp); arPtsOnCurve.append(ptTemp); polyLine.getPointAt(1, ptTemp); arPtsOnCurve.append(ptTemp); arPtsOnCurve.append(ptTemp); break; case 0:// 投影为圆 if (polyLine.isClosed())// 整个圆 { polyLine.getPointAt(0, ptTemp1); polyLine.getPointAt(1, ptTemp2); polyLine.getParamAtPoint(ptTemp1, dPam1); polyLine.getParamAtPoint(ptTemp2, dPam2); polyLine.getPointAtParam((dPam1+dPam2)*0.5, ptTemp); arPtsOnCurve.append(ptTemp1); arPtsOnCurve.append(ptTemp); arPtsOnCurve.append(ptTemp2); vtDir = ptTemp1 - ptTemp2; plan.set(TAuxTools::Mid(ptTemp1, ptTemp2), vtDir.rotateBy(PI * 0.5, vtNewNormal)); ptTemp.mirror(plan); arPtsOnCurve.append(ptTemp); arPtsOnCurve.append(ptTemp1); } else// 半个圆 { polyLine.getPointAt(0, ptTemp1); polyLine.getPointAt(1, ptTemp2); polyLine.getParamAtPoint(ptTemp1, dPam1); polyLine.getParamAtPoint(ptTemp2, dPam2); polyLine.getPointAtParam((dPam1+dPam2)*0.5, ptTemp); arPtsOnCurve.append(ptTemp1); arPtsOnCurve.append(ptTemp); arPtsOnCurve.append(ptTemp2); } break; } } return iRes; } BOOL TAuxTools::GetPrjPtsFromCircle(AcGePoint3dArray& ptArr, AcGePoint3dArray& arPtJudge) { XCircle cir; AcGeVector3d vtTmp1, vtTmp2, vtCirNor; AcGePoint3d ptCirCen, ptIn, ptU, ptD; AcGePoint3dArray arPtSides; AcGePlane plan; int iRes(-1); AcDbPolyline* pLine = new AcDbPolyline; if (NULL == pLine) return TRUE; for (int i = 0; i < ptArr.length(); ) { cir.Set(ptArr[i], ptArr[i+1], ptArr[i+2]); ptCirCen = cir.m_ptCenter.AsAcGePoint3d(); vtTmp1 = ptArr[i+1] - ptCirCen; vtTmp2 = ptArr[i+2] - ptCirCen; // 分节圆法向 vtCirNor = vtTmp1.crossProduct(vtTmp2); plan.set(ptCirCen, TAuxTools::GetUcsZvt()); iRes = TAuxTools::GetEllipseFromCircle(ptCirCen, cir.m_dRadius * 2, vtCirNor, TAuxTools::GetUcsZvt(), *pLine, vtCirNor); if (-1 == iRes) { if (NULL != pLine) delete pLine; return FALSE; } pLine->getPointAt(0, ptU); pLine->getPointAt(pLine->numVerts()-1, ptD); plan.set(arPtJudge[i / 3], TAuxTools::GetUcsZvt()); ptU = ptU.orthoProject(plan); ptD = ptD.orthoProject(plan); if (ptD.distanceTo(arPtJudge[ i / 3]) <= ptU.distanceTo(arPtJudge[ i / 3])) { // 总是先添加距离ptArrCen[ i / 3]近的点 arPtSides.append(ptD); arPtSides.append(ptU); } else { arPtSides.append(ptU); arPtSides.append(ptD); } pLine->reset(Adesk::kFalse, iRes); i = i+3;// 每3个点确定一个面 } if (NULL == pLine) delete pLine; arPtJudge.setLogicalLength(0); arPtJudge.append(arPtSides); return TRUE; } BOOL TAuxTools::MergerPline(AcDbPolyline* pPl,AcDbPolyline* pSrc) { AcGePoint3d ptStart,ptStart2; AcGePoint3d ptEnd,ptEnd2; pPl->getStartPoint(ptStart); pPl->getEndPoint(ptEnd); pSrc->getStartPoint(ptStart2); pSrc->getEndPoint(ptEnd2); AcGePoint2d pt2d; double dBulge = -1; if (ptStart.distanceTo(ptStart2) < 1.e-3) //sta 重合 { int nVerts = pSrc->numVerts(); for (int i = 1;i < nVerts; i++) { pSrc->getPointAt(i, pt2d); pSrc->getBulgeAt(i - 1, dBulge); pPl->addVertexAt(0, pt2d, -dBulge); } } else if (ptStart.distanceTo(ptEnd2) < 1.e-3) //end { int nVerts = pSrc->numVerts() - 1; for (int i = nVerts; i > 0; i--) { pSrc->getPointAt(i - 1, pt2d); pSrc->getBulgeAt(i - 1, dBulge); pPl->addVertexAt(0, pt2d, dBulge); } } else if (ptEnd.distanceTo(ptStart2) < 1.e-3) //sta 重合 { int nVerts = pPl->numVerts(); for (int i = 1; i < (int)pSrc->numVerts(); i++) { pSrc->getPointAt(i, pt2d); pSrc->getBulgeAt(i - 1, dBulge); if (1 == i) { pPl->setBulgeAt(nVerts - 1, dBulge); } pPl->addVertexAt(nVerts, pt2d, dBulge); nVerts++; } } else if (ptEnd.distanceTo(ptEnd2) < 1.e-3) //end { int nVerts = pPl->numVerts(); for (int i = pSrc->numVerts() - 1; i > -1; i--) { pSrc->getPointAt(i, pt2d); pSrc->getBulgeAt(i - 1, dBulge); pPl->addVertexAt(nVerts, pt2d, -dBulge); nVerts++; } } // Lixl处理两条PLine线不同高度的情况 else { ptStart2.z = ptStart.z; ptEnd2.z = ptEnd.z; int nVerts = pPl->numVerts(); int nPlVerts = nVerts - 1; if (ptEnd.distanceTo(ptStart2) < 1.e-3) { for (int i = 0; i < (int)pSrc->numVerts(); i++) { pSrc->getPointAt(i, pt2d); pSrc->getBulgeAt(i, dBulge); pPl->addVertexAt(nVerts, pt2d, dBulge); nVerts++; } pPl->setBulgeAt(nPlVerts, 0); } else if (ptEnd.distanceTo(ptEnd2) < 1.e-3) { for (int i = pSrc->numVerts()-1; i >= 0; i--) { pSrc->getPointAt(i, pt2d); pSrc->getBulgeAt(i-1, dBulge); if (0 == i) dBulge = 0.0; pPl->addVertexAt(nVerts, pt2d, -dBulge); nVerts++; } pPl->setBulgeAt(nPlVerts, 0); } } return TRUE; } int TAuxTools::PositionOnLine(AcGePoint3d ptSta, AcGePoint3d ptEnd, AcGePoint3d ptBase) { AcGeVector3d vt = ptSta - ptEnd; vt.normalize(); double dBS = ptBase.distanceTo(ptSta); double dBE = ptBase.distanceTo(ptEnd); double dSE = ptEnd.distanceTo(ptSta); //在两个点中间位置 if (((dBS + dBE) - dSE) < 1.e-3 ) { return 0; } else { //在S端左侧 if (dBS < dBE) { return 1; } //在E端右侧 else { return 2; } } return -1; } BOOL TAuxTools::isCodirectionalPt(AcGePoint3d ptSta, AcGePoint3d ptEnd, AcGeVector3d vtBase) { AcGeVector3d vt = ptSta - ptEnd; return vt.isCodirectionalTo(vtBase); } AcGePlane TAuxTools::GetHidePlane(AcGePoint3d pt1, AcGePoint3d pt2, AcGePoint3d pt3, AcGeVector3d vtNormal, double &dEle) { AcGePlane plan(pt1, pt2, pt3); AcGePoint3d ptOrth = AcGePoint3d::kOrigin.orthoProject(plan); plan.set(ptOrth, vtNormal); dEle = ptOrth.asVector().length(); if (!ptOrth.asVector().isCodirectionalTo(vtNormal)) dEle *= -1.0; return plan; } BOOL TAuxTools::InsertBlock(AcDbVoidPtrArray& entitySet,AcDbObjectId idBlock, AcGePoint3d ptBase, AcGeScale3d ScaleFactor,double dAngle) { AcDbBlockReference blcRfr; blcRfr.setNormal(AcGeVector3d::kZAxis); blcRfr.setBlockTableRecord(idBlock); blcRfr.setPosition(ptBase); blcRfr.setRotation(dAngle); blcRfr.setScaleFactors(ScaleFactor); blcRfr.explode(entitySet); return TRUE; } BOOL TAuxTools::GetIntersectWith(AcGePoint3d pt1,AcGePoint3d pt2,AcGePoint3d pt3,AcGePoint3d pt4,AcGePoint3d& ptIntersect) { AcGeLine3d line1,line2; line1.set(pt1,pt2); line2.set(pt3,pt4); return line1.intersectWith(line2, ptIntersect); } int TAuxTools::Getquadrant(AcGePoint3d ptCenter, AcGePoint3d pt, AcGeVector3d vtMain, AcGeVector3d vtNormal) { AcGeVector3d vtBr = pt - ptCenter; double dAngle = vtMain.angleTo(vtBr, vtNormal); if (dAngle >= PI * 0.5 && dAngle < PI) { return 2; } else if (dAngle >= PI && dAngle < PI * 1.5) { return 3; } else if (dAngle >= PI * 1.5 && dAngle < PI * 2 ) { return 4; } return 1; } // 用户X坐标向量 AcGeVector3d TAuxTools::GetUcsXvt() { AcGeVector3d vtX = AcGeVector3d::kXAxis; AcDbDatabase* pDb = acdbCurDwg(); if (NULL != pDb) vtX = pDb->ucsxdir(); return vtX; } AcGeVector3d TAuxTools::GetUcsYvt() { AcGeVector3d vtY = AcGeVector3d::kYAxis; AcDbDatabase* pDb = acdbCurDwg(); if (NULL != pDb) vtY = pDb->ucsydir(); return vtY; } AcGeVector3d TAuxTools::GetUcsZvt() { AcGeVector3d vtZ = AcGeVector3d::kZAxis; AcDbDatabase* pDb = acdbCurDwg(); if (NULL != pDb) vtZ = pDb->ucsxdir().crossProduct(pDb->ucsydir()); return vtZ; } ////////////////////////////////////////////////////////////////////////// // 风管沿程阻力水力计算 double TAuxTools::CalFricLoss( double dTemp, double dRough, double dDia, double dLength, double dVelocity ) { //double dDensity = CalDesity(dTemp); // 密度 double dDensity = TDbHvacDimension::m_dDensity; // 密度 //double dMoveVis = CalMoveVis(dTemp); // 运动黏度(m^2/s);范围:>0 double dMoveVis = TDbHvacDimension::m_dMoveVis * 1.e-6; double dRe = CalRe(dVelocity, dDia, dMoveVis); // 计算Re double dFricCoef = CalFricCoef(dRough, dDia, dRe); // 计算摩擦系数 return CalCircleFricLoss(dFricCoef, dDia, dLength, dDensity, dVelocity); } double TAuxTools::CalFricLoss( double dTemp, double dRough, double dWidth, double dHeight, double dLength, double dVelocity ) { double dDia = CalVelDia(dWidth, dHeight); return CalFricLoss(dTemp, dRough, dDia, dLength, dVelocity); } // 圆管沿程阻力 dFricCoef摩擦系数 管径(mm)、管长(m)、密度(kg/m^3)和流速(m/s)计算沿程阻力(Pa) double TAuxTools::CalCircleFricLoss(double dFricCoef, double dDia, double dLength, double dDensity, double dVelocity) { if ((dFricCoef < ZERO_AIR) || (dDia < ZERO_AIR) || (dLength < 0) || (dDensity < ZERO_AIR) || (dVelocity < 0)) return 0.0; return dFricCoef * dLength * dDensity * pow(dVelocity, 2) / (0.002 * dDia); } // 根据粗糙度(mm)、流速当量直径(mm)和雷诺数计算摩擦系数, 用柯列勃洛克-怀特公式计算 double TAuxTools::CalFricCoef(double dRough, double dCalDia, double dRe) { if ((dRough < 0.0) || (dCalDia < ZERO_AIR) || (dRe < ZERO_AIR)) return ZERO_AIR; if (dRe < 2000) return 64 / dRe; double dA, dB; // 系数a, b dA = dRough / (3.7 * dCalDia); dB = 2.51 / dRe; double dNewX, dOldX; // 用于迭代计算的新旧数据 =1/(FricCoef)^0.5 dNewX = 5.0; // 初始值为5 double e = 1.0; // 两次迭代之差 double t = 0.0; int nFlag = 0; // 控制最大迭代次数 while ((e > 0.0001) && (nFlag < 100)) { dOldX = dNewX; t = dA + dB * dOldX; if (t < ZERO_AIR) return 0.0; // 认为无解 dNewX = dOldX - (dOldX + 2 * log10(t)) * (t) * log(10.0) / ((t) * log(10.0) + 2 * dB); e = fabs(dNewX - dOldX); nFlag++; } if (nFlag >= 100) return 0.0; // 认为无解 return 1 / pow(dNewX, 2); } // 根据管宽(mm)和管高(mm)计算流速当量直径(mm) double TAuxTools::CalVelDia(double dWidth, double dHeight) { if ((dWidth < ZERO_AIR) || (dHeight < ZERO_AIR)) return 0.0; return 2 * dWidth * dHeight / (dWidth + dHeight); } // 流速(m/s)、流速当量直径(mm)和黏度(m^2/s)计算雷诺数 double TAuxTools::CalRe(double dVelocity, double dVelDia, double dMoveVis) { if ((dVelocity < 0.0) || (dVelDia < ZERO_AIR) || (dMoveVis < 1.0e-10)) return ZERO_AIR; return dVelocity * 0.001 * dVelDia / dMoveVis; } double TAuxTools::CalDesity(double dTemperature) { double dDensity[15] = {1.293, 1.270, 1.248, 1.226, 1.205, 1.185, 1.165, 1.146, 1.128, 1.093, 1.060, 1.029, 1.000, 0.973, 0.947}; double dTem[15] = {0, 5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 70, 80, 90, 100}; return CalTable(dTem, (double*)dDensity, dTemperature, 15); } double TAuxTools::CalMoveVis(double dTemperature) { double dMovVis[18] = {13.7, 14.7, 15.7, 16.6, 17.6, 18.6, 19.6, 20.5, 21.7, 22.9, 23.6, 26.2, 28.5, 30.6, 33.2, 35.8, 42.8, 49.9}; double dTem[18] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 120, 140, 160, 180, 200, 250, 300}; return CalTable(dTem, (double*)dMovVis, dTemperature, 18) * 1.0e-6; } /*----------------------------------------------------------------------------* * 功能描述: 用插值法从一维表格中取值 * 备 注: dAbscissa为表头;共m列数据;dX表示列值;表头升序 -----------------------------------------------------------------------------*/ double TAuxTools::CalTable(double dAbscissa[], double *pTable, double dX, int m) { if (dX < dAbscissa[0]) dX = dAbscissa[0]; else if (dX > dAbscissa[m - 1]) dX = dAbscissa[m - 1]; for(int i = 0; i < m; i++) { if (dAbscissa[i] == dAbscissa[i - 1]) // 与前一个表头相等 continue; if (dX == dAbscissa[i]) // 等于某个表头 return pTable[i]; else if (dX < dAbscissa[i]) // 小于某个表头,用查值 return (pTable[i] - pTable[i - 1])*(dX - dAbscissa[i - 1]) / (dAbscissa[i] - dAbscissa[i - 1]) + pTable[i - 1]; } return 0.0; } ////////////////////////////////////////////////////////////////////////// // 用于特性表修改某些参数后,更新遮挡关系 void TAuxTools::SetAndUpdateCover(TDbInterfacesObj* pObj, LPCTSTR pszName, TDb::OPMInfo* pInfo) { // 设置数据时,更新遮挡 if (NULL != pObj && NULL != pInfo->pXData && 0 != pInfo->pXData->nVt) { // 设置数据 TDbXDataMap* pMap = pObj->GetSpecialtyData(); if (NULL != pMap) { pMap->SetAt(pszName, *pInfo->pXData); pInfo->pXData->nVt = 0; // 设置处理完成标识 pObj->FlashCoverDisplay(); } } } // 获得字体样式表 void TAuxTools::GetAllTextStyleNameArray(CStringArray& arTextStyle) { AcDbTextStyleTable* pTextStyleTbl = NULL; AcDbTextStyleTableRecord* pTextStyleTblRec = NULL; if (acdbHostApplicationServices()->workingDatabase() \ ->getTextStyleTable(pTextStyleTbl, AcDb::kForRead) == Acad::eOk) { // 文字样式表记录 AcDbTextStyleTableIterator* pIterator = NULL; if (pTextStyleTbl->newIterator(pIterator) == Acad::eOk) { for (pIterator->start(); !pIterator->done(); pIterator->step()) { if (pIterator->getRecord(pTextStyleTblRec, AcDb::kForRead) == Acad::eOk) { LPCTSTR pszName = NULL; pTextStyleTblRec->getName(pszName); arTextStyle.Add(pszName); pTextStyleTblRec->close(); } } delete pIterator; } pTextStyleTbl->close(); } } // 获取最小分度角(曲面分化成小平面,相邻平面法向量间最小夹角) double TAuxTools::GetMinDiffAngle() { double dMinDiffAng = PI/12; GetGlobalContext()->GetAt(KEY_MINDIFFANG, dMinDiffAng); if (dMinDiffAng < 1e-3) return PI/12; return dMinDiffAng; } void TAuxTools::BuildRectDuct(const AcGePoint3d& ptStart, const AcGePoint3d& ptEnd, const AcGeVector3d& vtNormal, const double dSWidth, const double dSThick, const double dEWidth, const double dEThick, TXShell& xShell, const AcGeVector3d* pvtSSide/* = NULL*/, const AcGeVector3d* pvtESide/* = NULL*/) { // 计算参数 double dHalfSWidth = dSWidth / 2.0; double dHalfSThick = dSThick / 2.0; double dHalfEWidth = dEWidth / 2.0; double dHalfEThick = dEThick / 2.0; AcGeVector3d vtSSide; if (NULL == pvtSSide) { vtSSide = ptEnd - ptStart; vtSSide.rotateBy(PI / 2.0, vtNormal); } else { vtSSide = *pvtSSide; } vtSSide.normalize(); AcGeVector3d vtESide; if (NULL == pvtESide) { vtESide = ptEnd - ptStart; vtESide.rotateBy(PI / 2.0, vtNormal); } else { vtESide = *pvtESide; } vtESide.normalize(); // 计算端点 AcGePoint3d arpt[8]; arpt[0] = ptStart + vtSSide * dHalfSWidth + vtNormal * dHalfSThick; arpt[1] = ptStart + vtSSide * dHalfSWidth - vtNormal * dHalfSThick; arpt[2] = ptStart - vtSSide * dHalfSWidth - vtNormal * dHalfSThick; arpt[3] = ptStart - vtSSide * dHalfSWidth + vtNormal * dHalfSThick; arpt[4] = ptEnd + vtESide * dHalfEWidth + vtNormal * dHalfEThick; arpt[5] = ptEnd + vtESide * dHalfEWidth - vtNormal * dHalfEThick; arpt[6] = ptEnd - vtESide * dHalfEWidth - vtNormal * dHalfEThick; arpt[7] = ptEnd - vtESide * dHalfEWidth + vtNormal * dHalfEThick; // 添加碰撞面 xShell.AppendFace(new AcDbFace(arpt[0], arpt[1], arpt[2], arpt[3])); xShell.AppendFace(new AcDbFace(arpt[4], arpt[5], arpt[6], arpt[7])); xShell.AppendFace(new AcDbFace(arpt[0], arpt[1], arpt[5], arpt[4])); xShell.AppendFace(new AcDbFace(arpt[1], arpt[2], arpt[6], arpt[5])); xShell.AppendFace(new AcDbFace(arpt[2], arpt[3], arpt[7], arpt[6])); xShell.AppendFace(new AcDbFace(arpt[3], arpt[0], arpt[4], arpt[7])); } void TAuxTools::BuildCirDuct(const AcGePoint3d& ptStart, const AcGePoint3d& ptEnd, const double dSDiameter, const double dEDiameter, TXShell& xShell, const AcGeVector3d* pvtSRot/* = NULL*/, const AcGeVector3d* pvtERot/* = NULL*/, const AcGeVector3d* pvtSRotAxis/* = NULL*/, const AcGeVector3d* pvtERotAxis/* = NULL*/) { // 计算参数 double dSRadius = dSDiameter / 2.0; double dERadius = dEDiameter / 2.0; AcGeVector3d vtRotNormal = ptEnd - ptStart; AcGeVector3d vtSRot; if (NULL != pvtSRot && NULL != pvtSRotAxis) { vtSRot = *pvtSRot; } else { vtSRot = vtRotNormal.perpVector(); } vtSRot.normalize(); AcGeVector3d vtERot; if (NULL != pvtERot && NULL != pvtERotAxis) { vtERot = *pvtERot; } else { vtERot = vtRotNormal.perpVector(); } vtERot.normalize(); // 计算端点 AcGePoint3d arpt[12]; if (NULL != pvtSRotAxis && NULL != pvtERotAxis) { for (int i = 0; i < 6; ++i) { arpt[0 + i] = ptStart + vtSRot * dSRadius; arpt[6 + i] = ptEnd + vtERot * dERadius; vtSRot.rotateBy(PI / 3.0, *pvtSRotAxis); vtERot.rotateBy(-PI / 3.0, *pvtERotAxis); } } else { for (int i = 0; i < 6; ++i) { arpt[0 + i] = ptStart + vtSRot * dSRadius; arpt[6 + i] = ptEnd + vtERot * dERadius; vtSRot.rotateBy(PI / 3.0, vtRotNormal); vtERot.rotateBy(PI / 3.0, vtRotNormal); } } // 添加碰撞面 for (int j = 0; j < 5; ++j) { xShell.AppendFace(new AcDbFace(arpt[j], arpt[j + 1], arpt[j + 7], arpt[j + 6])); } xShell.AppendFace(new AcDbFace(arpt[5], arpt[0], arpt[6], arpt[11])); xShell.AppendFace(new AcDbFace(arpt[0], arpt[1], arpt[2], arpt[5])); xShell.AppendFace(new AcDbFace(arpt[2], arpt[3], arpt[4], arpt[5])); xShell.AppendFace(new AcDbFace(arpt[6], arpt[7], arpt[8], arpt[11])); xShell.AppendFace(new AcDbFace(arpt[8], arpt[9], arpt[10], arpt[11])); } void TAuxTools::BuildMinRectangle(const AcGePoint3dArray& arpt, AcDbExtents& ext) { int iLen = arpt.length(); if (0 == iLen) { return; } double dMaxX = arpt[0].x; double dMaxY = arpt[0].y; double dMaxZ = arpt[0].z; double dMinX = dMaxX; double dMinY = dMaxY; double dMinZ = dMaxZ; for (int i = 0; i < iLen; ++i) { if (dMaxX < arpt[i].x) { dMaxX = arpt[i].x; } if (dMaxY < arpt[i].y) { dMaxY = arpt[i].y; } if (dMaxZ < arpt[i].z) { dMaxZ = arpt[i].z; } if (dMinX > arpt[i].x) { dMinX = arpt[i].x; } if (dMinY > arpt[i].y) { dMinY = arpt[i].y; } if (dMinZ > arpt[i].z) { dMinZ = arpt[i].z; } } AcGePoint3d ptMax(dMaxX,dMaxY,dMaxZ); AcGePoint3d ptMin(dMinX,dMinY,dMinZ); ext.set(ptMin,ptMax); } BOOL TAuxTools::IsAutoWorkOffset() { BOOL bAuto(FALSE); GetGlobalContext(HVAC_AUTOOFFSET, bAuto); return bAuto; } BOOL TAuxTools::IsAutoWorkConnect() { BOOL bAuto(FALSE); GetGlobalContext(HVAC_AUTOCONNECT, bAuto); return bAuto; } BOOL TAuxTools::IsAutoWorkSize() { BOOL bAuto(FALSE); GetGlobalContext(HVAC_AUTOSIZE, bAuto); return bAuto; } void TAuxTools::BuildCir2RectDuct(const AcGePoint3d& ptCir, const AcGePoint3d& ptRec, const AcGeVector3d& vtNormal, const double dDiameter, const double dWidth, const double dThick, TXShell& xShell, const AcGeVector3d* pvtRot/* = NULL*/, const AcGeVector3d* pvtCirOut/* = NULL*/) { // 计算侧方向 AcGeVector3d vtRot; AcGeVector3d vtRotNormal; if (NULL != pvtRot && NULL != pvtCirOut) { vtRot = *pvtRot; vtRotNormal = *pvtCirOut; } else { vtRot = ptCir - ptRec; vtRot.rotateBy(PI / 2.0, vtNormal); } vtRot.normalize(); // 计算方口端点 double dHalfWidth = dWidth / 2.0; double dHalfThick = dThick / 2.0; AcGeVector3d vtSide = vtRot; AcGePoint3d arptRec[4]; arptRec[0] = ptRec + vtSide * dHalfWidth + vtNormal * dHalfThick; arptRec[1] = ptRec - vtSide * dHalfWidth + vtNormal * dHalfThick; arptRec[2] = ptRec - vtSide * dHalfWidth - vtNormal * dHalfThick; arptRec[3] = ptRec + vtSide * dHalfWidth - vtNormal * dHalfThick; // 计算圆口端点 double dRadius = dDiameter / 2.0; AcGePoint3d arptCir[8]; for (int i = 0; i < 8; ++i) { arptCir[i] = ptCir + vtRot * dRadius; vtRot.rotateBy(PI / 4.0, vtRotNormal); } // 添加碰撞面 xShell.AppendFace(new AcDbFace(arptCir[0], arptCir[1], arptRec[0], arptRec[0])); xShell.AppendFace(new AcDbFace(arptCir[1], arptCir[2], arptRec[0], arptRec[0])); xShell.AppendFace(new AcDbFace(arptCir[2], arptCir[3], arptRec[1], arptRec[1])); xShell.AppendFace(new AcDbFace(arptCir[3], arptCir[4], arptRec[1], arptRec[1])); xShell.AppendFace(new AcDbFace(arptCir[4], arptCir[5], arptRec[2], arptRec[2])); xShell.AppendFace(new AcDbFace(arptCir[5], arptCir[6], arptRec[2], arptRec[2])); xShell.AppendFace(new AcDbFace(arptCir[6], arptCir[7], arptRec[3], arptRec[3])); xShell.AppendFace(new AcDbFace(arptCir[7], arptCir[0], arptRec[3], arptRec[3])); xShell.AppendFace(new AcDbFace(arptRec[0], arptRec[1], arptCir[2], arptCir[2])); xShell.AppendFace(new AcDbFace(arptRec[1], arptRec[2], arptCir[4], arptCir[4])); xShell.AppendFace(new AcDbFace(arptRec[2], arptRec[3], arptCir[6], arptCir[6])); xShell.AppendFace(new AcDbFace(arptRec[3], arptRec[0], arptCir[0], arptCir[0])); xShell.AppendFace(new AcDbFace(arptCir[0], arptCir[1], arptCir[2], ptCir)); xShell.AppendFace(new AcDbFace(arptCir[2], arptCir[3], arptCir[4], ptCir)); xShell.AppendFace(new AcDbFace(arptCir[4], arptCir[5], arptCir[6], ptCir)); xShell.AppendFace(new AcDbFace(arptCir[6], arptCir[7], arptCir[0], ptCir)); xShell.AppendFace(new AcDbFace(arptRec[0], arptRec[1], arptRec[2], arptRec[3])); } void TAuxTools::BuildRecFace(const AcGePoint3d& pt, const double dWidth, const double dThick, const AcGeVector3d& vtNormal, const AcGeVector3d& vtFaceNormal, TXShell& xShell) { // 获得侧方向 AcGeVector3d vtSide = vtFaceNormal; vtSide.rotateBy(PI / 2.0, vtNormal); vtSide.normalize(); // 添加面 double dHalfWidth = dWidth / 2.0; double dHalfThick = dThick / 2.0; AcGePoint3d arpt[4]; arpt[0] = pt + vtSide * dHalfWidth + vtNormal * dHalfThick; arpt[1] = pt + vtSide * dHalfWidth - vtNormal * dHalfThick; arpt[2] = pt - vtSide * dHalfWidth - vtNormal * dHalfThick; arpt[3] = pt - vtSide * dHalfWidth + vtNormal * dHalfThick; xShell.AppendFace(new AcDbFace(arpt[0], arpt[1], arpt[2], arpt[3])); } void TAuxTools::BuildRecFace(const AcGePoint3d& pt, const double dWidth, const double dThick, const AcGeVector3d& vtNormal, const AcGeVector3d& vtFaceNormal, AcDbVoidPtrArray& dbPtArr) { // 获得侧方向 AcGeVector3d vtSide = vtFaceNormal; vtSide.rotateBy(PI / 2.0, vtNormal); vtSide.normalize(); // 添加面 double dHalfWidth = dWidth / 2.0; double dHalfThick = dThick / 2.0; AcGePoint3d arpt[4]; arpt[0] = pt + vtSide * dHalfWidth + vtNormal * dHalfThick; arpt[1] = pt + vtSide * dHalfWidth - vtNormal * dHalfThick; arpt[2] = pt - vtSide * dHalfWidth - vtNormal * dHalfThick; arpt[3] = pt - vtSide * dHalfWidth + vtNormal * dHalfThick; dbPtArr.append(new AcDbFace(arpt[0], arpt[1], arpt[2], arpt[3])); } void TAuxTools::BuildCirFace(const AcGePoint3d& pt, const double dDiameter, const AcGeVector3d& vtNormal, const AcGeVector3d& vtFaceNormal, TXShell& xShell) { // 获得侧方向 AcGeVector3d vtRot = vtNormal; vtRot.normalize(); double dRadius = dDiameter / 2.0; AcGePoint3d arpt[6]; for (int i = 0; i < 6; ++i) { arpt[i] = pt + vtRot * dRadius; vtRot.rotateBy(PI / 3.0, vtFaceNormal); } xShell.AppendFace(new AcDbFace(arpt[0], arpt[1], arpt[2], arpt[3])); xShell.AppendFace(new AcDbFace(arpt[3], arpt[4], arpt[5], arpt[0])); } void TAuxTools::BuildCirFace(const AcGePoint3d& pt, const double dDiameter, const AcGeVector3d& vtNormal, const AcGeVector3d& vtFaceNormal, AcDbVoidPtrArray& dbPtArr) { // 获得侧方向 AcGeVector3d vtRot = vtNormal; vtRot.normalize(); double dRadius = dDiameter / 2.0; AcGePoint3d arpt[6]; for (int i = 0; i < 6; ++i) { arpt[i] = pt + vtRot * dRadius; vtRot.rotateBy(PI / 3.0, vtFaceNormal); } dbPtArr.append(new AcDbFace(arpt[0], arpt[1], arpt[2], arpt[3])); dbPtArr.append(new AcDbFace(arpt[3], arpt[4], arpt[5], arpt[0])); } void TAuxTools::DealWithConEnt(AcDbObjectId idToDeal, const AcGeVector3d& vtOff, AcDbObjectId idFrom, AcGePoint3d ptFrom) { TDbXDataMap* pMap = NULL; ObjectKind eKind(TDb::eCabletry); OPENOBJ_BEGIN(idToDeal, AcDb::kForWrite, TDbInterfacesObj, pIfObj); if (NULL != pIfObj) { pMap = pIfObj->GetSpecialtyData(); if (NULL != pMap) { pMap->GetAt(KEY_RUNTIME, (int&)eKind); if (eKind == TDb::ePipe) { TDbHvacDuct* pDuct = TDbHvacDuct::cast(pIfObj); if (NULL != pDuct) { AcGePoint3d ptStart = pDuct->StartPoint(); AcGePoint3d ptEnd = pDuct->EndPoint(); AcGeVector3d vtDirect = ptEnd - ptStart; if (vtOff.isParallelTo(vtDirect)) { if (ptStart.distanceTo(ptFrom) < 1e-6) { AcGePoint3d ptNewStart = ptStart + vtOff; pDuct->SetStartPoint(ptNewStart); pDuct->UpdateInterfaceRec(ptStart, ptNewStart); } else if (ptEnd.distanceTo(ptFrom) < 1e-6) { AcGePoint3d ptNewEnd = ptEnd + vtOff; pDuct->SetEndPoint(ptNewEnd); pDuct->UpdateInterfaceRec(ptEnd, ptNewEnd); } } } } else { if (!pIfObj->GetInterface(ptFrom, TInterface())) // 没有实际连接 return; int nIfNum = pIfObj->GetInterfaceCount(); int i(0); TInterface tIf; AcDbObjectId id(AcDbObjectId::kNull); for (i = 0; i < nIfNum; i++) { tIf.Reset(); if (!pIfObj->GetInterface(i, tIf)) continue; id = tIf.GetConnectObject(); if (id != idFrom && id.isValid()) { DealWithConEnt(id, vtOff, idToDeal, tIf.GetPosition()); } } pIfObj->transformBy(vtOff); } } } OPENOBJ_END(); } void TAuxTools::DealWithConEnt( AcDbObjectIdArray idArrToDeal, const AcGePoint3dArray& ptArrOrig, const AcGePoint3dArray& ptArrNew, AcDbObjectId idFrom ) { int nSize = idArrToDeal.length(); if (nSize != ptArrOrig.length() || nSize != ptArrNew.length()) return; AcGeVector3d vtOff; int i(0); for (i = 0; i < nSize; i++) { if (idArrToDeal[i].isValid() && idFrom.isValid()) { vtOff = ptArrNew[i] - ptArrOrig[i]; if (vtOff.length() > 1e-6) { DealWithConEnt(idArrToDeal[i], vtOff, idFrom, ptArrOrig[i]); } } } } BOOL TAuxTools::GetInterfacePoint(const TImpSpecFitting* pFit, AcGePoint3dArray &ptArr ) { if (NULL == pFit) return FALSE; TInterface tIf; int i(0), nNum = pFit->GetInterfaceCount(); for (i = 0; i < nNum; i++) { tIf.Reset(); pFit->GetInterface(i, tIf); ptArr.append(tIf.GetPosition()); } return ptArr.length() > 0; } BOOL TAuxTools::GetInterfaceId( const TImpSpecFitting* pFit, AcDbObjectIdArray &idArr ) { if (NULL == pFit) return FALSE; TInterface tIf; AcDbObjectId id(AcDbObjectId::kNull); int i(0), nNum = pFit->GetInterfaceCount(); for (i = 0; i < nNum; i++) { tIf.Reset(); pFit->GetInterface(i, tIf); id = tIf.GetConnectObject(); if (id.isValid()) idArr.append(id); } return idArr.length() > 0; } // 获取面标高, 零点距到零点投影到该面的垂点的长度 double TAuxTools::GetPlaneEle( const AcGePlane &plan ) { AcGePoint3d ptOrth = AcGePoint3d::kOrigin.orthoProject(plan); double dEle = ptOrth.asVector().length(); AcGeVector3d vtZAxis(TAuxTools::GetUcsZvt()); if (!ptOrth.asVector().isCodirectionalTo(plan.normal())) dEle *= -1.0; return dEle; } //读扩展数据 CString TAuxTools::ReadXdata( ads_name name, const TCHAR*szName ) { AcDbObjectId idEnt; acdbGetObjectId(idEnt, name); return ReadXdata(idEnt, szName); } //读扩展数据 CString TAuxTools::ReadXdata( AcDbObjectId idEnt, const TCHAR*szName ) { AcDbObject *pObj = NULL; acdbOpenObject(pObj, idEnt, AcDb::kForRead); if(!pObj) return _T(""); resbuf *pRb = pObj->xData(szName); CString csRet; if (pRb != NULL) { resbuf *pTemp = pRb; if (pTemp->rbnext != NULL) { pTemp = pTemp->rbnext; if (pTemp->restype == 1000) csRet = pTemp->resval.rstring; } } ads_relrb(pRb); pObj->close(); return csRet; } //写扩展数据 BOOL TAuxTools::WriteXdata(ads_name name, const TCHAR*szName, const TCHAR*szValue) { AcDbObjectId idEnt; acdbGetObjectId(idEnt, name); return WriteXdata(idEnt, szName, szValue); } //写扩展数据 BOOL TAuxTools::WriteXdata(AcDbObjectId idEnt, const TCHAR*szName, const TCHAR*szValue) { AcDbObject *pObj = NULL; if(!XSymbolTable(_T("APPID"), szName)) ads_regapp(szName); acdbOpenObject(pObj, idEnt, AcDb::kForWrite); if(!pObj) return FALSE; resbuf *pXData = ads_buildlist(1001, szName, 1000, szValue, NULL); pObj->setXData(pXData); ads_relrb(pXData); pObj->close(); return TRUE; } // 通过id获取文字样式名 TCHAR* TAuxTools::GetFontStyle(AcDbObjectId idTextStyle) { AcDbTextStyleTableRecord* pTTR; if (acdbOpenObject(pTTR, idTextStyle, AcDb::kForRead) != Acad::eOk) return NULL; TCHAR* pName = NULL; if (pTTR->getName(pName) != Acad::eOk) { pTTR->close(); return NULL; } pTTR->close(); return pName; } BOOL TAuxTools::IsEquipAutoMove( TImpSpecEquipment* pImpEquip, AcGeVector3d vtOffset ) { if (NULL == pImpEquip) return FALSE; TInterface tIf; AcGeVector3d vtIf; int i(0), nIfNum(pImpEquip->GetInterfaceCount()); for (i = 0; i < nIfNum; i++) { tIf.Reset(); if (!pImpEquip->GetInterface(i, tIf)) continue; vtIf = tIf.GetOutDir(); if (!(vtOffset.isPerpendicularTo(vtIf) || vtOffset.isParallelTo(vtIf))) return FALSE; } return TRUE; } void TAuxTools::GetAirLetByDuct( const TDbHvacDuct* pDuct, AcDbObjectIdArray &idArrAir ) { AcDbObjectIdArray idArrAllEnt; GetAllAirFromModel(idArrAllEnt); int nPos(0); AcGeVector3d vtFlur; int i(0); for (i = 0; i < idArrAllEnt.length(); i++) { if (AirIsOnDuct(idArrAllEnt[i], pDuct, nPos, vtFlur)) idArrAir.append(idArrAllEnt[i]); } } // 从模型空间块表中获取所有的风口,性能有待改善 void TAuxTools::GetAllAirFromModel(AcDbObjectIdArray& arAirId) { // 需要非写方式打开实体时调用 // RBList rbMask = ads_buildlist( -4, _T(""), // -4, _T("or>"), NULL); // // // PickSet ssEquip(SS_FREE); // ssEquip.Get(_T("X"), NULL, NULL, rbMask); // long lIndex(0), lLen(ssEquip.Length()); // TInterface tIf; // TDb::ObjectKind eKind = TDb::eCabletry; // // for (lIndex = 0; lIndex < lLen; lIndex++) // { // OPENOBJ_BEGIN(ssEquip[lIndex], AcDb::kForRead, TDbHvacEquipment, pEqu); // if (pEqu != NULL) // { // pEqu->GetSpecialtyDataReadOnly()->GetAt(KEY_RUNTIME, (int&)eKind); // if (eKind == TDb::eAirlets) // { // tIf.Reset(); // pEqu->GetInterface(0, tIf); // if (tIf.GetConnectObject().isValid()) // continue; // // arAirId.append(pEqu->objectId()); // } // } // OPENOBJ_END(); // } AcDbBlockTable* pBlockTable = NULL; if(Acad::eOk != acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead)) return; AcDbBlockTableRecord* pBlockTableRecord = NULL; if(Acad::eOk != pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite)) { pBlockTable->close(); return; } pBlockTable->close(); AcDbObjectId idPre; AcDbBlockTableRecordIterator* pRecIter; pBlockTableRecord->newIterator(pRecIter); TDb::ObjectKind eKind; TInterface tIf; AcDbObjectId idCon = NULL; BOOL bConOk(FALSE); // 连接完好的不用统计,会自动联动 for (pRecIter->start(); !pRecIter->done(); pRecIter->step()) { pRecIter->getEntityId(idPre); OPENOBJ_BEGIN(idPre, AcDb::kForRead, TDbHvacEquipment, pEqu); if (pEqu != NULL) { pEqu->GetSpecialtyDataReadOnly()->GetAt(KEY_RUNTIME, (int&)eKind); if (eKind == TDb::eAirlets) { tIf.Reset(); pEqu->GetInterface(0, tIf); if (tIf.GetConnectObject().isValid()) continue; arAirId.append(idPre); } } OPENOBJ_END(); } pBlockTableRecord->close(); } // 判断风口是否在风管上 BOOL TAuxTools::AirIsOnDuct( const AcDbObjectId& idAir, const TDbHvacDuct* pDuct, int& nPos, AcGeVector3d& vtFlux ) { if (pDuct == NULL) return FALSE; OPENOBJ_BEGIN(idAir, AcDb::kForRead, TDbHvacEquipment, pEqu); if (pEqu == NULL) return FALSE; TDbXDataMap* pXMap = pEqu->GetSpecialtyDataReadOnly(); TDb::ObjectKind eKind; pXMap->GetAt(KEY_RUNTIME, (int&)eKind); if (eKind != TDb::eAirlets) return FALSE; AcGePoint3d ptStart, ptEnd, ptCenter; AcGeVector3d vtNorDuct, vtSect, vtNorAir, vtMain; double dWidthDt, dThickDt, dThickAir; pXMap->GetAt(HALT_CenterPoint, ptCenter); pXMap->GetAt(HALT_MainDir, vtMain); pXMap->GetAt(HVAC_Normal, vtNorAir); pXMap->GetAt(HALT_Thick, dThickAir); pDuct->getStartPoint(ptStart); pDuct->getEndPoint(ptEnd); vtNorDuct = pDuct->normal(); pXMap = pDuct->GetSpecialtyDataReadOnly(); pXMap->GetAt(HDCT_Width, dWidthDt); pXMap->GetAt(HDCT_Thick, dThickDt); TDb::HvacSectType eSectType; pXMap->GetAt(HVAC_SectType, (int&)eSectType); if (eSectType == TDb::eCircular) dThickDt = dWidthDt; vtSect = ptEnd - ptStart; nPos = CalPosBy3Point(ptStart, ptEnd, ptCenter); if (nPos == 0) // 不共线 { // 求风口在管上的投影点 AcGePlane plan(ptCenter, vtSect); AcGePoint3d ptConer = ptStart.orthoProject(plan); if (CalPosBy3Point(ptStart, ptEnd, ptConer) == 3) { double dLength = ptCenter.distanceTo(ptConer); dThickAir += 1.0; if (vtNorAir.isParallelTo(vtNorDuct)) { if (fabs(dLength - dThickDt / 2.0) < dThickAir) { nPos = 2; vtFlux = ptCenter - ptConer; vtFlux.normalize(); return TRUE; } } else if (vtNorAir.isPerpendicularTo(vtNorDuct)) { if (fabs(dLength - dWidthDt / 2.0) < dThickAir) { nPos = 3; vtFlux = ptCenter - ptConer; vtFlux.normalize(); return TRUE; } } } } else // 共线 { if (vtNorAir.isParallelTo(vtSect)) // 平行 { dThickAir += 1.0; if ((ptCenter.distanceTo(ptStart) < dThickAir) || (ptCenter.distanceTo(ptEnd) < dThickAir)) // 范围 { nPos = 1; vtFlux = vtNorAir; return TRUE; } } } OPENOBJ_END(); return FALSE; } // 判断点pt3与pt1和pt2的位置关系。0-不共线;1--在pt1外;2--同pt1;3--在pt1和pt2之间;4--同pt2;5--在pt2外 int TAuxTools::CalPosBy3Point(const AcGePoint3d& pt1, const AcGePoint3d& pt2, const AcGePoint3d& pt3) { if (pt3 == pt1) return 2; if (pt3 == pt2) return 4; AcGeVector3d vt13, vt23; vt13 = pt3 - pt1; vt23 = pt3 - pt2; if (!vt13.isParallelTo(vt23)) // 不共线 return 0; if (vt13.isCodirectionalTo(vt23)) { if (pt3.distanceTo(pt1) < pt3.distanceTo(pt2)) return 1; else return 5; } else { return 3; } return -1; } BOOL TAuxTools::Is2DView() { BOOL b2D(FALSE); struct resbuf rb = {NULL, RT3DPOINT, 0}; acedGetVar(_T("VIEWDIR"), &rb); AcGeVector3d vtDir = asVec3d(rb.resval.rpoint); if ((vtDir.isCodirectionalTo(AcGeVector3d::kZAxis) && TAuxTools::GetUcsZvt().isCodirectionalTo(AcGeVector3d::kZAxis))) { b2D = TRUE; } return b2D; } void TAuxTools::DoubleToString( double dValue, int nPreci, CString &csValue ) { CString csPreci; csPreci.Format(_T("%d"), nPreci); csValue.Format(_T("%.") + csPreci + _T("f"), dValue); } AcDbObjectId TAuxTools::GetProjBlockId(const AcDbObjectId& idSrc, AcGeVector3d vtNor, AcGeVector3d vtMain, AcGeVector3d vtPlaneSec, AcGeScale3d& scale, AcDbExtents* pExt) { // 图块正方向 AcGeVector3d vtFront = vtNor.crossProduct(vtMain); // 正方向与投影方向的角度 double dProjAng = vtFront.angleTo(vtPlaneSec, vtNor); // 是否镜像 BOOL bMirror = (PI / 2 < dProjAng && PI * 1.5 > dProjAng); // 旋转轴 AcGeVector3d vtAxis = vtPlaneSec.crossProduct(vtNor); // 旋转角度 double dAngle = vtNor.angleTo(vtPlaneSec, bMirror ? -vtAxis : vtAxis); // 矩阵 AcGeMatrix3d matNor, matHorz, matMirr; matNor.setToRotation(dAngle, vtAxis, AcGePoint3d::kOrigin); matHorz.setToRotation(-dProjAng, AcGeVector3d::kZAxis, AcGePoint3d::kOrigin); matMirr.setToRotation(PI, AcGeVector3d::kXAxis, AcGePoint3d::kOrigin); // 新图块ID AcDbObjectId idNew = AcDbObjectId::kNull; // 原始图块旋转之后的尺寸 AcGeScale3d scaOrg(1, 1, 1); // 生成图块名 CString csBlkName; OPENOBJ_BEGIN(idSrc, AcDb::kForRead, AcDbBlockTableRecord, pBlkRec); if(NULL != pBlkRec) { TCHAR* pName = NULL; pBlkRec->getName(pName); csBlkName.Format(_T("%s_%d%d%d%.6f%.6f%.6f"), pName, bMirror, (int)(dAngle * 180 / PI), (int)(dProjAng * 180 / PI), vtAxis.x, vtAxis.y, vtAxis.z); } else { return AcDbObjectId::kNull; } OPENOBJ_END(); AcDbBlockTable* pBlkTbl = NULL; acdbCurDwg()->getBlockTable(pBlkTbl, AcDb::kForWrite); if(NULL == pBlkTbl) return AcDbObjectId::kNull; AcGePoint3d ptMax, ptMin; if(pBlkTbl->has(csBlkName)) // 块存在 { pBlkTbl->getAt(csBlkName, idNew); OPENOBJ_BEGIN(idNew, AcDb::kForRead, AcDbBlockTableRecord, pBlkOld); if(NULL != pBlkOld) { AcDbExtents ext; ext.addBlockExt(pBlkOld); ptMax = ext.maxPoint(); ptMin = ext.minPoint(); scaOrg.set(ptMax.x - ptMin.x, ptMax.y - ptMin.y, ptMax.z - ptMin.z); } OPENOBJ_END(); } else { // 插入新图块 AcDbBlockTableRecord* pBlkNew = new AcDbBlockTableRecord; pBlkTbl->add(idNew, pBlkNew); pBlkNew->setName(csBlkName); AcDbBlockReference* pBlkRef = new AcDbBlockReference(AcGePoint3d::kOrigin , idSrc); pBlkRef->transformBy(matNor); pBlkRef->transformBy(matHorz); if(bMirror) pBlkRef->transformBy(matMirr); AcDbVoidPtrArray ptrArr; pBlkRef->explode(ptrArr); for(int i = 0; i < ptrArr.length(); i++) { AcDbEntity* pEnt = AcDbEntity::cast((AcDbEntity*)ptrArr[i]); if(NULL != pEnt) { pBlkNew->appendAcDbEntity(pEnt); pEnt->close(); } } delete pBlkRef; // 取得图块尺寸 AcDbExtents ext; ext.addBlockExt(pBlkNew); ptMax = ext.maxPoint(); ptMin = ext.minPoint(); scaOrg.set(ptMax.x - ptMin.x, ptMax.y - ptMin.y, ptMax.z - ptMin.z); // 设置图块插入点 //AcGePoint3d ptOrigin = Mid(ptMax, ptMin); //ptOrigin.y = ptMin.y; //pBlkNew->setOrigin(ptOrigin); pBlkNew->close(); } // 计算新图块比例 AcDbObjectId idTemp; AcDbBlockTableRecord* pBlkSca = new AcDbBlockTableRecord; pBlkTbl->add(idTemp, pBlkSca); pBlkTbl->close(); AcDbBlockReference* pBlkRefSca = new AcDbBlockReference(AcGePoint3d::kOrigin , idSrc); pBlkRefSca->setScaleFactors(scale); pBlkRefSca->transformBy(matNor); pBlkRefSca->transformBy(matHorz); if(bMirror) pBlkRefSca->transformBy(matMirr); AcDbVoidPtrArray ptrArr; pBlkRefSca->explode(ptrArr); for(int i = 0; i < ptrArr.length(); i++) { AcDbEntity* pEnt = AcDbEntity::cast((AcDbEntity*)ptrArr[i]); if(NULL != pEnt) { pBlkSca->appendAcDbEntity(pEnt); pEnt->close(); } } delete pBlkRefSca; // 取得新图块尺寸 AcDbExtents extSca; extSca.addBlockExt(pBlkSca); ptMax = extSca.maxPoint(); ptMin = extSca.minPoint(); if(NULL != pExt) pExt->addExt(extSca); scale.set((ptMax.x - ptMin.x) / scaOrg[X], (ptMax.y - ptMin.y) / scaOrg[Y], (ptMax.z - ptMin.z) / scaOrg[Z]); pBlkSca->erase(); pBlkSca->close(); return idNew; } extern TDbRelInterfaceReactor* g_pRelInterfaceReactor; TDbInterfaceRecord* TAuxTools::GetIntfPtrFromDB() { AcDbDatabase* pDb = acdbCurDwg(); if(NULL == pDb) return NULL; TDbInterfaceRecord* pIRec = NULL; g_pRelInterfaceReactor->m_mapDbToIRecPtr.Lookup(pDb,(void *&)pIRec); if (pIRec != NULL) { pIRec->m_bIsCatchBuf = true; return pIRec; } else // { } return NULL; } // pLine转换为TGGeCurveSegment,并添加到TDPtrList中 void TAuxTools::Poly2CurveSeg(AcDbPolyline* pLine, TDPtrList& segComs) { if (NULL == pLine) return ; AcGePoint3d pt1, pt2; double dBugle(0.0), dAng(0.0); TGGeCurveSegment tGetSeg; for(int i = 0; i <= (int)pLine->numVerts()-2; i++) { pLine->getPointAt(i, pt1); pLine->getBulgeAt(i, dBugle); pLine->getPointAt(i+1, pt2); // 直线 if (EQUAL_ZERO(dBugle)) { tGetSeg.SetLine(pt1, pt2); } // 此段为弧线 else { // 计算角度 dAng = atan(dBugle) * 4; tGetSeg.SetArc(pt1, pt2, dAng); } segComs.Append(new TGGeCurveSegment(tGetSeg)); } if (pLine->isClosed()) { dBugle = 0.0; pLine->getPointAt(pLine->numVerts()-1, pt1); pLine->getPointAt(0, pt2); pLine->getBulgeAt(pLine->numVerts()-1, dBugle); if (EQUAL_ZERO(dBugle)) tGetSeg.SetLine(pt1, pt2); else { dAng = atan(dBugle) * 4; tGetSeg.SetArc(pt1, pt2, dAng); } segComs.Append(new TGGeCurveSegment(tGetSeg)); } } BOOL TAuxTools::IsIncline(AcGeVector3d& vt) { AcDbDatabase* pDb = acdbCurDwg(); if (NULL == pDb) return FALSE; AcGeVector3d vtZAxis(pDb->ucsxdir().crossProduct(pDb->ucsydir())); return !vt.isParallelTo(vtZAxis) && !vt.isPerpendicularTo(vtZAxis); } void TAuxTools::Matrix3D2String( const AcGeMatrix3d &mat, CString &str ) { #if ADS <= 15 std::ostringstream stream; #else std::wostringstream stream; #endif for (int ln = 0; ln < 4; ++ln) { for (int col = 0; col < 4; ++col) { stream<ucsxdir().crossProduct(pDb->ucsydir()); } else { vtUseZAixs = *pVtNor; } AcGeCircArc3d arc(pt1, pt2, pt3); double dBulge = tan((arc.endAng() - arc.startAng()) * 0.25); AcGeVector3d vtMid = pt2 - pt1; AcGeVector3d vtEnd = pt3 - pt1; AcGeVector3d vtCross = vtMid.crossProduct(vtEnd); if (!vtCross.isCodirectionalTo(vtUseZAixs)) dBulge *= -1; return dBulge; } LPCTSTR TAuxTools::GetBlkNameById (AcDbObjectId id) { AcDbObject* pObj = NULL; if (Acad::eOk != acdbOpenObject(pObj, id, AcDb::kForRead)) { return NULL; } if (!pObj->isKindOf(AcDbBlockTableRecord::desc())) { pObj->close(); return NULL; } AcDbBlockTableRecord* pRec = AcDbBlockTableRecord::cast(pObj); ACHAR* pCh = NULL; pRec->getName(pCh); pRec->close(); pObj->close(); return pCh; } // add by dyc on 2014-01-21 解决Y型三通在比较大坐标值情况下以后后变成T型问题,求两圆交点 BOOL TAuxTools::CircleInsertWith(const AcGeCircArc3d& circleS, const AcGeCircArc3d& circleE, AcGePoint3d& ptInter1, AcGePoint3d& ptInter2) { AcGePoint3d ptCentS = circleS.center(); AcGePoint3d ptCentE = circleE.center(); double dRS = circleS.radius(); double dRE = circleE.radius(); double dSumR = dRS + dRE; double dDistanceES = ptCentS.distanceTo(ptCentE); AcGeVector3d vtES = ptCentE - ptCentS; BOOL bInsert = FALSE; vtES.normalize(); AcGePoint3d ptInsert; if(dDistanceES > dSumR) return bInsert; else if(fabs(dDistanceES - dSumR) <= 1e-6) { ptInsert = ptCentS + vtES * dRS; ptInter1 = ptInter2 = ptInsert; bInsert = TRUE; } else { double dLeftLength = (pow(dRS, 2) - pow(dRE, 2) + pow(dDistanceES, 2)) / (2 * dDistanceES); double dUpLength = sqrt(pow(dRS, 2) - pow(dLeftLength, 2)); double dDownLength = dUpLength; ptInsert = ptCentS + vtES * dLeftLength; vtES.rotateBy(PI * 0.5, AcGeVector3d::kZAxis); ptInter1 = ptInsert + vtES * dUpLength; ptInter2 = ptInsert - vtES * dDownLength; bInsert = TRUE; } return bInsert; } int TAuxTools::StrTokenize(LPCTSTR pszSrc, LPCTSTR pszDelimit, CStringArray& arSubs) { if(NULL == pszSrc || NULL == pszDelimit) return 0; CString sText = pszSrc; LPTSTR pszSub = _tcstok(sText.GetBuffer(0), pszDelimit); while(NULL != pszSub) { arSubs.Add(pszSub); pszSub = _tcstok(NULL, pszDelimit); } sText.ReleaseBuffer(); return (int)arSubs.GetSize(); } BOOL TAuxTools::IsVerticalLine(AcGePoint3d pt1, AcGePoint3d pt2) { AcGeVector3d vt = pt2 - pt1; return fabs(vt.x) < 1.0E-6 && fabs(vt.y) < 1.0E-6; } // 计算曲线遮挡 用于水管遮挡风管的情况 void TAuxTools::GetCurveGeomExtentsEdge(AcDbEntity* pEnt, TComplexCurve& crLoop) { if(NULL == pEnt) return; if(!pEnt->isKindOf(AcDbCurve::desc())) return; // 起点终点 AcDbCurve* pCurve = (AcDbCurve*)pEnt; AcGePoint3d ptStart, ptEnd; pCurve->getStartPoint(ptStart); pCurve->getEndPoint(ptEnd); // 立管不处理 if(IsVerticalLine(ptStart, ptEnd)) return; // 中点 double dPar1 = 0, dPar2 = 0; pCurve->getStartParam(dPar1); pCurve->getEndParam(dPar2); AcGePoint3d ptMid; pCurve->getPointAtParam((dPar1 + dPar2) / 2, ptMid); // 判断是否弧形 BOOL bArc = FALSE; AcGeVector3d vtSE = ptEnd - ptStart; AcGeVector3d ptSM = ptMid - ptStart; if(!vtSE.isParallelTo(ptSM)) { bArc = TRUE; } // 计算边界 double dBrWidth = 0; if(!TAuxTools::GetTHvacDataFromDwg(HVAC_PIPEHIDEWIDTH, dBrWidth)) GetGlobalContext()->GetAt(HVAC_PIPEHIDEWIDTH, dBrWidth); if(!DOWNEQUAL_ZERO(dBrWidth)) { AcGePoint3d ptS1, ptS2, ptE1, ptE2, ptM1, ptM2; if(bArc) { // 取得圆心 AcGeCircArc3d arc(ptStart, ptMid, ptEnd); AcGePoint3d ptCenter = arc.center(); AcGeVector3d vtDir; // start vtDir = ptStart - ptCenter; vtDir.normalize(); ptS1 = ptStart + vtDir * dBrWidth; ptS2 = ptStart - vtDir * dBrWidth; // end vtDir = ptEnd - ptCenter; vtDir.normalize(); ptE1 = ptEnd + vtDir * dBrWidth; ptE2 = ptEnd - vtDir * dBrWidth; // mid vtDir = ptMid - ptCenter; vtDir.normalize(); ptM1 = ptMid + vtDir * dBrWidth; ptM2 = ptMid - vtDir * dBrWidth; } else { // 方向 AcGeVector3d vtDir = ptEnd - ptStart; vtDir.rotateBy(0.5 * PI, AcGeVector3d::kZAxis); vtDir.normalize(); ptS1 = ptStart + vtDir * dBrWidth; ptS2 = ptStart - vtDir * dBrWidth; ptE1 = ptEnd + vtDir * dBrWidth; ptE2 = ptEnd - vtDir * dBrWidth; } TCurveElement tCurveEle; memset(&tCurveEle, 0, sizeof(TCurveElement)); tCurveEle.bHided = FALSE; tCurveEle.dWidth = 0.0; tCurveEle.gsMark = 0; tCurveEle.ptGe[0] = ptS1; tCurveEle.ptGe[1] = bArc ? ptM1 : ptE1; tCurveEle.ptGe[2] = ptE1; crLoop.append(tCurveEle); tCurveEle.ptGe[0] = ptE1; tCurveEle.ptGe[1] = ptE2; tCurveEle.ptGe[2] = ptE2; crLoop.append(tCurveEle); tCurveEle.ptGe[0] = ptE2; tCurveEle.ptGe[1] = bArc ? ptM2 : ptS2; tCurveEle.ptGe[2] = ptS2; crLoop.append(tCurveEle); tCurveEle.ptGe[0] = ptS2; tCurveEle.ptGe[1] = ptS1; tCurveEle.ptGe[2] = ptS1; crLoop.append(tCurveEle); } } void TAuxTools::MakeCurvePolyFaces(AcDbEntity* pEnt, AcDbVoidPtrArray& arFaces) { if(NULL == pEnt) return; if(!pEnt->isKindOf(AcDbCurve::desc())) return; // 起点终点 AcDbCurve* pCurve = (AcDbCurve*)pEnt; AcGePoint3d ptStart, ptEnd; pCurve->getStartPoint(ptStart); pCurve->getEndPoint(ptEnd); // 立管不处理 if(IsVerticalLine(ptStart, ptEnd)) return; // 中点 double dPar1 = 0, dPar2 = 0; pCurve->getStartParam(dPar1); pCurve->getEndParam(dPar2); AcGePoint3d ptMid; pCurve->getPointAtParam((dPar1 + dPar2) / 2, ptMid); // 投影到中点上 AcGePlane plane(Mid(ptStart, ptEnd), AcGeVector3d::kZAxis); ptStart = ptStart.orthoProject(plane); ptEnd = ptEnd.orthoProject(plane); ptMid = ptMid.orthoProject(plane); // 判断是否弧形 BOOL bArc = FALSE; AcGeVector3d vtSE = ptEnd - ptStart; AcGeVector3d ptSM = ptMid - ptStart; if(!vtSE.isParallelTo(ptSM)) { bArc = TRUE; } // 计算边界 double dBrWidth = 0; if(!TAuxTools::GetTHvacDataFromDwg(HVAC_PIPEHIDEWIDTH, dBrWidth)) GetGlobalContext()->GetAt(HVAC_PIPEHIDEWIDTH, dBrWidth); if(!DOWNEQUAL_ZERO(dBrWidth)) { if(!bArc) { // 方向 AcGeVector3d vtDir = ptEnd - ptStart; vtDir.normalize(); ptStart += vtDir * 0.1; ptEnd -= vtDir * 0.1; vtDir.rotateBy(0.5 * PI, AcGeVector3d::kZAxis); vtDir.normalize(); AcGePoint3d ptS1 = ptStart + vtDir * dBrWidth; AcGePoint3d ptS2 = ptStart - vtDir * dBrWidth; AcGePoint3d ptE1 = ptEnd + vtDir * dBrWidth; AcGePoint3d ptE2 = ptEnd - vtDir * dBrWidth; AcDbFace* pFace = new AcDbFace; pFace->setVertexAt(0, ptS1); pFace->setVertexAt(1, ptE1); pFace->setVertexAt(2, ptE2); pFace->setVertexAt(3, ptS2); arFaces.append(pFace); } else // 弧形以直线进行拟合 { double dAngle = GetMinDiffAngle(); // 取得圆心 圆心角 AcGeCircArc3d arc(ptStart, ptMid, ptEnd); double dRadius = arc.radius(); AcGePoint3d ptCent = arc.center(); AcGeVector3d vtMid = ptMid - ptCent; vtMid.normalize(); // 生成点 AcGePoint3dArray arPtUp, arPtDn; AcGePoint3d ptOn; AcGeVector3d vtLeft = vtMid; AcGeVector3d vtRight = vtMid; double dArcAngle = arc.endAng() - arc.startAng(); int nLoop = (int)(dArcAngle / dAngle / 2) + 1; for(int i = 0; i < nLoop; i++) { if(0 == i) { ptOn = ptCent + vtMid * (dRadius + dBrWidth); arPtUp.append(ptOn); ptOn = ptCent + vtMid * (dRadius - dBrWidth); arPtDn.append(ptOn); } else { // 左侧 vtLeft.rotateBy(dAngle, AcGeVector3d::kZAxis); ptOn = ptCent + vtLeft * (dRadius + dBrWidth); arPtUp.insertAt(0, ptOn); ptOn = ptCent + vtLeft * (dRadius - dBrWidth); arPtDn.insertAt(0, ptOn); // 右侧 vtRight.rotateBy(-dAngle, AcGeVector3d::kZAxis); ptOn = ptCent + vtRight * (dRadius + dBrWidth); arPtUp.append(ptOn); ptOn = ptCent + vtRight * (dRadius - dBrWidth); arPtDn.append(ptOn); } } // 起点终点 vtMid = ptEnd - ptCent; vtMid.normalize(); arPtUp.insertAt(0, ptCent + vtMid * (dRadius + dBrWidth)); arPtDn.insertAt(0, ptCent + vtMid * (dRadius - dBrWidth)); vtMid = ptStart - ptCent; vtMid.normalize(); arPtUp.append(ptCent + vtMid * (dRadius + dBrWidth)); arPtDn.append(ptCent + vtMid * (dRadius - dBrWidth)); // 生成遮挡面 AcDbFace* pFace = NULL; for(int i = 0; i < arPtUp.length() - 1; i++) { pFace = new AcDbFace; pFace->setVertexAt(0, arPtUp[i]); pFace->setVertexAt(1, arPtUp[i + 1]); pFace->setVertexAt(2, arPtDn[i + 1]); pFace->setVertexAt(3, arPtDn[i]); arFaces.append(pFace); } } } }