You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

338 lines
8.9 KiB

#include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier
#include "BasicEdge.h"
9 months ago
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=0AB
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;
}