#include "stdafx.h" #include "Bundle.h" #include #include #include #include #include #include #include using namespace std; //根据卡箍相对位置估计基本的通道,并维护与此相关的分支点信息 struct BasicChannel { Bundle bundles[N]; //所有通道 int bundleNum; //所有通道数量 int basicChannelNum;//基本通道数量 map PointConnectedTobranchPoint[MAXPointNum];//连接到分支点的点 //仅仅根据卡箍的相对位置创建近似的通道 inline void 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;jnext!=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; } } } //根据卡箍标号获取其所属的通道节点指针 inline BundleNode* getClipBundleNodePointer(int cid){ assert(clipSet.c[cid].bundleNodeID!=0); return &bdNode[clipSet.c[cid].bundleNodeID]; } //获取卡箍属于的通道id inline int getClipBundleID(Clip * pc){ BundleNode *pbn=&bdNode[pc->bundleNodeID]; return pbn->bundleID; } inline int getClipBundleID(int cid){ BundleNode *pbn=&bdNode[clipSet.c[cid].bundleNodeID]; 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; } else { int cnid=p.ref; int bnid=connectors[cnid].bundleNodeID; if(bnid==0)return Bundle::createBundleNode(p,inOut,bundleID); cout<<"---"<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; return 2; } //获取断头卡箍的进入通道方向 inline int getEXTClipInDir(Clip * pc){ BundleNode *pbn=&bdNode[pc->bundleNodeID]; if(pbn->pre==NULL)return pbn->inOut; else return (pbn->inOut)^1; } inline int getEXTClipInDir(int cid){ BundleNode *pbn=&bdNode[clipSet.c[cid].bundleNodeID]; if(pbn->pre==NULL)return pbn->inOut; else return (pbn->inOut)^1; } //获取中间卡箍在通道里的方向 inline int getMIDClipDir(int cid){ BundleNode *pbn=&bdNode[clipSet.c[cid].bundleNodeID]; 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); 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; return -1; } //根据一个卡箍的集合返回附近所有卡箍和分支点的集合 inline vector getBranchPointAndClip(vector cv,int offset){ vectorres; for(int i=0;ivb.size();j++){ res.push_back(pbn->vb[j]); } } return res; } /*合并两个bundle,短的并入长的 左边的bundle用指针pbd表示 右边的bundle用id表示 rev1,rev2分别代表左右两个bundle与path方向的关系 返回合并后的bundle与path的位置关系 pbd会指向合并后的bundle */ inline int mergeBundle(Bundle*& pbd,int bdid,int rev1,int rev2){ Bundle * pbd2=&bundles[bdid]; if(pbd->lengthlength){ 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; } } //加入一条路径来更新通道数据 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;igetBundleNodeByPoint(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; } vector > > resClip; vector > resBranchPoint; vector startBranchPoint; vector endBranchPoint; vector BundleConnectedToBranchPoint[MAXPointNum]; //连接到分支点的通道 int Out[N]; void printSingleBundle(int i,ofstream &ofs){ vector< pair >& partClip=resClip[i]; vector& partBranchPoint=resBranchPoint[i]; ofs<bundleNodeID; if(bid==150)cout<<(pb->Dis)<<" "<<(pb->position)<<" "<<(pb->pc2->name)<position)<(pb->Dis)); if(bdNode[bnid].rev==1){ cout<<"reverse"<reverse(); } ofs<referClip<<" "<position<