#include "stdafx.h" #include "insertequ.h" #include "KTCadUtilityex.h" #include "AecDbEarthWorm.h" #include "UITools.h" #include "AecDbPortRoom.h" #include "coretools.h" void DLLIMPEXP ConnectEarthWorm(AecDbEarthWorm* pWorm1, AecDbEarthWorm* pWorm2); namespace { #define ALIGN_OFFSET _T("Align_Offset") #define ALIGN_ROOM _T("Align_Room") #define ALIGN_TYPE _T("Align_Type") struct INSPos { AcGePoint3d m_pt; AcGeVector3d m_normal; double m_angle; int m_idDb; }; bool getEw(AcDbObjectIdArray &ids) { ads_name ent; ads_point pt; AcDbObjectId idSt(AcDbObjectId::kNull), idEd(AcDbObjectId::kNull); int nRes = acedEntSel(_T("\n请选择管廊起始段:"), ent, pt); if (nRes != RTNORM) return false; acdbGetObjectId(idSt, ent); if (!idSt.isValid()) return false; nRes = acedEntSel(_T("\n请选择管廊结束段:"), ent, pt); if (nRes != RTNORM) idEd = idSt; else acdbGetObjectId(idEd, ent); if (!idEd.isValid()) return false; if (!GetConnectedWorms(idSt, idEd, ids)) { acutPrintf(_T("\n提取管廊段失败。")); return false; } CString str(_T("")), strSection(_T("")), strFstSection(_T("")); int idx(-1); for (int i = 0; i < ids.length(); i++) { OPENOBJ_BEGIN(ids[i], AcDb::kForRead, AecDbEarthWorm, pEw) if (!pEw) continue; pEw->GetCrossSectionScr(str); idx = str.Find(_T("ext")); if (idx == -1) // 说明没有扩展数据,全部字符串都为几何信息 strSection = str; else strSection = str.Left(idx); if (i == 0) // 用第一个做标准,来检测后面的每一段管廊 { strFstSection = strSection; continue; } else { if (strSection.Compare(strFstSection) != 0) // 不一致,走人 { acutPrintf(_T("\n所选的管廊中,尺寸不完全一致,请检查。")); return false; } } OPENOBJ_END() } return !ids.isEmpty(); } bool getEwCenterLine(const int iRoom , const bool &bWhole , const AcDbObjectIdArray &ids , std::vector &segs) { EROOM room; AcArray arLnCenSegs(0); for (int i = 0; i < ids.length(); ++i) { OPENOBJ_BEGIN(ids[i], AcDb::kForRead, AecDbEarthWorm, pEw) if (!pEw) continue; arLnCenSegs.removeAll(); pEw->getCenterLineForPipe(arLnCenSegs, iRoom, bWhole); for (int j = 0; j < arLnCenSegs.length(); ++j) { LineSeg &lnseg = arLnCenSegs[j]; segs.push_back(AcGeLineSeg3d(lnseg.ptFr, lnseg.ptTo)); } OPENOBJ_END() } return !segs.empty(); } int getEwRoomCount(AcDbObjectId &id) { OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw) if (pEw) return pEw->GetRoomCount(); OPENOBJ_END() return 0; } bool getInsPos_BOSS(LPCTSTR pszBoss, const std::vector &segs) { //BOSS: 房间|左右位置|侧间隙|水平间隙|宽|高|长|直径|用途|公称直径|壁厚|重量|管道材质|管道系统|颜色|线形|编号|支墩类型|偏移|行|间隙|3D索引 return false; } // 外宽,外高,外壁厚,内壁厚 bool getEwGeoInfo(AecDbEarthWorm *pEw, double &dW, double &dH, double &dOutW, double &dInnerW) { if (!pEw) return false; AcGePoint2dArray arDatas; ESection sectionType; sectionType = pEw->ExtractEarthWormScr(arDatas); if (sectionType != eRect) return false; ////外壁厚,内隔壁厚 if (arDatas.length() > 0) { dOutW = arDatas.last().x; dInnerW = arDatas.last().y; } //总宽度 for (int i = 0; i < arDatas.length() - 1; i++) { dW+= arDatas.at(i).x; } dW+= (arDatas.length() - 2) * dInnerW; dW+= dOutW * 2.0; //总高度 dH = arDatas.first().y; dH += 2 * arDatas.last().x; return true; } void drawCircle(const AcGePoint2d &pt, const double &d = 1, const int &clr = 1) { #ifndef NDEBUG AcDbCircle *p = new AcDbCircle(AcGePoint3d(pt.x, pt.y, .0), AcGeVector3d::kZAxis, d); p->setColorIndex(clr); CoreTools::AddToModelSpace(p); #endif } void drawRay(const AcGePoint2d &pt, const AcGeVector2d &vt) { #ifndef NDEBUG AcDbRay *p = new AcDbRay(); p->setUnitDir(AcGeVector3d(vt.x, vt.y, .0)); p->setBasePoint(AcGePoint3d(pt.x, pt.y, .0)); CoreTools::AddToModelSpace(p); #endif } void drawXLine(const AcGePoint2d &pt, const AcGeVector2d &vt) { #ifndef NDEBUG AcDbXline *p = new AcDbXline(); p->setUnitDir(AcGeVector3d(vt.x, vt.y, .0)); p->setBasePoint(AcGePoint3d(pt.x, pt.y, .0)); CoreTools::AddToModelSpace(p); #endif } void offsetEw(AecDbEarthWorm *pEw, const double &dOffset) { if (!pEw) return; AcGePoint2d pt2dStart(AcGePoint2d::kOrigin), pt2dEnd(AcGePoint2d::kOrigin); AcGeVector2d dir(AcGeVector2d::kIdentity); dir = pEw->EndPoint(true) - pEw->StartPoint(); dir.normalize(); dir.rotateBy(PI * .5); dir *= dOffset; pt2dStart = pEw->StartPoint(); pt2dStart += dir; pEw->SetStartPoint(pt2dStart); pt2dEnd = pEw->EndPoint(true); pt2dEnd += dir; pEw->SetEndPoint(pt2dEnd); } } namespace InsEqu { void insertEqu() { AcDbObjectIdArray ids(0); if (!getEw(ids)) return; std::vector segs(0); if (!getEwCenterLine(0, true, ids, segs)) return; for (size_t i = 0; i < segs.size(); ++i) { AcGeLineSeg3d &seg(segs[i]); AcDbLine *pLine = new AcDbLine(seg.startPoint(), seg.endPoint()); CoreTools::AddToModelSpace(pLine); } } bool getAlignTypeByOffset(AecDbEarthWorm *pEw, int &alignType, int &idxRoom, double &dOffset) { if (!pEw) { dOffset = .0; alignType = eNone; idxRoom = -1; return false; } if (pEw->GetSpecialtyData()->GetAt(ALIGN_TYPE, alignType) && pEw->GetSpecialtyData()->GetAt(ALIGN_OFFSET, dOffset) && pEw->GetSpecialtyData()->GetAt(ALIGN_ROOM, idxRoom)) return true; return false; /* AcGePoint2d pt2d1, pt2d2; double dRoom // 舱内径宽 , dOutW(.0) // 外壁厚 , dInnerW(.0) // 内壁厚 , dW(.0); // 总宽 pt2d2 = pEw->GetSize(pt2d1); dOutW = pt2d1.x; dInnerW = pt2d1.y; dW = pt2d2.x; double dDelta(.5*dW + dOffset); ERoom rm; double dist(dOutW); int nCount(pEw->GetRoomCount()); for (size_t i = 0; i < nCount; ++i) { pEw->GetRoom(i, rm); dRoom = rm.ptGe[0].distanceTo(rm.ptGe[1]); idxRoom = i; if (DOWNEQUAL(dDelta, dist)) return eAlignLeft; dist += dRoom * .5; if (DOWNEQUAL(dDelta, dist)) return eAlignCenter; dist += dRoom * .5; if (DOWNEQUAL(dDelta, dist)) return eAlignRight; dist += dInnerW; } return eNone; */ } int getAlignType(const AecDbEarthWorm *pEw) { if (!pEw) return eNone; int type(eNone); pEw->GetSpecialtyData()->GetAt(ALIGN_TYPE, type); return type; } int getAlignType(const AcDbObjectId & id) { OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw) if (pEw) return getAlignType(pEw); OPENOBJ_END() return eNone; } int getAlignRoom(const AecDbEarthWorm *pEw) { if (!pEw) return -1; int idx(-1); pEw->GetSpecialtyData()->GetAt(ALIGN_ROOM, idx); return idx; } int getAlignRoom(const AcDbObjectId & id) { OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw) if (pEw) return getAlignRoom(pEw); OPENOBJ_END() return -1; } double getAlignOffset(const AecDbEarthWorm *pEw) { if (!pEw) return .0; double dOffset(.0); pEw->GetSpecialtyData()->GetAt(ALIGN_OFFSET, dOffset); return dOffset; } double getAlignOffset(const AcDbObjectId & id) { OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw) if (pEw) return getAlignOffset(pEw); OPENOBJ_END() return 0.0; } void generateControlLine() { AcDbObjectIdArray arIds(0); if (!GLTools::getConnectWorms(arIds)) return; if (arIds.isEmpty()) return; AcGePoint3d ptS(AcGePoint3d::kOrigin), ptE(AcGePoint3d::kOrigin), pt(AcGePoint3d::kOrigin); AcGePoint2d pt2d, pt2d1; double dH(.0),dOutW(.0), dBom(.0), dTop(.0) , dLeftH(.0), dRightH(.0), dInnerH(.0) , deltaL(.0), deltaR(.0); double dElevS(.0), dElevE(.0); AcDbCurve *pCurve(NULL); AcGeVector3d vt(AcGeVector3d::kIdentity); AcGeLineSeg3d seg; AcArray rms; for (int i = 0; i < arIds.length(); ++i) { OPENOBJ_BEGIN(arIds[i], AcDb::kForRead, AecDbEarthWorm, pEw) { if (!pEw) continue; // 带标高的basecurve就在廊径中间,以它为标准做变换 pCurve = pEw->GetBaseCurve(true); if (!pCurve) continue; pCurve->getStartPoint(ptS); pCurve->getEndPoint(ptE); ptS.z = ptE.z = .0; vt = ptE - ptS; dElevS = pEw->StartElevation(); dElevE = pEw->EndElevation(); ptS.z = dElevS; ptE.z = dElevE; pEw->GetSize(pt2d); dOutW = pt2d.x; // 外壁 dBom = pEw->GetBomThickAdd(); dBom += dOutW; // 下壁厚 dTop = pEw->GetTopThickAdd(); dTop += dOutW; // 上壁厚 dLeftH = pEw->GetLeftRoomHeight(); // 最左舱内高 dRightH = pEw->GetRightRoomHeight();// 最右舱内高 seg.set(ptS, ptE); rms.removeAll(); pEw->GetSectionRoomsTo(seg, rms, pt2d); for (int r = 0; r < rms.length(); ++r) { ERoom &ro(rms[r]); dInnerH = ro.ptGe[0].distanceTo(ro.ptGe[3]); dH = dInnerH + dTop + dBom; Midpoint(ro.ptGe[0], ro.ptGe[2], pt); if (r == 0) // 最左 { deltaL = abs(dInnerH - dLeftH); pt.z -= deltaL * .5; } if (r == rms.length() - 1) // 最右 { deltaR = abs(dInnerH - dRightH); pt.z -= deltaR * .5; } AcDbLine *pL = new AcDbLine(pt, pt + vt); pL->setColorIndex(r + 1); CoreTools::AddToModelSpace(pL); } } OPENOBJ_END() } } double getEarthwormOffset(AecDbEarthWorm * pEw, const int & idxRoom, const EAlignType & alignType) { if (!pEw) return .0; if (idxRoom == -1) return .0; if (alignType == eNone) return .0; AcGePoint2d pt2d1, pt2d2; double dRoom // 舱内径宽 , dOutW(.0) // 外壁厚 , dInnerW(.0) // 内壁厚 , dW(.0); // 总宽 pt2d2 = pEw->GetSize(pt2d1); dOutW = pt2d1.x; dInnerW = pt2d1.y; dW = pt2d2.x; ERoom rm; double dDelta(dOutW); // 先把左侧外壁厚加上 int nCount(pEw->GetRoomCount()); for (size_t i = 0; i < nCount; ++i) { pEw->GetRoom(i, rm); dRoom = rm.ptGe[0].distanceTo(rm.ptGe[1]); dDelta += dRoom; // 再加上此舱室内径宽 dDelta += dInnerW; // 再加上其右侧内壁厚 if (idxRoom == i) { // 把右侧内壁厚减掉 dDelta -= dInnerW; if (alignType == eAlignLeft) // 左对齐 dDelta -= dRoom; else if (alignType == eAlignCenter) // 中对齐 dDelta -= dRoom * .5; else // 右对齐 { // 不用动 } break; } } // 管廊默认是按照总宽度一半来做为中心的 return dDelta - dW * .5; } double getEarthwormOffset(AcDbObjectId & id, const int & idxRoom, const EAlignType & alignType) { OPENOBJ_BEGIN(id, AcDb::kForRead, AecDbEarthWorm, pEw) if (pEw) return getEarthwormOffset(pEw, idxRoom, alignType); OPENOBJ_END() return .0; } // 目的是先进行偏移(并不使用AecDbEarthworm类中的m_dOffset变量) void offsetAndConnectEws(AcDbObjectIdArray &ids , const int &alignType , const int &idxRoom , const double &dOldOffset) { if (ids.isEmpty()) return; if (alignType == eNone) return; double dOffset(.0); dOffset = getEarthwormOffset(ids.first(), idxRoom, (EAlignType)alignType); dOffset -= dOldOffset; AcDbObjectIdArray arPorts(0); for (int i = 0; i < ids.length(); ++i) { AcDbObjectId &id(ids[i]); OPENOBJ_BEGIN(id, AcDb::kForWrite, AecDbEarthWorm, pEw) { if (!pEw) continue; offsetEw(pEw, dOffset); pEw->GetPortRoomIds(arPorts); pEw->GetSpecialtyData()->SetAt(ALIGN_TYPE, alignType); pEw->GetSpecialtyData()->SetAt(ALIGN_ROOM, idxRoom); pEw->GetSpecialtyData()->SetAt(ALIGN_OFFSET, dOffset + dOldOffset); } OPENOBJ_END() } if (true) // 为测试加此语句 { for (int i = 0; i < ids.length() - 1; ++i) { AcDbObjectId &id1(ids[i]), &id2(ids[i + 1]); OPENOBJ_BEGIN(id1, AcDb::kForWrite, AecDbEarthWorm, pEw1) { OPENOBJ_BEGIN(id2, AcDb::kForWrite, AecDbEarthWorm, pEw2) { if (!pEw1 || !pEw2) continue; ConnectEarthWorm(pEw1, pEw2); } OPENOBJ_END() } OPENOBJ_END() } } for (int i = 0; i < arPorts.length(); ++i) { AcDbObjectId &id(arPorts.at(i)); OPENOBJ_BEGIN(id, AcDb::kForWrite, AecDbPortRoom, pPort) { if (!pPort) continue; pPort->UpdateDraw(); } OPENOBJ_END() } } void generateControlLine_old() { ads_name ent; ads_point pt; AcDbObjectId idSt(AcDbObjectId::kNull), idEd(AcDbObjectId::kNull); int nRes = acedEntSel(_T("\n请选择管廊:"), ent, pt); if (nRes != RTNORM) return; acdbGetObjectId(idSt, ent); if (!idSt.isValid()) return; AcDbObjectIdArray ids(0); if (!GetConnectedWorms(idSt, ids)) { acutPrintf(_T("\n获取相连管廊失败。")); return; } int count = getEwRoomCount(idSt); if (!count) return; std::vector segs(0); if (!getEwCenterLine(0, false, ids, segs)) return; for (size_t j = 0; j < segs.size(); ++j) { AcGeLineSeg3d &seg(segs[j]); AcDbLine *pLine = new AcDbLine(seg.startPoint(), seg.endPoint()); CoreTools::AddToModelSpace(pLine); } } }