#include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier #include "BasicEdge.h" BasicEdge basicEdge; // 预处理分支点和卡箍之间的连线关系 void BasicEdge::buildEdgeBetweenClipAndBranchPoint() { for (int i = 1; i <= 3000; i++) { for (int j = 0; j <= 1; j++) { assert(edge[i][j].size() == 0); } } for (int i = 1; i <= basicChannel.bundleNum; i++) { BundleNode *pbn = basicChannel.bundles[i].head; BundleNode *pre = NULL; while (pbn != NULL) { if (pre != NULL) { int cid1 = pre->pc->id; int cid2 = pbn->pc->id; int inOut1 = pre->inOut; int inOut2 = pbn->inOut; assert(cid1 != cid2); pair<int, int> pr = make_pair(cid2, inOut2); assert(pr.first == cid2); if (inOut1 != 0 && inOut1 != 1) { cout << "clip " << cid1 << " inOut=" << inOut1 << endl; } if (inOut2 != 0 && inOut2 != 1) { cout << "clip " << cid2 << " inOut=" << inOut2 << endl; } assert(inOut1 == 0 || inOut1 == 1); assert(inOut2 == 0 || inOut2 == 1); edge[cid1][inOut1].push_back(pr); pr = make_pair(cid1, inOut1 ^ 1); assert(pr.first == cid1); edge[cid2][inOut2 ^ 1].push_back(pr); } pre = pbn; pbn = pbn->next; } // cout<<i<<" "<<edge[94][1].size()<<endl; } for (int i = 1; i <= 3000; i++) { for (int j = 0; j <= 1; j++) { for (int k = 0; k < edge[i][j].size(); k++) { if (edge[i][j][k].first == i) cout << i << " " << j << " " << k << endl; assert(edge[i][j][k].first != i); } } } for (int i = 1; i <= branchPointSet.branchPointNum; i++) { BranchPoint *pb = &branchPointSet.b[i]; int cid1 = pb->pc1->id; int inOut1 = basicChannel.getClipInOut(cid1) ^ 1; int cid2 = pb->pc2->id; int inOut2 = basicChannel.getClipInOut(cid2); int inOut3 = basicChannel.isClipConnectedToClip(cid1, cid2); assert(inOut3 == inOut2); clip[i][0].push_back(make_pair(cid1, inOut1)); clip[i][0].push_back(make_pair(cid2, inOut2)); branchPoint[cid1][inOut1 ^ 1].push_back(make_pair(i, 1)); branchPoint[cid2][inOut2 ^ 1].push_back(make_pair(i, 1)); vector<int> vec = kdtree.search_by_dis(branchPointSet.b[i].coord, 600); for (int j = 0; j < vec.size(); j++) { int cid = vec[j]; if (!bvh.iscollect(clipSet.c[cid].coord, branchPointSet.b[i].coord)) { clip[i][1].push_back(make_pair(cid, 0)); // 这里相当于只存储卡箍,不存储进出信息,因为会变 int clipType = basicChannel.clipType(cid); if (clipType == 0) { branchPoint[cid][0].push_back(make_pair(i, 0)); branchPoint[cid][1].push_back(make_pair(i, 0)); } else if (clipType == 1) { int inDir = basicChannel.getEXTClipInDir(cid); branchPoint[cid][inDir ^ 1].push_back(make_pair(i, 0)); } } } } } // 返回卡箍能连接到的卡箍,如果没有能连接到的,返回只含有0的数组 vector<pair<int, int>> BasicEdge::getClipConnectedToClip(int cid, int inOut) { if (edge[cid][inOut].size() != 0) { if (edge[cid][inOut][0].first == 0) return edge[cid][inOut]; vector<pair<int, int>> res; for (int i = 0; i < edge[cid][inOut].size(); i++) { int v = edge[cid][inOut][i].first; assert(v != cid); int inOut2 = edge[cid][inOut][i].second; int clipType = basicChannel.clipType(v); if (clipType == 2) { int dir = basicChannel.isClipConnectedToClip(cid, v); if (dir != inOut2) continue; // 去除中间卡箍 } res.push_back(make_pair(v, inOut2)); } return res; } // 只有不在通道里的卡箍方向需要被处理,通道内卡箍应该提前处理好 vector<int> vec1 = kdtree.search_by_dis(clipSet.c[cid].coord, 600); for (int i = 0; i < vec1.size(); i++) { int v = vec1[i]; if (v == cid) continue; int clipType = basicChannel.clipType(v); if (clipType != 2 && !bvh.iscollect(clipSet.c[cid].coord, clipSet.c[v].coord)) { if (clipType == 0) { edge[cid][inOut].push_back(make_pair(v, 0)); edge[cid][inOut].push_back(make_pair(v, 1)); } else { int inDir = basicChannel.getEXTClipInDir(v); edge[cid][inOut].push_back(make_pair(v, inDir)); } } } if (edge[cid][inOut].size() == 0) edge[cid][inOut].push_back(make_pair(0, 0)); return edge[cid][inOut]; } /*根据分支点返回卡箍 mode=0为模式A,否则为模式B 其中模式B需要过滤掉通道中的卡箍 */ vector<pair<int, int>> BasicEdge::getClipConnectedToBranchPoint(int bid, int mode) { if (mode == 0) return clip[bid][0]; else { vector<pair<int, int>> v; for (int i = 0; i < clip[bid][1].size(); i++) { int cid = clip[bid][1][i].first; int clipType = basicChannel.clipType(cid); if (clipType == 0) { v.push_back(make_pair(cid, 0)); v.push_back(make_pair(cid, 1)); } else if (clipType == 1) { v.push_back(make_pair(cid, basicChannel.getEXTClipInDir(cid))); } else if (clipType == 2) { int dir = basicChannel.isBranchPointConnectedToClip(bid, cid); if (dir != -1) v.push_back(make_pair(cid, dir)); } } return v; } } /*根据卡箍返回分支点,卡箍与分支点在同一个Bundle上 卡箍分为3种,断头/通道中的点/孤立点 其中通道中的点只能采用模式A 孤立点只能采用模式B 断头可以根据inOut来判断采用哪种模式 offset代表偏移量,用来将分支点标号对应到Astar中点的标号 */ vector<pair<int, int>> BasicEdge::getBranchPointConnectedToClip(int cid, int inOut, int offset) { vector<pair<int, int>> v; for (int i = 0; i < branchPoint[cid][inOut].size(); i++) { int bid = branchPoint[cid][inOut][i].first; int mode = branchPoint[cid][inOut][i].second; v.push_back(make_pair(bid + offset, mode)); } return v; } // 返回Astar中编号为id的点能建立边的下个点 vector<pair<int, int>> BasicEdge::getNextPoint(int id, int mode, int offset) { int cid, bid; vector<pair<int, int>> v1, v2; if (id <= offset) { cid = id; v1 = this->getBranchPointConnectedToClip(cid, mode, offset); v2 = this->getClipConnectedToClip(cid, mode); if (v2.size() && v2[0].first != 0) v1.insert(v1.begin(), v2.begin(), v2.end()); return v1; } else { bid = id - offset; v1 = this->getClipConnectedToBranchPoint(bid, mode); return v1; } } /*返回端点可以连接到的点 p是端点坐标 offSet是分支点坐标的偏移量 isEnd=1表示这个端点是路径终点,否则是路径起点 */ vector<pair<int, int>> BasicEdge::getEXTNextPoint(P p, int offSet, int isEnd) { vector<pair<int, int>> res; vector<int> vec1 = kdtree.search_by_dis(p, 600); vec1 = basicChannel.getBranchPointAndClip(vec1, offSet); for (int i = 0; i < vec1.size(); i++) { int v = vec1[i]; if (v <= offSet) { int clipType = basicChannel.clipType(v); if (clipType == 0) { res.push_back(make_pair(v, 0)); res.push_back(make_pair(v, 1)); } if (clipType == 1) { int inDir = basicChannel.getEXTClipInDir(v); res.push_back(make_pair(v, inDir ^ isEnd)); } } else { if (isEnd) res.push_back(make_pair(v, 1)); else res.push_back(make_pair(v, 0)); } } return res; } // 根据新的路径更新边信息 void BasicEdge::addPath(Path path) { for (int i = 0; i < path.size(); i++) { P &p = path.points[i]; BundleNode *pbn; // 当前通道节点 if (p.type == 0) { // 卡箍 int cid = p.ref; pbn = basicChannel.getClipBundleNodePointer(cid); int clipType = basicChannel.clipType(cid); assert(clipType == 2); int inOut = basicChannel.getClipInOut(cid); // 更新edge卡箍到卡箍的边 edge[cid][inOut].clear(); if (pbn->next->type == 0) { int cid2 = pbn->next->pc->id; int inOut2 = basicChannel.getClipInOut(cid2); edge[cid][inOut].push_back(make_pair(cid2, inOut2)); } else edge[cid][inOut].push_back(make_pair(0, 0)); edge[cid][inOut ^ 1].clear(); if (pbn->pre->type == 0) { int cid2 = pbn->pre->pc->id; int inOut2 = basicChannel.getClipInOut(cid2); edge[cid][inOut ^ 1].push_back(make_pair(cid2, inOut2 ^ 1)); } else edge[cid][inOut ^ 1].push_back(make_pair(0, 0)); // 更新branch卡箍到分支点的边 if (branchPoint[cid][0].size() != 0 && branchPoint[cid][0][0].second == 0) { // 原本不在通道里 int vv = 0; for (int i = 0; i < branchPoint[cid][0].size(); i++) { int v = branchPoint[cid][0][i].first; if (basicChannel.isBranchPointConnectedToClip(v, cid) == 1) { vv = v; break; } } branchPoint[cid][0].clear(); if (vv != 0) branchPoint[cid][0].push_back(make_pair(vv, 0)); } if (branchPoint[cid][1].size() != 0 && branchPoint[cid][1][0].second == 0) { int vv = 0; for (int i = 0; i < branchPoint[cid][1].size(); i++) { int v = branchPoint[cid][1][i].first; if (basicChannel.isBranchPointConnectedToClip(v, cid) == 0) { vv = v; break; } } branchPoint[cid][1].clear(); if (vv != 0) branchPoint[cid][1].push_back(make_pair(vv, 0)); } // 排除异分支模式 } // 分支点不需要更新 } return; }