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.

676 lines
15 KiB

10 months ago
#include "stdafx.h"
#include "Bundle.h"
#include <cmath>
#include <vector>
#include <queue>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
10 months ago
using namespace std;
// ���ݿ�������λ�ù��ƻ�����ͨ������ά���������صķ�֧����Ϣ
struct BasicChannel
{
10 months ago
Bundle bundles[N]; // ����ͨ��
int bundleNum; // ����ͨ������
int basicChannelNum; // ����ͨ������
map<int, BundleNode *> PointConnectedTobranchPoint[MAXPointNum]; // ���ӵ���֧���ĵ�
10 months ago
// �������ݿ���������λ�ô������Ƶ�ͨ��
inline void createChannel()
{
10 months ago
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++;
10 months ago
}
if (cnt == 1)
{
10 months ago
Path path;
path.dia = 5;
int lastCid = 0;
int cid = i;
while (cid)
{
bool flag = true;
10 months ago
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;
10 months ago
break;
}
}
if (flag)
break;
10 months ago
}
path.processDir();
bundleNum++;
basicChannelNum++;
bundles[bundleNum] = Bundle(path, bundleNum);
10 months ago
}
}
}
// �������з�֧��
inline void 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);
10 months ago
pbn->vb.push_back(pb->id);
if (ppb != NULL)
{
ppb->pb2 = pb;
pb->pb1 = ppb;
10 months ago
}
ppb = pb;
pbn = pbn->next;
10 months ago
}
}
}
// ���ݿ������Ż�ȡ��������ͨ���ڵ�ָ��
inline BundleNode *getClipBundleNodePointer(int cid)
{
assert(clipSet.c[cid].bundleNodeID != 0);
10 months ago
return &bdNode[clipSet.c[cid].bundleNodeID];
}
// ��ȡ�������ڵ�ͨ��id
inline int getClipBundleID(Clip *pc)
{
BundleNode *pbn = &bdNode[pc->bundleNodeID];
10 months ago
return pbn->bundleID;
}
inline int getClipBundleID(int cid)
{
BundleNode *pbn = &bdNode[clipSet.c[cid].bundleNodeID];
10 months ago
return pbn->bundleID;
}
// ���ݵ���ȡ�����ڵ�bundleNode����������֧��,���������ھ��´���һ��
inline BundleNode *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;
10 months ago
}
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];
10 months ago
return pbn;
}
}
// ��ȡ������ͨ������������
inline int getClipInOut(int cid)
{
BundleNode *pbn = &bdNode[clipSet.c[cid].bundleNodeID];
10 months ago
return pbn->inOut;
}
// ���ؿ������ͣ�0Ϊ����������1Ϊ��ͷ������2Ϊ�м俨��
inline int 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;
10 months ago
return 2;
}
// ��ȡ��ͷ�����Ľ���ͨ������
inline int getEXTClipInDir(Clip *pc)
{
BundleNode *pbn = &bdNode[pc->bundleNodeID];
if (pbn->pre == NULL)
return pbn->inOut;
else
return (pbn->inOut) ^ 1;
10 months ago
}
inline int getEXTClipInDir(int cid)
{
BundleNode *pbn = &bdNode[clipSet.c[cid].bundleNodeID];
if (pbn->pre == NULL)
return pbn->inOut;
else
return (pbn->inOut) ^ 1;
10 months ago
}
// ��ȡ�м俨����ͨ�����ķ���
inline int getMIDClipDir(int cid)
{
BundleNode *pbn = &bdNode[clipSet.c[cid].bundleNodeID];
10 months ago
return pbn->inOut;
}
/*�ж�һ����֧���Ƿ���ͨ�������ӵ�һ������
ӷ-1
Ϸɷ֧ӵķ
*/
inline int 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);
10 months ago
return -1;
}
/*�ж�һ�������Ƿ���ͨ�������ӵ�һ������
ӷ-1
Ϸɿ1ӵ2ķ
*/
inline int 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;
10 months ago
return -1;
}
// ����һ�������ļ��Ϸ��ظ������п����ͷ�֧���ļ���
inline vector<int> getBranchPointAndClip(vector<int> cv, int offset)
{
vector<int> res;
for (int i = 0; i < cv.size(); i++)
{
int cid = cv[i];
10 months ago
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++)
{
10 months ago
res.push_back(pbn->vb[j]);
}
}
return res;
}
/*�ϲ�����bundle,�̵IJ��볤��
ߵbundleָpbdʾ
ұߵbundleidʾ
rev1,rev2ֱbundlepathĹϵ
غϲbundlepathλùϵ
pbdָϲbundle
*/
inline int 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);
10 months ago
}
pbn = nt;
10 months ago
}
if (rev1 != rev2)
{
swap(pbd->head, pbd->tail);
10 months ago
}
if (rev2 == 0)
{
pbd->tail->next = pbd2->head;
pbd2->head->pre = pbd->tail;
pbd2->head = pbd->head;
10 months ago
}
else
{
pbd->head->pre = pbd2->tail;
pbd2->tail->next = pbd->head;
pbd2->tail = pbd->tail;
10 months ago
}
if (pbd->id == this->bundleNum + 1)
delete pbd;
pbd = pbd2;
10 months ago
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);
10 months ago
}
pbn = nt;
10 months ago
}
if (rev1 != rev2)
{
swap(pbd2->head, pbd2->tail);
10 months ago
}
if (rev1 == 0)
{
pbd->tail->next = pbd2->head;
pbd2->head->pre = pbd->tail;
pbd->tail = pbd2->tail;
10 months ago
}
else
{
pbd->head->pre = pbd2->tail;
pbd2->tail->next = pbd->head;
pbd->head = pbd2->head;
10 months ago
}
return rev1;
}
}
// ����һ��·��������ͨ������
inline void 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; // 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;
10 months ago
}
else
{ // ��ʼ�������Ѽ���ͨ��
10 months ago
delete pbd;
pbd = &this->bundles[pbn->bundleID];
reverse = (pbd->tail == pbn);
10 months ago
}
}
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;
10 months ago
pbd->length++;
}
// ��ǰһ��ͨ���ڵ�����
if (pre != NULL)
{
if (!reverse)
{
pre->next = pbn;
pbn->pre = pre;
10 months ago
}
else
{
pre->pre = pbn;
pbn->next = pre;
10 months ago
}
}
if (i == path.size() - 1)
{ // ��ֹ������
// �����µ�ͨ��
if (pbd->id == this->bundleNum + 1)
{
10 months ago
this->bundleNum++;
this->bundles[pbd->id] = *pbd;
10 months ago
delete pbd;
}
}
}
if (pbn->id == 146)
{
10 months ago
;
int TTT = 1;
10 months ago
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))
{
10 months ago
;
}
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;
// ����ͨ����Ϣ
10 months ago
pbd->length++;
if (reverse)
pbd->head = pbn;
else
pbd->tail = pbn;
10 months ago
}
// ��ǰһ��ͨ���ڵ�����
if (pre != NULL)
{
if (!reverse)
{
pre->next = pbn;
pbn->pre = pre;
10 months ago
}
else
{
pre->pre = pbn;
pbn->next = pre;
10 months ago
}
}
}
// �����µ�ͨ��
if (pbd->id == this->bundleNum + 1)
{
10 months ago
this->bundleNum++;
this->bundles[pbd->id] = *pbd;
10 months ago
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))
{
10 months ago
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;
10 months ago
}
}
else
{
assert(id == cid1);
if (pbn2->next == pbn)
reverse = 0;
else
{
assert(pbn2->pre == pbn);
reverse = 1;
10 months ago
}
pbn = pbn2;
10 months ago
}
}
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;
// ����ͨ����Ϣ
10 months ago
pbd->length++;
pbd->head = pbn;
pbd->tail = pbn;
reverse = 0;
10 months ago
}
else
{
10 months ago
delete pbd;
pbd = &bundles[pbn->bundleID];
if (pbd->head == pbn)
reverse = 0;
else
{
assert(pbd->tail == pbn);
reverse = 1;
10 months ago
}
}
}
}
}
pre = pbn;
10 months ago
}
return;
}
vector<vector<pair<int, int>>> resClip;
vector<vector<int>> resBranchPoint;
10 months ago
vector<int> startBranchPoint;
vector<int> endBranchPoint;
vector<int> BundleConnectedToBranchPoint[MAXPointNum]; // ���ӵ���֧����ͨ��
10 months ago
int Out[N];
void 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;
10 months ago
P tp;
if (inOut == -1)
{
ofs << connectors[id].name << " " << 0 << endl;
tp = connectors[id].coord;
10 months ago
}
else
{
ofs << clipSet.c[id].name << " " << (inOut ^ 1) << endl;
tp = clipSet.c[id].coord;
10 months ago
}
if (inOut != 0)
tp.reverse();
//------------------------mark------------------------
ofs << tp.x << " " << tp.y << " " << tp.z << " ";
ofs << tp.dx << " " << tp.dy << " " << tp.dz << endl;
// for blender input
// ofs << tp.x * 100 << " " << tp.y * 100 << " " << tp.z * 100 << " ";
// ofs << tp.dx * 100 << " " << tp.dy * 100 << " " << tp.dz * 100 << endl;
10 months ago
}
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;
10 months ago
pb->reverse();
}
ofs << bid << " " << pb->referClip << " " << pb->position << endl;
10 months ago
}
}
// ��bundle��Ϣ����ʽҪ����ӡ����
inline void printBundle(string resultfile, bool basic = false)
{
10 months ago
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)
{
10 months ago
Out[i]++;
this->BundleConnectedToBranchPoint[this->startBranchPoint[i]].push_back(i);
}
if (this->endBranchPoint[i] != 0)
{
10 months ago
Out[i]++;
this->BundleConnectedToBranchPoint[this->endBranchPoint[i]].push_back(i);
}
if (Out[i] == 0)
q.push(i);
10 months ago
}
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];
10 months ago
Out[bdid]--;
if (Out[bdid] == 0)
q.push(bdid);
10 months ago
}
}
}
}
} basicChannel;