#include "stdafx.h" #include "resource.h" #include "DrawThunder3D.h" #include "CaculateResult.h" #include "ThunderXData.h" #include "dbgroup.h" #include "ThunderCmdGroup.h" #include "LightningRodData.h" #include "ktsetting.h" #include "ThunderCaculate.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif #define DSPACE 0.05 #define GRADUALLY_COUNT 10 TGDrawThunder::TGDrawThunder() { m_strLayer2d = LAY_EL_THUNDER_2D; m_strLayer3d = LAY_EL_THUNDER_3D; m_nSinglePinColorIndex = 256; m_nMultiPinColorIndex = 256; } TGDrawThunder::~TGDrawThunder() { } AcGePoint3d TGDrawThunder::Mid2Point(const AcGePoint3d& pt1, const AcGePoint3d& pt2) { return AcGePoint3d((pt1.x+pt2.x)/2,(pt1.y+pt2.y)/2,(pt1.z+pt2.z)/2); } //画3D避雷区域 void TGDrawThunder::DrawThunder3DArea(LPCTSTR pszGroupNo, lstCltResult& lstData, BOOL bPreview) { //生成新的实体 MakeThunderEntity(pszGroupNo,lstData, bPreview); CThunderXData xd; AcDbObjectId id; if (bPreview) { for (int i = 0;i < m_arPreview.length();++i) { id = AddToCurrentSpace((AcDbEntity*)m_arPreview[i],Adesk::kTrue); xd.SetXData(id, TEL_GROUP_NO, pszGroupNo); ThunderContainer->AppendPreview3DSolid(pszGroupNo, id); } m_arPreview.setLogicalLength(0); } else { for (int i = 0; i < m_arRegSolid.length(); ++i) { id = AddToCurrentSpace((AcDbEntity*)m_arRegSolid[i],Adesk::kTrue); xd.SetXData(id, TEL_GROUP_NO, pszGroupNo); ThunderContainer->Append3DSolid(pszGroupNo, id); } } } bool TGDrawThunder::DocGetMeterUnitDraw() { struct resbuf rb; acedGetVar(_T("INSUNITS"),&rb); if (rb.resval.rint == AcDb::kUnitsMeters) { return true; } return false; } //画2D保护区域 void TGDrawThunder::DrawThunder2DArea(const AcGeDoubleArray& arHeight, LPCTSTR pszGroupNo) { if (pszGroupNo == NULL) { return; } // 清理旧的实体 DeleteAllEntities(pszGroupNo); AcDbObjectIdArray arID; if (ThunderContainer->GetGroupThunder(pszGroupNo, arID) < 1) { return; } KTSetting::InitLayer(LAY_EL_THUNDER_2D); KTSetting::InitLayer(LAY_EL_THUNDER_3D); CRegProperty regProp(GetRegLocation(), TEL_OBJECTKEY); regProp.SetTopRootKey(HKEY_CURRENT_USER); regProp.GetValue(KEY_SINGLEPRO_COLOR,m_nSinglePinColorIndex); regProp.GetValue(KEY_UNIONPRO_COLOR,m_nMultiPinColorIndex); if (arHeight.length() < 1) { return; } CTGTempTol locTol(0.1, 0.1); // 绘制保护圆 DrawThunderCircle(arHeight, pszGroupNo, arID); // 计算避雷针数据 lstCltResult lstData; CalcThunderData(pszGroupNo, arHeight, arID, lstData); // 绘制三维 DrawThunder3DArea(pszGroupNo, lstData); // 根据三维绘制二维 double dScale = 1.0; if (!DocGetMeterUnitDraw()) dScale = 1000.0; AcDbObjectId id; AcGePoint3d ptOrg; AcGePlane plan; AcGeDoubleArray arTemp; CThunderXData thunderXData; AcDbRegion *pFirstReg = NULL; AcDbRegion *pReg = NULL; CString sTemp; for (int j = 0; j < arHeight.length(); ++j) { ptOrg.set(0,0,arHeight[j]*dScale); plan.set(ptOrg,AcGeVector3d::kXAxis,AcGeVector3d::kYAxis); if (m_arRegSolid.length() > 0) { ((AcDb3dSolid*)m_arRegSolid[0])->getSection(plan,pFirstReg); } if (pFirstReg != NULL) { for (int i = 1;i < m_arRegSolid.length();++i) { ((AcDb3dSolid*)m_arRegSolid[i])->getSection(plan,pReg); if (pReg != NULL) { pFirstReg->booleanOper(AcDb::kBoolUnite,pReg); delete pReg; pReg = NULL; } } pFirstReg->setLayer(m_strLayer2d); pFirstReg->setColorIndex(m_nMultiPinColorIndex); id = AddToCurrentSpace(pFirstReg,Adesk::kTrue); pFirstReg = NULL; // 二维区域写入保护高度扩展数据 arTemp.setLogicalLength(0); arTemp.append(arHeight[j]); sTemp.Format(_T("%g"),arHeight[j]); thunderXData.SetXData(id,TEL_GROUP_NO,pszGroupNo); thunderXData.SetXData(id,TEL_CURRENT_PROHEIGHT,sTemp); thunderXData.SetProtectHeightToObjEx(id, arHeight); ThunderContainer->AppendRegion(pszGroupNo, id); } } } void TGDrawThunder::DrawThunderLine(LPCTSTR pszGroupNo, const AcGeDoubleArray& arHeight) { // 清理旧的实体 DeleteThunLineEntities(pszGroupNo); if (pszGroupNo != NULL && arHeight.length() > 0) { KTSetting::InitLayer(LAY_EL_THUNDER_2D); KTSetting::InitLayer(LAY_EL_THUNDER_3D); CRegProperty regProp(GetRegLocation(), TEL_OBJECTKEY); regProp.SetTopRootKey(HKEY_CURRENT_USER); regProp.GetValue(KEY_SINGLEPRO_COLOR,m_nSinglePinColorIndex); regProp.GetValue(KEY_UNIONPRO_COLOR,m_nMultiPinColorIndex); AcDbObjectIdArray arID; ThunderContainer->GetGroupThunderLine(pszGroupNo, arID); if (arHeight.length() < 1 || arID.length() < 1) { return; } CTGTempTol locTol(0.1, 0.1); // 计算数据 MapThunderLineCltResult mapData; CalcThunLineData(pszGroupNo, arHeight, arID, mapData); // 绘制避雷线三维 DrawThunLine3D(pszGroupNo, mapData); // 添加到模型空间 AcDbObjectId id; AcDbEntity* p3dEnt = NULL; MapThunderLinePtr::iterator itT; for (itT = m_mapThunLinePtr.begin();itT != m_mapThunLinePtr.end();++itT) { m_arCollector.append(itT->second); } for (int i = 0; i < m_arCollector.length(); ++i) { p3dEnt = (AcDbEntity*)m_arCollector[i]; if (p3dEnt != NULL) { p3dEnt->setLayer(LAY_EL_THUNDER_3D); p3dEnt->setColorIndex(m_nMultiPinColorIndex); id = AddToCurrentSpace(p3dEnt,Adesk::kTrue); ThunderContainer->AppendLine3DSolid(pszGroupNo, id); } } // 根据三维实体生成二维区域 double dScale = 1.0; if (!DocGetMeterUnitDraw()) dScale = 1000.0; AcGePoint3d ptOrg; AcGePlane plan; AcGeDoubleArray arTemp; CThunderXData thunderXData; AcDbRegion *pFirstReg = NULL; AcDbRegion *pReg = NULL; CString sTemp; MapUnionLine::iterator itUnion; AcDbVoidPtrArray arPtrTemp; for (int j = 0; j < arHeight.length(); ++j) { arPtrTemp.setLogicalLength(0); ptOrg.set(0,0,arHeight[j]*dScale); plan.set(ptOrg,AcGeVector3d::kXAxis,AcGeVector3d::kYAxis); //1.单个避雷线reg for (itT = m_mapThunLinePtr.begin();itT != m_mapThunLinePtr.end();++itT) { arPtrTemp = itT->second; if (arPtrTemp.length() > 0) { ((AcDb3dSolid*)arPtrTemp[0])->getSection(plan,pFirstReg); if (pFirstReg != NULL) { for (int i = 1;i < arPtrTemp.length();++i) { ((AcDb3dSolid*)arPtrTemp[i])->getSection(plan,pReg); if (pReg != NULL) { pFirstReg->booleanOper(AcDb::kBoolUnite,pReg); delete pReg; pReg = NULL; } } pFirstReg->setLayer(m_strLayer2d); pFirstReg->setColorIndex(m_nSinglePinColorIndex); id = AddToCurrentSpace(pFirstReg,Adesk::kTrue); pFirstReg = NULL; // 二维区域写入保护高度扩展数据 arTemp.setLogicalLength(0); arTemp.append(arHeight[j]); sTemp.Format(_T("%g"),arHeight[j]); thunderXData.SetXData(id,KEY_LINE_GROUP_NO,pszGroupNo); thunderXData.SetXData(id,TEL_CURRENT_PROHEIGHT,sTemp); thunderXData.SetProtectHeightToObjEx(id, arHeight); ThunderContainer->AppendLineRegion(pszGroupNo, id); } } } //1.联合避雷线reg for (itUnion = m_mapLineUnRegSolid.begin();itUnion != m_mapLineUnRegSolid.end();++itUnion) { arPtrTemp = itUnion->second; if (arPtrTemp.length() > 0) { ((AcDb3dSolid*)arPtrTemp[0])->getSection(plan,pFirstReg); if (pFirstReg != NULL) { for (int i = 1;i < arPtrTemp.length();++i) { ((AcDb3dSolid*)arPtrTemp[i])->getSection(plan,pReg); if (pReg != NULL) { pFirstReg->booleanOper(AcDb::kBoolUnite,pReg); delete pReg; pReg = NULL; } } pFirstReg->setLayer(m_strLayer2d); pFirstReg->setColorIndex(m_nMultiPinColorIndex); id = AddToCurrentSpace(pFirstReg,Adesk::kTrue); pFirstReg = NULL; // 二维区域写入保护高度扩展数据 arTemp.setLogicalLength(0); arTemp.append(arHeight[j]); sTemp.Format(_T("%g"),arHeight[j]); thunderXData.SetXData(id,KEY_LINE_GROUP_NO,pszGroupNo); thunderXData.SetXData(id,TEL_CURRENT_PROHEIGHT,sTemp); thunderXData.SetProtectHeightToObjEx(id, arHeight); ThunderContainer->AppendLineRegion(pszGroupNo, id); } } } } m_arCollector.setLogicalLength(0); m_mapThunLinePtr.clear(); m_mapLineUnRegSolid.clear(); } } void TGDrawThunder::DeleteThunLineEntities(LPCTSTR pszGNo) { ThunderContainer->EreaseSpecGNoLineRegion(pszGNo); ThunderContainer->EreaseSpecGNoLine3dSolid(pszGNo); } void TGDrawThunder::ClassifyThunderLines(const AcDbObjectIdArray& arID, LstParallelTLine& lstID) { lstID.clear(); int nPos = -1; AcDbObjectIdArray arLoc,arTmp; arLoc.append(arID); while (arLoc.length() > 0) { arTmp.append(arLoc[0]); for (int i = 1;i < arLoc.length();++i) { if (CheckIsEqualLineTLine(arLoc[0], arLoc[i])) { arTmp.append(arLoc[i]); } } lstID.push_back(arTmp); for (int j = 0;j < arTmp.length();++j) { arLoc.find(arTmp[j],nPos); if (nPos >= 0 && nPos < arLoc.length()) { arLoc.removeAt(nPos); } } arTmp.setLogicalLength(0); } } BOOL TGDrawThunder::CheckIsEqualLineTLine(const AcDbObjectId& id1,const AcDbObjectId& id2) { BOOL bSuc = FALSE; if (id1.isValid() && id2.isValid()) { CString sGRadius,sGRadius2,sHeight,sHeight2; CThunderXData xd; OPENOBJ_BEGIN(id1,AcDb::kForRead,AcDbPolyline,pLine); if (pLine != NULL) { OPENOBJ_BEGIN(id2,AcDb::kForRead,AcDbPolyline,pLine2); if (pLine2 != NULL) { // 比较扩展数据 xd.GetXData(pLine,KEY_LINE_PRO_RADIUS,sGRadius); xd.GetXData(pLine,KEY_LINE_HEIGHT,sHeight); xd.GetXData(pLine2,KEY_LINE_PRO_RADIUS,sGRadius2); xd.GetXData(pLine2,KEY_LINE_HEIGHT,sHeight2); if (fabs(_tstof(sGRadius)-_tstof(sGRadius2)) < 1e-3 && fabs(_tstof(sHeight)-_tstof(sHeight2)) < 1e-3 ) { AcGePoint3d ptS,ptE,ptS2,ptE2; pLine->getStartPoint(ptS); pLine->getEndPoint(ptE); pLine2->getStartPoint(ptS2); pLine2->getEndPoint(ptE2); AcGeVector3d vt1 = ptE - ptS; AcGeVector3d vt2 = ptE2 - ptS2; if (vt1.isParallelTo(vt2)) // 平行 { // 共线 if (CheckPtIsOnLine(ptS,pLine2) || CheckPtIsOnLine(ptE,pLine2) || CheckPtIsOnLine(ptS2,pLine) || CheckPtIsOnLine(ptE2,pLine) ) { bSuc = TRUE; } } } } OPENOBJ_END(); } OPENOBJ_END(); } return bSuc; } BOOL TGDrawThunder::CheckPtIsOnLine(const AcGePoint3d& pt, AcDbPolyline* pLine) { if (pLine != NULL) { AcGePoint3d ptOn; pLine->getClosestPointTo(pt, ptOn); if (pt.distanceTo(ptOn) < 1e-3) { return TRUE; } } return FALSE; } void TGDrawThunder::GetThunderLineMaxPort(const AcDbObjectIdArray& arID, AcGePoint3d& ptS,AcGePoint3d& ptE) { // 前提:所有Pl平行且共线 AcGePoint3d ptT; std::list lstX,lstY,lstZ; for (int i = 0;i < arID.length();++i) { OPENOBJ_BEGIN(arID[i],AcDb::kForRead,AcDbPolyline,pLine); if (pLine != NULL) { pLine->getStartPoint(ptT); lstX.push_back(ptT.x); lstY.push_back(ptT.y); lstZ.push_back(ptT.z); pLine->getEndPoint(ptT); lstX.push_back(ptT.x); lstY.push_back(ptT.y); lstZ.push_back(ptT.z); } OPENOBJ_END(); } if (lstX.size() > 0 && lstY.size() > 0 && lstZ.size() > 0) { lstX.sort(); lstY.sort(); lstZ.sort(); ptS.x = lstX.front(); ptS.y = lstY.front(); ptS.z = lstZ.front(); ptE.x = lstX.back(); ptE.y = lstY.back(); ptE.z = lstZ.back(); } } int TGDrawThunder::CalcThunLineData(LPCTSTR pszGNo, const AcGeDoubleArray& arProHeight, const AcDbObjectIdArray& arID, MapThunderLineCltResult& mapData) { mapData.clear(); if (pszGNo != NULL && arID.length() > 0) { CThunderXData thundXData; for (int p = 0;p < arID.length();++p) { thundXData.SetProtectHeightToObjEx(arID[p], arProHeight); } AcDbObjectIdArray arLoc(arID); // 检查是否存在避雷针编号重复 AcDbObjectIdArray arRepeate; if (CheckHasRepeatNum(arLoc,arRepeate)) { acutPrintf(_T("\n 存在重复的避雷线编号,请修改编号。")); } // LstParallelTLine lstID; // LstParallelTLine::iterator it; // ClassifyThunderLines(arLoc, lstID); CStringArray arsXData; TGLightningRodData ltnData; TGThunderCaculate caculate; AcGePoint3d ptStart,ptEnd; lstCltResult lstTemp; CString sGRadius,sHeight,sNum,sGNo; for (int i = 0;i < arLoc.length();++i) { if (!arLoc[i].isValid()) { continue; } // GetThunderLineMaxPort(arIDTemp, ptStart, ptEnd); // ptStart.z = 0; // ptEnd.z = 0; lstTemp.clear(); OPENOBJ_BEGIN(arLoc[i],AcDb::kForRead,AcDbPolyline,pLine); if (pLine != NULL) { pLine->getStartPoint(ptStart); pLine->getEndPoint(ptEnd); ptStart.z = 0; ptEnd.z = 0; thundXData.GetXData(pLine,KEY_LINE_PRO_RADIUS,sGRadius); thundXData.GetXData(pLine,KEY_LINE_HEIGHT,sHeight); thundXData.GetXData(pLine,KEY_LINE_GROUP_NO,sGNo); thundXData.GetXData(pLine,TEL_ORDER_NUMBER,sNum); ltnData.SetGroundRadius(_tstof(sGRadius)); ltnData.SetHeight(_tstof(sHeight)); ltnData.SetNumber(_ttoi(sNum)); ltnData.SetGroupNO(_ttoi(sGNo)); ltnData.SetInsertPoint(ptStart); ltnData.m_arProtecedHeight.setLogicalLength(0); ltnData.m_arProtecedHeight.append(arProHeight); caculate.CaculateThunderData(<nData); lstTemp.push_back(caculate.m_result); ltnData.SetGroundRadius(_tstof(sGRadius)); ltnData.SetHeight(_tstof(sHeight)); ltnData.SetNumber(_ttoi(sNum)); ltnData.SetGroupNO(_ttoi(sGNo)); ltnData.SetInsertPoint(ptEnd); ltnData.m_arProtecedHeight.setLogicalLength(0); ltnData.m_arProtecedHeight.append(arProHeight); caculate.CaculateThunderData(<nData); lstTemp.push_back(caculate.m_result); } OPENOBJ_END(); mapData.insert(std::make_pair(arLoc[i],lstTemp)); } } return (mapData.size() > 0); } void TGDrawThunder::DrawThunLine3D(LPCTSTR pszGNo,MapThunderLineCltResult& mapData, BOOL bPreview) { AcDb3dSolid *pSolid = NULL; CThunderXData thundXData; lstCltResult::iterator it; MapThunderLineCltResult::iterator itMap; lstCltResult lstData; AcDbRegion* pSecReg = NULL; AcGePlane plan; AcGePoint3d ptPos; AcGeVector3d vtHor = AcGeVector3d::kZAxis,vtVer,vtNor; AcDbVoidPtrArray arPtr; // 绘制单个避雷线 for (itMap = mapData.begin();itMap != mapData.end();++itMap) { lstData = itMap->second; if (lstData.size() != 2) continue; ptPos = lstData.front().m_ptInsert; ptPos.z = 0.0; vtNor = lstData.back().m_ptInsert - lstData.front().m_ptInsert; vtVer = vtHor; vtVer.rotateBy(PI/2,vtNor); plan.set(ptPos,vtHor,vtVer); pSolid = Create3DSolid(lstData.front()); if (pSolid == NULL) { continue; } arPtr.setLogicalLength(0); arPtr.append(pSolid); // 实体截面 pSolid->getSection(plan, pSecReg); if (pSecReg != NULL) { pSolid = ExtrudeSolid(pSecReg, vtNor.normal(), vtNor.length()); if (pSolid != NULL) { arPtr.append(pSolid); } delete pSecReg; } pSolid = Create3DSolid(lstData.back()); if (pSolid != NULL) { arPtr.append(pSolid); for (int t = 0;t < arPtr.length();++t) { thundXData.SetXData((AcDbEntity*)arPtr[t], KEY_LINE_GROUP_NO, pszGNo); } // 添加预览 if (bPreview) { m_arLinePreview.append(arPtr); } else { m_mapThunLinePtr.insert(std::make_pair(itMap->first,arPtr)); } } else { for (int t = 0;t < arPtr.length();++t) { delete (AcDbEntity*)arPtr[t]; } } } // 生成联合保护区域 AcDbVoidPtrArray arTemp; AcDbVoidPtrArray arUnions; MapThunderLinePtr::iterator itFind; MapUnionLine::iterator itApFind; MapThunderLineCltResult::iterator itSub; AcDbObjectIdArray arSubGroup; MapGrouping mapGroup; MapGrouping::iterator itGroup; int nIndex = 0; for (itMap = mapData.begin();itMap != mapData.end();++itMap) { arTemp.setLogicalLength(0); arSubGroup.setLogicalLength(0); itSub = itMap; itSub++; for (itSub;itSub != mapData.end();++itSub) { if (CheckIsSuitToCreate(itMap->first,itMap->second,itSub->first,itSub->second)) { CreateUnionRegion(itMap->first,itMap->second,itSub->first,itSub->second,arUnions); if (arUnions.length() > 0) { if (bPreview) { m_arLinePreview.append(arUnions); arSubGroup.append(itSub->first); } else { m_arCollector.append(arUnions); arTemp.append(arUnions); arSubGroup.append(itSub->first); } arUnions.setLogicalLength(0); } } } if (arSubGroup.length() > 0) { arSubGroup.append(itMap->first); BOOL bAppend = FALSE; for (itGroup = mapGroup.begin();itGroup != mapGroup.end();++itGroup) { if (FindSubArray(itGroup->second, arSubGroup)) // 已经存在 { if ((itApFind = m_mapLineUnRegSolid.find(itGroup->first)) != m_mapLineUnRegSolid.end()) { itApFind->second.append(arTemp); bAppend = TRUE; break; } } } if (!bAppend) { for (int t = 0;t < arSubGroup.length();++t) { if ((itFind = m_mapThunLinePtr.find(arSubGroup[t])) != m_mapThunLinePtr.end()) { arTemp.append(itFind->second); } } nIndex++; if (arTemp.length() > 0) { m_mapLineUnRegSolid.insert(std::make_pair(nIndex,arTemp)); } // m_mapLineUnRegSolid.insert(std::make_pair(nIndex,arTempty)); mapGroup.insert(std::make_pair(nIndex,arSubGroup)); } } } // 端点处生成避雷针联合保护区域 AcDbVoidPtrArray arPtrs; for (itGroup = mapGroup.begin();itGroup != mapGroup.end();++itGroup) { Create2PortsUnionSolids(pszGNo, itGroup->second, mapData, arPtrs); if (arPtrs.length() > 0) { if (bPreview) { m_arLinePreview.append(arPtrs); } else { if ((itApFind = m_mapLineUnRegSolid.find(itGroup->first)) != m_mapLineUnRegSolid.end()) { m_arCollector.append(arPtrs); // 添加到模型空间 itApFind->second.append(arPtrs); // 添加到联合保护区域实体集 } else { ReleasePtrArray(arPtrs); } } arPtrs.setLogicalLength(0); } } if (bPreview) { AcDbEntity* pEnt = NULL; AcDbObjectId id; for (int i = 0;i < m_arLinePreview.length();++i) { pEnt = (AcDbEntity*)m_arLinePreview[i]; if (pEnt != NULL) { pEnt->setLayer(LAY_PREVIEW_THUNDER); pEnt->setColorIndex(m_nMultiPinColorIndex); id = AddToCurrentSpace(pEnt,Adesk::kTrue); thundXData.SetXData(id, KEY_LINE_GROUP_NO, pszGNo); ThunderContainer->AppendPreview3DSolid(pszGNo, id); } } m_arLinePreview.setLogicalLength(0); } } void TGDrawThunder::Create2PortsUnionSolids(LPCTSTR pszGNO, const AcDbObjectIdArray& arLine, MapThunderLineCltResult& mapData, AcDbVoidPtrArray& arSolids) { if (arLine.length() < 3 || mapData.size() < 1 || pszGNO == NULL ) { return; } AcGePoint3dArray arPtPort1,arPtPort2; AcGeVector3d vtDir; AcGePoint3d ptS,ptE; CCaculateResult rstTmp,rstTmp2; lstCltResult lstData1,lstData2; MapThunderLineCltResult::iterator it; OPENOBJ_BEGIN(arLine[0],AcDb::kForRead,AcDbPolyline,pLine); if (pLine != NULL) { pLine->getStartPoint(ptS); pLine->getEndPoint(ptE); if ((it = mapData.find(arLine[0])) != mapData.end()) { arPtPort1.append(ptS); GetCltResultByPosition(it->second, ptS, rstTmp); lstData1.push_back(rstTmp); arPtPort2.append(ptE); GetCltResultByPosition(it->second, ptE, rstTmp); lstData2.push_back(rstTmp); } vtDir = ptS - ptE; vtDir.normalize(); } OPENOBJ_END(); for (int i = 1;i < arLine.length();++i) { OPENOBJ_BEGIN(arLine[i],AcDb::kForRead,AcDbPolyline,pLine); if (pLine != NULL) { pLine->getStartPoint(ptS); pLine->getEndPoint(ptE); if ((it = mapData.find(arLine[i])) != mapData.end()) { GetCltResultByPosition(it->second, ptS, rstTmp); GetCltResultByPosition(it->second, ptE, rstTmp2); if (vtDir.isCodirectionalTo(ptS - ptE)) // 同向 { arPtPort1.append(ptS); lstData1.push_back(rstTmp); arPtPort2.append(ptE); lstData2.push_back(rstTmp2); } else { arPtPort1.append(ptE); lstData1.push_back(rstTmp2); arPtPort2.append(ptS); lstData2.push_back(rstTmp); } } } OPENOBJ_END(); } // 生成避雷针联合实体 Make3CenThunderEntity(pszGNO, lstData1,FALSE,&arSolids); Make3CenThunderEntity(pszGNO, lstData2,FALSE,&arSolids); } BOOL TGDrawThunder::FindSubArray(const AcDbObjectIdArray& arSrc, const AcDbObjectIdArray& arSub) { if (arSrc.length() < 1|| arSub.length() < 1) { return FALSE; } int nIndex = 0; for (int i = 0;i < arSub.length();++i) { if (!arSrc.find(arSub[i], nIndex)) { return FALSE; } } return TRUE; } AcDb3dSolid* TGDrawThunder::ExtrudeSolid(AcDbRegion* pDepReg, const AcGeVector3d& vtDirTo, double dLength) { AcDb3dSolid* pSolid = NULL; if (pDepReg != NULL) { AcGeVector3d vtDir(vtDirTo); int nScale = 1; if (!DocGetMeterUnitDraw()) { nScale *= 1000; } AcGeVector3d vtNor; pDepReg->getNormal(vtNor); int nDir = 1; if (!vtNor.isCodirectionalTo(vtDir)) { nDir = -1; } pSolid = new AcDb3dSolid; AcGeVector3d vtOff; AcGeMatrix3d mat; AcDb3dSolid* pTemp = new AcDb3dSolid; AcDb3dSolid* pTemp2 = new AcDb3dSolid; int nCount = (int)dLength / (EXTRUDE_MAX_SIZE*nScale); double dSpare = dLength - (nCount * EXTRUDE_MAX_SIZE*nScale); if (nCount > 0) { pSolid->extrude(pDepReg, EXTRUDE_MAX_SIZE*nScale*nDir, 0); pTemp2->copyFrom(pSolid); } for (int t = 1;t < nCount;++t) { vtOff = vtDir.normal() * t * EXTRUDE_MAX_SIZE*nScale; mat.setToTranslation(vtOff); pTemp->cleanBody(); pTemp->copyFrom(pTemp2); pTemp->transformBy(mat); pSolid->booleanOper(AcDb::kBoolUnite, pTemp); } if (dSpare > 0) { vtOff = vtDir.normal() * nCount * EXTRUDE_MAX_SIZE*nScale; mat.setToTranslation(vtOff); pDepReg->transformBy(mat); pTemp->cleanBody(); pTemp->extrude(pDepReg,dSpare*nDir,0); pSolid->booleanOper(AcDb::kBoolUnite, pTemp); } delete pTemp; delete pTemp2; } return pSolid; } AcDb3dSolid* TGDrawThunder::ExtrudeSolidAlongPath(AcDbRegion* pDepReg, AcDbCurve* pCve) { AcDb3dSolid* pSolid = NULL; if (pDepReg != NULL && pCve != NULL) { int nScale = 1; if (!DocGetMeterUnitDraw()) { nScale *= 1000; } pSolid = new AcDb3dSolid; AcGePoint3d ptS,ptE; CalcLinePorts(pDepReg, pCve, ptS, ptE); double dLength = ptS.distanceTo(ptE); AcGeVector3d vtDir = ptE - ptS; vtDir.normalize(); AcGeVector3d vtOff; AcGeMatrix3d mat; AcDb3dSolid* pTemp = new AcDb3dSolid; AcDb3dSolid* pTemp2 = new AcDb3dSolid; AcDbLine* pLine = NULL; AcDbObjectId idTmp; Acad::ErrorStatus es; int nCount = (int)dLength / (EXTRUDE_ALONGPATH_MAX_SIZE*nScale); double dSpare = dLength - (nCount * EXTRUDE_ALONGPATH_MAX_SIZE*nScale); if (nCount > 0) { ptE = ptS + vtDir * EXTRUDE_ALONGPATH_MAX_SIZE*nScale; pLine = new AcDbLine(ptS,ptE); idTmp = AddToCurrentSpace(pLine,Adesk::kTrue); es = pSolid->extrudeAlongPath(pDepReg, pLine); pTemp2->copyFrom(pSolid); EreaseObj(idTmp); } // 由于端点处截取的reg是不规则的 // 因此需要重新截取新的reg for (int t = 1;t < nCount;++t) { vtOff = vtDir.normal() * t * EXTRUDE_ALONGPATH_MAX_SIZE*nScale; mat.setToTranslation(vtOff); pTemp->cleanBody(); pTemp->copyFrom(pTemp2); pTemp->transformBy(mat); pSolid->booleanOper(AcDb::kBoolUnite, pTemp); } if (dSpare > 0) { ptS += vtDir.normal() * nCount * EXTRUDE_ALONGPATH_MAX_SIZE*nScale; ptE = ptS + vtDir * dSpare; pLine = new AcDbLine(ptS, ptE); idTmp = AddToCurrentSpace(pLine,Adesk::kTrue); if (nCount < 1) { pTemp->cleanBody(); es = pTemp->extrudeAlongPath(pDepReg, pLine); pSolid->booleanOper(AcDb::kBoolUnite, pTemp); } else { AcGePoint3d ptTmp = ptS - vtDir.normal() * nScale; AcGeVector3d vtT = vtDir.crossProduct(AcGeVector3d::kZAxis); AcGePlane plan; plan.set(ptTmp,vtT,AcGeVector3d::kZAxis); AcDbRegion* pReg = NULL; pSolid->getSection(plan,pReg); if (pReg != NULL) { pTemp->cleanBody(); es = pTemp->extrudeAlongPath(pReg, pLine); delete pReg; pSolid->booleanOper(AcDb::kBoolUnite, pTemp); } } EreaseObj(idTmp); } delete pTemp; delete pTemp2; } return pSolid; } void TGDrawThunder::CalcLinePorts(AcDbRegion* pReg, AcDbCurve* pCve, AcGePoint3d& ptS, AcGePoint3d& ptE) { if (pReg != NULL && pCve != NULL) { pCve->getStartPoint(ptS); pCve->getEndPoint(ptE); AcDbVoidPtrArray arPtr; pReg->explode(arPtr); AcGePoint3d ptOn; AcDbCurve* pL = NULL; for (int i = 0;i < arPtr.length();++i) { pL = AcDbCurve::cast((AcDbEntity*)arPtr[i]); if (pL != NULL) { pL->getClosestPointTo(ptS, ptOn); if (ptS.distanceTo(ptOn) < 1e-3) { break; } pL->getClosestPointTo(ptE, ptOn); if (ptE.distanceTo(ptOn) < 1e-3) { ptOn = ptE; ptE = ptS; ptS = ptOn; break; } } } for (int j = 0;j < arPtr.length();++j) { delete (AcDbEntity*)arPtr[j]; } } } AcGeVector3d TGDrawThunder::CalcRegionNormal(const AcGePoint3d& pt, AcDbRegion* pReg) { AcGeVector3d vtNor; if (pReg != NULL) { AcGePlane plan; pReg->getPlane(plan); AcGePoint3d ptOn = pt.orthoProject(plan); vtNor = pt - ptOn; } return vtNor; } BOOL TGDrawThunder::CheckIsSuitToCreate(const AcDbObjectId& id1, lstCltResult& lstData1, const AcDbObjectId& id2, lstCltResult& lstData2) { BOOL bSuit = FALSE; // 只处理0< h <= hr的情况 if (lstData1.size() < 1 || lstData2.size() < 1) { return bSuit; } double dGRadius = lstData1.begin()->m_dGroundRadius; double dHeight = lstData1.begin()->m_dHeight; if (dHeight < 0 || dHeight > dGRadius) { return bSuit; } dGRadius = lstData2.begin()->m_dGroundRadius; dHeight = lstData2.begin()->m_dHeight; if (dHeight < 0 || dHeight > dGRadius) { return bSuit; } if (id1.isValid() && id2.isValid()) { OPENOBJ_BEGIN(id1,AcDb::kForRead,AcDbPolyline,pLine); if (pLine != NULL) { OPENOBJ_BEGIN(id2,AcDb::kForRead,AcDbPolyline,pLine2); if (pLine2 != NULL) { AcGePoint3d ptS,ptE,ptS2,ptE2; AcGeVector3d vt1,vt2; pLine->getStartPoint(ptS); pLine->getEndPoint(ptE); ptS.z = 0; ptE.z = 0; vt1 = ptS - ptE; pLine2->getStartPoint(ptS2); pLine2->getEndPoint(ptE2); ptS2.z = 0; ptE2.z = 0; vt2 = ptS2 - ptE2; if (vt1.isParallelTo(vt2)) // 平行 { AcDbLine ln(ptS,ptE); AcGePoint3d ptOn; ln.getClosestPointTo(ptS2, ptOn, Adesk::kTrue); double dDist = ptS2.distanceTo(ptOn); if (dDist > 1e-3) //不共线 { CString sGroundRadius,sHeight; CThunderXData xd; xd.GetXData(pLine, KEY_LINE_PRO_RADIUS, sGroundRadius); xd.GetXData(pLine, KEY_LINE_HEIGHT, sHeight); double dScale = 1.0; if (!DocGetMeterUnitDraw()) dScale *= 1000; double dD = 2*pow(_tstof(sHeight)*dScale*(2*_tstof(sGroundRadius)*dScale-_tstof(sHeight)*dScale),0.5); if (dDist < dD) { bSuit = TRUE; } } } } OPENOBJ_END(); } OPENOBJ_END(); } return bSuit; } static AcDbObjectId ShowPoint(const AcGePoint3d& pt, Adesk::UInt16 nColorIndex) { AcDbCircle* pCir = new AcDbCircle(pt, AcGeVector3d::kZAxis, 1000); pCir->setColorIndex(nColorIndex); return AddToCurrentSpace(pCir, Adesk::kTrue); } BOOL TGDrawThunder::CreatePortUnionSolid(const AcDbObjectId& id1,lstCltResult& lstData1,const AcDbObjectId& id2,lstCltResult& lstData2,AcDbVoidPtrArray& arSolids) { if (id1.isValid() && id2.isValid()) { CCaculateResult data1,data2; OPENOBJ_BEGIN(id1,AcDb::kForRead,AcDbPolyline,pLine); if (pLine != NULL) { OPENOBJ_BEGIN(id2,AcDb::kForRead,AcDbPolyline,pLine2); if (pLine2 != NULL) { AcGePoint3d ptS,ptE,ptS2,ptE2; pLine->getStartPoint(ptS); pLine->getEndPoint(ptE); pLine2->getStartPoint(ptS2); pLine2->getEndPoint(ptE2); double dDist = 0.0; std::map mapPt; LinePtPair ptPair; dDist = ptS.distanceTo(ptS2); ptPair.pt1 = ptS; ptPair.pt2 = ptS2; mapPt.insert(std::make_pair(dDist,ptPair)); dDist = ptS.distanceTo(ptE2); ptPair.pt1 = ptS; ptPair.pt2 = ptE2; mapPt.insert(std::make_pair(dDist,ptPair)); dDist = ptE.distanceTo(ptS2); ptPair.pt1 = ptE; ptPair.pt2 = ptS2; mapPt.insert(std::make_pair(dDist,ptPair)); dDist = ptE.distanceTo(ptE2); ptPair.pt1 = ptE; ptPair.pt2 = ptE2; mapPt.insert(std::make_pair(dDist,ptPair)); lstCltResult lstLoc; lstLoc.insert(lstLoc.end(),lstData1.begin(),lstData1.end()); lstLoc.insert(lstLoc.end(),lstData2.begin(),lstData2.end()); ptS = mapPt.begin()->second.pt1; ptE = mapPt.begin()->second.pt2; GetCltResultByPosition(lstLoc, ptS, data1); GetCltResultByPosition(lstLoc, ptE, data2); } OPENOBJ_END(); } OPENOBJ_END(); AcDb3dSolid* pSolid = GetThunderAreaBy2Pin(data1, data2, TRUE); if (pSolid != NULL) { arSolids.append(pSolid); } } return (arSolids.length() > 0); } BOOL TGDrawThunder::CreateUnionRegion(const AcDbObjectId& id1,lstCltResult& lstData1,const AcDbObjectId& id2,lstCltResult& lstData2,AcDbVoidPtrArray& arSolids) { if (id1.isValid() && id2.isValid() && lstData1.size() == 2 && lstData2.size() == 2 ) { int nScale = 1; if (!DocGetMeterUnitDraw()) nScale *= 1000; // 计算两线共线部分 T3DNODE node1,node2; if (!Get2LinePublicSegment(id1, id2, node1, node2)) { // 两避雷线不存在共线时单独处理距离较近的一端 return CreatePortUnionSolid(id1, lstData1, id2, lstData2, arSolids); } // 绑定数据 T3DCALCNODE data1,data2; AttachThunderData(lstData1, lstData2, node1, node2, data1, data2); // 创建两端端点避雷针联合保护区域 AcDb3dSolid* pInt1 = GetThunderAreaBy2Pin(data1.rstPort, data1.rstPro, FALSE); AcDb3dSolid* pInt2 = GetThunderAreaBy2Pin(data2.rstPort, data2.rstPro, FALSE); if (pInt1 != NULL && pInt2 != NULL) { // 创建共线部分实体 // 共线实体拉伸方向(以data1为拉伸起始点) AcGeVector3d vtDir = GetPubleSolidExDir(id1, data1, data2); // 生成共线实体的实体 AcDb3dSolid* pIntPubSolid = GetThunderAreaBy2Pin(data1.rstPro, data1.rstVF, FALSE); AcDb3dSolid* pIntPubSolid2 = GetThunderAreaBy2Pin(data2.rstPro, data2.rstVF, FALSE); if (pIntPubSolid != NULL && pIntPubSolid2 != NULL) { AcDb3dSolid* pRetSolid = CreatePublicSolid(pIntPubSolid, data1.rstPro, data1.rstVF, vtDir); if (pRetSolid != NULL) { double dHeight = lstData1.front().m_dHeight; if (dHeight < lstData2.front().m_dHeight) { dHeight = lstData2.front().m_dHeight; } AcDb3dSolid* pPortSolid = CreateScissorSolid(data1, pIntPubSolid, pInt1, AcGeVector3d::kZAxis, dHeight*nScale); if (pPortSolid != NULL) { arSolids.append(pPortSolid); } pPortSolid = CreateScissorSolid(data2, pIntPubSolid2, pInt2, AcGeVector3d::kZAxis, dHeight*nScale); if (pPortSolid != NULL) { arSolids.append(pPortSolid); } arSolids.append(pRetSolid); } } if (pIntPubSolid != NULL) delete pIntPubSolid; if (pIntPubSolid2 != NULL) delete pIntPubSolid2; arSolids.append(pInt1); arSolids.append(pInt2); } else { if (pInt1 != NULL) delete pInt1; if (pInt2 != NULL) delete pInt2; } } return (arSolids.length() > 0); } AcDb3dSolid* TGDrawThunder::CreateScissorSolid(T3DCALCNODE& data, AcDb3dSolid* pPub, AcDb3dSolid* pPort, const AcGeVector3d& vtDir, double dLength) { AcDb3dSolid* pRetSolid = NULL; if (pPub != NULL && pPort != NULL) { if (data.rstPort.m_ptInsert.distanceTo(data.rstVF.m_ptInsert) < 1e-3) { return pRetSolid; } // 创建三点实体 AcGePoint3dArray arPts; arPts.append(data.rstPort.m_ptInsert); arPts.append(data.rstPro.m_ptInsert); arPts.append(data.rstVF.m_ptInsert); // 整体 pRetSolid = CreateExtendSolid(arPts, vtDir, dLength); if (pRetSolid != NULL) { // 被削减体 AcDbArc* pArc1 = GetSolidTopArc(pPub, data.rstPro, data.rstVF); AcDbArc* pArc2 = GetSolidTopArc(pPort, data.rstPro, data.rstPort); if (pArc1 != NULL && pArc2 != NULL) { AcGePoint3d ptTmp = data.rstPro.m_ptInsert; ptTmp.z += data.rstPro.m_dHeight; if (!DocGetMeterUnitDraw()) { ptTmp.z *= 1000; } AcDbVoidPtrArray arFace; CreateSliceFace(pArc1,ptTmp, pArc2, ptTmp, arFace); AcDb3dSolid* pRemoveSolid = CreateRemovedSolid(pRetSolid, arFace, pArc1->center()); ReleasePtrArray(arFace); CreateSliceFace(pArc2,ptTmp, pArc1, ptTmp, arFace); AcDb3dSolid* pRemoveSolid2 = CreateRemovedSolid(pRetSolid, arFace, pArc2->center()); ReleasePtrArray(arFace); AcDb3dSolid* pBackUp = new AcDb3dSolid; pBackUp->copyFrom(pRetSolid); if (pRemoveSolid != NULL) { if (pRetSolid->booleanOper(AcDb::kBoolSubtract, pRemoveSolid) != Acad::eOk) { pRetSolid->copyFrom(pBackUp); } else { pBackUp->copyFrom(pRetSolid); } delete pRemoveSolid; } if (pRemoveSolid2 != NULL) { if (pRetSolid->booleanOper(AcDb::kBoolSubtract, pRemoveSolid2) != Acad::eOk) { pRetSolid->copyFrom(pBackUp); } delete pRemoveSolid2; } delete pBackUp; } if (pArc1 != NULL) delete pArc1; if (pArc2 != NULL) delete pArc2; } } return pRetSolid; } AcDb3dSolid* TGDrawThunder::CreatePublicSolid(AcDb3dSolid* pIntPubSolid, CCaculateResult& rst1, CCaculateResult& rst2, const AcGeVector3d& vtDir) { AcDb3dSolid* pRetSolid = NULL; if (pIntPubSolid != NULL) { AcGePlane plan; AcGeVector3d vtPlan = rst1.m_ptInsert - rst2.m_ptInsert; plan.set(rst1.m_ptInsert, vtPlan, AcGeVector3d::kZAxis); AcDbRegion* pReg = NULL; pIntPubSolid->getSection(plan, pReg); if (pReg != NULL) { pRetSolid = ExtrudeSolid(pReg, vtDir, vtDir.length()); delete pReg; } } return pRetSolid; } AcGeVector3d TGDrawThunder::GetPubleSolidExDir(const AcDbObjectId& id, T3DCALCNODE& data1, T3DCALCNODE& data2) { AcGeVector3d vtDir; if (id.isValid()) { OPENOBJ_BEGIN(id, AcDb::kForRead, AcDbPolyline, pLine); if (pLine != NULL) { AcGePoint3d ptS, ptE; pLine->getClosestPointTo(data2.rstPro.m_ptInsert, ptS); pLine->getClosestPointTo(data1.rstPro.m_ptInsert, ptE); vtDir = ptS - ptE; } OPENOBJ_END(); } return vtDir; } void TGDrawThunder::AttachThunderData(lstCltResult& lstData1, lstCltResult& lstData2, T3DNODE& node1, T3DNODE& node2, T3DCALCNODE& data1, T3DCALCNODE& data2) { lstCltResult lstFind; lstFind.insert(lstFind.end(), lstData1.begin(), lstData1.end()); lstFind.insert(lstFind.end(), lstData2.begin(), lstData2.end()); GetCltResultByPosition(lstFind, node1.ptPort, data1.rstPort); GetCltResultByPosition(lstFind, node1.ptPro, data1.rstPro); GetCltResultByPosition(lstFind, node2.ptPort, data2.rstPort); GetCltResultByPosition(lstFind, node2.ptPro, data2.rstPro); data1.rstVF = data1.rstPort; data1.rstVF.m_ptInsert = node1.ptVF; data1.rstVF.m_ptInsert.z = 0.0; data2.rstVF = data2.rstPort; data2.rstVF.m_ptInsert = node2.ptVF; data2.rstVF.m_ptInsert.z = 0.0; } BOOL TGDrawThunder::GetCltResultByPosition(lstCltResult& lstSrc, const AcGePoint3d& ptPos, CCaculateResult& data) { int nScale = 1; if (!DocGetMeterUnitDraw()) nScale *= 1000; AcGePoint3d ptT; lstCltResult::const_iterator it; for (it = lstSrc.begin();it != lstSrc.end();++it) { ptT = it->m_ptInsert; ptT.z += it->m_dHeight * nScale; if (ptPos.distanceTo(ptT) < 1e-3) { data = *it; return TRUE; } } return FALSE; } BOOL TGDrawThunder::Get2LinePublicSegment(const AcDbObjectId& idLine, const AcDbObjectId& idLine2, T3DNODE& node1, T3DNODE& node2) { /************************************************************************ ptPro ptVF ptPort +------+------+ | | +----+------+ ptPort ptVF ptPro ************************************************************************/ BOOL bSuc = FALSE; if (idLine.isValid() && idLine2.isValid()) { OPENOBJ_BEGIN(idLine,AcDb::kForRead,AcDbPolyline,pCve1); if (pCve1 != NULL) { OPENOBJ_BEGIN(idLine2,AcDb::kForRead,AcDbPolyline,pCve2); if (pCve2 != NULL) { AcGePoint3d ptS,ptE,ptS2,ptE2; pCve1->getStartPoint(ptS); pCve1->getEndPoint(ptE); pCve2->getStartPoint(ptS2); pCve2->getEndPoint(ptE2); AcGePoint3d ptVF,ptVF2; AcDbLine ln(ptS,ptE); AcDbLine ln2(ptS2,ptE2); if ( CheckPoint2LineVerFootPoint(&ln, ptS2, ptVF) && !CheckPoint2LineVerFootPoint(&ln, ptE2, ptVF2) ) { node1.ptPro = ptS2; node1.ptVF = ptVF; node1.ptPort = GetVFootLinePort(ptS2 - ptE2, &ln); if ( CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF) && !CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF2)) { node2.ptVF = ptVF; node2.ptPro = ptS; node2.ptPort = GetVFootLinePort(ptS - ptE, &ln2); bSuc = TRUE; } else if ( CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF) && !CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF2)) { node2.ptVF = ptVF; node2.ptPro = ptE; node2.ptPort = GetVFootLinePort(ptE - ptS, &ln2); bSuc = TRUE; } else if (CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF) && CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF2)) { node1.ptPro = ptS; node1.ptVF = ptVF; node1.ptPort = GetVFootLinePort(ptS - ptE, &ln2); node2.ptPro = ptE; node2.ptVF = ptVF2; node2.ptPort = GetVFootLinePort(ptE - ptS, &ln2); bSuc = TRUE; } } else if ( CheckPoint2LineVerFootPoint(&ln, ptE2, ptVF) && !CheckPoint2LineVerFootPoint(&ln, ptS2, ptVF2)) { node1.ptVF = ptVF; node1.ptPro = ptE2; node1.ptPort = GetVFootLinePort(ptE2 - ptS2, &ln); if ( CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF) && !CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF2)) { node2.ptVF = ptVF; node2.ptPro = ptS; node2.ptPort = GetVFootLinePort(ptS - ptE, &ln2); bSuc = TRUE; } else if ( CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF) && !CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF2)) { node2.ptVF = ptVF; node2.ptPro = ptE; node2.ptPort = GetVFootLinePort(ptE - ptS, &ln2); bSuc = TRUE; } else if (CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF) && CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF2)) { node1.ptPro = ptS; node1.ptVF = ptVF; node1.ptPort = GetVFootLinePort(ptS - ptE, &ln2); node2.ptPro = ptE; node2.ptVF = ptVF2; node2.ptPort = GetVFootLinePort(ptE - ptS, &ln2); bSuc = TRUE; } } else if (CheckPoint2LineVerFootPoint(&ln, ptS2, ptVF) && CheckPoint2LineVerFootPoint(&ln, ptE2, ptVF2)) { node1.ptPro = ptS2; node1.ptVF = ptVF; node1.ptPort = GetVFootLinePort(ptS2 - ptE2, &ln); node2.ptPro = ptE2; node2.ptVF = ptVF2; node2.ptPort = GetVFootLinePort(ptE2 - ptS2, &ln); bSuc = TRUE; } else if (!CheckPoint2LineVerFootPoint(&ln, ptS2, ptVF) && !CheckPoint2LineVerFootPoint(&ln, ptE2, ptVF2)) { if (CheckPoint2LineVerFootPoint(&ln2, ptS, ptVF) && CheckPoint2LineVerFootPoint(&ln2, ptE, ptVF2)) { node1.ptPro = ptS; node1.ptVF = ptVF; node1.ptPort = GetVFootLinePort(ptS - ptE, &ln2); node2.ptPro = ptE; node2.ptVF = ptVF2; node2.ptPort = GetVFootLinePort(ptE - ptS, &ln2); bSuc = TRUE; } } } OPENOBJ_END(); } OPENOBJ_END(); } return bSuc; } AcGePoint3d TGDrawThunder::GetVFootLinePort(const AcGeVector3d& vtDir, AcDbLine* pLine) { AcGePoint3d ptPort; if (pLine != NULL) { AcGeVector3d vt = pLine->startPoint() - pLine->endPoint(); if (vt.isCodirectionalTo(vtDir)) { ptPort = pLine->startPoint(); } else { ptPort = pLine->endPoint(); } } return ptPort; } BOOL TGDrawThunder::CheckPoint2LineVerFootPoint(AcDbLine* pLine, const AcGePoint3d& pt, AcGePoint3d& ptVF) { BOOL bSuc = FALSE; if (pLine != NULL) { pLine->getClosestPointTo(pt, ptVF, Adesk::kTrue); AcGePoint3d ptT; pLine->getClosestPointTo(ptVF, ptT, Adesk::kFalse); if (ptVF.distanceTo(ptT) < 1e-3) { bSuc = TRUE; } } return bSuc; } BOOL TGDrawThunder::BooleanOperSolid(AcDb3dSolid* pMainSolid, AcDb3dSolid* pSubSolid, AcDb::BoolOperType nType, const AcGeVector3d& vtDir, double dDist) { BOOL bSuc = FALSE; if (pMainSolid != NULL && pSubSolid != NULL ) { AcDb3dSolid* pNewMain = new AcDb3dSolid; pNewMain->copyFrom(pMainSolid); AcDb3dSolid* pNewSub = new AcDb3dSolid; pNewSub->copyFrom(pSubSolid); AcGeVector3d vtOff = vtDir.normal() * dDist; AcGeMatrix3d mat; mat.setToTranslation(vtOff); pNewSub->transformBy(mat); if (pNewMain->booleanOper(nType, pNewSub) == Acad::eOk) { pMainSolid->copyFrom(pNewMain); bSuc = TRUE; } delete pNewMain; delete pNewSub; } return bSuc; } AcDb3dSolid* TGDrawThunder::CreateRemovedSolid(AcDb3dSolid* pSolid, const AcDbVoidPtrArray& arFace, const AcGePoint3d& ptOr) { AcDb3dSolid* pRetSolid = NULL; if (pSolid != NULL && arFace.length() > 0) { pRetSolid = new AcDb3dSolid; pRetSolid->copyFrom(pSolid); // 分割整个实体 AcDb3dSolid* pTmpSolid = NULL; AcDbFace* pFace = NULL; AcGePlane SlicePlan; for (int i = 0;i < arFace.length();++i) { pFace = AcDbFace::cast((AcRxObject*)arFace[i]); if (pFace != NULL) { GetPlaneFromSpecFace(pFace, ptOr, SlicePlan); pRetSolid->getSlice(SlicePlan, Adesk::kFalse, pTmpSolid); } } } return pRetSolid; } AcDb3dSolid* TGDrawThunder::GetSolidFromFace(AcDbFace* pFace, double dHeight) { AcDb3dSolid* pSolid = NULL; if (pFace != NULL) { AcGePoint3d arPt[4]; pFace->getVertexAt(0, arPt[0]); pFace->getVertexAt(1, arPt[1]); pFace->getVertexAt(2, arPt[2]); arPt[3] = arPt[0]; AcDbLine* pLine = NULL; AcDbVoidPtrArray arLines; for (int i = 0;i < 3;++i) { pLine = new AcDbLine(arPt[i],arPt[i+1]); arLines.append(pLine); } AcDbVoidPtrArray arRegs; AcDbRegion::createFromCurves(arLines, arRegs); if (arRegs.length() > 0) { AcDbRegion* pReg = AcDbRegion::cast((AcRxObject*)arRegs[0]); if (pReg != NULL) { pSolid = new AcDb3dSolid; pSolid->extrude(pReg, dHeight, 0.0); } } ReleasePtrArray(arLines); ReleasePtrArray(arRegs); } return pSolid; } void TGDrawThunder::GetPlaneFromSpecFace(AcDbFace* pFace, const AcGePoint3d& ptOr, AcGePlane& plan) { if (pFace != NULL) { AcGePoint3d pt1,pt2,pt3; pFace->getVertexAt(0, pt1); pFace->getVertexAt(1, pt2); pFace->getVertexAt(2, pt3); plan.set(pt1, pt2, pt3); AcGePoint3d ptOn; ptOn = ptOr.orthoProject(plan); AcGeVector3d vtNor = ptOr - ptOn; plan.set(ptOn, vtNor); } } void TGDrawThunder::CreateSliceFace(AcDbArc* pMainArc, const AcGePoint3d& ptS1, AcDbArc* pSubArc, const AcGePoint3d& ptS2, AcDbVoidPtrArray& arFace) { if (pMainArc != NULL && pSubArc != NULL) { // 收集点 int i,j; double dParaS,dParaE,dT; AcGePoint3d ptOn; AcGePoint3dArray arPt1,arPt2; AcGeDoubleArray arDPara; // 弧线1 pMainArc->getStartParam(dParaS); pMainArc->getEndParam(dParaE); int nCount = (int)((dParaE - dParaS)/DSPACE); arDPara.append(dParaS); for (i = 1;i <= nCount;++i) { dT = dParaS + DSPACE * i; arDPara.append(dT); } arDPara.append(dParaE); for (j = 0;j < arDPara.length();++j) { dT = arDPara[j]; pMainArc->getPointAtParam(dT, ptOn); arPt1.append(ptOn); } if (arPt1.length() < 2) return; // 弧线2 arDPara.setLogicalLength(0); pSubArc->getStartParam(dParaS); pSubArc->getEndParam(dParaE); nCount = (int)((dParaE - dParaS)/DSPACE); arDPara.append(dParaS); for (i = 1;i < nCount;++i) { dT = dParaS + DSPACE * i; arDPara.append(dT); } arDPara.append(dParaE); for (j = 0;j < arDPara.length();++j) { dT = arDPara[j]; pSubArc->getPointAtParam(dT, ptOn); arPt2.append(ptOn); } if (arPt2.length() < 2) return; AcGePoint3d ptTmp; pMainArc->getStartPoint(ptTmp); if (ptTmp.distanceTo(ptS1) > 1e-3) { arPt1.reverse(); } pSubArc->getStartPoint(ptTmp); if (ptTmp.distanceTo(ptS2) > 1e-3) { arPt2.reverse(); } if (ptS1.distanceTo(ptS2) < 1e-3) { arPt2.removeFirst(); } // 创建face AcDbFace* pFace = NULL; if (arPt1.length() > arPt2.length()) { for (i = 0;i < arPt1.length()-1;++i) { if (i >= arPt2.length()) { pFace = new AcDbFace(arPt2.last(),arPt1[i],arPt1[i+1]); arFace.append(pFace); } else { pFace = new AcDbFace(arPt2[i],arPt1[i],arPt1[i+1]); arFace.append(pFace); } } } else { for (i = 0;i < arPt1.length()-1;++i) { pFace = new AcDbFace(arPt2[i],arPt1[i],arPt1[i+1]); arFace.append(pFace); } for (i;i < arPt2.length()-1;++i) { pFace = new AcDbFace(arPt1.last(),arPt2[i],arPt2[i+1]); arFace.append(pFace); } } } } AcDbArc* TGDrawThunder::GetSolidTopArc(AcDb3dSolid* pSolid1,const CCaculateResult& result1,const CCaculateResult& result2) { AcDbArc* pArc = NULL; if (pSolid1 != NULL) { std::list lstPtPair; LINEPTPAIR ptPair; AcGePoint3d ptS,ptE; int nScale = 1; if (!DocGetMeterUnitDraw()) { nScale *= 1000; } ptPair.pt1 = result1.m_ptInsert; ptPair.pt1.z += result1.m_dHeight * nScale; ptPair.pt2 = result2.m_ptInsert; ptPair.pt2.z += result2.m_dHeight * nScale; lstPtPair.push_back(ptPair); pArc = GetSolidTopArcByLoop(pSolid1, lstPtPair); } return pArc; } AcDbArc* TGDrawThunder::GetSolidTopArcByLoop(AcDbEntity* pEnt, std::list& lstPtPair) { AcDbArc* pRetArc = NULL; if (pEnt != NULL) { AcDbVoidPtrArray arPtr; pEnt->explode(arPtr); AcGePoint3d ptS,ptE; AcGePoint3d ptT,ptT2; AcDbArc* pArc = NULL; for (int i = 0;i < arPtr.length();++i) { pArc = AcDbArc::cast((AcDbEntity*)arPtr[i]); if (pArc != NULL) { pArc->getStartPoint(ptS); pArc->getEndPoint(ptE); std::list::iterator it; for (it = lstPtPair.begin();it != lstPtPair.end();++it) { ptT = it->pt1; ptT2 = it->pt2; if ((ptS.distanceTo(it->pt1) < 1e-3 && ptE.distanceTo(it->pt2) < 1e-3 ) || (ptS.distanceTo(it->pt2) < 1e-3 && ptE.distanceTo(it->pt1) < 1e-3 ) ) { pRetArc = new AcDbArc; pRetArc->copyFrom(pArc); break; } } if (pRetArc != NULL) break; } else { pRetArc = GetSolidTopArcByLoop((AcDbEntity*)arPtr[i], lstPtPair); if (pRetArc != NULL) { break; } } } ReleasePtrArray(arPtr); } return pRetArc; } AcDb3dSolid* TGDrawThunder::CreateExtendSolid(const AcGePoint3dArray& arPts, const AcGeVector3d& vtDir, double dLength) { AcDb3dSolid* pRetSolid = NULL; if (arPts.length() > 2) { AcGePoint3dArray arLoc; arLoc.append(arPts); arLoc.append(arPts.first()); AcDbLine* pLine = NULL; AcDbVoidPtrArray arLines,arRegs; int nCount = arLoc.length() - 1; for (int i = 0;i < nCount;++i) { pLine = new AcDbLine(arLoc[i], arLoc[i+1]); arLines.append(pLine); } AcDbRegion::createFromCurves(arLines, arRegs); if (arRegs.length() > 0) { AcDbRegion* pReg = AcDbRegion::cast((AcRxObject*)arRegs[0]); if (pReg != NULL) { pRetSolid = ExtrudeSolid(pReg, vtDir, dLength); } } ReleasePtrArray(arLines); ReleasePtrArray(arRegs); } return pRetSolid; } void TGDrawThunder::ReleasePtrArray(AcDbVoidPtrArray& arPtr) { for (int i = 0;i < arPtr.length();++i) { delete (AcDbEntity*)arPtr[i]; } arPtr.setLogicalLength(0); } void TGDrawThunder::ShowPtrArray(AcDbVoidPtrArray& arPtr) { AcDbGroup* pGroup = new AcDbGroup; for (int i = 0;i < arPtr.length();++i) { pGroup->append(AddToCurrentSpace((AcDbEntity*)arPtr[i], Adesk::kTrue)); } AcDbDictionary* pGroupDict = NULL; acdbHostApplicationServices()->workingDatabase() ->getGroupDictionary(pGroupDict, AcDb::kForWrite); if (pGroupDict != NULL) { AcDbObjectId id; pGroupDict->setAt(_T("*A"),pGroup,id); pGroupDict->close(); pGroup->close(); } else { delete pGroup; } arPtr.setLogicalLength(0); } AcDbLine* TGDrawThunder::GetSolidExtrudePath(AcDb3dSolid* pSolid1, AcDb3dSolid* pSolid2, std::list& lstPtPair) { AcDbLine* pLine = NULL; if (pSolid1 != NULL && pSolid2 != NULL && lstPtPair.size() > 0) { AcGePoint3d ptS,ptE; if (GetSolidCopingLowPoint(pSolid1, lstPtPair, ptS) && GetSolidCopingLowPoint(pSolid2, lstPtPair, ptE) ) { pLine = new AcDbLine(ptS, ptE); } } return pLine; } BOOL TGDrawThunder::GetSolidCopingLowPoint(AcDbEntity* pEnt, std::list& lstPtPair, AcGePoint3d& ptOut) { BOOL bSuc = FALSE; if (pEnt != NULL) { AcDbVoidPtrArray arPtr; pEnt->explode(arPtr); AcGePoint3d ptS,ptE; AcDbArc* pArc = NULL; for (int i = 0;i < arPtr.length();++i) { pArc = AcDbArc::cast((AcDbEntity*)arPtr[i]); if (pArc != NULL) { pArc->getStartPoint(ptS); pArc->getEndPoint(ptE); std::list::iterator it; for (it = lstPtPair.begin();it != lstPtPair.end();++it) { if ((ptS.distanceTo(it->pt1) < 1e-3 && ptE.distanceTo(it->pt2) < 1e-3 ) || (ptS.distanceTo(it->pt2) < 1e-3 && ptE.distanceTo(it->pt1) < 1e-3 ) ) { ptOut = GetArcMidPiont(pArc, it->pt1, it->pt2); bSuc = TRUE; break; } } if (bSuc) break; } else { if (GetSolidCopingLowPoint((AcDbEntity*)arPtr[i], lstPtPair, ptOut)) { bSuc = TRUE; break; } } } for (int j = 0;j < arPtr.length();++j) { delete (AcDbEntity*)arPtr[j]; } } return bSuc; } AcGePoint3d TGDrawThunder::GetArcMidPiont(AcDbArc* pArc, const AcGePoint3d& ptS, const AcGePoint3d& ptE) { if (pArc != NULL) { AcDbLine ln(ptS, ptE); AcGePoint3d ptOn; AcGePoint3d ptCent = pArc->center(); ln.getClosestPointTo(ptCent, ptOn); ln.setStartPoint(ptOn); ln.setEndPoint(ptCent); AcGePoint3dArray arPt; ln.intersectWith(pArc, AcDb::kExtendThis, arPt); if (arPt.length() > 0) { return arPt.first(); } } return AcGePoint3d::kOrigin; } AcDb3dSolid* TGDrawThunder::CreateUnion3DRegion(const AcDb3dSolid* pBaseSolid,CCaculateResult& data1,CCaculateResult& data2,AcDbCurve* pCve) { if (pBaseSolid == NULL || pCve == NULL) { return NULL; } AcDb3dSolid* pSolid = NULL; // 截取面reg AcGeVector3d vt = data2.m_ptInsert - data1.m_ptInsert; AcGePlane plan; plan.set(data1.m_ptInsert,vt,AcGeVector3d::kZAxis); AcDbRegion* pReg = NULL; Acad::ErrorStatus es = pBaseSolid->getSection(plan, pReg); if (pReg != NULL) { pSolid = ExtrudeSolidAlongPath(pReg, pCve); delete pReg; } return pSolid; } AcDb3dSolid* TGDrawThunder::CreateBoolSubtractSolid(const AcDb3dSolid* pBaseSolid,CCaculateResult& data1,CCaculateResult& data2,AcDbCurve* pCve) { if (pBaseSolid == NULL || pCve == NULL) { return NULL; } AcDb3dSolid* pSolid = NULL; // 创建reg AcGePoint3d pt1 = data1.m_ptInsert; AcGePoint3d pt2 = data2.m_ptInsert; AcGePoint3d pt3 = pt2; AcGePoint3d pt4 = pt1; int nScale = 1; if (!DocGetMeterUnitDraw()) { nScale *= 1000; } double dH = data1.m_dHeight; if (dH < data2.m_dHeight) dH = data2.m_dHeight; pt1.z += dH * nScale; pt2.z += dH * nScale; AcDbVoidPtrArray arPtr; AcDbLine* pLine = NULL; pLine = new AcDbLine(pt1, pt2); arPtr.append(pLine); pLine = new AcDbLine(pt2, pt3); arPtr.append(pLine); pLine = new AcDbLine(pt3, pt4); arPtr.append(pLine); pLine = new AcDbLine(pt4, pt1); arPtr.append(pLine); AcDbVoidPtrArray arRegions; AcDbRegion::createFromCurves(arPtr, arRegions); ReleasePtrArray(arPtr); if (arRegions.length() < 1) { return NULL; } AcDbRegion* pReg = (AcDbRegion*)arRegions[0]; if (pReg != NULL) { AcGePoint3d ptS,ptE; CalcLinePorts(pReg, pCve, ptS, ptE); AcGeVector3d vt = ptS - ptE; ptE = ptS + vt; AcGeVector3d vtNor = CalcRegionNormal(ptE, pReg); pSolid = ExtrudeSolid(pReg, vtNor, vt.length()); } ReleasePtrArray(arRegions); return pSolid; } void TGDrawThunder::DrawThunder2DArea(LPCTSTR pszGroupNo, const AcDbObjectIdArray& arID) { if (pszGroupNo == NULL || arID.length() < 1) { return; } CTGTempTol locTol(0.1, 0.1); // 计算避雷针数据 AcGeDoubleArray arProHeight; CThunderXData xd; xd.GetProtectHeightFromObjEx(arID[0], arProHeight); lstCltResult lstData; CalcThunderData(pszGroupNo, arProHeight, arID, lstData); // 绘制三维 DrawThunder3DArea(pszGroupNo, lstData, TRUE); } void TGDrawThunder::DrawThunderLine(LPCTSTR pszGroupNo, const AcDbObjectIdArray& arID) { if (pszGroupNo == NULL || arID.length() < 1) { return; } CTGTempTol locTol(0.1, 0.1); // 计算避雷针数据 AcGeDoubleArray arProHeight; CThunderXData xd; xd.GetProtectHeightFromObjEx(arID[0], arProHeight); MapThunderLineCltResult mapData; CalcThunLineData(pszGroupNo, arProHeight, arID, mapData); // 绘制避雷线三维 DrawThunLine3D(pszGroupNo, mapData, TRUE); } AcGePoint3d TGDrawThunder::CalcSolidTopPoint(const CCaculateResult& result) { int nScale = 1; if (!DocGetMeterUnitDraw()) nScale *= 1000; AcGePoint3d ptTop; if (result.m_dHeight < result.m_dGroundRadius) { ptTop = result.m_ptInsert; ptTop.z += result.m_dHeight*nScale; } else { AcGePoint3d ptS = result.m_ptInsert; AcGePoint3d ptE = ptS; ptE.z += result.m_dHeight*nScale; AcDbLine ln(ptS,ptE); AcDbCircle cir(result.m_ptGroundCenter,AcGeVector3d::kXAxis,result.m_dGroundRadius*nScale); AcGePoint3dArray arPt; ln.intersectWith(&cir,AcDb::kOnBothOperands,arPt); if (arPt.length() == 1) { ptTop = arPt.first(); } else if (arPt.length() == 2) { double dDist1 = ptS.distanceTo(arPt.first()); double dDist2 = ptS.distanceTo(arPt.last()); if (dDist1 > dDist2) { ptTop = arPt.last(); } else { ptTop = arPt.first(); } } } return ptTop; } //生成单针的避雷区域实体 AcDb3dSolid* TGDrawThunder::Create3DSolid(const CCaculateResult& result) { int nScale = 1; if (!DocGetMeterUnitDraw()) nScale *= 1000; AcGePoint3d ptStart = result.m_ptInsert; AcGePoint3d ptEnd = CalcSolidTopPoint(result); AcDbLine* pLine = new AcDbLine; pLine->setStartPoint(ptStart); pLine->setEndPoint(ptEnd); pLine->setNormal(AcGeVector3d::kXAxis); // CopyEnt(pLine); //得到需要旋转的REG AcGePoint3d ptReg = result.m_ptGroundCenter; ptReg.z = 0.0; AcDbLine* pLine2 = new AcDbLine; pLine2->setStartPoint(ptReg); pLine2->setEndPoint(ptStart); pLine2->setNormal(AcGeVector3d::kXAxis); // CopyEnt(pLine2); AcDbCircle cir(result.m_ptGroundCenter,AcGeVector3d::kXAxis,result.m_dGroundRadius*nScale); AcDbArc* pArc = GetArcSegmentFromCircle(&cir, ptEnd, ptReg); // CopyEnt(pArc); AcDbVoidPtrArray arPtrs; arPtrs.append(pArc); arPtrs.append(pLine); arPtrs.append(pLine2); //生成3D实体 AcDb3dSolid *pSolid = NULL; AcDbVoidPtrArray arRegions; AcDbRegion::createFromCurves(arPtrs, arRegions); if (arRegions.length() > 0) { AcDbRegion* pRegion = AcDbRegion::cast((AcDbEntity*)arRegions[0]); if (pRegion != NULL) { AcGeVector3d vtAxis = ptEnd - ptStart; AcDbRevolveOptions rev; pSolid = new AcDb3dSolid; Acad::ErrorStatus es = pSolid->revolve(pRegion,result.m_ptInsert,vtAxis,2 * PI); //acutPrintf(_T("\nrevolve %d!"),es); //ZWCAD 不支持,改为微分方式 //acedAlert(_T("ZRX 开发包目前没有实现AcDb3dSolid 接口!")); } } ReleasePtrArray(arPtrs); ReleasePtrArray(arRegions); return pSolid; } AcDbArc* TGDrawThunder::GetArcSegmentFromCircle(AcDbCircle* pCir, const AcGePoint3d& ptS, const AcGePoint3d& ptE, BOOL bInferior) { AcDbArc* pArc = NULL; if (pCir != NULL) { double dPara,dPara2; pCir->getParamAtPoint(ptS,dPara); pCir->getParamAtPoint(ptE,dPara2); if (fabs(dPara-0.0) < 1e-3 && dPara2 > PI ) { dPara = 2*PI; } else if (fabs(dPara2-0.0) < 1e-3 && dPara > PI) { dPara2 = 2*PI; } if (bInferior) // 劣弧 { if (dPara > dPara2) { double dT = dPara; dPara = dPara2; dPara2 = dT; } } else // 优弧 { if (dPara < dPara2) { double dT = dPara; dPara = dPara2; dPara2 = dT; } } pArc = new AcDbArc(pCir->center(), pCir->normal(), pCir->radius(), dPara, dPara2); } return pArc; } //得到2针的避雷区域 AcDb3dSolid* TGDrawThunder::GetThunderAreaBy2Pin(const CCaculateResult& result1,const CCaculateResult& result2,BOOL bCheck) { AcDb3dSolid* pRetInt = NULL; double dHeight1 = 0.0,dHeight2 = 0.0,dGroundRadius = 0.0,dProRadius1 = 0.0,dProRadius2 = 0.0; double dScale = 1.0; if (!DocGetMeterUnitDraw()) dScale *= 1000; dHeight1 = result1.m_dHeight*dScale; dHeight2 = result2.m_dHeight*dScale; dGroundRadius = result1.m_dGroundRadius*dScale; dProRadius1 = result1.m_dProRadius*dScale; dProRadius2 = result2.m_dProRadius*dScale; //判断两针之间是否有影响 if (bCheck) { double dDis = result1.m_ptInsert.distanceTo(result2.m_ptInsert); if (fabs(dHeight1 - dHeight2) < 0.01) { if (dDis >= 2*pow(dHeight2*(2*dGroundRadius-dHeight2),0.5)) { return pRetInt; } } else { if (dDis >= pow(dHeight1*(2*dGroundRadius-dHeight1),0.5) + pow(dHeight2*(2*dGroundRadius-dHeight2),0.5)) { return pRetInt; } } } AcDb3dSolid *pCircleSolid1 = NULL; AcDb3dSolid *pCircleSolid2 = NULL; AcDb3dSolid *pTopSolid = NULL; //生成滚球实体 GetSphereSolids(result1.m_ptInsert,result2.m_ptInsert,dProRadius1,dProRadius2,dGroundRadius,pCircleSolid1,pCircleSolid2); if (pCircleSolid1 != NULL && pCircleSolid2 != NULL) { pTopSolid = GetTopSphereSolid(result1,result2,dGroundRadius); pRetInt = Get2DIntersectionArea(result1,result2); if (pRetInt != NULL && pTopSolid != NULL) { // 如果布尔运算失败则会删除两实体的内部对象 // 此处要做保留操作 AcDb3dSolid* pTmpInt = new AcDb3dSolid; pTmpInt->copyFrom(pRetInt); if (pRetInt->booleanOper(AcDb::kBoolSubtract,pCircleSolid1) != Acad::eOk) { pRetInt->copyFrom(pTmpInt); } else { pTmpInt->copyFrom(pRetInt); }; if (pRetInt->booleanOper(AcDb::kBoolSubtract,pCircleSolid2) != Acad::eOk) { pRetInt->copyFrom(pTmpInt); } else { pTmpInt->copyFrom(pRetInt); } if (fabs(result1.m_dHeight-result2.m_dHeight) < 1e-3) { if (pRetInt->booleanOper(AcDb::kBoolSubtract,pTopSolid) != Acad::eOk) { pRetInt->copyFrom(pTmpInt); } } delete pTmpInt; } } if (pCircleSolid1 != NULL) delete pCircleSolid1; if (pCircleSolid2 != NULL) delete pCircleSolid2; if (pTopSolid != NULL) delete pTopSolid; return pRetInt; } //生成滚球实体 void TGDrawThunder::GetSphereSolids(const AcGePoint3d& ptInsert1,const AcGePoint3d& ptInsert2,double dProRadius1,double dProRadius2,double dGroundRadius,AcDb3dSolid*& pCircleSolid1,AcDb3dSolid*& pCircleSolid2) { AcDbCircle circle1(ptInsert1,AcGeVector3d::kZAxis,dProRadius1); AcDbCircle circle2(ptInsert2,AcGeVector3d::kZAxis,dProRadius2); AcGePoint3dArray arPt; IntersectWith2Circle(&circle1, &circle2, arPt); if (arPt.length() != 2) { return; } //得到最大保护半径的交点 AcGeMatrix3d matrix; AcGePoint3d ptCen1 = arPt[0]; AcGePoint3d ptCen2 = arPt[1]; ptCen1.z += dGroundRadius; ptCen2.z += dGroundRadius; pCircleSolid1 = new AcDb3dSolid; if (pCircleSolid1 != NULL) { pCircleSolid1->createSphere(dGroundRadius); matrix.setToTranslation(ptCen1.asVector()); pCircleSolid1->transformBy(matrix); } pCircleSolid2 = new AcDb3dSolid; if (pCircleSolid2 != NULL) { pCircleSolid2->createSphere(dGroundRadius); matrix.setToTranslation(ptCen2.asVector()); pCircleSolid2->transformBy(matrix); } } //生成2避雷针中间一块区域 AcDb3dSolid* TGDrawThunder::Get2DIntersectionArea(const CCaculateResult& result1,const CCaculateResult& result2) { AcDb3dSolid* pSolid = new AcDb3dSolid; if (pSolid == NULL) return NULL; double dHeight1 = result1.m_dHeight; double dHeight2 = result2.m_dHeight; if (!DocGetMeterUnitDraw()) { dHeight1 *= 1000; dHeight2 *= 1000; } AcDbRegion *pRegion = GetRegionByCircle(result1,result2); if (pRegion == NULL) { delete pSolid; return NULL; } Acad::ErrorStatus es; if (dHeight2 > dHeight1) es = pSolid->extrude(pRegion,dHeight2,0); else es = pSolid->extrude(pRegion,dHeight1,0); delete pRegion; return pSolid; } //生成顶部球实体 AcDb3dSolid* TGDrawThunder::GetTopSphereSolid(const CCaculateResult& result1,const CCaculateResult& result2,double dGroundRadius,AcGePoint3d* pt) { AcGePoint3d ptCen,ptThunderCen1,ptThunderCen2; ptThunderCen1 = result1.m_ptInsert; ptThunderCen2 = result2.m_ptInsert; double dHeight1 = 0.0,dHeight2 = 0.0; if (!DocGetMeterUnitDraw()) { dHeight1 = result1.m_dHeight*1000; dHeight2 = result2.m_dHeight*1000; } else { dHeight1 = result1.m_dHeight; dHeight2 = result2.m_dHeight; } double dDis = result1.m_ptInsert.distanceTo(result2.m_ptInsert); double dDisLeft = (pow(dGroundRadius-dHeight2,2) - pow(dGroundRadius-dHeight1,2) + pow(dDis,2))/(2*dDis); AcDbLine line(result1.m_ptInsert,result2.m_ptInsert); line.getPointAtDist(dDisLeft,ptCen); ptCen.z += dGroundRadius; ptThunderCen1.z += dHeight1; ptThunderCen2.z += dHeight2; double dRadius = ptThunderCen1.distanceTo(ptCen); Acad::ErrorStatus es; AcDb3dSolid *pSolid = new AcDb3dSolid; if (pSolid == NULL) return NULL; es = pSolid->createSphere(dRadius); AcGeMatrix3d matrix; matrix.setCoordSystem(ptCen,AcGeVector3d::kXAxis,AcGeVector3d::kYAxis,AcGeVector3d::kZAxis); pSolid->transformBy(matrix); if (pt != NULL) { *pt = ptCen; } return pSolid; } //生成3维实体对象 void TGDrawThunder::MakeThunderEntity(LPCTSTR pszGroupNo, lstCltResult& lstData, BOOL bPreview) { AcDb3dSolid *pSolid = NULL; CThunderXData thundXData; //单针实体 lstCltResult::iterator it; for (it = lstData.begin();it != lstData.end();++it) { pSolid = Create3DSolid(*it); if (pSolid != NULL) { pSolid->setLayer(m_strLayer3d); pSolid->setColorIndex(m_nMultiPinColorIndex); thundXData.SetXData(pSolid, TEL_GROUP_NO, pszGroupNo); if (bPreview) { pSolid->setLayer(LAY_PREVIEW_THUNDER); m_arPreview.append(pSolid); } else { m_arRegSolid.append(pSolid); } } } //生成2避雷针的区域 lstCltResult::iterator itSub; for (it = lstData.begin();it != lstData.end();++it) { itSub = it; itSub++; for (itSub;itSub != lstData.end();++itSub) { pSolid = GetThunderAreaBy2Pin(*it,*itSub); if (pSolid != NULL) { pSolid->setLayer(m_strLayer3d); pSolid->setColorIndex(m_nMultiPinColorIndex); thundXData.SetXData(pSolid, TEL_GROUP_NO, pszGroupNo); if (bPreview) { pSolid->setLayer(LAY_PREVIEW_THUNDER); m_arPreview.append(pSolid); } else { m_arRegSolid.append(pSolid); } } } } //生成3避雷针的区域 if (lstData.size() >= 3) Make3CenThunderEntity(pszGroupNo, lstData, bPreview); } //显示层 void TGDrawThunder::ShowLayer(LPCTSTR lpLayerName,BOOL bShow) { if (lpLayerName == NULL) return; AcDbLayerTable *pLayerTable = NULL; acdbHostApplicationServices()->workingDatabase() ->getSymbolTable(pLayerTable, AcDb::kForRead); AcDbLayerTableRecord *pRecord = NULL; AcDbObjectId id; pLayerTable->getAt(lpLayerName,pRecord,AcDb::kForWrite); pLayerTable->close(); if (pRecord == NULL) return; if (_tcsicmp(lpLayerName,LAY_PREVIEW_THUNDER) == 0) { AcCmColor color; color.setColorIndex(4); pRecord->setColor(color); } if (bShow) pRecord->setIsOff(FALSE); else pRecord->setIsOff(TRUE); pRecord->close(); } //生成3针形成中间的避雷区域 void TGDrawThunder::Make3CenThunderEntity(LPCTSTR pszGroupNo, lstCltResult& lstData,BOOL bPreview, AcDbVoidPtrArray* pArPtr) { if (lstData.size() == 0) { return; } AcArray arPtInsert; AcGeDoubleArray arRadius; lstCltResult::iterator it; double dScale = 1.0; if (!DocGetMeterUnitDraw()) dScale *= 1000; for (it = lstData.begin();it != lstData.end();++it) { arPtInsert.append(it->m_ptInsert); arRadius.append(it->m_dProRadius*dScale); } Acad::ErrorStatus es; AcArray arSolid; AcArray arPt; //得到联合区域的边部滚球 GetSphereSolids(arPtInsert,arRadius,lstData.front().m_dGroundRadius*dScale,arSolid,arPt); AcArray arInterSolid; //得到中间区域 Get3DIntersectionArea(lstData,arPt,arInterSolid); if (arInterSolid.length() == 0) return; CThunderXData thundXData; AcDbVoidPtrArray arTop; for (int m = 0; m < arInterSolid.length(); ++m) { if (m > 0) { GetSphereSolids(arPtInsert,arRadius,lstData.front().m_dGroundRadius*dScale,arSolid,arPt); } for (int k = 0; k < arSolid.length(); k++) { es = arInterSolid[m]->booleanOper(AcDb::kBoolSubtract,arSolid[k]); } GetTopSphereSolid(lstData,arTop); if (arTop.length() < 1) { arSolid.setLogicalLength(0); arPt.setLogicalLength(0); delete arInterSolid[m]; continue; } for (int j = 0; j < arTop.length(); j++) { es = arInterSolid[m]->booleanOper(AcDb::kBoolSubtract,(AcDb3dSolid*)arTop[j]); delete (AcDb3dSolid*)arTop[j]; } arTop.setLogicalLength(0); if (arInterSolid[m] != NULL) { arInterSolid[m]->setLayer(m_strLayer3d); arInterSolid[m]->setColorIndex(m_nMultiPinColorIndex); thundXData.SetXData(arInterSolid[m], TEL_GROUP_NO, pszGroupNo); if (bPreview) { arInterSolid[m]->setLayer(LAY_PREVIEW_THUNDER); m_arPreview.append(arInterSolid[m]); if (pArPtr != NULL) { AcDb3dSolid* pSolid = new AcDb3dSolid; pSolid->copyFrom(arInterSolid[m]); pArPtr->append(pSolid); } } else { m_arRegSolid.append(arInterSolid[m]); if (pArPtr != NULL) { AcDb3dSolid* pSolid = new AcDb3dSolid; pSolid->copyFrom(arInterSolid[m]); pArPtr->append(pSolid); } } } arPt.setLogicalLength(0); } } //得到3针滚球球心 BOOL TGDrawThunder::Get3PinSphereCen(const AcGePoint3d& pt1,const AcGePoint3d& pt2,const AcGePoint3d& pt3,double dGroundRadius,const AcGeVector3d& vecParal,AcGePoint3d& ptCenter,double dProRadius) { AcGePlane plan(pt1,pt2,pt3); AcGeVector3d vecNormal = plan.normal(); AcGeVector3d vec12,vec23,vec31; vec12 = pt1 - pt2; vec23 = pt2 - pt3; vec31 = pt3 - pt1; AcGeVector3d vecNormal12,vecNormal23,vecNormal31; AcGePlane plan12(pt1,vec12,vecNormal); AcGePlane plan23(pt2,vec23,vecNormal); AcGePlane plan31(pt3,vec31,vecNormal); vecNormal12 = plan12.normal(); vecNormal23 = plan23.normal(); vecNormal31 = plan31.normal(); vecNormal12.normalize(); vecNormal23.normalize(); vecNormal31.normalize(); //得到各边中点 AcGePoint3d ptCen12,ptCen23,ptCen31; ptCen12.x = (pt1.x + pt2.x)/2; ptCen12.y = (pt1.y + pt2.y)/2; ptCen12.z = (pt1.z + pt2.z)/2; ptCen23.x = (pt3.x + pt2.x)/2; ptCen23.y = (pt3.y + pt2.y)/2; ptCen23.z = (pt3.z + pt2.z)/2; ptCen31.x = (pt1.x + pt3.x)/2; ptCen31.y = (pt1.y + pt3.y)/2; ptCen31.z = (pt1.z + pt3.z)/2; AcGePoint3d ptEnd12,ptEnd23,ptEnd31; AcGePoint3d ptStart12,ptStart23,ptStart31; ptEnd12 = ptCen12 + vecNormal12*dGroundRadius; ptEnd23 = ptCen23 + vecNormal23*dGroundRadius; ptEnd31 = ptCen31 + vecNormal31*dGroundRadius; ptStart12 = ptCen12 - vecNormal12*dGroundRadius; ptStart23 = ptCen23 - vecNormal23*dGroundRadius; ptStart31 = ptCen31 - vecNormal31*dGroundRadius; AcDbLine line12(ptStart12,ptEnd12); AcDbLine line23(ptStart23,ptEnd23); AcGePoint3dArray arPts; line12.intersectWith(&line23,AcDb::kExtendBoth,arPts); if (arPts.length() != 1) return FALSE; //中垂线交点到点距离 double dDis = arPts[0].distanceTo(pt1); if (dDis > dProRadius) return FALSE; //球心到面的投影距离 double dDisPer = pow(pow(dGroundRadius,2) - pow(dDis,2),0.5); vecNormal.normalize(); if (vecNormal.angleTo(vecParal) < PI/2) ptCenter = arPts[0] + vecNormal*dDisPer; else ptCenter = arPts[0] - vecNormal*dDisPer; return TRUE; } //生成3避雷针中间一块区域 AcDb3dSolid* TGDrawThunder::Get3DIntersectionArea(const CCaculateResult& result1,const CCaculateResult& result2,const CCaculateResult& result3 ) { AcArray arPtInter; double dRadius1 = result1.m_dProRadius; double dRadius2 = result2.m_dProRadius; double dRadius3 = result3.m_dProRadius; if (!DocGetMeterUnitDraw()) //毫米单位 { dRadius1 *= 1000; dRadius2 *= 1000; dRadius3 *= 1000; } Get3PeripheryPoints(result1.m_ptInsert,result2.m_ptInsert,result3.m_ptInsert,dRadius1,dRadius2,dRadius3,arPtInter); AcDbVoidPtrArray arRegs; AcDbLine line; for (int i = 0; i < arPtInter.length(); ++i) { if (result1.m_ptInsert.distanceTo(arPtInter[i]) - dRadius1 < 0.01) { AcDbLine *pLine = new AcDbLine(result1.m_ptInsert,arPtInter[i]); arRegs.append(pLine); } if (result2.m_ptInsert.distanceTo(arPtInter[i]) - dRadius2 < 0.01) { AcDbLine *pLine = new AcDbLine(result2.m_ptInsert,arPtInter[i]); arRegs.append(pLine); } if (result3.m_ptInsert.distanceTo(arPtInter[i]) - dRadius3 < 0.01) { AcDbLine *pLine = new AcDbLine(result3.m_ptInsert,arPtInter[i]); pLine->setColorIndex(1); arRegs.append(pLine); } } AcDbVoidPtrArray arRegions; arRegions.setPhysicalLength(10); arRegions.setGrowLength(1); AcDbRegion::createFromCurves(arRegs, arRegions); ReleasePtrArray(arRegs); if (arRegions.length() != 1) return NULL; AcDbRegion *pReg = AcDbRegion::cast((AcRxObject*)arRegions[0]); if (pReg == NULL) return NULL; double dHeight1 = result1.m_dHeight; double dHeight2 = result2.m_dHeight; double dHeight3 = result3.m_dHeight; double dGroundRadius = result3.m_dGroundRadius; if (!DocGetMeterUnitDraw()) { dHeight1 *= 1000; dHeight2 *= 1000; dHeight3 *= 1000; dGroundRadius *= 1000; } Acad::ErrorStatus es; AcDb3dSolid *pSolid = new AcDb3dSolid; if (dHeight1 >= dHeight2 && dHeight1 >= dHeight3) es = pSolid->extrude(pReg,dHeight1,0); else if (dHeight2 >= dHeight3 && dHeight2 >= dHeight1) es = pSolid->extrude(pReg,dHeight2,0); else if (dHeight3 >= dHeight2 && dHeight3 >= dHeight1) es = pSolid->extrude(pReg,dHeight3,0); ReleasePtrArray(arRegions); return pSolid; } //得到两圆圆心到交点连成的REG AcDbRegion *TGDrawThunder::GetRegionByCircle(const CCaculateResult& result1,const CCaculateResult& result2) { AcGePoint3d ptStart,ptEnd; ptStart = result1.m_ptInsert; ptEnd = result2.m_ptInsert; double dProRadius1 = result1.m_dProRadius; double dProRadius2 = result2.m_dProRadius; if (!DocGetMeterUnitDraw()) { dProRadius1 *= 1000; dProRadius2 *= 1000; } AcDbCircle circle1(ptStart,AcGeVector3d::kZAxis,dProRadius1); AcDbCircle circle2(ptEnd,AcGeVector3d::kZAxis,dProRadius2); AcGePoint3dArray arPt; IntersectWith2Circle(&circle1, &circle2, arPt); if (arPt.length() != 2) return NULL; //构造3维体 AcDbLine line1(arPt[0],result1.m_ptInsert); AcDbLine line2(result1.m_ptInsert,arPt[1]); AcDbLine line3(arPt[1],result2.m_ptInsert); AcDbLine line4(result2.m_ptInsert,arPt[0]); AcDbVoidPtrArray arRegs; arRegs.append(&line1); arRegs.append(&line2); arRegs.append(&line3); arRegs.append(&line4); AcDbVoidPtrArray arRegions; AcDbRegion::createFromCurves(arRegs, arRegions); if (arRegions.length() != 1) { ReleasePtrArray(arRegions); return NULL; } AcDbRegion *pRegion= AcDbRegion::cast((AcRxObject*)arRegions[0]); return pRegion; } void TGDrawThunder::Get3PeripheryPoints(const AcGePoint3d& ptInsert1,const AcGePoint3d& ptInsert2,const AcGePoint3d& ptInsert3,double dProRadius1,double dProRadius2,double dProRadius3,AcArray& arPtInter) { AcGePoint3d ptSphere1,ptSphere2,ptSphere3; AcDbCircle circle1(ptInsert1,AcGeVector3d::kZAxis,dProRadius1); AcDbCircle circle2(ptInsert2,AcGeVector3d::kZAxis,dProRadius2); AcGePoint3dArray arPt1; IntersectWith2Circle(&circle1, &circle2, arPt1); if (arPt1.length() != 2) return; if (arPt1[0].distanceTo(ptInsert3) > arPt1[1].distanceTo(ptInsert3)) ptSphere1 = arPt1[0]; else ptSphere1 = arPt1[1]; AcDbCircle circle3(ptInsert2,AcGeVector3d::kZAxis,dProRadius2); AcDbCircle circle4(ptInsert3,AcGeVector3d::kZAxis,dProRadius3); AcGePoint3dArray arPt2; IntersectWith2Circle(&circle3, &circle4, arPt2); if (arPt2.length() != 2) return; if (arPt2[0].distanceTo(ptInsert1) > arPt2[1].distanceTo(ptInsert1)) ptSphere2 = arPt2[0]; else ptSphere2 = arPt2[1]; AcDbCircle circle5(ptInsert3,AcGeVector3d::kZAxis,dProRadius3); AcDbCircle circle6(ptInsert1,AcGeVector3d::kZAxis,dProRadius1); AcGePoint3dArray arPt3; IntersectWith2Circle(&circle5, &circle6, arPt3); if (arPt3.length() != 2) return; if (arPt3[0].distanceTo(ptInsert2) > arPt3[1].distanceTo(ptInsert2)) ptSphere3 = arPt3[0]; else ptSphere3 = arPt3[1]; arPtInter.append(ptSphere1); arPtInter.append(ptSphere2); arPtInter.append(ptSphere3); } void TGDrawThunder::GetSphereSolids(const AcArray& arPt,const AcGeDoubleArray& arRadius,double dGroundRadius,AcArray& arSolid,AcArray& arPtSec) { if (arPt.length() != arRadius.length()) return; BOOL bHasResult = TRUE; for (int i = 0; i < arPt.length(); ++i) { for (int j = i + 1; j < arPt.length(); ++j) { AcDbCircle circle1(arPt[i],AcGeVector3d::kZAxis,arRadius[i]); AcDbCircle circle2(arPt[j],AcGeVector3d::kZAxis,arRadius[j]); AcGePoint3dArray arPtInter; IntersectWith2Circle(&circle1, &circle2, arPtInter); if (arPtInter.length() != 2) continue; for (int k = 0; k < arPt.length(); ++k) { if (k == i || k == j) continue; if (arPtInter[0].distanceTo(arPt[k]) < arRadius[k]) bHasResult = FALSE; } if (bHasResult) arPtSec.append(arPtInter[0]); bHasResult = TRUE; for (int l = 0; l < arPt.length(); ++l) { if (l == i || l == j) continue; if (arPtInter[1].distanceTo(arPt[l]) < arRadius[l]) bHasResult = FALSE; } if (bHasResult) arPtSec.append(arPtInter[1]); bHasResult = TRUE; } } AcGePoint3d ptResult; for (int m = 0; m < arPtSec.length(); ++m) { ptResult = arPtSec[m]; ptResult.z += dGroundRadius; AcDb3dSolid *pSolid = new AcDb3dSolid; pSolid->createSphere(dGroundRadius); AcGeMatrix3d matrix; matrix.setCoordSystem(ptResult,AcGeVector3d::kXAxis,AcGeVector3d::kYAxis,AcGeVector3d::kZAxis); pSolid->transformBy(matrix); arSolid.append(pSolid); } } //生成顶部球体和中间区域 void TGDrawThunder::GetTopSphereSolid(lstCltResult& arResult, AcDbVoidPtrArray& arTopPtr) { AcGePoint3dArray arPt; if (arResult.size() <= 0) return; double dGroundRadius = arResult.front().m_dGroundRadius; double dProRadius = 0.0; double dScale = 1.0; if (!DocGetMeterUnitDraw()) { dGroundRadius *= 1000; dProRadius *= 1000; dScale *= 1000; } lstCltResult::iterator it,itSub,itThird; for (it = arResult.begin();it != arResult.end();++it) { itSub = it; itSub++; for (itSub;itSub != arResult.end(); ++itSub) { itThird = itSub; itThird++; for (itThird;itThird != arResult.end();++itThird) { double dHeight1 = it->m_dHeight; double dHeight2 = itSub->m_dHeight; double dHeight3 = itThird->m_dHeight; if (!DocGetMeterUnitDraw()) { dHeight1 *= 1000; dHeight2 *= 1000; dHeight3 *= 1000; } AcGePoint3d ptTop1 = it->m_ptInsert; AcGePoint3d ptTop2 = itSub->m_ptInsert; AcGePoint3d ptTop3 = itThird->m_ptInsert; ptTop1.z += dHeight1; ptTop2.z += dHeight2; ptTop3.z += dHeight3; AcGeVector3d vecParal = ptTop1 - it->m_ptInsert; AcGePoint3d ptCen; double dDis = 0.0; dProRadius = it->m_dProRadius*dScale; if (Get3PinSphereCen(ptTop1,ptTop2,ptTop3,dGroundRadius,vecParal,ptCen,dProRadius)) { BOOL bNeedSphere = TRUE; AcGePoint3d ptTemp; lstCltResult::iterator itL; for (itL = arResult.begin();itL != arResult.end();++itL) { if (itL == it || itL == itThird || itL == itSub) { continue; } ptTemp = itL->m_ptInsert; if (!DocGetMeterUnitDraw()) ptTemp.z += 1000*itL->m_dHeight; else ptTemp.z += itL->m_dHeight; double dDisdis = ptCen.distanceTo(ptTemp); if (dGroundRadius - dDisdis > 0.00001) { bNeedSphere = FALSE; break; } } if (bNeedSphere) arPt.append(ptCen); else bNeedSphere = TRUE; } } } } for (int m = 0; m < arPt.length(); ++m) { AcDb3dSolid *pSolid = new AcDb3dSolid; pSolid->createSphere(dGroundRadius); AcGeMatrix3d matrix; matrix.setCoordSystem(arPt[m],AcGeVector3d::kXAxis,AcGeVector3d::kYAxis,AcGeVector3d::kZAxis); pSolid->transformBy(matrix); arTopPtr.append(pSolid); } } //得到中间区域 void TGDrawThunder::Get3DIntersectionArea(lstCltResult& arResult,const AcArray& arPtInter,AcArray& arSolid) { if (arResult.size() <= 0) return; AcDbVoidPtrArray arRegs; double dRadius = 0.0; AcGePoint3d ptT,ptInterT; lstCltResult::iterator it; for (int i = 0; i < arPtInter.length(); ++i) { for (it = arResult.begin();it != arResult.end();++it) { if (!DocGetMeterUnitDraw()) dRadius = it->m_dProRadius*1000; else dRadius = it->m_dProRadius; if (it->m_ptInsert.distanceTo(arPtInter[i]) - dRadius < 0.01) { AcDbLine *pLine = new AcDbLine(it->m_ptInsert,arPtInter[i]); arRegs.append(pLine); } } } Acad::ErrorStatus es; AcDbVoidPtrArray arRegions; es = AcDbRegion::createFromCurves(arRegs, arRegions); ReleasePtrArray(arRegs); if (arRegions.length() < 1) return; double dGroundRadius = arResult.front().m_dGroundRadius; if (!DocGetMeterUnitDraw()) { dGroundRadius *= 1000; } double dArea = 0.0; for (int l = 0; l < arRegions.length(); ++l) { AcDbRegion *pRegTemp = AcDbRegion::cast((AcRxObject*)arRegions[l]); AcDb3dSolid *pSolid = new AcDb3dSolid; es = pSolid->extrude(pRegTemp,dGroundRadius,0); arSolid.append(pSolid); } ReleasePtrArray(arRegions); } void TGDrawThunder::DeleteAllEntities(LPCTSTR pszGroupNo) { ThunderContainer->EreaseSpecGNoCircl(pszGroupNo); ThunderContainer->EreaseSpecGNoRegion(pszGroupNo); ThunderContainer->EreaseSpecGNo3dSolid(pszGroupNo); m_arRegSolid.setLogicalLength(0); } // 更改图层 void TGDrawThunder::Set2dLayer(const CString& strLayer2d) { m_strLayer2d = strLayer2d; } void TGDrawThunder::Set3dLayer(const CString& strLayer3d) { m_strLayer3d = strLayer3d; } int TGDrawThunder::GetNowCaculateResult(lstCltResult& lstData) { lstData.clear(); TContainerSingleton::LstGroupIDMap mapData; TContainerSingleton::LstGroupIDMap::iterator it; ThunderContainer->GetThunderMap(mapData); CStringArray arsXData; CThunderXData thundXData; TGLightningRodData ltnData; TGThunderCaculate caculate; AcGePoint3d ptInsert; TContainerSingleton::LstIDData lstID; TContainerSingleton::LstIDData::iterator itLst; AcGeDoubleArray arProHeight; int nMaxProSize = 0; for (it = mapData.begin();it != mapData.end();++it) { lstID = it->second; if (lstID.size() < 1) continue; thundXData.GetProtectHeightFromObjEx(lstID.front(), arProHeight); if (arProHeight.length() > nMaxProSize) { nMaxProSize = arProHeight.length(); } for (itLst = lstID.begin();itLst != lstID.end();++itLst) { ptInsert = ThunderContainer->GetThunderInsertPosition(*itLst); if (thundXData.GetBaseInformationExData(*itLst, arsXData, TEL_THUNDER_BASEINFOR) ) { ltnData.SetGroundRadius(_tstof(arsXData.GetAt(CThunderXData::eXDataPinRadius))); ltnData.SetHeight(_tstof(arsXData.GetAt(CThunderXData::eXDataPinHeight))); ltnData.SetNumber(_ttoi(arsXData.GetAt(CThunderXData::eXDataPinNum))); ltnData.SetInsertPoint(ptInsert); ltnData.SetObjectID(*itLst); ltnData.SetGroupNO(_ttoi(it->first)); ltnData.m_arProtecedHeight.setLogicalLength(0); ltnData.m_arProtecedHeight.append(arProHeight); caculate.CaculateThunderData(<nData); lstData.push_back(caculate.m_result); } } } return nMaxProSize; } BOOL TGDrawThunder::CheckHasRepeatNum(AcDbObjectIdArray& arID, AcDbObjectIdArray& arIDRepeated) { arIDRepeated.setLogicalLength(0); if (arID.length() < 1) { return FALSE; } std::list lstNum; std::list::iterator it; CString sNum; CThunderXData xd; AcDbObjectIdArray arLoc; for (int i = 0;i < arID.length();++i) { if (arID[i].isValid()) { xd.GetXData(arID[i], TEL_ORDER_NUMBER, sNum); if ((it = std::find(lstNum.begin(),lstNum.end(),_ttoi(sNum))) != lstNum.end()) { arIDRepeated.append(arID[i]); } else { lstNum.push_back(_ttoi(sNum)); arLoc.append(arID[i]); } } } arID.setLogicalLength(0); arID.append(arLoc); return arIDRepeated.length() > 0; } void TGDrawThunder::DrawThunderCircle(const AcGeDoubleArray& arProHeight, LPCTSTR pszGroupNo, const AcDbObjectIdArray& arID) { if (pszGroupNo == NULL || arID.length() < 1) { return; } // 绘制圆 CThunderXData thunderXData; AcDbObjectId idCir; AcDbObjectIdArray arThun,arCir; CStringArray arXData; CString sTemp; AcGePoint3d ptInsert; for (int i = 0;i < arID.length();++i) { ptInsert = ThunderContainer->GetThunderInsertPosition(arID[i]); thunderXData.SetProtectHeightToObjEx(arID[i], arProHeight); thunderXData.GetBaseInformationExData(arID[i], arXData, TEL_THUNDER_BASEINFOR); for (int j = 0;j < arProHeight.length();++j) { idCir = DrawCircleRingThunder(arXData, ptInsert, arProHeight[j]); if (idCir.isValid()) { sTemp.Format(_T("%g"),arProHeight[j]); thunderXData.SetXData(idCir,TEL_CURRENT_PROHEIGHT,sTemp); thunderXData.SetXData(idCir, TEL_GROUP_NO, pszGroupNo); thunderXData.SetProtectHeightToObjEx(idCir, arProHeight); arCir.append(idCir); } } // 将避雷针id存入多个圆的扩展数据 arThun.append(arID[i]); for (int k = 0;k < arCir.length();++k) { thunderXData.SetEntityIdToExData(arThun, arCir[k], TEL_THUNDER_ID); } // 将多个圆存入避雷针的扩展数据 thunderXData.SetEntityIdToExData(arCir, arID[i], TEL_THUNDER_ID); ThunderContainer->AppendCircle(pszGroupNo, arCir); arCir.setLogicalLength(0); arThun.setLogicalLength(0); } } // 在避雷针的周围画圆 AcDbObjectId TGDrawThunder::DrawCircleRingThunder(const CStringArray& arXData, AcGePoint3d& ptInsert, double dProHt) { AcDbObjectId idCir = AcDbObjectId::kNull; if (arXData.GetSize() < 3) { return idCir; } AcDbCircle* pCircle = NULL; double dRadius = 0.0; double dScale = 1.0; if (!DocGetMeterUnitDraw()) dScale = 1000.0; else dScale = 1.0; dRadius = pow((_tstof(arXData.GetAt(CThunderXData::eXDataPinHeight))) * (2 * (_tstof(arXData.GetAt(CThunderXData::eXDataPinRadius))) - (_tstof(arXData.GetAt(CThunderXData::eXDataPinHeight)))), 0.5) - pow((dProHt) * (2 * (_tstof(arXData.GetAt(CThunderXData::eXDataPinRadius))) - dProHt), 0.5); double dValue = 0.0; dValue = dProHt * dScale; ptInsert[Z] = dValue; pCircle = new AcDbCircle(ptInsert, AcGeVector3d::kZAxis, dRadius * dScale); if (pCircle == NULL) { return idCir; } pCircle->setLayer(LAY_EL_THUNDER_2D); pCircle->setColorIndex(m_nSinglePinColorIndex); idCir = AddToCurrentSpace(pCircle, Adesk::kTrue); return idCir; } BOOL TGDrawThunder::CalcThunderData(LPCTSTR pszGNo, const AcGeDoubleArray& arProHeight, const AcDbObjectIdArray& arID, lstCltResult& lstData) { lstData.clear(); if (pszGNo != NULL && arID.length() > 0) { AcDbObjectIdArray arLoc(arID); // 检查是否存在避雷针编号重复 AcDbObjectIdArray arRepeate; if (CheckHasRepeatNum(arLoc,arRepeate)) { acutPrintf(_T("\n 存在重复的避雷针编号,请修改编号。")); } CStringArray arsXData; CThunderXData thundXData; TGLightningRodData ltnData; TGThunderCaculate caculate; AcGePoint3d ptInsert; for (int i = 0;i < arLoc.length();++i) { ptInsert = ThunderContainer->GetThunderInsertPosition(arLoc[i]); if (thundXData.GetBaseInformationExData(arLoc[i], arsXData, TEL_THUNDER_BASEINFOR) ) { ltnData.SetGroundRadius(_tstof(arsXData.GetAt(CThunderXData::eXDataPinRadius))); ltnData.SetHeight(_tstof(arsXData.GetAt(CThunderXData::eXDataPinHeight))); ltnData.SetNumber(_ttoi(arsXData.GetAt(CThunderXData::eXDataPinNum))); ltnData.SetInsertPoint(ptInsert); ltnData.SetObjectID(arLoc[i]); ltnData.SetGroupNO(_ttoi(pszGNo)); ltnData.m_arProtecedHeight.setLogicalLength(0); ltnData.m_arProtecedHeight.append(arProHeight); caculate.CaculateThunderData(<nData); lstData.push_back(caculate.m_result); } } } return (lstData.size() > 0); } void TGDrawThunder::PickupSymbolBySpecGroupNO(PickSet& ssSymbol, LPCTSTR pszGroupNo) { if (pszGroupNo != NULL && _ttoi(pszGroupNo) > 0) { PickSet ssTmp(SS_FREE); CThunderXData thundXData; CString sGroupNo; for (long i = 0;i < ssSymbol.Length();++i) { OPENOBJ_BEGIN(ssSymbol[i],AcDb::kForRead,AcDbEntity,pEnt); if (pEnt != NULL) { thundXData.GetXData(pEnt, TEL_GROUP_NO, sGroupNo); } OPENOBJ_END(); if (sGroupNo.CompareNoCase(pszGroupNo) == 0) { ssTmp += ssSymbol[i]; sGroupNo.Empty(); } } ssSymbol.Free(); ssSymbol += ssTmp; } } AcDbObjectId TGDrawThunder::CopyEnt(AcDbEntity* pEnt) { AcDbObjectId id; if (pEnt) { AcDbEntity* pNew = CopyEntPtr(pEnt); if (pNew) { id = AddToCurrentSpace(pNew,Adesk::kTrue); } } return id; } AcDbEntity* TGDrawThunder::CopyEntPtr(AcDbEntity* pEnt) { AcDbEntity* pLoc = NULL; if (pEnt) { AcDb3dSolid* pp = AcDb3dSolid::cast(pEnt); if (pp) { pLoc = new AcDb3dSolid; pLoc->copyFrom(pEnt); } AcDbLine* p2 = AcDbLine::cast(pEnt); if (p2) { pLoc = new AcDbLine; pLoc->copyFrom(pEnt); } AcDbArc* p3 = AcDbArc::cast(pEnt); if (p3) { pLoc = new AcDbArc; pLoc->copyFrom(pEnt); } AcDbRegion* pReg = AcDbRegion::cast(pEnt); if (pReg) { pLoc = new AcDbRegion; pLoc->copyFrom(pEnt); } } return pLoc; } void TGDrawThunder::EreaseObj(const AcDbObjectId& id) { if (id.isValid()) { OPENOBJ_BEGIN(id,AcDb::kForWrite,AcDbEntity,pEnt); if (pEnt != NULL) { pEnt->erase(); } OPENOBJ_END(); } } BOOL TGDrawThunder::IntersectWith2Circle(AcDbCircle* pCir1, AcDbCircle* pCir2, AcGePoint3dArray& arPt) { if (pCir1 != NULL && pCir2 != NULL) { pCir1->intersectWith(pCir2, AcDb::kOnBothOperands, arPt); if (arPt.length() < 1) { double dRadius1 = pCir1->radius(); double dRadius2 = pCir2->radius(); double dDist = pCir1->center().distanceTo(pCir2->center()); if (fabs(dDist - (dRadius1+dRadius2)) < 1e-3) // 相切 { AcDbLine ln(pCir1->center(), pCir2->center()); ln.intersectWith(pCir1, AcDb::kOnBothOperands, arPt); } else if (dDist < (dRadius1+dRadius2)) // 相交 { AcDbVoidPtrArray arPtr,arReg1,arReg2; AcDbCircle* pC1 = new AcDbCircle(pCir1->center(), pCir1->normal(), pCir1->radius()); arPtr.append(pC1); AcDbRegion::createFromCurves(arPtr, arReg1); ReleasePtrArray(arPtr); AcDbCircle* pC2 = new AcDbCircle(pCir2->center(), pCir2->normal(), pCir2->radius()); arPtr.append(pC2); AcDbRegion::createFromCurves(arPtr, arReg2); ReleasePtrArray(arPtr); if (arReg1.length() > 0 && arReg2.length() > 0) { AcDbRegion* pReg1 = (AcDbRegion*)arReg1.first(); AcDbRegion* pReg2 = (AcDbRegion*)arReg2.first(); if (pReg1 != NULL && pReg2 != NULL) { pReg1->booleanOper(AcDb::kBoolIntersect, pReg2); AcGePoint3d ptT; AcDbVoidPtrArray arExplode; pReg1->explode(arExplode); AcDbArc* pArc = NULL; for (int i = 0;i < arExplode.length();++i) { pArc = (AcDbArc*)arExplode[i]; if (pArc != NULL) { pArc->getStartPoint(ptT); arPt.append(ptT); pArc->getEndPoint(ptT); arPt.append(ptT); break; } } ReleasePtrArray(arExplode); } } ReleasePtrArray(arReg1); ReleasePtrArray(arReg2); } } } return arPt.length() > 0; } AcDb3dSolid* TGDrawThunder::CreateRepair3DSolid(AcDb3dSolid* pInt1,const CCaculateResult& pInt1Data1,const CCaculateResult& pInt1Data2, AcDb3dSolid* pInt2,const CCaculateResult& pInt2Data1,const CCaculateResult& pInt2Data2) { AcDb3dSolid* pRetSolid = NULL; if (pInt1 == NULL || pInt2 == NULL) { return pRetSolid; } // 截取面reg AcGeVector3d vt = pInt1Data1.m_ptInsert - pInt1Data2.m_ptInsert; AcGePlane plan; plan.set(pInt1Data1.m_ptInsert,vt,AcGeVector3d::kZAxis); AcDbRegion* pReg = NULL; pInt1->getSection(plan, pReg); if (pReg == NULL) return pRetSolid; vt = pInt2Data1.m_ptInsert - pInt2Data2.m_ptInsert; plan.set(pInt2Data1.m_ptInsert,vt,AcGeVector3d::kZAxis); AcDbRegion* pReg2 = NULL; pInt2->getSection(plan, pReg2); if (pReg2 == NULL) { delete pReg; return pRetSolid; } // 计算延伸路径 AcDbLine path; CalcStretchPaht(pReg,pInt1Data1,pInt1Data2,pReg2,pInt2Data1,pInt2Data2,&path); // 取需要延伸实体的reg double dDist1 = pInt1Data1.m_ptInsert.distanceTo(pInt1Data2.m_ptInsert); double dDist2 = pInt2Data1.m_ptInsert.distanceTo(pInt2Data2.m_ptInsert); if (dDist1 > dDist2) { pRetSolid = ExtrudeSolidAlongPath(pReg2, &path); } else { pRetSolid = ExtrudeSolidAlongPath(pReg, &path); } delete pReg; delete pReg2; return pRetSolid; } BOOL TGDrawThunder::CalcStretchPaht(AcDbEntity* pEnt1,const CCaculateResult& pInt1Data1,const CCaculateResult& pInt1Data2, AcDbEntity* pEnt2,const CCaculateResult& pInt2Data1,const CCaculateResult& pInt2Data2, AcDbLine* pPath) { if (pEnt1 != NULL && pEnt2 != NULL && pPath != NULL ) { std::list lstPtPair; LINEPTPAIR ptPair; AcGePoint3d ptS,ptE; int nScale = 1; if (!DocGetMeterUnitDraw()) { nScale *= 1000; } ptPair.pt1 = pInt1Data1.m_ptInsert; ptPair.pt1.z += pInt1Data1.m_dHeight * nScale; ptPair.pt2 = pInt1Data2.m_ptInsert; ptPair.pt2.z += pInt1Data2.m_dHeight * nScale; lstPtPair.push_back(ptPair); ptPair.pt1 = pInt2Data1.m_ptInsert; ptPair.pt1.z += pInt2Data1.m_dHeight * nScale; ptPair.pt2 = pInt2Data2.m_ptInsert; ptPair.pt2.z += pInt2Data2.m_dHeight * nScale; lstPtPair.push_back(ptPair); if (GetSolidCopingLowPoint(pEnt1, lstPtPair, ptS) && GetSolidCopingLowPoint(pEnt2, lstPtPair, ptE) ) { pPath->setStartPoint(ptS); pPath->setEndPoint(ptE); return TRUE; } } return FALSE; }