void MazeRouter::routePowerNet(oaInt4 nid) { //We assume that each contact that needs to connect to VDD can route directly up in Metal1. //We assume that each contact that needs to connect to VSS can route directly down in Metal1. //This appears reasonable with the given test cases, and the knowledge of P/N diffusion regions and normal CMOS logic. oaUInt4 dim_m, dim_n, dim_k = 0; __grid->getDims(&dim_m, &dim_n, &dim_k); //Metal 1 cannot be used to route vertically to VDD/VSS if it's direction is not V or B //Use metal 2 instead if that's the case //oaUInt4 layer = 0; //if(__rules->getMetal1Direction() == 'H') { // layer = 1; //} //cout << "In routePowerNet! dim_m = " << dim_m << " dim_n = " << dim_n << endl; //Weiche //Let's loop through all contacts that are on the net, and generate their routes one-by-one. for (oaInt4 i = 0; i < __contactCells[nid].size(); i++) { Cell* contact = __contactCells[nid][i]; oaUInt4 m,n,k = 0; contact->getPosition(&m, &n, &k); oaInt4 j = n; bool done = false; //if(layer == 1) { // contact->setNeedsVia(); //} //int nCellsInRail=11; //Weiche //int nCellsInRail=0; //Weiche while (!done) { //Iterate through cells until we hit a rail //cout<<"before at m="<<m<<" j="<<j<<" k="<<k<<endl; //Weiche Cell* curr = __grid->at(m,j,k); //Cell* curr = __grid->at(m,j,layer); //Cell* vdd_vss = __grid->at(m,j,k); //cout<<"after at m="<<m<<" j="<<j<<" k="<<k; //Weiche CellStatus status = curr->getStatus(); //CellStatus status2 = vdd_vss->getStatus(); oaUInt4 net_id = curr->getNetID(); //oaUInt4 net_id2 = vdd_vss->getNetID(); //Check cell underneath to see it it's vdd or vss /*if(layer == 1) { if(status2 == CellVDDRail && nid == VDD_NET_ID) { done = true; /*__grid->at(m,j+1,layer)->setBacktrace(__grid->at(m,j,layer)); __grid->at(m,j+2,layer)->setBacktrace(__grid->at(m,j+1,layer)); __grid->at(m,j+3,layer)->setBacktrace(__grid->at(m,j+2,layer)); __grid->at(m,j+4,layer)->setBacktrace(__grid->at(m,j+3,layer)); __grid->at(m,j+5,layer)->setBacktrace(__grid->at(m,j+4,layer)); __grid->at(m,j+5,0)->setBacktrace(__grid->at(m,j+5,layer)); __grid->at(m,j+5,0)->setNeedsVia(); vdd_vss->setNeedsVia(); vdd_vss->setBacktrace(curr); } else if(status2 == CellVSSRail && nid == VSS_NET_ID) { done = true; /*__grid->at(m,j-1,layer)->setBacktrace(__grid->at(m,j,layer)); __grid->at(m,j-2,layer)->setBacktrace(__grid->at(m,j-1,layer)); __grid->at(m,j-3,layer)->setBacktrace(__grid->at(m,j-2,layer)); __grid->at(m,j-4,layer)->setBacktrace(__grid->at(m,j-3,layer)); __grid->at(m,j-5,layer)->setBacktrace(__grid->at(m,j-4,layer)); __grid->at(m,j-5,0)->setBacktrace(__grid->at(m,j-5,layer)); __grid->at(m,j-5,0)->setNeedsVia(); vdd_vss->setNeedsVia(); vdd_vss->setBacktrace(curr); } }*/ switch (status) { case CellVDDRail: //cout<<" case CellVDDRail"<<endl; //Weiche if (nid == VDD_NET_ID) { /*if(nCellsInRail>0) //Weiche { curr->setStatus(CellFilled); curr->setNetType(contact->getNetType()); curr->setNetID(nid); nCellsInRail--; if(nCellsInRail==5) curr->setNeedsVia(); }*/ /*if(nCellsInRail==0){ //Weiche curr->setStatus(CellFilled); curr->setNetType(contact->getNetType()); curr->setNetID(nid); curr->setNeedsVia(); done = true; }*/ done = true; } else { cout << "Somehow hit the VDD rail while routing VSS!" << endl; __foundRoute = false; //__grid->print(); exit(1); } break; case CellVSSRail: //cout<<" case CellVSSRail"<<endl; //Weiche if (nid == VSS_NET_ID){ /*if(nCellsInRail>0) //Weiche { curr->setStatus(CellFilled); curr->setNetType(contact->getNetType()); curr->setNetID(nid); nCellsInRail--; if(nCellsInRail==5) curr->setNeedsVia(); }*/ /* if(nCellsInRail==0){ //Weiche curr->setStatus(CellFilled); curr->setNetType(contact->getNetType()); curr->setNetID(nid); curr->setNeedsVia(); done = true; }*/ done = true; } else { cout << "Somehow hit the VSS rail while routing VDD!" << endl; __foundRoute = false; //__grid->print(); exit(1); } break; case CellFilled: //cout<<" case CellFilled"<<endl; //Weiche case CellContact: //cout<<" case CellContact"<<endl; //Weiche if (net_id != nid) { //cout << "net_id = " << net_id << " nid = " << nid << endl; //Weiche cout << "We have a problem routing power net " << contact->getNetType() << "! We hit an occupied cell that wasn't ours. Here's the Grid." << endl; __foundRoute = false; //cout<<"m: "<<m<<", j: "<<j<<", k: "<<k<<endl; //Weiche //__grid->print(); exit(1); } break; case CellKeepout: //cout<<" case CellKeepout"<<endl; //Weiche cout << "We have a problem routing power net " << contact->getNetType() << "! We hit a keepout region. Here's the Grid." << endl; __foundRoute = false; __grid->print(); exit(1); break; case CellFree: //cout<<" case CellFree"<<endl; //Weiche curr->setStatus(CellFilled); curr->setNetType(contact->getNetType()); curr->setNetID(nid); break; } if (nid == VDD_NET_ID) { //create backtrace //if(i == 1) // curr->setBacktrace(__grid->at(m,j-1,k)); if (i > 0) curr->setBacktrace(__grid->at(m,j-1,k)); j++; } else { //create backtrace //if(i == 1) // curr->setBacktrace(__grid->at(m,j+1,k)); if (i > 0) curr->setBacktrace(__grid->at(m,j+1,k)); j--; } } } }
void Margolus::PareEnergyFull(Cell& cellIn, Cell& cellOut, double& energy) { // modifier & active in one cell for (pSub & subA : cellIn.GetSubs()) { if (subA->GetType() == ACTIVE) { for (pSub & subM : cellIn.GetSubs()) { if (subM->GetType() == MODIFIER) { energy += GetEnergyCell(subA->GetName(), subM->GetName()); } } } } // other if (cellOut.HaveSolid()) { if (cellIn.HaveModifier()) { for (pSub & subIn : cellIn.GetSubs()) { if (subIn->GetType() != ACTIVE) { energy += GetEnergy(subIn->GetName(), cellOut.GetSub(0)->GetName()); } } } else { for (pSub & subIn : cellIn.GetSubs()) { energy += GetEnergy(subIn->GetName(), cellOut.GetSub(0)->GetName()); } } } else { if (cellIn.HaveSolid()) { if (cellOut.HaveModifier()) { for (pSub & subOut : cellOut.GetSubs()) { if (subOut->GetType() != ACTIVE) { energy += GetEnergy(subOut->GetName(), cellIn.GetSub(0)->GetName()); } } } else { for (pSub & subOut : cellOut.GetSubs()) { energy += GetEnergy(subOut->GetName(), cellIn.GetSub(0)->GetName()); } } } else { for (pSub & subIn : cellIn.GetSubs()) { for (pSub & subOut : cellOut.GetSubs()) { energy += GetEnergy(subIn->GetName(), subOut->GetName()); } } } } }
//The core function which summarizes the data and forms the pivot table. void PivotMain::Summarize() { Map* myMap = d->selection->lastSheet()->map(); const QRect range3=d->selection->lastRange(); Sheet* sheet=myMap->createSheet("Filtered Sheet"); sheet=filter(); if(sheet==d->selection->lastSheet()) { d->filtersize=range3.bottom(); } const QRect range(1,1,d->selection->lastRange().right(),d->filtersize); QColor color,color2("lightGray"); color.setBlue(50); QPen pen(color); Style st,st2,st3,str,stl,stb,stt; st.setFontUnderline(true); st3.setBackgroundColor("lightGray"); st.setRightBorderPen(pen); st.setLeftBorderPen(pen); st.setTopBorderPen(pen); st.setBottomBorderPen(pen); str.setRightBorderPen(pen); stl.setLeftBorderPen(pen); stt.setTopBorderPen(pen); stb.setBottomBorderPen(pen); static int z=1; Sheet* mySheet=myMap->createSheet("Pivot Sheet"+QString::number(z++)); int r = range.right(); int row=range.top(); int bottom=range.bottom(); Cell cell; ValueConverter *c; Value res(0); ValueCalc *calc= new ValueCalc(c); QVector<Value> vect; for (int i = 1; i <= r; ++i) { cell= Cell(sheet,i,row); vect.append(Value(cell.value())); } d->func=d->mainWidget.selectOption->currentText();//check for the function to be performed //For Creating QLists for Rows,Columns,Values and PageField int counter; QListWidgetItem *item1; QList<QListWidgetItem *> rowList,columnList,valueList,pageList; counter= d->mainWidget.Rows->count(); for(int i=0;i<counter;i++) { item1=d->mainWidget.Rows->item(i); rowList.append(item1); } counter= d->mainWidget.Columns->count(); for(int i=0;i<counter;i++) { item1=d->mainWidget.Columns->item(i); columnList.append(item1); } /*counter= d->mainWidget.PageFields->count(); for(int i=0;i<counter;i++) { item1=d->mainWidget.PageFields->item(i); pageList.append(item1); }*/ counter= d->mainWidget.Values->count(); for(int i=0;i<counter;i++) { item1=d->mainWidget.Values->item(i); valueList.append(item1); } //Summarization using vectors int rowpos=-1,colpos=-1,valpos=-1; QVector<Value> rowVector; QVector<QVector<Value> > rowVectorArr(rowList.size()); QVector<QVector<Value> > columnVectorArr(columnList.size()); QVector<Value> columnVector,valueVector; QVector<int> rowposVect,colposVect,valposVect; for(int i=0;i<rowList.size();i++) { rowpos=vect.indexOf(Value(rowList.at(i)->text())); for(int j=row+1;j<=bottom;j++) { cell =Cell(sheet,rowpos+1,j); if(rowVector.contains(Value(cell.value()))==0) { rowVector.append(Value(cell.value())); rowVectorArr[i].append(Value(cell.value())); } } rowposVect.append(rowpos); } for(int i=0;i<columnList.size();i++) { colpos=vect.indexOf(Value(columnList.at(i)->text())); for(int j=row+1;j<=bottom;j++) { cell =Cell(sheet,colpos+1,j); if(columnVector.contains(Value(cell.value()))==0) { columnVector.append(Value(cell.value())); columnVectorArr[i].append(Value(cell.value())); } } colposVect.append(colpos); } int count=1,count2=0,prevcount=1; QVector<QVector<Value> > rowVect(rowposVect.count()); for(int i=0;i<rowposVect.count();i++) { for(int j=i+1;j<rowposVect.count();j++) { count*=rowVectorArr[j].count(); } for(int k=0;k<(rowVectorArr[i].count())*prevcount;k++) { Cell(mySheet,((k)*count)+1+colposVect.count(),i+1).setValue(rowVectorArr[i].at(k%rowVectorArr[i].count())); for(int l=0;l<count;l++) rowVect[i].append(rowVectorArr[i].at(k%rowVectorArr[i].count())); count2++; } prevcount=count2; count=1; count2=0; } count=1,count2=0,prevcount=1; QVector<QVector<Value> > colVect(colposVect.count()); for(int i=0;i<colposVect.count();i++) { for(int j=i+1;j<colposVect.count();j++) { count*=columnVectorArr[j].count(); } for(int k=0;k<(columnVectorArr[i].count())*prevcount;k++) { Cell(mySheet,i+1,((k)*count)+1+rowposVect.count()).setValue(columnVectorArr[i].at(k%columnVectorArr[i].count())); // Cell(mySheet,i+1,((k)*count)+1+rowposVect.count()).setStyle(st2); for(int l=0;l<count;l++) colVect[i].append(columnVectorArr[i].at(k%columnVectorArr[i].count())); count2++; } prevcount=count2; count=1; count2=0; } // Styling for(int m=0;m<colVect[0].count();m++) { Cell(mySheet,1,m+1+rowList.count()).setStyle(stl); Cell(mySheet,columnList.count(),m+1+rowList.count()).setStyle(str); Cell(mySheet,columnList.count()+rowVect[0].count(),m+1+rowList.count()).setStyle(str); } for(int m=0;m<rowVect[0].count();m++) { Cell(mySheet,m+1+columnList.count(),1).setStyle(stt); Cell(mySheet,m+1+columnList.count(),rowList.count()).setStyle(stb); Cell(mySheet,m+1+columnList.count(),rowList.count()+colVect[0].count()).setStyle(stb); } for(int m=0;m<rowList.count();m++) { Cell(mySheet,columnList.count()+1,m+1).setStyle(stl); Cell(mySheet,columnList.count()+rowVect[0].count(),m+1).setStyle(str); } for(int m=0;m<columnList.count();m++) { Cell(mySheet,m+1,rowList.count()+1).setStyle(stt); Cell(mySheet,m+1,rowList.count()+colVect[0].count()).setStyle(stb); } //Styling Done for(int i=0;i<valueList.size();i++) { valpos=vect.indexOf(Value(valueList.at(i)->text())); valposVect.append(valpos); } QString title=d->func + "-" + valueList.at(0)->text(); Cell(mySheet,1,1).setValue(Value(title)); Cell(mySheet,1,1).setStyle(st); for(int l=0;l<rowVect[0].count();l++) { for(int m=0;m<colVect[0].count();m++) { QVector<Value> aggregate; for(int k=row+1;k<=bottom;k++) { int flag=0; for(int i=0;i<rowposVect.count();i++) { for(int j=0;j<colposVect.count();j++) { if(!(Cell(sheet,rowposVect.at(i)+1,k).value()==rowVect[i].at(l) && Cell(sheet,colposVect.at(j)+1,k).value()==colVect[j].at(m))) flag=1; } } if(flag==0) aggregate.append(Cell(sheet,valpos+1,k).value()); } if(d->func!="average") calc->arrayWalk(aggregate,res,calc->awFunc(d->func),Value(0)); else { calc->arrayWalk(aggregate,res,calc->awFunc("sum"),Value(0)); if(aggregate.count()!=0) res=calc->div(res,aggregate.count()); } Cell(mySheet,l+colposVect.count()+1,m+rowposVect.count()+1).setValue(res); if(m%2==0) Cell(mySheet,l+colposVect.count()+1,m+rowposVect.count()+1).setStyle(st3); aggregate.clear(); res=Value(0); } } //For Adding the functions: Total Rows & Total Columns int colmult=1,rowmult=1; for(int x=0;x<columnList.size();x++) colmult*=columnVectorArr[x].count(); for(int x=0;x<rowList.size();x++) rowmult*=rowVectorArr[x].count(); //Totalling Columns if(d->mainWidget.TotalColumns->isChecked()) { Cell(mySheet,1,rowList.size()+colmult+1).setValue(Value("Total Column")); for(int z=columnList.size()+1;z<=rowmult+columnList.size();z++) { QVector<Value> vector; for(int y=rowList.size()+1;y<=colmult+rowList.size();y++) { vector.append(Cell(mySheet,z,y).value()); } if(d->func!="average") calc->arrayWalk(vector,res,calc->awFunc(d->func),Value(0)); else { calc->arrayWalk(vector,res,calc->awFunc("sum"),Value(0)); if(vector.count()!=0) res=calc->div(res,vector.count()); } Cell(mySheet,z,rowList.size()+colmult+1).setValue(res); res=Value(0); } } //Totalling Rows if(d->mainWidget.TotalRows->isChecked()) { Cell(mySheet,columnList.size()+rowmult+1,1).setValue(Value("Total Row")); for(int z=rowList.size()+1;z<=colmult+rowList.size();z++) { QVector<Value> vector; for(int y=columnList.size()+1;y<=rowmult+columnList.size();y++) { vector.append(Cell(mySheet,y,z).value()); } if(d->func!="average") calc->arrayWalk(vector,res,calc->awFunc(d->func),Value(0)); else { calc->arrayWalk(vector,res,calc->awFunc("sum"),Value(0)); if(vector.count()!=0) res=calc->div(res,vector.count()); } Cell(mySheet,columnList.size()+rowmult+1,z).setValue(res); res=Value(0); } } //Clearing Vectors rowVector.clear(); columnVector.clear(); valueVector.clear(); rowposVect.clear(); colposVect.clear(); valposVect.clear(); //Adding built sheet to myMap for viewing myMap->addSheet(mySheet); }//Summarize
double GlobalPlanner::getRisk(Cell & cell) { double risk = explorePenalty; if (occProb.find(cell) != occProb.end()) { risk = octomap::probability(occProb[cell]); } Cell front = Cell(cell.x()+1, cell.y(), cell.z()); Cell back = Cell(cell.x()-1, cell.y(), cell.z()); Cell right = Cell(cell.x(), cell.y()+1, cell.z()); Cell left = Cell(cell.x(), cell.y()-1, cell.z()); Cell up = Cell(cell.x(), cell.y(), cell.z()+1); Cell down = Cell(cell.x(), cell.y(), cell.z()-1); if (occProb.find(front) != occProb.end()) { risk += octomap::probability(occProb[front]); } if (occProb.find(back) != occProb.end()) { risk += octomap::probability(occProb[back]); } if (occProb.find(right) != occProb.end()) { risk += octomap::probability(occProb[right]); } if (occProb.find(left) != occProb.end()) { risk += octomap::probability(occProb[left]); } if (occProb.find(up) != occProb.end()) { risk += octomap::probability(occProb[up]); } if (occProb.find(down) != occProb.end()) { risk += octomap::probability(occProb[down]); } double prior = heightPrior[floor(cell.z())]; // ROS_INFO("risk: %f \t prior: %f \n", risk, prior); return risk * prior; }
double distance2D(const Cell & a, const Cell & b) { return sqrt(squared(a.x() - b.x()) + squared(a.y() - b.y())); }
bool MainWindow::updateConnections() { bool newconnection[BoardSize * BoardSize]; for(int i = 0; i < BoardSize * BoardSize; i++) newconnection[i] = false; CellList list; if(!root->isRotated()) { newconnection[root->index()] = true; list.append(root); } while(!list.isEmpty()) { Cell* cell = list.first(); Cell* ucell = uCell(cell); Cell* rcell = rCell(cell); Cell* dcell = dCell(cell); Cell* lcell = lCell(cell); if((cell->dirs() & Cell::U) && ucell && (ucell->dirs() & Cell::D) && !newconnection[ucell->index()] && !ucell->isRotated()) { newconnection[ucell->index()] = true; list.append(ucell); } if((cell->dirs() & Cell::R) && rcell && (rcell->dirs() & Cell::L) && !newconnection[rcell->index()] && !rcell->isRotated()) { newconnection[rcell->index()] = true; list.append(rcell); } if((cell->dirs() & Cell::D) && dcell && (dcell->dirs() & Cell::U) && !newconnection[dcell->index()] && !dcell->isRotated()) { newconnection[dcell->index()] = true; list.append(dcell); } if((cell->dirs() & Cell::L) && lcell && (lcell->dirs() & Cell::R) && !newconnection[lcell->index()] && !lcell->isRotated()) { newconnection[lcell->index()] = true; list.append(lcell); } list.removeFirst(); } bool isnewconnection = false; for(int i = 0; i < BoardSize * BoardSize; i++) { if(!board[i]->isConnected() && newconnection[i]) isnewconnection = true; board[i]->setConnected(newconnection[i]); } return isnewconnection; }
//----------------------------------------------------------------------------- std::size_t QuadrilateralCell::orientation(const Cell& cell) const { const Point up(0.0, 0.0, 1.0); return cell.orientation(up); }
Cell* Parser::Parse_Define(Cell* cell, bool topLevel) { UNUSED(topLevel); THROW_ERROR_IF(cell->Length() < 3, cell, "'define' does not take " << cell->Length() << " arguments"); // Example: (define (add a b) (+ a b)) // (define add (lambda (a b) (+ a b))) Cell* pParams = cell->Cdr()->Car(); Cell* pBody = cell->Cdr()->Cdr(); // (define (f args..) body) // Parse the arguments, if necessary, and call back into the Parse if (pParams->GetType() & Cell::PairType) { // f Cell* f = pParams->Car(); // (Args) Cell* args = pParams->Cdr(); // (define) Cell* pDefine = Cell::Pair(Cell::Symbol(Sym::Symbol("_define")), nullptr); // (lambda) Cell* pLambda = Cell::Pair(Cell::Symbol(Sym::Symbol("_lambda")), nullptr); // (lambda (args) pLambda = pLambda->Append(args); // (lambda (args) (body) // Body is a list of expressions. ((+ a a) ...) while (pBody && pBody->Car()) { pLambda = pLambda->Append(pBody->Car()); pBody = pBody->Cdr(); } // (define f) pDefine = pDefine->Append(f); // (define f (lamda ...)) pDefine = pDefine->Append(pLambda); return Parse_Cell(pDefine); } // A parsed define, ready to store else { THROW_ERROR_IF(cell->Length()!= 3, cell, "'define' does not take " << cell->Length() << " arguments"); THROW_ERROR_IF(!(pParams->GetType() & Cell::SymbolType), cell, "Expected Symbol in define"); pBody = Parse_Cell(pBody->Car()); // (define) Cell* pDefine = Cell::Pair(Cell::Symbol(Sym::Symbol("_define")), nullptr); // (define (params) pDefine = pDefine->Append(pParams); // (define (params) (pBody)) pDefine = pDefine->Append(pBody); return pDefine; } }
void Random::doorCell(Cell &cell) { cell.dungeonFloorA(); }
bool MazeRouter::route() { __foundRoute = true; //assume true until we find an issue cout << "Special routing power nets..." << endl; //cout << "Special routing power nets: " << VDD_NET_ID << " for VDD and " << VSS_NET_ID << " for VSS." << endl; //Weiche routePowerNet(VDD_NET_ID); routePowerNet(VSS_NET_ID); //Single-contact IO nets: special case. No routing, only pin needed, but it gets high priority. cout << "Generating pins for single-contact IO nets..." << endl; __grid->reset(); for (oaInt4 net = 2; net < __contactCells.size(); net++) { if (__contactCells[net][0]->getNetType() == "IO" && __contactCells[net].size() == 1) { oaUInt4 m,n,k = 0; Cell* c = __contactCells[net][0]; c->getPosition(&m,&n,&k); //We want to do this at the contact M1, since M2 pins are not required. //Propagate pin name (used later in creating text label)) __grid->at(m,n,k)->setPin(true); __grid->at(m,n,k)->setPinName(c->getPinName()); } } //Multi-contact IO nets. Need routing. Choose pin location after routing is done cout << "Maze routing multi-contact IO nets..." << endl; for (oaInt4 net = 2; net < __contactCells.size(); net++) { if (__contactCells[net][0]->getNetType() == "IO" && __contactCells[net].size() > 1) { //Clean reset for each net __grid->reset(); generateKeepouts(net); //Basic approach: route from contact to contact in order of appearance. for (oaInt4 contactIndex = 0; contactIndex < __contactCells[net].size()-1; contactIndex++) { __grid->softReset(); //Preserve keepouts during soft reset so we don't waste time recomputing them if (contactIndex == 0) //set pin during first segment mazeRoute(net, contactIndex+1, contactIndex, true); else mazeRoute(net, contactIndex+1, contactIndex, false); } /* //Yasmine's "better" approach: route between closest pairs of contacts first. You are welcome to try this. Disabled by default. //Get closest pairs vector<ClosestPairIndices> closestPairs; closestPairs=ClosestPairIndices::getClosestPairs(__contactCells[net]); int nPairs=closestPairs.size(); for (oaInt4 pairIndex = 0; pairIndex <nPairs; pairIndex++) { __grid->softReset(); //Preserve keepouts during soft reset so we don't waste time recomputing them if (pairIndex == 0) //set pin during first segment mazeRoute(net, closestPairs[pairIndex].getIndex1(), closestPairs[pairIndex].getIndex2(), true); else mazeRoute(net, closestPairs[pairIndex].getIndex1(), closestPairs[pairIndex].getIndex2(), false); } */ } } //Multi-contact S nets, no pins needed. cout << "Maze routing S nets..." << endl; for (oaInt4 net = 2; net < __contactCells.size(); net++) { //Mark: perhaps change this to order by HPWL bounding box of nets? Smallest first? //Reset the grid weights, distances, sources, and sinks. Clear any keepout cells that were leftover from a previous maze route. if (__contactCells[net][0]->getNetType() == "S") { //Clean reset for each net __grid->reset(); generateKeepouts(net); //Generate keepouts for all nets OTHER than this one! for (oaInt4 contactIndex = 0; contactIndex < __contactCells[net].size()-1; contactIndex++) { __grid->softReset(); mazeRoute(net, contactIndex+1, contactIndex, false); //Assume we always have >=2 pins for this net type, otherwise it wouldn't even make sense. } /* //Yasmine's "better" approach: route between closest pairs of contacts first. You are welcome to try this. Disabled by default. vector<ClosestPairIndices> closestPairs; closestPairs=ClosestPairIndices::getClosestPairs(__contactCells[net]); int nPairs=closestPairs.size(); for (oaInt4 pairIndex = 0; pairIndex <nPairs; pairIndex++) { __grid->softReset(); //Preserve keepouts during soft reset so we don't waste time recomputing them mazeRoute(net, closestPairs[pairIndex].getIndex1(), closestPairs[pairIndex].getIndex2(), false); } */ } } __grid->reset(); //__grid->print(); return __foundRoute; }
bool Cell::operator==(const Cell& other) const { return ((coordinateX == other.getX()) && (coordinateY == other.getY())); }
void MazeRouter::generateKeepout(Cell* c) { oaUInt4 mtmp,ntmp,ktmp = 0; oaInt4 m,n,k = 0; oaUInt4 dim_m, dim_n, dim_k = 0; c->getPosition(&mtmp,&ntmp,&ktmp); m = mtmp; n = ntmp; k = ktmp; __grid->getDims(&dim_m, &dim_n, &dim_k); oaInt4 leftBound = 0; oaInt4 rightBound = 0; oaInt4 topBound = 0; oaInt4 bottomBound = 0; Cell* tmp = NULL; CellStatus tmpStatus; CellStatus cStatus = c->getStatus(); //SET LATERAL AND LONGITUDINAL BOUNDS DEPENDING ON LAYER AND LINE END STATUS if (k == 0) { //metal1 if(__rules->getMetal1Direction() == 'V') { //vertical only leftBound = m-__keepoutRadius_lateral; if (leftBound < 0) leftBound = 0; rightBound = m+__keepoutRadius_lateral; if (rightBound > dim_m-1) rightBound = dim_m-1; //check line end top condition if (n+1 < dim_n) { tmp = __grid->at(m,n+1,k); //get cell above tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end topBound = n; else { //line end if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail topBound = n+__keepoutRadius_powerRail; else //cell of interest is regular net topBound = n+__keepoutRadius_longitudinal; } if (topBound > dim_n-1) topBound = dim_n-1; } //check line end bottom condition if (n-1 >= 0) { tmp = __grid->at(m,n-1,k); //get cell below tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end bottomBound = n; else { //line end if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail bottomBound = n-__keepoutRadius_powerRail; else //cell of interest is regular net bottomBound = n-__keepoutRadius_longitudinal; } if (bottomBound < 0) bottomBound = 0; } } else if(__rules->getMetal1Direction() == 'H') { //horizontal only bottomBound = n-__keepoutRadius_lateral; if (bottomBound < 0) bottomBound = 0; topBound = n+__keepoutRadius_lateral; if (topBound > dim_n-1) topBound = dim_n-1; //check line end right condition if (m+1 < dim_m) { tmp = __grid->at(m+1,n,k); //get cell to right tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end rightBound = m; else //line end rightBound = m+__keepoutRadius_longitudinal; if (rightBound > dim_m-1) rightBound = dim_m-1; } //check line end left condition if (m-1 >= 0) { tmp = __grid->at(m-1,n,k); //get cell to left tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end leftBound = m; else //line end leftBound = m-__keepoutRadius_longitudinal; if (leftBound < 0) leftBound = 0; } } else { //bidirectional Cell* tmptop; Cell* tmpbottom; Cell* tmpleft; Cell* tmpright; CellStatus tmptops; CellStatus tmpbottoms; CellStatus tmplefts; CellStatus tmprights; bool isVertical = false; //check cell above if (n + 1 < dim_n) { tmptop = __grid->at(m, n + 1, k); tmptops = tmptop->getStatus(); if (tmptops == CellFilled || tmptops == CellContact){ //not line end topBound = n; isVertical = true; } else { //line end if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail topBound = n + __keepoutRadius_powerRail; else //regular cell topBound = n + __keepoutRadius_longitudinal; } if (topBound > dim_n - 1) topBound = dim_n - 1; } //check cell below if (n - 1 >= 0) { tmpbottom = __grid->at(m, n - 1, k); tmpbottoms = tmpbottom->getStatus(); if (tmpbottoms == CellFilled || tmpbottoms == CellContact){ //not line end bottomBound = n; isVertical = true; } else { //line end if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail bottomBound = n - __keepoutRadius_powerRail; else bottomBound = n - __keepoutRadius_longitudinal; } if (bottomBound < 0) bottomBound = 0; } //Vertical segment - bounds on left and right sides if (isVertical) { //left side if (m - 1 >= 0) { tmpleft = __grid->at(m - 1, n, k); tmplefts = tmpleft->getStatus(); if (tmplefts == CellFilled || tmplefts == CellContact) { //right corner connecting vertical and horizontal segments leftBound = m; } else { //left side is empty leftBound = m - __keepoutRadius_lateral; if (leftBound < 0) leftBound = 0; } } //right side if (m + 1 < dim_m) { tmpright = __grid->at(m + 1, n, k); tmprights = tmpright->getStatus(); if (tmprights == CellFilled || tmprights == CellContact) { //left corner connecting vertical and horizontal segments rightBound = m; } else { //right side is empty rightBound = m + __keepoutRadius_lateral; if (rightBound > dim_m - 1) rightBound = dim_m - 1; } } } //if not verical then it's horizontal if (!isVertical) { if (m - 1 >= 0) { tmpleft = __grid->at(m - 1, n, k); tmplefts = tmpleft->getStatus(); if (tmplefts == CellFilled || tmplefts == CellContact) //not line end leftBound = m; else //line end leftBound = m - __keepoutRadius_longitudinal; if (leftBound < 0) leftBound = 0; } if (m + 1 < dim_m) { tmpright = __grid->at(m + 1, n, k); tmprights = tmpright->getStatus(); if (tmprights == CellFilled || tmprights == CellContact) //not line end rightBound = m; else //line end rightBound = m + __keepoutRadius_longitudinal; if (rightBound > dim_m - 1) rightBound = dim_m - 1; } topBound = n + __keepoutRadius_lateral; if (topBound > dim_n - 1) topBound = dim_n - 1; bottomBound = n - __keepoutRadius_lateral; if (bottomBound < 0) bottomBound = 0; } } } if (k == 1) { //metal2 if(__rules->getMetal2Direction() == 'V') { //vertical only leftBound = m-__keepoutRadius_lateral; if (leftBound < 0) leftBound = 0; rightBound = m+__keepoutRadius_lateral; if (rightBound > dim_m-1) rightBound = dim_m-1; //check line end top condition if (n+1 < dim_n) { tmp = __grid->at(m,n+1,k); //get cell above tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end topBound = n; else { //line end if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail topBound = n+__keepoutRadius_powerRail; else //cell of interest is regular net topBound = n+__keepoutRadius_longitudinal; } if (topBound > dim_n-1) topBound = dim_n-1; } //check line end bottom condition if (n-1 >= 0) { tmp = __grid->at(m,n-1,k); //get cell below tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end bottomBound = n; else { //line end if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail bottomBound = n-__keepoutRadius_powerRail; else //cell of interest is regular net bottomBound = n-__keepoutRadius_longitudinal; } if (bottomBound < 0) bottomBound = 0; } } else if(__rules->getMetal2Direction() == 'H') { //horizontal only bottomBound = n-__keepoutRadius_lateral; if (bottomBound < 0) bottomBound = 0; topBound = n+__keepoutRadius_lateral; if (topBound > dim_n-1) topBound = dim_n-1; //check line end right condition if (m+1 < dim_m) { tmp = __grid->at(m+1,n,k); //get cell to right tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end rightBound = m; else //line end rightBound = m+__keepoutRadius_longitudinal; if (rightBound > dim_m-1) rightBound = dim_m-1; } //check line end left condition if (m-1 >= 0) { tmp = __grid->at(m-1,n,k); //get cell to left tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end leftBound = m; else //line end leftBound = m-__keepoutRadius_longitudinal; if (leftBound < 0) leftBound = 0; } } else if(__rules->getMetal2Direction() == 'B') { //bidirectional Cell* tmptop; Cell* tmpbottom; Cell* tmpleft; Cell* tmpright; CellStatus tmptops; CellStatus tmpbottoms; CellStatus tmplefts; CellStatus tmprights; bool isVertical = false; //top if (n + 1 < dim_n) { tmptop = __grid->at(m, n + 1, k); tmptops = tmptop->getStatus(); if (tmptops == CellFilled || tmptops == CellContact){ //not line end topBound = n; isVertical = true; } else { //line end if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail topBound = n + __keepoutRadius_powerRail; else //regular cell topBound = n + __keepoutRadius_longitudinal; } if (topBound > dim_n - 1) topBound = dim_n - 1; } //bottom if (n - 1 >= 0) { tmpbottom = __grid->at(m, n - 1, k); tmpbottoms = tmpbottom->getStatus(); if (tmpbottoms == CellFilled || tmpbottoms == CellContact){ //not line end bottomBound = n; isVertical = true; } else { //line end if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail bottomBound = n - __keepoutRadius_powerRail; else bottomBound = n - __keepoutRadius_longitudinal; } if (bottomBound < 0) bottomBound = 0; } //Vertical segment - bounds on left and right sides if (isVertical) { //left side if (m - 1 >= 0) { tmpleft = __grid->at(m - 1, n, k); tmplefts = tmpleft->getStatus(); if (tmplefts == CellFilled || tmplefts == CellContact) { //right corner connecting vertical and horizontal segments leftBound = m; } else { //left side is empty leftBound = m - __keepoutRadius_lateral; if (leftBound < 0) leftBound = 0; } } //right side if (m + 1 < dim_m) { tmpright = __grid->at(m + 1, n, k); tmprights = tmpright->getStatus(); if (tmprights == CellFilled || tmprights == CellContact) { //left corner connecting vertical and horizontal segments rightBound = m; } else { //right side is empty rightBound = m + __keepoutRadius_lateral; if (rightBound > dim_m - 1) rightBound = dim_m - 1; } } } //if not verical then it's horizontal if (!isVertical) { if (m - 1 >= 0) { tmpleft = __grid->at(m - 1, n, k); tmplefts = tmpleft->getStatus(); if (tmplefts == CellFilled || tmplefts == CellContact) //not line end leftBound = m; else //line end leftBound = m - __keepoutRadius_longitudinal; if (leftBound < 0) leftBound = 0; } if (m + 1 < dim_m) { tmpright = __grid->at(m + 1, n, k); tmprights = tmpright->getStatus(); if (tmprights == CellFilled || tmprights == CellContact) //not line end rightBound = m; else //line end rightBound = m + __keepoutRadius_longitudinal; if (rightBound > dim_m - 1) rightBound = dim_m - 1; } topBound = n + __keepoutRadius_lateral; if (topBound > dim_n - 1) topBound = dim_n - 1; bottomBound = n - __keepoutRadius_lateral; if (bottomBound < 0) bottomBound = 0; } } } if (k == 2) { //metal3 if(__rules->getMetal3Direction() == 'V') { //vertical only leftBound = m-__keepoutRadius_lateral; if (leftBound < 0) leftBound = 0; rightBound = m+__keepoutRadius_lateral; if (rightBound > dim_m-1) rightBound = dim_m-1; //check line end top condition if (n+1 < dim_n) { tmp = __grid->at(m,n+1,k); //get cell above tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end topBound = n; else { //line end if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail topBound = n+__keepoutRadius_powerRail; else //cell of interest is regular net topBound = n+__keepoutRadius_longitudinal; } if (topBound > dim_n-1) topBound = dim_n-1; } //check line end bottom condition if (n-1 >= 0) { tmp = __grid->at(m,n-1,k); //get cell below tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end bottomBound = n; else { //line end if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail bottomBound = n-__keepoutRadius_powerRail; else //cell of interest is regular net bottomBound = n-__keepoutRadius_longitudinal; } if (bottomBound < 0) bottomBound = 0; } } else if(__rules->getMetal3Direction() == 'H') { //horizontal only bottomBound = n-__keepoutRadius_lateral; if (bottomBound < 0) bottomBound = 0; topBound = n+__keepoutRadius_lateral; if (topBound > dim_n-1) topBound = dim_n-1; //check line end right condition if (m+1 < dim_m) { tmp = __grid->at(m+1,n,k); //get cell to right tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end rightBound = m; else //line end rightBound = m+__keepoutRadius_longitudinal; if (rightBound > dim_m-1) rightBound = dim_m-1; } //check line end left condition if (m-1 >= 0) { tmp = __grid->at(m-1,n,k); //get cell to left tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end leftBound = m; else //line end leftBound = m-__keepoutRadius_longitudinal; if (leftBound < 0) leftBound = 0; } } else if(__rules->getMetal3Direction() == 'B') { //bidirectional leftBound = m-__keepoutRadius_lateral; if (leftBound < 0) leftBound = 0; rightBound = m+__keepoutRadius_lateral; if (rightBound > dim_m-1) rightBound = dim_m-1; //check line end top condition if (n+1 < dim_n) { tmp = __grid->at(m,n+1,k); //get cell above tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end topBound = n; else { //line end if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail topBound = n+__keepoutRadius_powerRail; else //cell of interest is regular net topBound = n+__keepoutRadius_longitudinal; } if (topBound > dim_n-1) topBound = dim_n-1; } //check line end bottom condition if (n-1 >= 0) { tmp = __grid->at(m,n-1,k); //get cell below tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end bottomBound = n; else { //line end if (cStatus == CellVDDRail || cStatus == CellVSSRail) //cell of interest is power rail bottomBound = n-__keepoutRadius_powerRail; else //cell of interest is regular net bottomBound = n-__keepoutRadius_longitudinal; } if (bottomBound < 0) bottomBound = 0; } bottomBound = n-__keepoutRadius_lateral; if (bottomBound < 0) bottomBound = 0; topBound = n+__keepoutRadius_lateral; if (topBound > dim_n-1) topBound = dim_n-1; //check line end right condition if (m+1 < dim_m) { tmp = __grid->at(m+1,n,k); //get cell to right tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end rightBound = m; else //line end rightBound = m+__keepoutRadius_longitudinal; if (rightBound > dim_m-1) rightBound = dim_m-1; } //check line end left condition if (m-1 >= 0) { tmp = __grid->at(m-1,n,k); //get cell to left tmpStatus = tmp->getStatus(); if (tmpStatus == CellFilled || tmpStatus == CellContact) //not line end leftBound = m; else //line end leftBound = m-__keepoutRadius_longitudinal; if (leftBound < 0) leftBound = 0; } } } oaInt4 newBottom = bottomBound; oaInt4 newRight = rightBound; oaInt4 newLeft = leftBound; oaInt4 newTop = topBound; oaInt4 increase = 10; oaInt4 decrease = 10; if(k == 0 && __rules->getMetal1Direction() == 'B') { newBottom -= decrease; newRight += increase; newLeft -= decrease; newTop += increase; } else if(k == 1 && __rules->getMetal2Direction() == 'B') { newBottom -= decrease; newRight += increase; newLeft -= decrease; newTop += increase; } else if(k == 2 && __rules->getMetal3Direction() == 'B') { newBottom -= decrease; newRight += increase; newLeft -= decrease; newTop += increase; } if (newTop > dim_n-1) newTop = dim_n-1; if (newRight > dim_m-1) newRight = dim_m-1; if (newBottom < 0) newBottom = 0; if (newLeft < 0) newLeft = 0; /*for (oaInt4 j = topBound; j >= bottomBound; j--) { for (oaInt4 i = leftBound; i <= rightBound; i++) { tmp = __grid->at(i,j,k); if (tmp->getStatus() == CellFree) { tmp->setStatus(CellKeepout); } } }*/ for (oaInt4 j = newTop; j >= newBottom; j--) { for (oaInt4 i = newLeft; i <= newRight; i++) { tmp = __grid->at(i,j,k); if (tmp->getStatus() == CellFree) { tmp->setStatus(CellKeepout); } } } }
void MazeRouter::doBacktrace(Cell* source, Cell* sink, bool setPin) { Cell* curr = sink; Cell* tmp = NULL; oaUInt4 currm,currn,currk = 0; oaUInt4 tmpm,tmpn,tmpk = 0; //Handle pin if (setPin) { curr->getPosition(&currm,&currn,&currk); tmp = curr->getBacktrace(); tmp->getPosition(&tmpm,&tmpn,&tmpk); if (currm == tmpm && currn == tmpn && currk == (tmpk+1)%2) { //backtrace is above the contact, set pin on M2 (the backtraced cell). tmp->setPin(true); tmp->setPinName(source->getPinName()); } else { //set pin on the contact (sink) curr->setPin(true); } } // backtrace sink to source curr = sink; tmp = curr; while (tmp != source) { if (curr->getStatus() == CellFree) { curr->setStatus(CellFilled); curr->setNetID(source->getNetID()); curr->setNetType(source->getNetType()); } //check if we need a via. oaInt4 currm_dbu, currn_dbu = 0; oaInt4 tmpm_dbu, tmpn_dbu = 0; curr->getPosition(&currm, &currn, &currk); curr->getAbsolutePosition(&currm_dbu,&currn_dbu); tmp->getPosition(&tmpm,&tmpn,&tmpk); tmp->getAbsolutePosition(&tmpm_dbu,&tmpn_dbu); if (currk == 0 && tmpk == 1) { //change from layer 1 to layer 0 //set via on curr, which is M1. curr->setNeedsVia(); cout << "Via needed at cell (" << currm << "," << currn << "," << currk << ") ---> (" << currm_dbu << "," << currn_dbu << ")" << endl; } else if (currk == 1 && tmpk == 0) { //change from layer 0 to layer 1 //set via on tmp, which is M1. tmp->setNeedsVia(); cout << "Via needed at cell (" << tmpm << "," << tmpn << "," << tmpk << ") ---> (" << tmpm_dbu << "," << tmpn_dbu << ")" << endl; } else if (currk == 1 && tmpk == 2) { //change from layer 2 to layer 1 //set via on curr, which is M2. curr->setNeedsVia(); cout << "Via needed at cell (" << currm << "," << currn << "," << currk << ") ---> (" << currm_dbu << "," << currn_dbu << ")" << endl; } else if (currk == 2 && tmpk == 1) { //change from layer 1 to layer 2 //set via on tmp, which is M2. tmp->setNeedsVia(); cout << "Via needed at cell (" << tmpm << "," << tmpn << "," << tmpk << ") ---> (" << tmpm_dbu << "," << tmpn_dbu << ")" << endl; } else if (currk == 0 && tmpk == 2) { //change from layer 2 to layer 0 //set via on curr, which is M1. curr->setNeedsVia(); Cell * temp = __grid->at(currm, currn, (currk+1)); CellStatus tempStatus = temp->getStatus(); //if(tempStatus == CellFree) temp->setStatus(CellFilled); temp->setNeedsVia(); cout << "Via needed at cell (" << currm << "," << currn << "," << currk << ") ---> (" << currm_dbu << "," << currn_dbu << ")" << endl; cout << "Via needed at cell (" << currm << "," << currn << "," << currk+1 << ") ---> (" << currm_dbu << "," << currn_dbu << ")" << endl; cout << "temp->needsVia(): " << temp->needsVia() << endl; } else if (currk == 2 && tmpk == 0) { //change from layer 0 to layer 2 //set via on tmp, which is M1. tmp->setNeedsVia(); Cell * temp = __grid->at(currm, currn, (currk-1)); CellStatus tempStatus = temp->getStatus(); //if(tempStatus == CellFree) temp->setStatus(CellFilled); temp->setNeedsVia(); cout << "Via needed at cell (" << tmpm << "," << tmpn << "," << tmpk << ") ---> (" << tmpm_dbu << "," << tmpn_dbu << ")" << endl; cout << "Via needed at cell (" << currm << "," << currn << "," << currk-1 << ") ---> (" << currm_dbu << "," << currn_dbu << ")" << endl; cout << "temp->needsVia(): " << temp->needsVia() << endl; } tmp = curr; curr = curr->getBacktrace(); } }
void MazeRouter::mazeRoute(oaUInt4 netID, oaInt4 contactIndex0, oaInt4 contactIndex1, bool setPin) { //Lee's algorithm //First, choose two endpoints to connect, and set them as source and sink. Cell* source = __contactCells[netID][contactIndex0]; Cell* sink = __contactCells[netID][contactIndex1]; source->setIsRouted(); source->setSource(true); sink->setSink(true); oaUInt4 sourcem, sourcen, sourcek = 0; oaInt4 sourceNetID = source->getNetID(); oaUInt4 sinkm, sinkn, sinkk = 0; source->getPosition(&sourcem,&sourcen,&sourcek); sink->getPosition(&sinkm,&sinkn,&sinkk); //cout<<"source m: "<<(int)sourcem<<" sourcen "<<(int)sourcen<<endl; //Weiche //Next, initialize our plist and nlist (two adjacent BFS wavefronts) vector<Cell*> plist; vector<Cell*> nlist; vector<Cell*> neighbors; bool path_exists = false; oaUInt4 dist = 0; Cell* curr = NULL; oaUInt4 m,n,k = 0; oaUInt4 dim_m, dim_n, dim_k = 0; __grid->getDims(&dim_m,&dim_n,&dim_k); plist.push_back(source); //we start with the source only. while (plist.size() > 0 && !path_exists) { //One wave for (int p = 0; p < plist.size(); p++) { curr = plist[p]; //Iterate over neighbors of curr curr->getPosition(&m,&n,&k); neighbors.clear(); if (k == 0) { //bottom layer, M1, route vertically only if(__rules->getMetal1Direction() == 'V') { //vertical only if (n-1 >= 0) neighbors.push_back(__grid->at(m,n-1,k)); if (n+1 < dim_n) neighbors.push_back(__grid->at(m,n+1,k)); } else if(__rules->getMetal1Direction() == 'H') { //horizontal only if (m-1 >= 0) neighbors.push_back(__grid->at(m-1,n,k)); if (m+1 < dim_m) neighbors.push_back(__grid->at(m+1,n,k)); } else if(__rules->getMetal1Direction() == 'B') { //bidirectional if (m-1 >= 0) neighbors.push_back(__grid->at(m-1,n,k)); if (m+1 < dim_m) neighbors.push_back(__grid->at(m+1,n,k)); if (n-1 >= 0) neighbors.push_back(__grid->at(m,n-1,k)); if (n+1 < dim_n) neighbors.push_back(__grid->at(m,n+1,k)); } neighbors.push_back(__grid->at(m,n,1)); if(num_of_layers == 3) neighbors.push_back(__grid->at(m,n,2)); } else if(k == 1){ //M2 if(__rules->getMetal2Direction() == 'V') { //vertial only if (n-1 >= 0) neighbors.push_back(__grid->at(m,n-1,k)); if (n+1 < dim_n) neighbors.push_back(__grid->at(m,n+1,k)); } else if(__rules->getMetal2Direction() == 'H') { //horizontal only if (m-1 >= 0) neighbors.push_back(__grid->at(m-1,n,k)); if (m+1 < dim_m) neighbors.push_back(__grid->at(m+1,n,k)); } else if(__rules->getMetal2Direction() == 'B') { //bidirectional if (n-1 >= 0) neighbors.push_back(__grid->at(m,n-1,k)); if (n+1 < dim_n) neighbors.push_back(__grid->at(m,n+1,k)); if (m-1 >= 0) neighbors.push_back(__grid->at(m-1,n,k)); if (m+1 < dim_m) neighbors.push_back(__grid->at(m+1,n,k)); } neighbors.push_back(__grid->at(m,n,0)); if(num_of_layers == 3) neighbors.push_back(__grid->at(m,n,2)); } else if(k == 2){ //M3 if(__rules->getMetal3Direction() == 'V') { //vertial only if (n-1 >= 0) neighbors.push_back(__grid->at(m,n-1,k)); if (n+1 < dim_n) neighbors.push_back(__grid->at(m,n+1,k)); } else if(__rules->getMetal3Direction() == 'H') { //horizontal only if (m-1 >= 0) neighbors.push_back(__grid->at(m-1,n,k)); if (m+1 < dim_m) neighbors.push_back(__grid->at(m+1,n,k)); } else if(__rules->getMetal3Direction() == 'B') { //bidirectional if (n-1 >= 0) neighbors.push_back(__grid->at(m,n-1,k)); if (n+1 < dim_n) neighbors.push_back(__grid->at(m,n+1,k)); if (m-1 >= 0) neighbors.push_back(__grid->at(m-1,n,k)); if (m+1 < dim_m) neighbors.push_back(__grid->at(m+1,n,k)); } neighbors.push_back(__grid->at(m,n,1)); neighbors.push_back(__grid->at(m,n,0)); } Cell* next = NULL; CellStatus nextstatus; oaInt4 netID = -1; for (int d = 0; d < neighbors.size(); d++) { next = neighbors[d]; nextstatus = next->getStatus(); netID = next->getNetID(); if (!next->touched() && //cell must NOT be touched and... (nextstatus == CellFree || //free, or ((nextstatus == CellFilled || nextstatus == CellContact) && //filled or contact, and... netID == sourceNetID))) { //same net ID as source. next->touch(); next->setDistance(dist+1); next->setBacktrace(curr); nlist.push_back(next); if (next->isSink()) { //HURRAY WE FOUND IT path_exists = true; } /* //test by Yasmine: enough to touch any of cells of this net unsigned int hSrc,vSrc,lSrc, hNext,vNext,lNext, hCurr,vCurr,lCurr; source->getPosition(&hSrc,&vSrc,&lSrc); curr->getPosition(&hCurr,&vCurr,&lCurr); next->getPosition(&hNext,&vNext, &lNext); if(hNext==hSrc//vertically aligned && lNext==lSrc//same layer && lSrc==lCurr//same layer (no via just before the reached cell) && lNext==0)//heuristic to try to favor keeping on M1 layer { if(((nextstatus==CellFilled)//filled or contact but already routed ||(nextstatus==CellContact && (next->isRouted()))) && netID==sourceNetID && next!=source) { path_exists=true; sink=next; } } //end test */ } } } dist++; plist = nlist; nlist.clear(); } if (path_exists) { #ifdef DEBUG cout << "Found a path from Cell (" << sourcem << "," << sourcen << "," << sourcek << ") to (" << sinkm << "," << sinkn << "," << sinkk << ")" << endl; #endif doBacktrace(source, sink, setPin); } else { cout << "DID NOT find a path from Cell (" << sourcem << "," << sourcen << "," << sourcek << ") to (" << sinkm << "," << sinkn << "," << sinkk << ")" << endl; __foundRoute = false; } }
bool MergeCommand::preProcessing() { if (isColumnOrRowSelected()) { KMessageBox::information(0, i18n("Merging of columns or rows is not supported.")); return false; } if (m_firstrun) { setText(name()); // reduce the region to the region occupied by merged cells Region mergedCells; ConstIterator endOfList = constEnd(); for (ConstIterator it = constBegin(); it != endOfList; ++it) { Element* element = *it; QRect range = element->rect(); int right = range.right(); int bottom = range.bottom(); for (int row = range.top(); row <= bottom; ++row) { for (int col = range.left(); col <= right; ++col) { Cell cell = Cell(m_sheet, col, row); if (cell.doesMergeCells()) { QRect rect(col, row, cell.mergedXCells() + 1, cell.mergedYCells() + 1); mergedCells.add(rect); } } } } if (m_merge) { // MergeCommand // we're in the manipulator's first execution // initialize the undo manipulator m_unmerger = new MergeCommand(); if (!m_mergeHorizontal && !m_mergeVertical) { m_unmerger->setReverse(true); } m_unmerger->setSheet(m_sheet); m_unmerger->setRegisterUndo(false); m_unmerger->add(mergedCells); } else { // DissociateManipulator clear(); add(mergedCells); } } if (m_merge) { // MergeCommand if (m_reverse) { // dissociate } else { // merge // Dissociate cells before merging the whole region. // For horizontal/vertical merging the cells stay // as they are. E.g. the region contains a merged cell // occupying two rows. Then the horizontal merge should // keep the height of two rows and extend the merging to the // region's width. In this case the unmerging is done while // processing each region element. if (!m_mergeHorizontal && !m_mergeVertical) { m_unmerger->redo(); } } } // Clear the associated selection, if any. The merge/dissociate process will restore // selections. This ensures that the selection isn't broken after merging. if (m_selection) m_selection->Region::clear(); return AbstractRegionCommand::preProcessing(); }
void Random::wallItemCell(Cell &cell) { cell.dungeonWallA(); }
bool MergeCommand::process(Element* element) { if (element->type() != Element::Range || element->isRow() || element->isColumn()) { // TODO Stefan: remove these elements?! return true; } // sanity check if (m_sheet->isProtected() || m_sheet->map()->isProtected()) { return false; } QRect range = element->rect(); int left = range.left(); int right = range.right(); int top = range.top(); int bottom = range.bottom(); int height = range.height(); int width = range.width(); bool doMerge = m_reverse ? (!m_merge) : m_merge; if (doMerge) { if (m_mergeHorizontal) { for (int row = top; row <= bottom; ++row) { int rows = 0; for (int col = left; col <= right; ++col) { Cell cell = Cell(m_sheet, col, row); if (cell.doesMergeCells()) { rows = qMax(rows, cell.mergedYCells()); cell.mergeCells(col, row, 0, 0); } } Cell cell = Cell(m_sheet, left, row); if (!cell.isPartOfMerged()) { cell.mergeCells(left, row, width - 1, rows); } } } else if (m_mergeVertical) { for (int col = left; col <= right; ++col) { int cols = 0; for (int row = top; row <= bottom; ++row) { Cell cell = Cell(m_sheet, col, row); if (cell.doesMergeCells()) { cols = qMax(cols, cell.mergedXCells()); cell.mergeCells(col, row, 0, 0); } } Cell cell = Cell(m_sheet, col, top); if (!cell.isPartOfMerged()) { cell.mergeCells(col, top, cols, height - 1); } } } else { Cell cell = Cell(m_sheet, left, top); cell.mergeCells(left, top, width - 1, height - 1); } } else { // dissociate for (int col = left; col <= right; ++col) { for (int row = top; row <= bottom; ++row) { Cell cell = Cell(m_sheet, col, row); if (!cell.doesMergeCells()) { continue; } cell.mergeCells(col, row, 0, 0); } } } // adjust selection if (m_selection) m_selection->isEmpty() ? m_selection->initialize(range, m_sheet) : m_selection->extend(range, m_sheet); return true; }
//----------------------------------------------------------------------------- void MultiMesh::_build_quadrature_rules_overlap() { begin(PROGRESS, "Building quadrature rules of cut cells' overlap."); // Get quadrature order const std::size_t quadrature_order = parameters["quadrature_order"]; // Clear quadrature rules _quadrature_rules_overlap.clear(); _quadrature_rules_interface.clear(); // Resize quadrature rules _quadrature_rules_overlap.resize(num_parts()); _quadrature_rules_interface.resize(num_parts()); // Clear and resize facet normals _facet_normals.clear(); _facet_normals.resize(num_parts()); // FIXME: test prebuild map from boundary facets to full mesh cells // for all meshes: Loop over all boundary mesh facets to find the // full mesh cell which contains the facet. This is done in two // steps: Since the facet is on the boundary mesh, we first map this // facet to a facet in the full mesh using the // boundary_cell_map. Then we use the full_facet_cell_map to find // the corresponding cell in the full mesh. This cell is to match // the cutting_cell_no. // Build map from boundary facets to full mesh std::vector<std::vector<std::vector<std::pair<std::size_t, std::size_t>>>> full_to_bdry(num_parts()); for (std::size_t part = 0; part < num_parts(); ++part) { full_to_bdry[part].resize(_meshes[part]->num_cells()); // Get map from boundary mesh to facets of full mesh const std::size_t tdim_boundary = _boundary_meshes[part]->topology().dim(); const auto& boundary_cell_map = _boundary_meshes[part]->entity_map(tdim_boundary); // Generate facet to cell connectivity for full mesh const std::size_t tdim = _meshes[part]->topology().dim(); _meshes[part]->init(tdim_boundary, tdim); const MeshConnectivity& full_facet_cell_map = _meshes[part]->topology()(tdim_boundary, tdim); for (std::size_t boundary_facet = 0; boundary_facet < boundary_cell_map.size(); ++boundary_facet) { // Find the facet in the full mesh const std::size_t full_mesh_facet = boundary_cell_map[boundary_facet]; // Find the cells in the full mesh (for interior facets we // can have 2 facets, but here we should only have 1) dolfin_assert(full_facet_cell_map.size(full_mesh_facet) == 1); const auto& full_cells = full_facet_cell_map(full_mesh_facet); full_to_bdry[part][full_cells[0]].push_back(std::make_pair(boundary_facet, full_mesh_facet)); } } // Iterate over all parts for (std::size_t cut_part = 0; cut_part < num_parts(); cut_part++) { // Iterate over cut cells for current part const auto& cmap = collision_map_cut_cells(cut_part); for (auto it = cmap.begin(); it != cmap.end(); ++it) { // Get cut cell const unsigned int cut_cell_index = it->first; const Cell cut_cell(*(_meshes[cut_part]), cut_cell_index); // Get dimensions const std::size_t tdim = cut_cell.mesh().topology().dim(); const std::size_t gdim = cut_cell.mesh().geometry().dim(); // Data structure for the volume triangulation of the cut_cell std::vector<double> volume_triangulation; // Data structure for the overlap quadrature rule std::vector<quadrature_rule> overlap_qr; // Data structure for the interface quadrature rule std::vector<quadrature_rule> interface_qr; // Data structure for the facet normals of the interface. The // numbering matches the numbering of interface_qr. This means // we have one normal for each quadrature point, since this is // how the data are grouped during assembly: for each pair of // colliding cells, we build a list of quadrature points and a // corresponding list of facet normals. std::vector<std::vector<double>> interface_n; // Data structure for the interface triangulation std::vector<double> interface_triangulation; // Data structure for normals to the interface. The numbering // should match the numbering of interface_triangulation. std::vector<Point> triangulation_normals; // Iterate over cutting cells const auto& cutting_cells = it->second; for (auto jt = cutting_cells.begin(); jt != cutting_cells.end(); jt++) { // Get cutting part and cutting cell const std::size_t cutting_part = jt->first; const std::size_t cutting_cell_index = jt->second; const Cell cutting_cell(*(_meshes[cutting_part]), cutting_cell_index); // Topology of this cut part const std::size_t tdim_boundary = _boundary_meshes[cutting_part]->topology().dim(); // Must have the same topology at the moment (FIXME) dolfin_assert(cutting_cell.mesh().topology().dim() == tdim); // Data structure for local interface triangulation std::vector<double> local_interface_triangulation; // Data structure for the local interface normals. The // numbering should match the numbering of // local_interface_triangulation. std::vector<Point> local_triangulation_normals; // Data structure for the overlap part quadrature rule quadrature_rule overlap_part_qr; // Data structure for the interface part quadrature rule quadrature_rule interface_part_qr; // Data structure for the interface part facet normals. The // numbering matches the numbering of interface_part_qr. std::vector<double> interface_part_n; // Iterate over boundary cells for (auto boundary_cell_index : full_to_bdry[cutting_part][cutting_cell_index]) { // Get the boundary facet as a cell in the boundary mesh const Cell boundary_cell(*_boundary_meshes[cutting_part], boundary_cell_index.first); // Get the boundary facet as a facet in the full mesh const Facet boundary_facet(*_meshes[cutting_part], boundary_cell_index.second); // Triangulate intersection of cut cell and boundary cell const auto triangulation_cut_boundary = cut_cell.triangulate_intersection(boundary_cell); // The normals to triangulation_cut_boundary std::vector<Point> normals_cut_boundary; // Add quadrature rule and normals for triangulation if (triangulation_cut_boundary.size()) { dolfin_assert(interface_part_n.size() == interface_part_qr.first.size()); const auto num_qr_points = _add_quadrature_rule(interface_part_qr, triangulation_cut_boundary, tdim_boundary, gdim, quadrature_order, 1); const std::size_t local_facet_index = cutting_cell.index(boundary_facet); const Point n = -cutting_cell.normal(local_facet_index); for (std::size_t i = 0; i < num_qr_points.size(); ++i) { _add_normal(interface_part_n, n, num_qr_points[i], gdim); normals_cut_boundary.push_back(n); } dolfin_assert(interface_part_n.size() == interface_part_qr.first.size()); } // Triangulate intersection of boundary cell and previous volume triangulation const auto triangulation_boundary_prev_volume = IntersectionTriangulation::triangulate_intersection(boundary_cell, volume_triangulation, tdim); // Add quadrature rule and normals for triangulation if (triangulation_boundary_prev_volume.size()) { dolfin_assert(interface_part_n.size() == interface_part_qr.first.size()); const auto num_qr_points = _add_quadrature_rule(interface_part_qr, triangulation_boundary_prev_volume, tdim_boundary, gdim, quadrature_order, -1); const std::size_t local_facet_index = cutting_cell.index(boundary_facet); const Point n = -cutting_cell.normal(local_facet_index); for (std::size_t i = 0; i < num_qr_points.size(); ++i) _add_normal(interface_part_n, n, num_qr_points[i], gdim); dolfin_assert(interface_part_n.size() == interface_part_qr.first.size()); } // Update triangulation local_interface_triangulation.insert(local_interface_triangulation.end(), triangulation_cut_boundary.begin(), triangulation_cut_boundary.end()); // Update interface facet normals local_triangulation_normals.insert(local_triangulation_normals.end(), normals_cut_boundary.begin(), normals_cut_boundary.end()); } // Triangulate the intersection of the previous interface // triangulation and the cutting cell (to remove) std::vector<double> triangulation_prev_cutting; std::vector<Point> normals_prev_cutting; IntersectionTriangulation::triangulate_intersection(cutting_cell, interface_triangulation, triangulation_normals, triangulation_prev_cutting, normals_prev_cutting, tdim_boundary); // Add quadrature rule for triangulation if (triangulation_prev_cutting.size()) { dolfin_assert(interface_part_n.size() == interface_part_qr.first.size()); const auto num_qr_points = _add_quadrature_rule(interface_part_qr, triangulation_prev_cutting, tdim_boundary, gdim, quadrature_order, -1); for (std::size_t i = 0; i < num_qr_points.size(); ++i) _add_normal(interface_part_n, normals_prev_cutting[i], num_qr_points[i], gdim); dolfin_assert(interface_part_n.size() == interface_part_qr.first.size()); } // Update triangulation interface_triangulation.insert(interface_triangulation.end(), local_interface_triangulation.begin(), local_interface_triangulation.end()); // Update normals triangulation_normals.insert(triangulation_normals.end(), local_triangulation_normals.begin(), local_triangulation_normals.end()); // Do the volume segmentation // Compute volume triangulation of intersection of cut and cutting cells const auto triangulation_cut_cutting = cut_cell.triangulate_intersection(cutting_cell); // Compute triangulation of intersection of cutting cell and // the (previous) volume triangulation const auto triangulation_cutting_prev = IntersectionTriangulation::triangulate_intersection(cutting_cell, volume_triangulation, tdim); // Add these new triangulations volume_triangulation.insert(volume_triangulation.end(), triangulation_cut_cutting.begin(), triangulation_cut_cutting.end()); // Add quadrature rule with weights corresponding to the two // triangulations _add_quadrature_rule(overlap_part_qr, triangulation_cut_cutting, tdim, gdim, quadrature_order, 1); _add_quadrature_rule(overlap_part_qr, triangulation_cutting_prev, tdim, gdim, quadrature_order, -1); // Add quadrature rule for overlap part overlap_qr.push_back(overlap_part_qr); // Add quadrature rule for interface part interface_qr.push_back(interface_part_qr); // Add facet normal for interface part interface_n.push_back(interface_part_n); } // Store quadrature rules for cut cell _quadrature_rules_overlap[cut_part][cut_cell_index] = overlap_qr; _quadrature_rules_interface[cut_part][cut_cell_index] = interface_qr; // Store facet normals for cut cell _facet_normals[cut_part][cut_cell_index] = interface_n; } } end(); }
void MainWindow::addRandomDir(CellList& list) { Cell* cell = list.first(); Cell* ucell = uCell(cell); Cell* rcell = rCell(cell); Cell* dcell = dCell(cell); Cell* lcell = lCell(cell); typedef QMap<Cell::Dirs, Cell*> CellMap; CellMap freecells; if(ucell && ucell->dirs() == Cell::Free) freecells[Cell::U] = ucell; if(rcell && rcell->dirs() == Cell::Free) freecells[Cell::R] = rcell; if(dcell && dcell->dirs() == Cell::Free) freecells[Cell::D] = dcell; if(lcell && lcell->dirs() == Cell::Free) freecells[Cell::L] = lcell; if(freecells.isEmpty()) return; CellMap::ConstIterator it = freecells.constBegin(); for(int i = rand() % freecells.count(); i > 0; --i) ++it; cell->setDirs(Cell::Dirs(cell->dirs() | it.key())); it.value()->setDirs(contrdirs[it.key()]); list.append(it.value()); }
QVariant GridModel::data(const QModelIndex& index, int role) const { Cell* subject = _grid.cellAt(index.row(), index.column()); switch(role) { // sets the actual content of the cell case Qt::EditRole: case Qt::DisplayRole: { if( subject->value() == Cell::UNKNOWN ) return QVariant(""); else { QChar value = _grid.alphabet().at(subject->value()); return QVariant(value); } break; } // sets the cell alignment case Qt::TextAlignmentRole: { return QVariant(Qt::AlignCenter); break; } case Qt::ToolTipRole: case Qt::StatusTipRole: { QList<char> d = subject->domain().toList(); QString ret = ""; qSort(d); if( d.isEmpty() ){ if( subject->value() != Cell::UNKNOWN ){ return QVariant(); } else { return QVariant("No domain!"); } } else { ret += _grid.alphabet().at(d.takeFirst()); for( auto i=d.begin(); i!=d.end(); ++i ){ ret += "/"; ret += _grid.alphabet().at(*i); } return QVariant(ret); } break; } case Qt::FontRole: { if( subject->isGiven() ){ return QVariant(givenFont); } else { return QVariant(); } break; } case Qt::BackgroundRole: { if( showDomainColor && subject->value() == Cell::UNKNOWN ){ double restrictionRatio = (double)subject->domain().size()/subject->fullDomain.size(); //QColor bgColor(55+200*restrictionRatio, 255, 55+200*restrictionRatio); QColor bgColor = QColor::fromHsv(255*restrictionRatio, 100, 255); return QVariant(bgColor); } break; } case Qt::ForegroundRole: break; default: return QVariant(); break; } return QVariant(); }
//Saves the map. Good for editing maps, not good for saving a game in mid-play because unit statuses are not saved. void InformationStorage::saveMap(string filename, Map *level) { TiXmlDocument doc; string s; TiXmlDeclaration* decl = new TiXmlDeclaration("1.0", "", ""); doc.LinkEndChild(decl); //Set up the root of the XML document TiXmlElement *root = new TiXmlElement("TileInfo"); doc.LinkEndChild(root); //Set up the Units, Buildings, and Tiles blocks TiXmlElement *units = new TiXmlElement("Units"); TiXmlElement *buildings = new TiXmlElement("Buildings"); TiXmlElement *tiles = new TiXmlElement("Tiles"); //Set up pointers to be used throughout saving the map TiXmlElement *elem; GameObject *gObj = 0; Unit *unit = 0; Building *building = 0; Terrain *tile = 0; //Set the width, height, and player count in the XML based on the level tiles->SetAttribute("width", level->width); tiles->SetAttribute("height", level->height); tiles->SetAttribute("playercount", level->playerCount()); //Add the units, buildings, and tiles blocks to the root root->LinkEndChild(units); root->LinkEndChild(buildings); root->LinkEndChild(tiles); Cell* cell; //Go through every cell of the map, and check what the terrain, unit(if any), and building(if any) //there is, and store it in the xml for(int i=0; i<level->width; i++) { for(int j=0; j<level->height; j++) { cell = level->getCell(i, j); gObj = cell->objectAtLayer(CellLayers::Unit); if(gObj) { //Add the unit to the units tag unit = (Unit*)gObj; elem = new TiXmlElement("Unit"); elem->SetAttribute("id", unit->id); elem->SetAttribute("pId", unit->getOwner()->id); elem->SetAttribute("x", i); elem->SetAttribute("y", j); units->LinkEndChild(elem); } gObj = cell->objectAtLayer(CellLayers::Building); if(gObj) { //Add the building to the buildings tag building = (Building*)gObj; elem = new TiXmlElement("Building"); elem->SetAttribute("id", building->id); elem->SetAttribute("pId", building->getOwner()->id); elem->SetAttribute("x", i); elem->SetAttribute("y", j); buildings->LinkEndChild(elem); } //Don't bother checking for terrain, there should always be one there. gObj = cell->objectAtLayer(CellLayers::Terrain); tile = (Terrain*)gObj; elem = new TiXmlElement("Tile"); elem->SetAttribute("shorthand", tile->id); elem->SetAttribute("x", i); elem->SetAttribute("y", j); tiles->LinkEndChild(elem); } } doc.SaveFile(filename.c_str()); }
/* Subrender routing for filling the Layer image object with thumbnails view scene */ void Thumblay::subrender() { Graphics *gfx = Graphics::FromImage(this->image); gfx->Clear(CLR_WHITE); Cacher *cacher = this->cacher; if( cacher != NULL ){ Image *thumb = NULL; Cell *cell = NULL; int i, x, y, mx, my, count; bool top, bot, left, right; right = false; left = false; top = false; bot = false; mx = OVL_MARGIN + 2 * (THB_SMSIZE + THB_SPACE); my = mx; x = y = OVL_MARGIN; count = 0; for( i = -THB_COUNT - this->picker; i <= THB_COUNT - this->picker; i++ ){ cacher->lockCache(); if( cacher->getCache() != NULL ){ cell = cacher->getCache()->gettoThat(i); if( cell != NULL ){ thumb = cell->getImageThumb(); if( thumb != NULL ){ if( i != 0 ){ gfx->DrawImage(thumb,x,y,THB_SMSIZE,THB_SMSIZE); gfx->DrawRectangle(this->Pen_Border, x, y, THB_SMSIZE, THB_SMSIZE); } else { mx = x + (int)((THB_SIZE - THB_SMSIZE)/4); my = y + (int)((THB_SIZE - THB_SMSIZE)/4); } } if( i == -THB_ROW ) top = true; if( i == THB_ROW ) bot = true; if( i == -1 && cacher->getCache()->isThatHead() == false ) left = true; if( i == 1 && cacher->getCache()->isThatTail() == false ) right = true; } } count++; x += THB_SMSIZE + THB_SPACE; if( count >= THB_ROW ){ x = OVL_MARGIN; y += THB_SMSIZE + THB_SPACE; count = 0; } cacher->unlockCache(); } int frame = 2; cacher->lockCache(); if( cacher->getCache() != NULL ){ cell = cacher->getThat(); if( cell != NULL ){ thumb = cell->getImageThumb(); if( thumb != NULL ){ gfx->FillRectangle(this->Brush_Back, mx - THB_SIZE/4, my - THB_SIZE/4, THB_SIZE, THB_SIZE); gfx->DrawImage(thumb, mx - THB_SIZE/4, my - THB_SIZE/4, THB_SIZE, THB_SIZE); gfx->DrawRectangle(this->Pen_Border, mx - THB_SIZE/4, my - THB_SIZE/4, THB_SIZE, THB_SIZE); gfx->DrawRectangle( this->Pen_DarkBorder, mx - frame - THB_SIZE/4, my - frame - THB_SIZE/4, THB_SIZE + 2*frame, THB_SIZE + 2*frame ); } } } cacher->unlockCache(); int size = 3; int width = 10; int ax = (int)(mx - frame - THB_SIZE/4); int ay = (int)(my - frame - THB_SIZE/4); int asize = THB_SIZE + 2*frame; Point arrow[3]; if( top == true ){ arrow[0].X = (int)(ax + (THB_SIZE/2) - width); arrow[0].Y = ay; arrow[1].X = (int)(ax + (THB_SIZE/2)); arrow[1].Y = ay - width; arrow[2].X = (int)(ax + (THB_SIZE/2) + width); arrow[2].Y = ay; gfx->FillPolygon(this->Brush_DarkBack,arrow,size); } if( bot == true ){ arrow[0].X = (int)(ax + (THB_SIZE/2) - width); arrow[0].Y = ay + asize; arrow[1].X = (int)(ax + (THB_SIZE/2)); arrow[1].Y = ay + asize + width; arrow[2].X = (int)(ax + (THB_SIZE/2) + width); arrow[2].Y = ay + asize; gfx->FillPolygon(this->Brush_DarkBack,arrow,size); } if( left == true ){ arrow[0].X = ax; arrow[0].Y = (int)(ay + (THB_SIZE/2) - width); arrow[1].X = ax - width; arrow[1].Y = (int)(ay + (THB_SIZE/2)); arrow[2].X = ax; arrow[2].Y = (int)(ay + (THB_SIZE/2) + width); gfx->FillPolygon(this->Brush_DarkBack,arrow,size); } if( right == true ){ arrow[0].X = ax + asize; arrow[0].Y = (int)(ay + (THB_SIZE/2) - width); arrow[1].X = ax + asize + width; arrow[1].Y = (int)(ay + (THB_SIZE/2)); arrow[2].X = ax + asize; arrow[2].Y = (int)(ay + (THB_SIZE/2) + width); gfx->FillPolygon(this->Brush_DarkBack,arrow,size); } } if( this->ticker > TICKER_OFF ){ int tsize = TICKER_SIZE; int tx,ty; if( this->ticker == 0 ){ tx = OVL_SIZE - 2*TICKER_INDENT; ty = OVL_SIZE - 2*TICKER_INDENT; } if( this->ticker == 1 ){ tx = OVL_SIZE - TICKER_INDENT; ty = OVL_SIZE - 2*TICKER_INDENT; } if( this->ticker == 2 ){ tx = OVL_SIZE - TICKER_INDENT; ty = OVL_SIZE - TICKER_INDENT; } if( this->ticker == 3 ){ tx = OVL_SIZE - 2*TICKER_INDENT; ty = OVL_SIZE - TICKER_INDENT; } gfx->FillRectangle(this->Brush_DarkBack,tx,ty,tsize,tsize); } delete gfx; }
bool GlobalPlanner::FindPath(std::vector<Cell> & path) { Cell s = Cell(currPos); Cell t = Cell(goalPos.x(), goalPos.y(), 2); if (occupied.find(s) != occupied.end()) { goingBack = true; for (int i=pathBack.size()-1; i >= 0; i -= 2){ path.push_back(pathBack[i]); } ROS_INFO("Current position is occupied, going back. Path size is %d", path.size()); return true; } if (occupied.find(t) != occupied.end()) { ROS_INFO("Goal position is occupied"); return false; } ROS_INFO("Trying to find path from %d,%d to %d,%d", s.x(), s.y(), t.x(), t.y()); std::map<Cell, Cell> parent; std::map<Cell, double> distance; std::set<Cell> seen; std::priority_queue< std::pair<Cell,double>, std::vector< std::pair<Cell,double> >, CompareDist> pq; pq.push(std::make_pair(s, 0.0)); distance[s] = 0.0; int numIter = 0; while (!pq.empty() && numIter++ < maxIterations) { auto cellDistU = pq.top(); pq.pop(); Cell u = cellDistU.first; double d = distance[u]; if (seen.find(u) != seen.end()) { continue; } seen.insert(u); if (u == t) { break; } std::vector< std::pair<Cell, double> > neighbors; getNeighbors(u, neighbors); for (auto cellDistV : neighbors) { Cell v = cellDistV.first; double risk = getRisk(v); double newDist = d + cellDistV.second + riskFactor * risk; double oldDist = inf; if (distance.find(v) != distance.end()) { oldDist = distance[v]; } if (occupied.find(v) == occupied.end() && seen.find(v) == seen.end() && newDist < oldDist) { parent[v] = u; distance[v] = newDist; double heuristic = newDist + overEstimateFactor*distance2D(v, t); pq.push(std::make_pair(v, heuristic)); } } } if (seen.find(t) == seen.end()) { ROS_INFO(" Failed to find a path"); return false; } Cell walker = t; pathCells.clear(); while (!(walker == s)) { path.push_back(walker); pathCells.insert(walker); walker = parent[walker]; } std::reverse(path.begin(),path.end()); ROS_INFO("Found path with %d iterations, iterations / distance squared: %f", numIter, numIter / squared(path.size())); return true; }
int main(int argc,char ** argv) { Solver::Initialize(&argc,&argv,""); // Initialize the solver and MPI activity #if defined(USE_PARTITIONER) Partitioner::Initialize(&argc,&argv); // Initialize the partitioner activity #endif if( argc > 1 ) { TagReal phi; TagReal tag_F; TagRealArray tag_K; TagRealArray tag_BC; TagReal phi_ref; Mesh * m = new Mesh(); // Create an empty mesh double ttt = Timer(); bool repartition = false; m->SetCommunicator(INMOST_MPI_COMM_WORLD); // Set the MPI communicator for the mesh if( m->GetProcessorRank() == 0 ) // If the current process is the master one std::cout << argv[0] << std::endl; if( m->isParallelFileFormat(argv[1]) ) { m->Load(argv[1]); // Load mesh from the parallel file format repartition = true; } else { if( m->GetProcessorRank() == 0 ) m->Load(argv[1]); // Load mesh from the serial file format } BARRIER; if( m->GetProcessorRank() == 0 ) std::cout << "Processors: " << m->GetProcessorsNumber() << std::endl; if( m->GetProcessorRank() == 0 ) std::cout << "Load(MPI_File): " << Timer()-ttt << std::endl; //~ double ttt2 = Timer(); //~ Mesh t; //~ t.SetCommunicator(INMOST_MPI_COMM_WORLD); //~ t.SetParallelFileStrategy(0); //~ t.Load(argv[1]); //~ BARRIER //~ if( m->GetProcessorRank() == 0 ) std::cout << "Load(MPI_Scatter): " << Timer()-ttt2 << std::endl; #if defined(USE_PARTITIONER) if (m->GetProcessorsNumber() > 1) { // currently only non-distributed meshes are supported by Inner_RCM partitioner ttt = Timer(); Partitioner * p = new Partitioner(m); p->SetMethod(Partitioner::INNER_KMEANS,Partitioner::Partition); // Specify the partitioner p->Evaluate(); // Compute the partitioner and store new processor ID in the mesh delete p; BARRIER; if( m->GetProcessorRank() == 0 ) std::cout << "Evaluate: " << Timer()-ttt << std::endl; ttt = Timer(); m->Redistribute(); // Redistribute the mesh data m->ReorderEmpty(CELL|FACE|EDGE|NODE); // Clean the data after reordring BARRIER; if( m->GetProcessorRank() == 0 ) std::cout << "Redistribute: " << Timer()-ttt << std::endl; } #endif ttt = Timer(); phi = m->CreateTag("Solution",DATA_REAL,CELL,NONE,1); // Create a new tag for the solution phi bool makerefsol = true; if( m->HaveTag("PERM" ) ) { tag_K = m->GetTag("PERM"); makerefsol = false; std::cout << "Permeability from grid" << std::endl; } else { std::cout << "Set perm" << std::endl; tag_K = m->CreateTag("PERM",DATA_REAL,CELL,NONE,1); // Create a new tag for K tensor for( Mesh::iteratorCell cell = m->BeginCell(); cell != m->EndCell(); ++cell ) // Loop over mesh cells tag_K[*cell][0] = 1.0; // Store the tensor K value into the tag } if( m->HaveTag("BOUNDARY_CONDITION") ) { tag_BC = m->GetTag("BOUNDARY_CONDITION"); makerefsol = false; std::cout << "Boundary conditions from grid" << std::endl; } else { std::cout << "Set boundary conditions" << std::endl; double x[3]; tag_BC = m->CreateTag("BOUNDARY_CONDITION",DATA_REAL,FACE,FACE,3); for( Mesh::iteratorFace face = m->BeginFace(); face != m->EndFace(); ++face ) if( face->Boundary() && !(face->GetStatus() == Element::Ghost) ) { face->Centroid(x); tag_BC[*face][0] = 1; //dirichlet tag_BC[*face][1] = 0; //neumann tag_BC[*face][2] = func(x,0);//face->Mean(func, 0); } } if( m->HaveTag("FORCE") ) { tag_F = m->GetTag("FORCE"); makerefsol = false; std::cout << "Force from grid" << std::endl; } else if( makerefsol ) { std::cout << "Set rhs" << std::endl; tag_F = m->CreateTag("FORCE",DATA_REAL,CELL,NONE,1); // Create a new tag for external force double x[3]; for( Mesh::iteratorCell cell = m->BeginCell(); cell != m->EndCell(); ++cell ) // Loop over mesh cells { cell->Centroid(x); tag_F[*cell] = -func_rhs(x,1); //tag_F[*cell] = -cell->Mean(func_rhs,1); } } if(m->HaveTag("REFERENCE_SOLUTION") ) phi_ref = m->GetTag("REFERENCE_SOLUTION"); else if( makerefsol ) { phi_ref = m->CreateTag("REFRENCE_SOLUTION",DATA_REAL,CELL,NONE,1); double x[3]; for( Mesh::iteratorCell cell = m->BeginCell(); cell != m->EndCell(); ++cell ) { cell->Centroid(x); phi_ref[*cell] = func(x,0);//cell->Mean(func, 0); } } ttt = Timer(); m->ExchangeGhost(1,FACE); m->ExchangeData(tag_K,CELL,0); // Exchange the tag_K data over processors BARRIER; if( m->GetProcessorRank() == 0 ) std::cout << "Exchange ghost: " << Timer()-ttt << std::endl; ttt = Timer(); Solver S("inner_ilu2"); // Specify the linear solver to ASM+ILU2+BiCGStab one S.SetParameter("absolute_tolerance", "1e-8"); S.SetParameter("schwartz_overlap", "2"); Residual R; // Residual vector Sparse::LockService Locks; Sparse::Vector Update; // Declare the solution and the right-hand side vectors { Mesh::GeomParam table; table[CENTROID] = CELL | FACE; table[NORMAL] = FACE; table[ORIENTATION] = FACE; table[MEASURE] = CELL | FACE; table[BARYCENTER] = CELL | FACE; m->PrepareGeometricData(table); } BARRIER if( m->GetProcessorRank() == 0 ) std::cout << "Prepare geometric data: " << Timer()-ttt << std::endl; { Automatizator aut; Automatizator::MakeCurrent(&aut); INMOST_DATA_ENUM_TYPE iphi = aut.RegisterTag(phi,CELL); aut.EnumerateEntries(); // Set the indeces intervals for the matrix and vectors R.SetInterval(aut.GetFirstIndex(),aut.GetLastIndex()); R.InitLocks(); Update.SetInterval(aut.GetFirstIndex(),aut.GetLastIndex()); dynamic_variable Phi(aut,iphi); // Solve \nabla \cdot \nabla phi = f equation //for( Mesh::iteratorFace face = m->BeginFace(); face != m->EndFace(); ++face ) #if defined(USE_OMP) #pragma omp parallel #endif { variable flux; //should be more efficient to define here to avoid multiple memory allocations if storage for variations should be expanded rMatrix x1(3,1), x2(3,1), xf(3,1), n(3,1); double d1, d2, k1, k2, area, T, a, b, c; #if defined(USE_OMP) #pragma omp for #endif for(Storage::integer iface = 0; iface < m->FaceLastLocalID(); ++iface ) if( m->isValidFace(iface) ) { Face face = Face(m,ComposeFaceHandle(iface)); Element::Status s1,s2; Cell r1 = face->BackCell(); Cell r2 = face->FrontCell(); if( ((!r1->isValid() || (s1 = r1->GetStatus()) == Element::Ghost)?0:1) + ((!r2->isValid() || (s2 = r2->GetStatus()) == Element::Ghost)?0:1) == 0) continue; area = face->Area(); // Get the face area face->UnitNormal(n.data()); // Get the face normal face->Centroid(xf.data()); // Get the barycenter of the face r1->Centroid(x1.data()); // Get the barycenter of the cell k1 = n.DotProduct(rMatrix::FromTensor(tag_K[r1].data(), tag_K[r1].size(),3)*n); d1 = fabs(n.DotProduct(xf-x1)); if( !r2->isValid() ) // boundary condition { // bnd_pnt is a projection of the cell center to the face // a*pb + bT(pb-p1) = c // F = T(pb-p1) // pb = (c + bTp1)/(a+bT) // F = T/(a+bT)(c - ap1) T = k1/d1; a = 0; b = 1; c = 0; if( tag_BC.isValid() && face.HaveData(tag_BC) ) { a = tag_BC[face][0]; b = tag_BC[face][1]; c = tag_BC[face][2]; //std::cout << "a " << a << " b " << b << " c " << c << std::endl; } R.Lock(Phi.Index(r1)); R[Phi.Index(r1)] -= T/(a + b*T) * area * (c - a*Phi(r1)); R.UnLock(Phi.Index(r1)); } else { r2->Centroid(x2.data()); k2 = n.DotProduct(rMatrix::FromTensor(tag_K[r2].data(), tag_K[r2].size(),3)*n); d2 = fabs(n.DotProduct(x2-xf)); T = 1.0/(d1/k1 + d2/k2); flux = T* area * (Phi(r2) - Phi(r1)); if( s1 != Element::Ghost ) { R.Lock(Phi.Index(r1)); R[Phi.Index(r1)] -= flux; R.UnLock(Phi.Index(r1)); } if( s2 != Element::Ghost ) { R.Lock(Phi.Index(r2)); R[Phi.Index(r2)] += flux; R.UnLock(Phi.Index(r2)); } } } } if( tag_F.isValid() ) { #if defined(USE_OMP) #pragma omp parallel for #endif for( Storage::integer icell = 0; icell < m->CellLastLocalID(); ++icell ) if( m->isValidCell(icell) ) { Cell cell = Cell(m,ComposeCellHandle(icell)); if( cell->GetStatus() != Element::Ghost ) R[Phi.Index(cell)] -= tag_F[cell] * cell->Volume(); } } BARRIER; if( m->GetProcessorRank() == 0 ) std::cout << "Matrix assemble: " << Timer()-ttt << std::endl; //m->RemoveGeometricData(table); // Clean the computed geometric data if( argc > 3 ) // Save the matrix and RHS if required { ttt = Timer(); R.GetJacobian().Save(std::string(argv[2])); // "A.mtx" R.GetResidual().Save(std::string(argv[3])); // "b.rhs" BARRIER; if( m->GetProcessorRank() == 0 ) std::cout << "Save matrix \"" << argv[2] << "\" and RHS \"" << argv[3] << "\": " << Timer()-ttt << std::endl; } ttt = Timer(); S.SetMatrix(R.GetJacobian()); // Compute the preconditioner for the original matrix S.Solve(R.GetResidual(),Update); // Solve the linear system with the previously computted preconditioner BARRIER; if( m->GetProcessorRank() == 0 ) { std::cout << S.Residual() << " " << S.Iterations() << " " << S.ReturnReason() << std::endl; std::cout << "Solve system: " << Timer()-ttt << std::endl; } ttt = Timer(); if( phi_ref.isValid() ) { Tag error = m->CreateTag("error",DATA_REAL,CELL,NONE,1); double err_C = 0.0, err_L2 = 0.0, vol = 0.0; #if defined(USE_OMP) #pragma omp parallel #endif { double local_err_C = 0; #if defined(USE_OMP) #pragma omp for reduction(+:err_L2) reduction(+:vol) #endif for( Storage::integer icell = 0; icell < m->CellLastLocalID(); ++icell ) if( m->isValidCell(icell) ) { Cell cell = Cell(m,ComposeCellHandle(icell)); if( cell->GetStatus() != Element::Ghost ) { double old = phi[cell]; double exact = phi_ref[cell]; double res = Update[Phi.Index(cell)]; double sol = old-res; double err = fabs (sol - exact); if (err > local_err_C) local_err_C = err; err_L2 += err * err * cell->Volume(); vol += cell->Volume(); cell->Real(error) = err; phi[cell] = sol; } } #if defined(USE_OMP) #pragma omp critical #endif { if( local_err_C > err_C ) err_C = local_err_C; } } err_C = m->AggregateMax(err_C); // Compute the maximal C norm for the error err_L2 = sqrt(m->Integrate(err_L2)/m->Integrate(vol)); // Compute the global L2 norm for the error if( m->GetProcessorRank() == 0 ) std::cout << "err_C = " << err_C << std::endl; if( m->GetProcessorRank() == 0 ) std::cout << "err_L2 = " << err_L2 << std::endl; } } BARRIER; if( m->GetProcessorRank() == 0 ) std::cout << "Compute true residual: " << Timer()-ttt << std::endl; ttt = Timer(); m->ExchangeData(phi,CELL,0); // Data exchange over processors BARRIER; if( m->GetProcessorRank() == 0 ) std::cout << "Exchange phi: " << Timer()-ttt << std::endl; std::string filename = "result"; if( m->GetProcessorsNumber() == 1 ) filename += ".vtk"; else filename += ".pvtk"; ttt = Timer(); m->Save(filename); m->Save("result.pmf"); BARRIER; if( m->GetProcessorRank() == 0 ) std::cout << "Save \"" << filename << "\": " << Timer()-ttt << std::endl; delete m; }
void Listlay::subrender() { Graphics *gfx = Graphics::FromImage(this->image); gfx->Clear(CLR_WHITE); Cacher *cacher = this->core->getCacher(); if( cacher != NULL ){ FwCHAR *string = NULL; FwCHAR *name = NULL; Cell *cell = NULL; int i, x, y; bool top, bot, archived = false; top = false; bot = false; x = LST_X; y = LST_Y; for( i = -CACHE_SIZE; i < CACHE_SIZE; i++ ){ cacher->lockCache(); if( cacher->getCache() != NULL ){ cell = cacher->getCache()->gettoThat(i); if( cell != NULL ){ if( cell->getFile() != NULL ){ name = cell->getFile()->getFileName(); } if( name != NULL ){ if( i == 0 ) gfx->FillRectangle(this->Brush_LiteBack,0,y+1,OVL_SIZE,FONTSIZE+2); string = name; if( cell->getFile()->isArchived() == true ){ if( archived == false ) archived = true; string = new FwCHAR(L"~"); string->mergeWith(name); x = 3*LST_X; } else if( archived == true ){ archived = false; x = LST_X; } gfx->DrawString(string->toWCHAR(), string->toLength(), this->Font_Default, PointF((REAL)x,(REAL)y), this->Brush_DarkBack); if( archived == true ) delete string; } if( i == -1 && cacher->getCache()->isThatHead() == false ) top = true; if( i == 1 && cacher->getCache()->isThatTail() == false ) bot = true; } } cacher->unlockCache(); y += (FONTSIZE + 2); } int size = 3; int width = 20; int ax = (int)(OVL_SIZE/2); int ay = LST_Y; int asize = OVL_SIZE - 2*LST_Y; Point arrow[3]; if( top == true ){ arrow[0].X = ax - width; arrow[0].Y = ay; arrow[1].X = ax; arrow[1].Y = ay - width; arrow[2].X = ax + width; arrow[2].Y = ay; gfx->FillPolygon(this->Brush_LiteBack,arrow,size); } if( bot == true ){ arrow[0].X = ax - width; arrow[0].Y = ay + asize; arrow[1].X = ax; arrow[1].Y = ay + asize + width; arrow[2].X = ax + width; arrow[2].Y = ay + asize; gfx->FillPolygon(this->Brush_LiteBack,arrow,size); } } if( this->ticker > TICKER_OFF ){ int tsize = TICKER_SIZE; int tx,ty; if( this->ticker == 0 ){ tx = OVL_SIZE - 2*TICKER_INDENT; ty = OVL_SIZE - 2*TICKER_INDENT; } if( this->ticker == 1 ){ tx = OVL_SIZE - TICKER_INDENT; ty = OVL_SIZE - 2*TICKER_INDENT; } if( this->ticker == 2 ){ tx = OVL_SIZE - TICKER_INDENT; ty = OVL_SIZE - TICKER_INDENT; } if( this->ticker == 3 ){ tx = OVL_SIZE - 2*TICKER_INDENT; ty = OVL_SIZE - TICKER_INDENT; } gfx->FillRectangle(this->Brush_DarkBack,tx,ty,tsize,tsize); } delete gfx; }
void BinnedCorr2<D1,D2>::process11(const Cell<D1,C>& c1, const Cell<D2,C>& c2) { if (c1.getW() == 0. || c2.getW() == 0.) return; const double dsq = MetricHelper<M>::DistSq(c1.getPos(),c2.getPos()); const double s1ps2 = c1.getAllSize()+c2.getAllSize(); if (MetricHelper<M>::TooSmallDist(c1.getPos(), c2.getPos(), s1ps2, dsq, _minsep, _minsepsq)) return; if (MetricHelper<M>::TooLargeDist(c1.getPos(), c2.getPos(), s1ps2, dsq, _maxsep, _maxsepsq)) return; // See if need to split: bool split1=false, split2=false; CalcSplitSq(split1,split2,c1,c2,dsq,s1ps2,_bsq); if (split1) { if (split2) { if (!c1.getLeft()) { std::cerr<<"minsep = "<<_minsep<<", maxsep = "<<_maxsep<<std::endl; std::cerr<<"minsepsq = "<<_minsepsq<<", maxsepsq = "<<_maxsepsq<<std::endl; std::cerr<<"c1.Size = "<<c1.getSize()<<", c2.Size = "<<c2.getSize()<<std::endl; std::cerr<<"c1.SizeSq = "<<c1.getSizeSq()<< ", c2.SizeSq = "<<c2.getSizeSq()<<std::endl; std::cerr<<"c1.N = "<<c1.getN()<<", c2.N = "<<c2.getN()<<std::endl; std::cerr<<"c1.Pos = "<<c1.getPos(); std::cerr<<", c2.Pos = "<<c2.getPos()<<std::endl; std::cerr<<"dsq = "<<dsq<<", s1ps2 = "<<s1ps2<<std::endl; } Assert(c1.getLeft()); Assert(c1.getRight()); Assert(c2.getLeft()); Assert(c2.getRight()); process11<C,M>(*c1.getLeft(),*c2.getLeft()); process11<C,M>(*c1.getLeft(),*c2.getRight()); process11<C,M>(*c1.getRight(),*c2.getLeft()); process11<C,M>(*c1.getRight(),*c2.getRight()); } else { Assert(c1.getLeft()); Assert(c1.getRight()); process11<C,M>(*c1.getLeft(),c2); process11<C,M>(*c1.getRight(),c2); } } else { if (split2) { Assert(c2.getLeft()); Assert(c2.getRight()); process11<C,M>(c1,*c2.getLeft()); process11<C,M>(c1,*c2.getRight()); } else if (dsq >= _minsepsq && dsq < _maxsepsq) { XAssert(NoSplit(c1,c2,sqrt(dsq),_b)); directProcess11<C,M>(c1,c2,dsq); } } }
void Margolus::CreateRotateBlock3D(Block3D & block, Rotate3D rotate, cuint& ix, cuint& iy, cuint& iz, bool act, bool mod) { block.rotate = rotate; memset(block.move, 0, sizeof(block.move)); // front for (uint x = 0; x < 2; ++x) { for (uint y = 0; y < 2; ++y) { for (uint z = 0; z < 2; ++z) { block.cells[x][y][z].Clear(); for (pSub & sub : cells[ix + x][iy + y][iz + z].GetSubs()) { if (sub->GetType() == ACTIVE || sub->GetType() == MODIFIER) { x == 0 ? --block.move[1] : --block.move[2]; y == 0 ? --block.move[3] : --block.move[4]; z == 0 ? --block.move[5] : --block.move[6]; } } } } } switch (rotate) { case ClockWiceX: for (uint x = 0; x < 2; ++x) { for (uint i = 0; i < 4; ++i) { Cell cell = cells[ix + x][iy + indexF[i][0]][iz + indexF[i][1]]; if (cell.HaveSolid()) { block.cells[x][indexF[i][0]][indexF[i][1]] = cell; } else { if (cell.HaveActive()) { uint q = act ? 1 : 0; for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == ACTIVE) { block.cells[x][indexF[i + q][0]][indexF[i + q][1]].AddSub(sub); } } } if (cell.HaveModifier()) { if (mod) { for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == MODIFIER) { int u = 1; while (true) { if (cells[ix + x][iy + indexF[i + u][0]][iz + indexF[i + u][1]].HaveSolid()) { ++u; } else { block.cells[x][indexF[i + u][0]][indexF[i + u][1]].AddSub(sub); break; } } } } } else { for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == MODIFIER) { block.cells[x][indexF[i][0]][indexF[i][1]].AddSub(sub); } } } } } } } break; case CounterClockWiceX: for (uint x = 0; x < 2; ++x) { for (uint i = 0; i < 4; ++i) { Cell cell = cells[ix + x][iy + indexB[i][0]][iz + indexB[i][1]]; if (cell.HaveSolid()) { block.cells[x][indexB[i][0]][indexB[i][1]] = cell; } else { if (cell.HaveActive()) { uint q = act ? 1 : 0; for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == ACTIVE) { block.cells[x][indexB[i + q][0]][indexB[i + q][1]].AddSub(sub); } } } if (cell.HaveModifier()) { if (mod) { for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == MODIFIER) { int u = 1; while (true) { if (cells[ix+ x][iy + indexB[i + u][0]][iz + indexB[i + u][1]].HaveSolid()) { ++u; } else { block.cells[x][indexB[i + u][0]][indexB[i + u][1]].AddSub(sub); break; } } } } } else { for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == MODIFIER) { block.cells[x][indexB[i][0]][indexB[i][1]].AddSub(sub); } } } } } } } break; case ClockWiceY: for (uint y = 0; y < 2; ++y) { for (uint i = 0; i < 4; ++i) { Cell cell = cells[ix + indexF[i][1]][iy + y][iz + indexF[i][0]]; if (cell.HaveSolid()) { block.cells[indexF[i][1]][y][indexF[i][0]] = cell; } else { if (cell.HaveActive()) { uint q = act ? 1 : 0; for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == ACTIVE) { block.cells[indexF[i + q][1]][y][indexF[i + q][0]].AddSub(sub); } } } if (cell.HaveModifier()) { if (mod) { for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == MODIFIER) { int u = 1; while (true) { if (cells[ix + indexF[i + u][1]][iy + y][iz + indexF[i + u][0]].HaveSolid()) { ++u; } else { block.cells[indexF[i + u][1]][y][indexF[i + u][0]].AddSub(sub); break; } } } } } else { for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == MODIFIER) { block.cells[indexF[i][1]][y][indexF[i][0]].AddSub(sub); } } } } } } } break; case CounterClockWiceY: for (uint y = 0; y < 2; ++y) { for (uint i = 0; i < 4; ++i) { Cell cell = cells[ix + indexB[i][1]][iy + y][iz + indexB[i][0]]; if (cell.HaveSolid()) { block.cells[indexB[i][1]][y][indexB[i][0]] = cell; } else { if (cell.HaveActive()) { uint q = act ? 1 : 0; for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == ACTIVE) { block.cells[indexB[i + q][1]][y][indexB[i + q][0]].AddSub(sub); } } } if (cell.HaveModifier()) { if (mod) { for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == MODIFIER) { int u = 1; while (true) { if (cells[ix + indexB[i + u][1]][iy + y][iz + indexB[i + u][0]].HaveSolid()) { ++u; } else { block.cells[indexB[i + u][1]][y][indexB[i + u][0]].AddSub(sub); break; } } } } } else { for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == MODIFIER) { block.cells[indexB[i][1]][y][indexB[i][0]].AddSub(sub); } } } } } } } break; case ClockWiceZ: for (uint z = 0; z < 2; ++z) { for (uint i = 0; i < 4; ++i) { Cell cell = cells[ix + indexF[i][0]][iy + indexF[i][1]][iz + z]; if (cell.HaveSolid()) { block.cells[indexF[i][0]][indexF[i][1]][z] = cell; } else { if (cell.HaveActive()) { uint q = act ? 1 : 0; for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == ACTIVE) { block.cells[indexF[i + q][0]][indexF[i + q][1]][z].AddSub(sub); } } } if (cell.HaveModifier()) { if (mod) { for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == MODIFIER) { int u = 1; while (true) { if (cells[ix + indexF[i + u][0]][iy + indexF[i + u][1]][z].HaveSolid()) { ++u; } else { block.cells[indexF[i + u][0]][indexF[i + u][1]][z].AddSub(sub); break; } } } } } else { for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == MODIFIER) { block.cells[indexF[i][0]][indexF[i][1]][z].AddSub(sub); } } } } } } } break; case CounterClockWiceZ: for (uint z = 0; z < 2; ++z) { for (uint i = 0; i < 4; ++i) { Cell cell = cells[ix + indexB[i][0]][iy + indexB[i][1]][iz + z]; if (cell.HaveSolid()) { block.cells[indexB[i][0]][indexB[i][1]][z] = cell; } else { if (cell.HaveActive()) { uint q = act ? 1 : 0; for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == ACTIVE) { block.cells[indexB[i + q][0]][indexB[i + q][1]][z].AddSub(sub); } } } if (cell.HaveModifier()) { if (mod) { for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == MODIFIER) { int u = 1; while (true) { if (cells[ix + indexB[i + u][0]][iy + indexB[i + u][1]][iz + z].HaveSolid()) { ++u; } else { block.cells[indexB[i + u][0]][indexB[i + u][1]][z].AddSub(sub); break; } } } } } else { for (pSub & sub : cell.GetSubs()) { if (sub->GetType() == MODIFIER) { block.cells[indexB[i][0]][indexB[i][1]][z].AddSub(sub); } } } } } } } break; } for (uint x = 0; x < 2; ++x) { for (uint y = 0; y < 2; ++y) { for (uint z = 0; z < 2; ++z) { for (pSub & sub : block.cells[x][y][z].GetSubs()) { if (sub->GetType() == ACTIVE || sub->GetType() == MODIFIER) { x == 0 ? ++block.move[1] : ++block.move[2]; y == 0 ? ++block.move[3] : ++block.move[4]; z == 0 ? ++block.move[5] : ++block.move[6]; } } } } } }
static void ProcessXi( const Cell<KData,C>& c1, const Cell<KData,C>& c2, const double , XiData<KData,KData>& xi, int k) { xi.xi[k] += c1.getData().getWK() * c2.getData().getWK(); }
// era: encode references absolutely QDomDocument CopyCommand::saveAsXml(const Region& region, bool era) { QDomDocument xmlDoc("spreadsheet-snippet"); xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"")); QDomElement root = xmlDoc.createElement("spreadsheet-snippet"); xmlDoc.appendChild(root); // find the upper left corner of the selection const QRect boundingRect = region.boundingRect(); int left = boundingRect.left(); int top = boundingRect.top(); // for tiling the clipboard content in the selection root.setAttribute("rows", QString::number(boundingRect.height())); root.setAttribute("columns", QString::number(boundingRect.width())); const Region::ConstIterator end(region.constEnd()); for (Region::ConstIterator it = region.constBegin(); it != end; ++it) { Sheet *const sheet = (*it)->sheet(); const QRect range = (*it)->rect(); CellStorage *const storage = sheet->cellStorage(); // // Entire rows selected? // if ((*it)->isRow()) { QDomElement rows = xmlDoc.createElement("rows"); rows.setAttribute("count", QString::number(range.height())); rows.setAttribute("row", QString::number(range.top() - top + 1)); root.appendChild(rows); // Save all cells. for (int row = range.top(); row <= range.bottom(); ++row) { Cell cell = storage->firstInRow(row); for (; !cell.isNull(); cell = storage->nextInRow(cell.column(), cell.row())) { if (!cell.isPartOfMerged()) { root.appendChild(cell.save(xmlDoc, 0, top - 1, era)); } } } // TODO Stefan: Inefficient, use cluster functionality // Save the row formats if there are any //const RowFormat* format; for (int row = range.top(); row <= range.bottom(); ++row) { if (!sheet->rowFormats()->isDefaultRow(row)) { QDomElement e = RowFormat(sheet->rowFormats(), row).save(xmlDoc, top - 1); if (!e.isNull()) { rows.appendChild(e); } } } continue; } // // Entire columns selected? // if ((*it)->isColumn()) { QDomElement columns = xmlDoc.createElement("columns"); columns.setAttribute("count", QString::number(range.width())); columns.setAttribute("column", QString::number(range.left() - left + 1)); root.appendChild(columns); // Save all cells. for (int col = range.left(); col <= range.right(); ++col) { Cell cell = storage->firstInColumn(col); for (; !cell.isNull(); cell = storage->nextInColumn(cell.column(), cell.row())) { if (!cell.isPartOfMerged()) { root.appendChild(cell.save(xmlDoc, left - 1, 0, era)); } } } // TODO Stefan: Inefficient, use the cluster functionality // Save the column formats if there are any const ColumnFormat* format; for (int col = range.left(); col <= range.right(); ++col) { format = sheet->columnFormat(col); if (format && !format->isDefault()) { QDomElement e = format->save(xmlDoc, left - 1); if (!e.isNull()) { columns.appendChild(e); } } } continue; } // Save all cells. Cell cell; for (int row = range.top(); row <= range.bottom(); ++row) { if (range.left() == 1) { cell = storage->firstInRow(row); } else { cell = storage->nextInRow(range.left() - 1, row); } while (!cell.isNull() && cell.column() >= range.left() && cell.column() <= range.right()) { if (!cell.isPartOfMerged()) { root.appendChild(cell.save(xmlDoc, left - 1, top - 1, era)); } cell = storage->nextInRow(cell.column(), cell.row()); } } } return xmlDoc; }
//lĂnea recta horitzontal cap a l'est void Path::addCell(double x, double y) { Cell c; c.setTypeEnd(_NONE); setPositionXY(&c,x,y); cellsPath.push_back(c); }