void TrainingSetGenerator::GenerateUsingNormals(const PointCloud & input, const NormalCloud & normals, float gap) { Grid2Num.Resize(input.height, input.width); Pixel2Num.resize(input.height * input.width); int indexNoNan = 0; for (int y = 0; y < input.height; ++y) { for (int x = 0; x < input.width; ++x) { PointType point = input.at(x, y); NormalType normal = normals.at(x, y); int & num = Pixel2Num[y * input.width + x]; if (pointHasNan(point) || pcl_isnan(normal.normal_x)) { num = -1; continue; } auto nv3f = normal.getNormalVector3fMap(); pcl::flipNormalTowardsViewpoint(point, 0, 0, 0, nv3f[0], nv3f[1], nv3f[2]); nv3f *= -1; nv3f /= nv3f.norm(); nv3f *= Step_ * gap; num = AddPoint(x, y, point, +1); PointType shifted(point); shifted.getVector3fMap() += nv3f; AddPoint(x, y, shifted, -1); indexNoNan++; } } }
//!Shift the bitset to the left n positions //!Size of the bitset will not change. If values are shifted off bitset then //!they will be lost. //!\param n Number of positions to shift the bits dynamic_bitset& dynamic_bitset::operator<<= (size_t n){ //If shifting more than 32 then need to insert integer before size_t start(0); if (n>=32){ size_t ints_to_add = n/32; n %=32; array.insert(array.begin(), ints_to_add, 0); array.resize(num_ints); if (n==0){ return *this; } } if (n!=0){ uint32_t shifted(lso(array[start],n)); for(size_t i = start+1; i < num_ints ; ++i){ shifted = lsoso(array[i], shifted, n); } //Clear those bits that are outside of the current scope (bits in buffer region) uint32_t mask = (1 << 32-buffer) - 1; array[num_ints-1] &= mask; } return *this; }
BVValue BVValue::shift(const BVValue& _other, bool _left, bool _arithmetic) const { std::size_t firstSize = width() - 1; std::size_t highestRelevantPos = 0; bool fillWithOnes = !_left && _arithmetic && (*this)[width() - 1]; while ((firstSize >>= 1) != 0) ++highestRelevantPos; for (std::size_t i = highestRelevantPos + 1; i < _other.width(); ++i) { if (_other[i]) { Base allZero(width()); return BVValue(fillWithOnes ? ~allZero : allZero); } } Base shifted(fillWithOnes ? ~mValue : mValue); std::size_t shiftBy = 1; for (std::size_t i = 0; i <= highestRelevantPos && i < _other.width(); ++i) { if (_other[i]) { if (_left) { shifted <<= shiftBy; } else { shifted >>= shiftBy; } } shiftBy *= 2; } return BVValue(fillWithOnes ? ~shifted : shifted); }
void UBKeyButton::paintContent(QPainter& painter) { if (keybt) { QString text(QChar(shifted() ? keybt->symbol2 : keybt->symbol1)); QRect textRect(rect().x()+2, rect().y()+2, rect().width()-4, rect().height()-4); painter.drawText(textRect, Qt::AlignCenter, text); } }
void UBKeyButton::onPress() { if (keybt!=NULL) { int codeIndex = keyboard->nSpecialModifierIndex * 2 + shifted(); if (keyboard->nSpecialModifierIndex) { if (keybt->codes[codeIndex].empty()) { sendUnicodeSymbol(keyboard->specialModifier); sendUnicodeSymbol(keybt->codes[shifted()]); } else { sendUnicodeSymbol(keybt->codes[codeIndex]); } keyboard->nSpecialModifierIndex = 0; } else { int nSpecialModifierIndex = shifted()? keybt->modifier2 : keybt->modifier1; if (nSpecialModifierIndex) { keyboard->nSpecialModifierIndex = nSpecialModifierIndex; keyboard->specialModifier = keybt->codes[codeIndex]; } else { sendUnicodeSymbol(keybt->codes[codeIndex]); } } } if (keyboard->shift) { keyboard->shift = false; keyboard->update(); } }
void special_esc(bool pressed) { if (pressed) { if (shifted() || guied()) { add_key(KC_GRV); } else { add_key(KC_ESC); } send_keyboard_report(); } else { clear_keyboard_but_mods(); } }
void QuadTree::add_object(GameObject *object) { Aabb aabb = object->get_bounding_box(); if (aabb.m_min.x < -m_radius || aabb.m_max.x > m_radius || aabb.m_min.z < -m_radius || aabb.m_max.z > m_radius) { get_root()->add_object(object); return; } const Vector3 offset(m_radius, m_radius, m_radius); Aabb shifted(aabb); shifted.m_min += offset; shifted.m_max += offset; shifted.m_min *= m_inv_radius; shifted.m_max *= m_inv_radius; const size_t min_x = static_cast<size_t>(clamp(std::floor(shifted.m_min.x), 0.0f, 255.0f)); const size_t min_y = static_cast<size_t>(clamp(std::floor(shifted.m_min.z), 0.0f, 255.0f)); const size_t max_x = static_cast<size_t>(clamp(std::ceil(shifted.m_max.x), 0.0f, 255.0f)); const size_t max_y = static_cast<size_t>(clamp(std::ceil(shifted.m_max.z), 0.0f, 255.0f)); const size_t x_xor = (min_x ^ max_x); // const size_t lx = !x_xor ? 7UL : 8UL - highest_bit(x_xor); const size_t lx = !x_xor ? 7UL : 7UL - highest_bit(x_xor); const size_t y_xor = (min_y ^ max_y); // const size_t ly = !y_xor ? 7UL : 8UL - highest_bit(y_xor); const size_t ly = !y_xor ? 7UL : 7UL - highest_bit(y_xor); const size_t level = (lx < ly) ? lx : ly; const size_t x = min_x >> (8UL - level); const size_t y = min_y >> (8UL - level); QuadTreeNode &node = m_levels[level][y * (1UL << level) + x]; DER_ASSERT( node.get_center().x - node.get_radius() <= aabb.m_min.x ); DER_ASSERT( node.get_center().x + node.get_radius() >= aabb.m_max.x ); DER_ASSERT( node.get_center().y - node.get_radius() <= aabb.m_min.z ); DER_ASSERT( node.get_center().y + node.get_radius() >= aabb.m_max.z ); m_object_node_map[object->getID()] = &node; node.add_object(object); }
int main() { // Load images cv::Mat img1 = cv::imread("./output/ps0-1-a-1.png"); std::cout << img1.type() << std::endl; cv::Mat img2 = cv::imread("./output/ps0-1-a-2.png"); if (!img1.data) { std::cerr << "Could not open or find image 1" << std::endl; return -1; } else if (!img2.data){ std::cerr << "Could not open or find image 2" << std::endl; return -1; } // Extract color channels from image 1 std::vector<cv::Mat> channels(3); cv::split(img1, channels); // Swap channels cv::Mat temp(channels[0]); // Store blue channels[0] = channels[2]; // Swap blue with red channels[2] = temp; // Swap red with blue; // Save swapped image cv::Mat swapped1; cv::merge(channels, swapped1); cv::imwrite("./output/ps0-2-a-1.png", swapped1); cv::split(img1, channels); // Save red and img1_green channels of image 1 cv::Mat img1_green(channels[1]); cv::Mat img1_red(channels[2]); cv::imwrite("./output/ps0-2-b-1.png", img1_green); cv::imwrite("./output/ps0-2-c-1.png", img1_red); //Take the center square region of 100x100 pixels of img1_green // and insert them into the center of red cv::Rect r(img1_green.cols / 2 - 50, img1_green.rows / 2 - 50, 100, 100); cv::Mat combined = img1_red, green_roi = img1_green(r); green_roi.copyTo(combined(cv::Rect(combined.cols/2 - 50, combined.rows/2 - 50, 100, 100))); cv::imwrite("./output/ps0-3-a-1.png", combined); // Subtract the mean from all pixels, then divide by standard deviation, // then multiply by 10 and add the mean back in cv::Mat modified, mean, stdDev; cv::meanStdDev(img1_green, mean, stdDev); cv::subtract(img1_green, mean, modified); cv::divide(modified, stdDev, modified); cv::multiply(modified, 10, modified); cv::add(modified, mean, modified); cv::imwrite("./output/ps0-4-b-1.png", modified); // Shift img1_green to the left by 2 pixels cv::Mat shifted = cv::Mat::zeros(img1_green.size(), img1_green.type()); img1_green(cv::Rect(2, 0, img1_green.cols - 2, img1_green.rows)).copyTo( shifted(cv::Rect(0, 0, img1_green.cols - 2, img1_green.rows))); cv::imwrite("./output/ps0-4-c-1.png", shifted); // Subtract shifted from img1_green cv::Mat subtracted; cv::subtract(img1_green, shifted, subtracted); cv::imwrite("./output/ps0-4-d-1.png", subtracted); // Add Gaussian noise to img1's green channel cv::split(channels, img1); cv::Mat noise(img1.cols, img1.rows, img1.type()); cv::randn(noise, 0, 5); cv::normalize(noise, noise, 0, 255, CV_MINMAX, img1.type()); channels[1] += noise; cv::Mat green_noise; cv::merge(channels, green_noise); // display images // cv::imshow("Original Image 1", img1); // cv::imshow("Swapped Image 1", swapped1); cv::imshow("Green Image 1", img1_green); // cv::imshow("Red Image 1", img1_red); // cv::imshow("Combined", combined); // cv::imshow("Modified", modified); // cv::imshow("Shifted", shifted); // cv::imshow("Subtracted", subtracted); cv::imshow("Green Noise", green_noise); // std::string window2 = "Image 2"; // cv::namedWindow(window2); // cv::imshow(window2, img2); cv::waitKey(0); return 0; }
static Keyboard::Keycode Keysym(unsigned keysym, unsigned keyflags) { #define pressed(keysym) (GetAsyncKeyState(keysym) & 0x8000) #define enabled(keysym) (GetKeyState(keysym)) #define shifted() (pressed(VK_LSHIFT) || pressed(VK_RSHIFT)) #define extended() (keyflags & (1 << 24)) switch(keysym) { case VK_ESCAPE: return Keyboard::Keycode::Escape; case VK_F1: return Keyboard::Keycode::F1; case VK_F2: return Keyboard::Keycode::F2; case VK_F3: return Keyboard::Keycode::F3; case VK_F4: return Keyboard::Keycode::F4; case VK_F5: return Keyboard::Keycode::F5; case VK_F6: return Keyboard::Keycode::F6; case VK_F7: return Keyboard::Keycode::F7; case VK_F8: return Keyboard::Keycode::F8; case VK_F9: return Keyboard::Keycode::F9; //Keyboard::Keycode::F10 (should be captured under VK_MENU from WM_SYSKEY(UP,DOWN); but this is not working...) case VK_F11: return Keyboard::Keycode::F11; case VK_F12: return Keyboard::Keycode::F12; //Keyboard::Keycode::PrintScreen //Keyboard::Keycode::SysRq case VK_SCROLL: return Keyboard::Keycode::ScrollLock; case VK_PAUSE: return Keyboard::Keycode::Pause; //Keyboard::Keycode::Break case VK_INSERT: return extended() ? Keyboard::Keycode::Insert : Keyboard::Keycode::KeypadInsert; case VK_DELETE: return extended() ? Keyboard::Keycode::Delete : Keyboard::Keycode::KeypadDelete; case VK_HOME: return extended() ? Keyboard::Keycode::Home : Keyboard::Keycode::KeypadHome; case VK_END: return extended() ? Keyboard::Keycode::End : Keyboard::Keycode::KeypadEnd; case VK_PRIOR: return extended() ? Keyboard::Keycode::PageUp : Keyboard::Keycode::KeypadPageUp; case VK_NEXT: return extended() ? Keyboard::Keycode::PageDown : Keyboard::Keycode::KeypadPageDown; case VK_UP: return extended() ? Keyboard::Keycode::Up : Keyboard::Keycode::KeypadUp; case VK_DOWN: return extended() ? Keyboard::Keycode::Down : Keyboard::Keycode::KeypadDown; case VK_LEFT: return extended() ? Keyboard::Keycode::Left : Keyboard::Keycode::KeypadLeft; case VK_RIGHT: return extended() ? Keyboard::Keycode::Right : Keyboard::Keycode::KeypadRight; case VK_OEM_3: return !shifted() ? Keyboard::Keycode::Grave : Keyboard::Keycode::Tilde; case '1': return !shifted() ? Keyboard::Keycode::Number1 : Keyboard::Keycode::Exclamation; case '2': return !shifted() ? Keyboard::Keycode::Number2 : Keyboard::Keycode::At; case '3': return !shifted() ? Keyboard::Keycode::Number3 : Keyboard::Keycode::Pound; case '4': return !shifted() ? Keyboard::Keycode::Number4 : Keyboard::Keycode::Dollar; case '5': return !shifted() ? Keyboard::Keycode::Number5 : Keyboard::Keycode::Percent; case '6': return !shifted() ? Keyboard::Keycode::Number6 : Keyboard::Keycode::Power; case '7': return !shifted() ? Keyboard::Keycode::Number7 : Keyboard::Keycode::Ampersand; case '8': return !shifted() ? Keyboard::Keycode::Number8 : Keyboard::Keycode::Asterisk; case '9': return !shifted() ? Keyboard::Keycode::Number9 : Keyboard::Keycode::ParenthesisLeft; case '0': return !shifted() ? Keyboard::Keycode::Number0 : Keyboard::Keycode::ParenthesisRight; case VK_OEM_MINUS: return !shifted() ? Keyboard::Keycode::Minus : Keyboard::Keycode::Underscore; case VK_OEM_PLUS: return !shifted() ? Keyboard::Keycode::Equal : Keyboard::Keycode::Plus; case VK_BACK: return Keyboard::Keycode::Backspace; case VK_OEM_4: return !shifted() ? Keyboard::Keycode::BracketLeft : Keyboard::Keycode::BraceLeft; case VK_OEM_6: return !shifted() ? Keyboard::Keycode::BracketRight : Keyboard::Keycode::BraceRight; case VK_OEM_5: return !shifted() ? Keyboard::Keycode::Backslash : Keyboard::Keycode::Pipe; case VK_OEM_1: return !shifted() ? Keyboard::Keycode::Semicolon : Keyboard::Keycode::Colon; case VK_OEM_7: return !shifted() ? Keyboard::Keycode::Apostrophe : Keyboard::Keycode::Quote; case VK_OEM_COMMA: return !shifted() ? Keyboard::Keycode::Comma : Keyboard::Keycode::CaretLeft; case VK_OEM_PERIOD: return !shifted() ? Keyboard::Keycode::Period : Keyboard::Keycode::CaretRight; case VK_OEM_2: return !shifted() ? Keyboard::Keycode::Slash : Keyboard::Keycode::Question; case VK_TAB: return Keyboard::Keycode::Tab; case VK_CAPITAL: return Keyboard::Keycode::CapsLock; case VK_RETURN: return !extended() ? Keyboard::Keycode::Return : Keyboard::Keycode::Enter; case VK_SHIFT: return !pressed(VK_RSHIFT) ? Keyboard::Keycode::ShiftLeft : Keyboard::Keycode::ShiftRight; case VK_CONTROL: return !pressed(VK_RCONTROL) ? Keyboard::Keycode::ControlLeft : Keyboard::Keycode::ControlRight; case VK_LWIN: return Keyboard::Keycode::SuperLeft; case VK_RWIN: return Keyboard::Keycode::SuperRight; case VK_MENU: if(keyflags & (1 << 24)) return Keyboard::Keycode::AltRight; return Keyboard::Keycode::AltLeft; case VK_SPACE: return Keyboard::Keycode::Space; case VK_APPS: return Keyboard::Keycode::Menu; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': if(enabled(VK_CAPITAL)) { if(shifted()) { return (Keyboard::Keycode)((unsigned)Keyboard::Keycode::a + keysym - 'A'); } else { return (Keyboard::Keycode)((unsigned)Keyboard::Keycode::A + keysym - 'A'); } } else { if(shifted()) { return (Keyboard::Keycode)((unsigned)Keyboard::Keycode::A + keysym - 'A'); } else { return (Keyboard::Keycode)((unsigned)Keyboard::Keycode::a + keysym - 'A'); } } break; case VK_NUMLOCK: return Keyboard::Keycode::NumLock; case VK_DIVIDE: return Keyboard::Keycode::Divide; case VK_MULTIPLY: return Keyboard::Keycode::Multiply; case VK_SUBTRACT: return Keyboard::Keycode::Subtract; case VK_ADD: return Keyboard::Keycode::Add; case VK_DECIMAL: return Keyboard::Keycode::Point; case VK_NUMPAD1: return Keyboard::Keycode::Keypad1; case VK_NUMPAD2: return Keyboard::Keycode::Keypad2; case VK_NUMPAD3: return Keyboard::Keycode::Keypad3; case VK_NUMPAD4: return Keyboard::Keycode::Keypad4; case VK_NUMPAD5: return Keyboard::Keycode::Keypad5; case VK_NUMPAD6: return Keyboard::Keycode::Keypad6; case VK_NUMPAD7: return Keyboard::Keycode::Keypad7; case VK_NUMPAD8: return Keyboard::Keycode::Keypad8; case VK_NUMPAD9: return Keyboard::Keycode::Keypad9; case VK_NUMPAD0: return Keyboard::Keycode::Keypad0; case VK_CLEAR: return Keyboard::Keycode::KeypadCenter; } return Keyboard::Keycode::None; #undef pressed #undef enabled #undef shifted #undef extended }
Int_t run_insert() { //gDebug = 5; // Generate a unique RunID FairRunIdGenerator runID; UInt_t runId = runID.generateId(); // Create the Runtime Database ( parameter manager class ) FairRuntimeDb* db = FairRuntimeDb::instance(); // Set the SQL based IO as second input FairParTSQLIo* input_db = new FairParTSQLIo(); input_db->SetVerbosity(1); // Set Global SeqNo ( Replication Global Index Base ) //inp2->SetGlobalSeqNoIn(); // Shutdown Mode ( True, False ) input_db->SetShutdown(kTRUE); // Open first input input_db->open(); db->setFirstInput(input_db); // Set the output=input db->setOutput(input_db); // Write a Run R3BDBRunInfo rInfo; rInfo.SetRunId(11334465); ValTimeStamp now; rInfo.SetRunTime(now); if (!rInfo.Commit()) cout << "-E- Error Writing Run Info " << endl; R3BDBRunInfo rInfo2; rInfo2.SetRunId(11334469); ValTimeStamp shifted(now.GetSec()+1,0); rInfo2.SetRunTime(shifted); if (!rInfo2.Commit()) cout << "-E- Error Writing Run Info2 " << endl; // Read it back in // make a extended query to get ConfigFileText ValTimeStamp tsStart(1970, 1, 1, 0, 0, 0); ValTimeStamp tsEnd(2038, 1,18,19,14, 7); FairDbExtSqlContent extContextConfig(FairDbExtSqlContent::kStarts,tsStart,tsEnd, Detector::kLand, // any DataType::kData); // any string seqSelectConfig = Form("SEQNO=%d",rInfo.GetRunId()); FairDbReader<R3BDBRunInfo> rsConfig("R3BDBRUNINFO",extContextConfig,FairDb::kAnyVersion, seqSelectConfig.c_str()); Int_t nConfig = rsConfig.GetNumRows(); cout << "nConfig: = " << nConfig << endl; const R3BDBRunInfo* rpInfo = rsConfig.GetRow(0); if (rpInfo) cout << " run # " << rpInfo->GetRunId() << " has time: " << rpInfo->GetRunTime().AsString("s") << endl; // FairRuntimeDB deletion if (db) delete db; return 0; }
//the call function that lets ClusterPlanarizationLayout compute a layout //for the input using \a weight for the computation of the cluster planar subgraph void ClusterPlanarizationLayout::call( Graph& G, ClusterGraphAttributes& acGraph, ClusterGraph& cGraph, EdgeArray<double>& edgeWeight, bool simpleCConnect) //default true { m_nCrossings = 0; bool subGraph = false; // c-planar subgraph computed? //check some simple cases if (G.numberOfNodes() == 0) return; //------------------------------------------------------------- //we set pointers and arrays to the working graph, which can be //the original or, in the case of non-c-planar input, a copy Graph* workGraph = &G; ClusterGraph* workCG = &cGraph; ClusterGraphAttributes* workACG = &acGraph; //potential copy of original if non c-planar Graph GW; //list of non c-planarity causing edges List<edge> leftEdges; //list of nodepairs to be connected (deleted edges) List<NodePair> leftWNodes; //store some information //original to copy NodeArray<node> resultNode(G); EdgeArray<edge> resultEdge(G); ClusterArray<cluster> resultCluster(cGraph); //copy to original NodeArray<node> orNode(G); EdgeArray<edge> orEdge(G); ClusterArray<cluster> orCluster(cGraph); for(node workv : G.nodes) { resultNode[workv] = workv; //will be set to copy if non-c-planar orNode[workv] = workv; } for(edge worke : G.edges) { resultEdge[worke] = worke; //will be set to copy if non-c-planar orEdge[worke] = worke; } for (cluster workc : cGraph.clusters) { resultCluster[workc] = workc; //will be set to copy if non-c-planar orCluster[workc] = workc; } //----------------------------------------------- //check if instance is clusterplanar and embed it CconnectClusterPlanarEmbed CCPE; //cccp bool cplanar = CCPE.embed(cGraph, G); List<edge> connectEdges; //if the graph is not c-planar, we have to check the reason and to //correct the problem by planarising or inserting connection edges if (!cplanar) { bool connect = false; if ( (CCPE.errCode() == CconnectClusterPlanarEmbed::nonConnected) || (CCPE.errCode() == CconnectClusterPlanarEmbed::nonCConnected) ) { //we insert edges to make the input c-connected makeCConnected(cGraph, G, connectEdges, simpleCConnect); //save edgearray info for inserted edges for(edge e : connectEdges) { resultEdge[e] = e; orEdge[e] = e; } connect = true; CCPE.embed(cGraph, G); if ( (CCPE.errCode() == CconnectClusterPlanarEmbed::nonConnected) || (CCPE.errCode() == CconnectClusterPlanarEmbed::nonCConnected) ) { cerr << "no correct connection made\n"<<flush; OGDF_THROW(AlgorithmFailureException); } }//if not cconnected if ((CCPE.errCode() == CconnectClusterPlanarEmbed::nonPlanar) || (CCPE.errCode() == CconnectClusterPlanarEmbed::nonCPlanar)) { subGraph = true; EdgeArray<bool> inSubGraph(G, false); CPlanarSubClusteredGraph cps; if (edgeWeight.valid()) cps.call(cGraph, inSubGraph, leftEdges, edgeWeight); else cps.call(cGraph, inSubGraph, leftEdges); #ifdef OGDF_DEBUG // for(edge worke : G.edges) { // if (inSubGraph[worke]) // acGraph.strokeColor(worke) = "#FF0000"; // } #endif //--------------------------------------------------------------- //now we delete the copies of all edges not in subgraph and embed //the subgraph (use a new copy) //construct copy workGraph = &GW; workCG = new ClusterGraph(cGraph, GW, resultCluster, resultNode, resultEdge); //---------------------- //reinit original arrays orNode.init(GW, nullptr); orEdge.init(GW, nullptr); orCluster.init(*workCG, nullptr); //set array entries to the appropriate values for (node workv : G.nodes) orNode[resultNode[workv]] = workv; for (edge worke : G.edges) orEdge[resultEdge[worke]] = worke; for (cluster workc : cGraph.clusters) orCluster[resultCluster[workc]] = workc; //---------------------------------------------------- //create new ACG and copy values (width, height, type) workACG = new ClusterGraphAttributes(*workCG, workACG->attributes()); for (node workv : GW.nodes) { //should set same attributes in construction!!! if (acGraph.attributes() & GraphAttributes::nodeType) workACG->type(workv) = acGraph.type(orNode[workv]); workACG->height(workv) = acGraph.height(orNode[workv]); workACG->width(workv) = acGraph.width(orNode[workv]); } if (acGraph.attributes() & GraphAttributes::edgeType) { for (edge worke : GW.edges) { workACG->type(worke) = acGraph.type(orEdge[worke]); //all other attributes are not needed or will be set } } for(edge ei : leftEdges) { edge e = resultEdge[ei]; NodePair np; np.m_src = e->source(); np.m_tgt = e->target(); leftWNodes.pushBack(np); GW.delEdge(e); } CconnectClusterPlanarEmbed CCP; #ifdef OGDF_DEBUG bool subPlanar = #endif CCP.embed(*workCG, GW); OGDF_ASSERT(subPlanar); }//if not planar else { if (!connect) OGDF_THROW_PARAM(PreconditionViolatedException, pvcClusterPlanar); } }//if //if multiple CCs are handled, the connectedges (their copies resp.) //can be deleted here //now CCPE should give us the external face ClusterPlanRep CP(*workACG, *workCG); OGDF_ASSERT(CP.representsCombEmbedding()); const int numCC = CP.numberOfCCs(); //equal to one //preliminary OGDF_ASSERT(numCC == 1); // (width,height) of the layout of each connected component Array<DPoint> boundingBox(numCC); for (int ikl = 0; ikl < numCC; ikl++) { CP.initCC(ikl); CP.setOriginalEmbedding(); OGDF_ASSERT(CP.representsCombEmbedding()) Layout drawing(CP); //m_planarLayouter.get().setOptions(4);//progressive adjEntry ae = nullptr; //internally compute adjEntry for outer face //edges that are reinserted in workGraph (in the same //order as leftWNodes) List<edge> newEdges; m_planarLayouter.get().call(CP, ae, drawing, leftWNodes, newEdges, *workGraph); OGDF_ASSERT(leftWNodes.size()==newEdges.size()) OGDF_ASSERT(leftEdges.size()==newEdges.size()) ListConstIterator<edge> itE = newEdges.begin(); ListConstIterator<edge> itEor = leftEdges.begin(); while (itE.valid()) { orEdge[*itE] = *itEor; ++itE; ++itEor; } //hash index over cluster ids HashArray<int, ClusterPosition> CA; computeClusterPositions(CP, drawing, CA); // copy layout into acGraph // Later, we move nodes and edges in each connected component, such // that no two overlap. for(int i = CP.startNode(); i < CP.stopNode(); ++i) { node vG = CP.v(i); acGraph.x(orNode[vG]) = drawing.x(CP.copy(vG)); acGraph.y(orNode[vG]) = drawing.y(CP.copy(vG)); for(adjEntry adj : vG->adjEdges) { if ((adj->index() & 1) == 0) continue; edge eG = adj->theEdge(); edge orE = orEdge[eG]; if (orE) drawing.computePolylineClear(CP,eG,acGraph.bends(orE)); } }//for //even assignment for all nodes is not enough, we need all clusters for(cluster c : workCG->clusters) { int clNumber = c->index(); //int orNumber = originalClId[c]; cluster orCl = orCluster[c]; if (c != workCG->rootCluster()) { OGDF_ASSERT(CA.isDefined(clNumber)); acGraph.height(orCl) = CA[clNumber].m_height; acGraph.width(orCl) = CA[clNumber].m_width; acGraph.y(orCl) = CA[clNumber].m_miny; acGraph.x(orCl) = CA[clNumber].m_minx; }//if real cluster } // the width/height of the layout has been computed by the planar // layout algorithm; required as input to packing algorithm boundingBox[ikl] = m_planarLayouter.get().getBoundingBox(); }//for connected components //postProcess(acGraph); // // arrange layouts of connected components // Array<DPoint> offset(numCC); m_packer.get().call(boundingBox,offset,m_pageRatio); // The arrangement is given by offset to the origin of the coordinate // system. We still have to shift each node, edge and cluster by the offset // of its connected component. const Graph::CCsInfo &ccInfo = CP.ccInfo(); for(int i = 0; i < numCC; ++i) { const double dx = offset[i].m_x; const double dy = offset[i].m_y; HashArray<int, bool> shifted(false); // iterate over all nodes in ith CC for(int j = ccInfo.startNode(i); j < ccInfo.stopNode(i); ++j) { node v = ccInfo.v(j); acGraph.x(orNode[v]) += dx; acGraph.y(orNode[v]) += dy; // update cluster positions accordingly //int clNumber = cGraph.clusterOf(orNode[v])->index(); cluster cl = cGraph.clusterOf(orNode[v]); if ((cl->index() > 0) && !shifted[cl->index()]) { acGraph.y(cl) += dy; acGraph.x(cl) += dx; shifted[cl->index()] = true; }//if real cluster for(adjEntry adj : v->adjEdges) { if ((adj->index() & 1) == 0) continue; edge e = adj->theEdge(); //edge eOr = orEdge[e]; if (orEdge[e]) { DPolyline &dpl = acGraph.bends(orEdge[e]); for(DPoint &p : dpl) { p.m_x += dx; p.m_y += dy; } } } }//for nodes }//for numcc while (!connectEdges.empty()) { G.delEdge(connectEdges.popFrontRet()); } if (subGraph) { //originalClId.init(); orCluster.init(); orNode.init(); orEdge.init(); delete workCG; delete workACG; }//if subgraph created acGraph.removeUnnecessaryBendsHV(); }//call