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.
 
 
 

551 lines
13 KiB

#include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier
#include "BasicChannel.h"
//仅仅根据卡箍的相对位置创建近似的通道
void BasicChannel::createChannel() {
Clip* c = clipSet.c;
int clipNum = clipSet.clipnum;
for (int i = 1; i <= clipNum; i++) {
if (c[i].bundleNodeID != 0)continue;
int cnt = 0;
for (int j = 0; j < c[i].channelEdge.size(); j++) {
int cid = c[i].channelEdge[j];
if (clipSet.bothConnect(i, cid))cnt++;
}
if (cnt == 1) {
Path path;
path.dia = 5;
int lastCid = 0;
int cid = i;
while (cid) {
bool flag = true;
path.points.push_back(c[cid].coord);
for (int j = 0; j < c[cid].channelEdge.size(); j++) {
int cid2 = c[cid].channelEdge[j];
if (cid2 == lastCid)continue;
if (clipSet.bothConnect(cid, cid2)) {
lastCid = cid;
cid = cid2;
flag = false;
break;
}
}
if (flag)break;
}
path.processDir();
bundleNum++;
basicChannelNum++;
bundles[bundleNum] = Bundle(path, bundleNum);
}
}
}
//创建所有分支点
void BasicChannel::createBranchPoint() {
for (int i = 1; i <= bundleNum; i++) {
BranchPoint* ppb = NULL;
BundleNode* pbn = bundles[i].head;
while (pbn != NULL && pbn->next != NULL) {
BranchPoint* pb = branchPointSet.addBranchPoint(pbn->pc, pbn->next->pc, pbn->id);
pbn->vb.push_back(pb->id);
if (ppb != NULL) {
ppb->pb2 = pb;
pb->pb1 = ppb;
}
ppb = pb;
pbn = pbn->next;
}
}
}
//根据卡箍标号获取其所属的通道节点指针
BundleNode* BasicChannel::getClipBundleNodePointer(int cid) {
assert(clipSet.c[cid].bundleNodeID != 0);
return &bdNode[clipSet.c[cid].bundleNodeID];
}
//获取卡箍属于的通道id
int BasicChannel::getClipBundleID(Clip* pc) {
BundleNode* pbn = &bdNode[pc->bundleNodeID];
return pbn->bundleID;
}
int BasicChannel::getClipBundleID(int cid) {
BundleNode* pbn = &bdNode[clipSet.c[cid].bundleNodeID];
return pbn->bundleID;
}
//根据点获取其属于的bundleNode,不包括分支点,如果不存在就新创建一个
BundleNode* BasicChannel::getBundleNodeByPoint(P& p, int inOut, int bundleID) {
assert(p.type == 0 || p.type == 3);
if (p.type == 0) {
int cid = p.ref;
int bnid = clipSet.c[cid].bundleNodeID;
if (bnid == 0)return Bundle::createBundleNode(p, inOut, bundleID);
BundleNode* pbn = &bdNode[bnid];
return pbn;
}
else {
int cnid = p.ref;
int bnid = connectors[cnid].bundleNodeID;
if (bnid == 0)return Bundle::createBundleNode(p, inOut, bundleID);
cout << "---" << bnid << endl;
BundleNode* pbn = &bdNode[bnid];
return pbn;
}
}
//获取卡箍在通道里的正方向
int BasicChannel::getClipInOut(int cid) {
BundleNode* pbn = &bdNode[clipSet.c[cid].bundleNodeID];
return pbn->inOut;
}
//返回卡箍类型,0为孤立卡箍,1为断头卡箍,2为中间卡箍
int BasicChannel::clipType(int cid) {
int bundleNodeID = clipSet.c[cid].bundleNodeID;
if (bundleNodeID == 0)return 0;
BundleNode* pbn = &bdNode[bundleNodeID];
if (pbn->pre == NULL && pbn->next == NULL)return 0;
if (pbn->pre == NULL || pbn->next == NULL)return 1;
return 2;
}
//获取断头卡箍的进入通道方向
int BasicChannel::getEXTClipInDir(Clip* pc) {
BundleNode* pbn = &bdNode[pc->bundleNodeID];
if (pbn->pre == NULL)return pbn->inOut;
else return (pbn->inOut) ^ 1;
}
int BasicChannel::getEXTClipInDir(int cid) {
BundleNode* pbn = &bdNode[clipSet.c[cid].bundleNodeID];
if (pbn->pre == NULL)return pbn->inOut;
else return (pbn->inOut) ^ 1;
}
//获取中间卡箍在通道里的方向
int BasicChannel::getMIDClipDir(int cid) {
BundleNode* pbn = &bdNode[clipSet.c[cid].bundleNodeID];
return pbn->inOut;
}
/*判断一个分支点是否在通道中连接到一个卡箍
如果不连接返回-1
如果连接上返回由分支点连接到卡箍的方向
*/
int BasicChannel::isBranchPointConnectedToClip(int bid, int cid) {
BundleNode* pbn = &bdNode[clipSet.c[cid].bundleNodeID];
if (pbn->next != NULL &&
pbn->next->type == 1 &&
pbn->next->pb->id == bid)return getMIDClipDir(cid) ^ 1;
if (pbn->pre != NULL &&
pbn->pre->type == 1 &&
pbn->pre->pb->id == bid)return getMIDClipDir(cid);
return -1;
}
/*判断一个卡箍是否在通道中连接到一个卡箍
如果不连接返回-1
如果连接上返回由卡箍1连接到卡箍2的方向
*/
int BasicChannel::isClipConnectedToClip(int cid1, int cid2) {
BundleNode* pbn = &bdNode[clipSet.c[cid1].bundleNodeID];
if (pbn->next != NULL &&
pbn->next->type == 0 &&
pbn->next->pc->id == cid2)return getMIDClipDir(cid2);
if (pbn->pre != NULL &&
pbn->pre->type == 0 &&
pbn->pre->pc->id == cid2)return getMIDClipDir(cid2) ^ 1;
return -1;
}
//根据一个卡箍的集合返回附近所有卡箍和分支点的集合
vector<int> BasicChannel::getBranchPointAndClip(vector<int> cv, int offset) {
vector<int>res;
for (int i = 0; i < cv.size(); i++) {
int cid = cv[i];
res.push_back(cid);
int bundleNodeID = clipSet.c[cid].bundleNodeID;
if (bundleNodeID == 0)continue;
BundleNode* pbn = &bdNode[bundleNodeID];
for (int j = 0; j < pbn->vb.size(); j++) {
res.push_back(pbn->vb[j]);
}
}
return res;
}
/*合并两个bundle,短的并入长的
左边的bundle用指针pbd表示
右边的bundle用id表示
rev1,rev2分别代表左右两个bundle与path方向的关系
返回合并后的bundle与path的位置关系
pbd会指向合并后的bundle
*/
int BasicChannel::mergeBundle(Bundle*& pbd, int bdid, int rev1, int rev2) {
Bundle* pbd2 = &bundles[bdid];
if (pbd->length < pbd2->length) {
pbd->abandoned = true;
pbd2->length += pbd->length;
BundleNode* pbn = pbd->head;
while (pbn != NULL) {
pbn->bundleID = bdid;
BundleNode* nt = pbn->next;
if (rev1 != rev2) {
(pbn->inOut) ^= 1;
(pbn->rev) ^= 1;
swap(pbn->pre, pbn->next);
}
pbn = nt;
}
if (rev1 != rev2) {
swap(pbd->head, pbd->tail);
}
if (rev2 == 0) {
pbd->tail->next = pbd2->head;
pbd2->head->pre = pbd->tail;
pbd2->head = pbd->head;
}
else {
pbd->head->pre = pbd2->tail;
pbd2->tail->next = pbd->head;
pbd2->tail = pbd->tail;
}
if (pbd->id == this->bundleNum + 1)delete pbd;
pbd = pbd2;
return rev2;
}
else {
pbd2->abandoned = true;
pbd->length += pbd2->length;
BundleNode* pbn = pbd2->head;
while (pbn != NULL) {
pbn->bundleID = pbd->id;
BundleNode* nt = pbn->next;
if (rev1 != rev2) {
pbn->inOut ^= 1;
pbn->rev ^= 1;
swap(pbn->pre, pbn->next);
}
pbn = nt;
}
if (rev1 != rev2) {
swap(pbd2->head, pbd2->tail);
}
if (rev1 == 0) {
pbd->tail->next = pbd2->head;
pbd2->head->pre = pbd->tail;
pbd->tail = pbd2->tail;
}
else {
pbd->head->pre = pbd2->tail;
pbd2->tail->next = pbd->head;
pbd->head = pbd2->head;
}
return rev1;
}
}
//加入一条路径来更新通道数据
void BasicChannel::addPath(Path path) {
Bundle* pbd = new Bundle();
pbd->id = bundleNum + 1; //pdb代表当前通道
int reverse = 0;//reverse=1代表path和bundle反向
BundleNode* pre = NULL;
for (int i = 0; i < path.size(); i++) {
P p = path.points[i];
int inOut = path.inOut[i];
BundleNode* pbn = nullptr; //pbn代表当前通道节点
//非分支点
if (p.type == 0 || p.type == 3) {
pbn = this->getBundleNodeByPoint(p, inOut ^ reverse, pbd->id);
//存在则返回,没有则新建
//起始连接器
if (i == 0) {
if (pbn->bundleID == pbd->id) { //起始连接器未加入通道
pbd->head = pbn;
pbd->tail = pbn;
pbd->length = 1;
reverse = 0;
}
else { //起始连接器已加入通道
delete pbd;
pbd = &this->bundles[pbn->bundleID];
reverse = (pbd->tail == pbn);
}
}
else { //非起始连接器
int rev2 = (pbn->inOut != inOut);
if (pbn->bundleID != pbd->id) //新节点已经属于别的通道
reverse = this->mergeBundle(pbd, pbn->bundleID, reverse, rev2);
//短的通道向长的通道合并,方向以长通道为准
else if (pbn->pre == NULL && pbn->next == NULL) {//新节点还没有属于任何通道
if (reverse)pbd->head = pbn;
else pbd->tail = pbn;
pbd->length++;
}
//和前一个通道节点链接
if (pre != NULL) {
if (!reverse) {
pre->next = pbn;
pbn->pre = pre;
}
else {
pre->pre = pbn;
pbn->next = pre;
}
}
if (i == path.size() - 1) { //终止连接器
//创建新的通道
if (pbd->id == this->bundleNum + 1) {
this->bundleNum++;
this->bundles[pbd->id] = *pbd;
delete pbd;
}
}
}
if (pbn->id == 146) {
;
int TTT = 1;
TTT++;
;
}
}
else { //分支点
int bid = p.ref;
BranchPoint* pb = branchPointSet.getBranchPointPointer(bid);
int cid1 = pb->pc1->id, cid2 = pb->pc2->id;
//分支点作为上一个通道的结尾
P& tp = path.points[i - 1];
int id = tp.ref;
//同段分支点
if (tp.type == 0 && (id == cid1 || id == cid2)) {
;
}
else { //异段分支点
if (tp.type == 0)id *= 3;
else if (tp.type == 3)id = id * 3 + 1;
else id = id * 3 + 2;
//给卡箍id*3,连接器id*3+1,分支点id*3+2,把他们区分开
//找到分支点对应通道节点,或新建一个
pbn = this->PointConnectedTobranchPoint[bid][id];
if (pbn == NULL) {
pbn = Bundle::createBundleNode(p, inOut, pbd->id);
this->PointConnectedTobranchPoint[bid][id] = pbn;
//更新通道信息
pbd->length++;
if (reverse)pbd->head = pbn;
else pbd->tail = pbn;
}
//和前一个通道节点链接
if (pre != NULL) {
if (!reverse) {
pre->next = pbn;
pbn->pre = pre;
}
else {
pre->pre = pbn;
pbn->next = pre;
}
}
}
//创建新的通道
if (pbd->id == this->bundleNum + 1) {
this->bundleNum++;
this->bundles[pbd->id] = *pbd;
delete pbd;
}
//分支点作为下一个通道的开头
if (i != path.size() - 1) {
//创建临时新通道
pbd = new Bundle();
pbd->id = this->bundleNum + 1;
P& tp = path.points[i + 1];
int id = tp.ref;
//同段分支点
if (tp.type == 0 && (id == cid1 || id == cid2)) {
delete pbd;
int bundleID = this->getClipBundleID(cid1);
pbd = &this->bundles[bundleID];
pbn = this->getClipBundleNodePointer(cid1);
BundleNode* pbn2 = this->getClipBundleNodePointer(cid2);
if (id == cid2) {
if (pbn->next == pbn2)reverse = 0;
else {
assert(pbn->pre == pbn2);
reverse = 1;
}
}
else {
assert(id == cid1);
if (pbn2->next == pbn)reverse = 0;
else {
assert(pbn2->pre == pbn);
reverse = 1;
}
pbn = pbn2;
}
}
else { //异段分支点
if (tp.type == 0)id *= 3;
else if (tp.type == 3)id = id * 3 + 1;
else id = id * 3 + 2;
//给卡箍id*3,连接器id*3+1,分支点id*3+2,把他们区分开
//找到分支点对应通道节点,或新建一个
pbn = this->PointConnectedTobranchPoint[bid][id];
if (pbn == NULL) {
pbn = Bundle::createBundleNode(p, inOut, pbd->id);
this->PointConnectedTobranchPoint[bid][id] = pbn;
//更新通道信息
pbd->length++;
pbd->head = pbn;
pbd->tail = pbn;
reverse = 0;
}
else {
delete pbd;
pbd = &bundles[pbn->bundleID];
if (pbd->head == pbn)reverse = 0;
else {
assert(pbd->tail == pbn);
reverse = 1;
}
}
}
}
}
pre = pbn;
}
return;
}
void BasicChannel::printSingleBundle(int i, ofstream& ofs) {
vector< pair<int, int> >& partClip = resClip[i];
vector<int>& partBranchPoint = resBranchPoint[i];
ofs << partClip.size() << " " << 1 <<
" " << startBranchPoint[i] << " " << endBranchPoint[i] << endl;
for (int j = 0; j < partClip.size(); j++) {
int id = partClip[j].first;
int inOut = partClip[j].second;
P tp;
if (inOut == -1) {
ofs << connectors[id].name << " " << 0 << endl;
tp = connectors[id].coord;
}
else {
ofs << clipSet.c[id].name << " " << (inOut ^ 1) << endl;
tp = clipSet.c[id].coord;
}
if (inOut != 0)tp.reverse();
ofs << tp.x << " " << tp.y << " " << tp.z << " ";
ofs << tp.dx << " " << tp.dy << " " << tp.dz << endl;
}
ofs << partBranchPoint.size() << endl;
for (int j = 0; j < partBranchPoint.size(); j++) {
int bid = partBranchPoint[j];
BranchPoint* pb = branchPointSet.getBranchPointPointer(bid);
int bnid = pb->bundleNodeID;
if (bid == 150)cout << (pb->Dis) << " " << (pb->position) << " " << (pb->pc2->name) << endl;
assert((pb->position) < (pb->Dis));
if (bdNode[bnid].rev == 1) {
cout << "reverse" << endl;
pb->reverse();
}
ofs << bid << " " << pb->referClip << " " << pb->position << endl;
}
}
//把bundle信息按格式要求打印出来
void BasicChannel::printBundle(string resultfile, bool basic) {
ofstream ofs;
ofs.open(resultfile.c_str(), ios::out);
cout << "bundleNum: " << bundleNum << endl;
for (int i = 1; i <= bundleNum; i++)
if (!bundles[i].abandoned || basic)
bundles[i].updateOutput(resClip, resBranchPoint,
startBranchPoint, endBranchPoint, basic);
cout << "resClip.size()= " << resClip.size() << endl;
ofs << resClip.size() << endl;
//ofs<<76<<endl;
queue<int>q;
for (int i = 0; i < resClip.size(); i++)Out[i] = 0;
for (int i = 0; i < resClip.size(); i++) {
if (startBranchPoint[i] != 0) {
Out[i]++;
this->BundleConnectedToBranchPoint[this->startBranchPoint[i]].push_back(i);
}
if (this->endBranchPoint[i] != 0) {
Out[i]++;
this->BundleConnectedToBranchPoint[this->endBranchPoint[i]].push_back(i);
}
if (Out[i] == 0)q.push(i);
}
while (!q.empty()) {
int x = q.front(); q.pop();
this->printSingleBundle(x, ofs);
for (int i = 0; i < this->resBranchPoint[x].size(); i++) {
int bid = this->resBranchPoint[x][i];
for (int j = 0; j < this->BundleConnectedToBranchPoint[bid].size(); j++) {
int bdid = this->BundleConnectedToBranchPoint[bid][j];
Out[bdid]--;
if (Out[bdid] == 0)q.push(bdid);
}
}
}
}