Main Page Namespace List Class Hierarchy Compound List File List Namespace Members Compound Members File Members Related Pages

# VisualDAG.cpp

Go to the documentation of this file.

    00001
    00049 #include <LEDA/graphwin.h>
    00050 #include <LEDA/color.h>
    00051 #include <LEDA/impl/x_window.h>
    00052 #include "DAG.h"
    00053 #include "ShockGraph.h"
    00054 #include "VisualDAG.h"
    00055 #include "UnixFuncPrototypes.h"
    00056
    00057 #include <stdio.h>
    00058
    00059 // Graph window params
    00060 #define GW_LEFT_MARGIN    50
    00061 #define GW_RIGHT_MARGIN   50
    00062 #define GW_TOP_MARGIN     50
    00063 #define GW_BOTTOM_MARGIN  50
    00064 #define NODE_WIDTH                54
    00065 #define NODE_HEIGHT               25
    00066 #define NODE_FONT_SIZE    11
    00067
    00068 #define HGAP                    (NODE_WIDTH / 4)
    00069 #define VGAP                    (NODE_HEIGHT * 2)
    00070
    00071 // Skeleton window params
    00072 #define SW_LEFT_MARGIN    50
    00073 #define SW_RIGHT_MARGIN   50
    00074 #define SW_TOP_MARGIN     50
    00075 #define SW_BOTTOM_MARGIN  50
    00076 /* #define SW_LEFT_MARGIN    5
    00077 #define SW_RIGHT_MARGIN   5
    00078 #define SW_TOP_MARGIN     5
    00079 #define SW_BOTTOM_MARGIN  5 */
    00080 #define SW_CENTER_MARGIN  20
    00081 #define SW_WIN_WIDTH      800
    00082
    00083 // matching window parms
    00084 #define Y_OFFSET 10
    00085
    00086 unsigned char* ReadPPMFile(const char* szPPMFileName, int* pnRows, int* pnCols);
    00087
    00088
    00089 /* Useful piece of help on leda colors...
    00090
    00091         Colors can be created from rgb-values, from names in a color data base (X11),
    00092         or from the 16 integer constants (enumeration in <LEDA/incl/impl/x\_window.h>)
    00093         $black$, $white$, $red$, $green$, $blue$, $yellow$, $violet$, $orange$;
    00094         $cyan$, $brown$, $pink$, $green2$, $blue2$, $grey1$, $grey2$, $grey3$.
    00095 */
    00096
    00097 void RecomputeTSV(leda_GraphWin& gw, leda_node v)
    00098 {
    00099         DAG& dag = dynamic_cast<DAG&>(gw.get_graph());
    00100
    00101         dag.ComputeTSVs(dag.GetFirstRootNode());
    00102         dag.PrintTSVs();
    00103 }
    00104
    00105 void OnRecomputeTSV(leda_GraphWin& gw, const leda_point& pt)
    00106 {
    00107         double x = pt.xcoord(), y = pt.ycoord();
    00108         leda_list<leda_node> nodes = gw.get_nodes_in_area(x, y, x, y);
    00109
    00110         RecomputeTSV(gw, nodes.pop());
    00111 }
    00112
    00113 void OnDisplayNodeEigenSum(leda_GraphWin& gw, const leda_point& pt)
    00114 {
    00115         const DAG& dag = dynamic_cast<DAG&>(gw.get_graph());
    00116         double x = pt.xcoord(), y = pt.ycoord();
    00117         leda_node v = gw.get_nodes_in_area(x, y, x, y).pop();
    00118
    00119         if (v != nil)
    00120         {
    00121                 double n = dag.GetNode(v)->GetEigenLbl();
    00122                 char sz[50];
    00123                 sprintf(sz, "Eigenvalue Sum = %.4f.", n);
    00124                 gw.message(sz);
    00125         }
    00126 }
    00127
    00128 void OnDisplayNodeInfo(leda_GraphWin& gw, const leda_point& pt)
    00129 {
    00130         const DAG& dag = dynamic_cast<DAG&>(gw.get_graph());
    00131         double x = pt.xcoord(), y = pt.ycoord();
    00132         leda_node v = gw.get_nodes_in_area(x, y, x, y).pop();
    00133
    00134         if (v != nil)
    00135         {
    00136                 double n = dag.GetNode(v)->GetEigenLbl();
    00137                 char sz[500];
    00138
    00139                 const ShockGraph* pSG = dynamic_cast<const ShockGraph*>(&dag);
    00140
    00141                 if (pSG) {
    00142                         sprintf(sz, "%s %d: DFS index: %d, EigenSum: %.4f, Shock Pts: %d",
    00143                                 (const char*)pSG->GetObjName(),
    00144                                 pSG->GetViewNumber(),
    00145                                 pSG->GetNodeDFSIndex(v),
    00146                                 n,
    00147                                 pSG->NodeLength(v));
    00148
    00149                         cout << endl; pSG->GetSGNode(v)->Print();
    00150                         cout << endl; pSG->GetSGNode(v)->m_shocks.Print();
    00151                 }
    00152                 else
    00153                         sprintf(sz, "Label:%s\nEigenSum: %.4f.", (const char*)dag.GetDAGLbl(), n);
    00154
    00155                 gw.message(sz);
    00156         }
    00157 }
    00158
    00159 void OnShowAdjMatrix(leda_GraphWin& gw, const leda_point& pt)
    00160 {
    00161         DAG& dag = dynamic_cast<DAG&>(gw.get_graph());
    00162
    00163         dag.PrintAdjMatrix();
    00164 }
    00165
    00166 void OnNewNode(leda_GraphWin& gw, leda_node v)
    00167 {
    00168         DAG& dag = dynamic_cast<DAG&>(gw.get_graph());
    00169
    00170         dag[v] = dag.CreateNodeObject((const char*)gw.get_label(v));
    00171         RecomputeTSV(gw, v);
    00172 }
    00173
    00174 void OnNewEdge(leda_GraphWin& gw, leda_edge e)
    00175 {
    00176         DAG& dag = dynamic_cast<DAG&>(gw.get_graph());
    00177
    00178         dag[e] = 1.0;
    00179         RecomputeTSV(gw, dag.source(e));
    00180 }
    00181
    00182 void OnDelNode(leda_GraphWin& gw)
    00183 {
    00184         RecomputeTSV(gw, nil);
    00185 }
    00186
    00187 void OnDelEdge(leda_GraphWin& gw)
    00188 {
    00189         RecomputeTSV(gw, nil);
    00190 }
    00191
    00192 int CompNumOfLeaves(DAG& g, leda_node v, NodeIndexMap& map)
    00193 {
    00194         if (!map.defined(v))
    00195         {
    00196                 leda_node u;
    00197                 int n = 0;
    00198
    00199                 if (g.outdeg(v) == 0)
    00200                         n = 1;
    00201                 else
    00202                         forall_adj_nodes(u, v)
    00203                                 n += CompNumOfLeaves(g, u, map);
    00204
    00205                 return map[v] = n;
    00206         }
    00207
    00208         return map[v];
    00209 }
    00210
    00216 double SetNodePos(leda_GraphWin& gw, DAG& g, leda_node v, POINT top_left, NodeIndexMap& map)
    00217 {
    00218         leda_node u;
    00219         int num_lea = map[v];
    00220
    00221         double w = num_lea * NODE_WIDTH + (num_lea - 1) * HGAP;
    00222
    00223         leda_point pos(top_left.x + w / 2, top_left.y);
    00224
    00225         gw.set_position(v, pos);
    00226
    00227         top_left.y -= NODE_HEIGHT + VGAP;
    00228
    00229         forall_adj_nodes(u, v)
    00230         {
    00231                 if (indeg(u) <= 1 || g.GetNodeLevel(u) == g.GetNodeLevel(v) + 1)
    00232                         top_left.x += SetNodePos(gw, g, u, top_left, map) + HGAP;
    00233         }
    00234
    00235         return w;
    00236 }
    00237
    00238 void ShowTree(DAG& g)
    00239 {
    00240         leda_node v, r = g.GetFirstRootNode();
    00241
    00242         // Compute graph's dimensions. Diameter and height
    00243         int nMaxHeight = 0;
    00244
    00245         forall_nodes(v, g)
    00246                 if (g.GetNodeLevel(v) > nMaxHeight)
    00247                         nMaxHeight = g.GetNodeLevel(v);
    00248
    00249         NodeIndexMap map;
    00250         int nLeaves = CompNumOfLeaves(g, r, map);
    00251
    00252         // Set window's dimensions
    00253         int nWinWidth = NODE_WIDTH * nLeaves + HGAP * (nLeaves - 1)
    00254                 + GW_LEFT_MARGIN + GW_RIGHT_MARGIN;
    00255
    00256         int nWinHeight = NODE_HEIGHT * (nMaxHeight + 1) + VGAP * nMaxHeight
    00257                 + GW_TOP_MARGIN + GW_BOTTOM_MARGIN;
    00258
    00259         // Create window
    00260         leda_GraphWin gw(g, nWinWidth, nWinHeight);
    00261         gw.win_init(0, nWinWidth, 0);
    00262
    00263         // Set node positions
    00264         POINT top_left;
    00265
    00266         top_left.x = GW_LEFT_MARGIN;
    00267         top_left.y = gw.get_ymax() - GW_TOP_MARGIN - NODE_HEIGHT / 2;
    00268
    00269         SetNodePos(gw, g, r, top_left, map);
    00270
    00271         // Set nodes' attributes
    00272         forall_nodes(v, g)
    00273         {
    00274                 const DAGNodePtr node = g.GetNode(v);
    00275
    00276                 gw.set_label(v, (const char*)node->GetLblForGraph());
    00277                 gw.set_color(v, node->GetColorForGraph());
    00278                 gw.set_shape(v, (leda_gw_node_shape)node->GetShapeForGraph());
    00279         }
    00280
    00281         gw.set_node_shape(leda_ellipse_node, false);
    00282         gw.set_node_width(NODE_WIDTH, true);
    00283         gw.set_node_height(NODE_HEIGHT, true);
    00284
    00285         // Global params
    00286         gw.set_node_label_font(leda_roman_font, NODE_FONT_SIZE);
    00287         gw.set_show_status(false);
    00288
    00289         gw.add_node_menu("Recompute TSV", OnRecomputeTSV);
    00290         gw.add_node_menu("Display EigenSum", OnDisplayNodeEigenSum);
    00291         gw.add_node_menu("Display node info", OnDisplayNodeInfo);
    00292         gw.add_node_menu("Show adj matrix", OnShowAdjMatrix);
    00293         gw.set_new_node_handler(OnNewNode);
    00294         gw.set_new_edge_handler(OnNewEdge);
    00295         gw.set_del_node_handler(OnDelNode);
    00296         gw.set_del_edge_handler(OnDelEdge);
    00297
    00298         //gw.place_into_win();
    00299         gw.display();
    00300         gw.message((const char*)g.GetDAGLbl());
    00301
    00302         gw.edit();
    00303 }
    00304
    00305 void ShowGraph(DAG& g)
    00306 {
    00307         ShowTree(g);
    00308 }
    00309
    00311 // SGMatchWnd
    00312
    00313 SGMatchWnd::SGMatchWnd()
    00314 {
    00315         m_pWnd = NULL;
    00316         m_bShowLabels = true;
    00317         m_bShowNodeType = false;
    00318         m_nShowColorLines = 0;
    00319         m_bShowCoords = true;
    00320
    00321         m_pSGInfo1 = m_pSGInfo2 = NULL;
    00322 }
    00323
    00324 SGMatchWnd::~SGMatchWnd()
    00325 {
    00326         if (m_pWnd) delete m_pWnd;
    00327
    00328         delete m_pSGInfo1;
    00329         delete m_pSGInfo2;
    00330 }
    00331
    00332 bool SGMatchWnd::Create(const ShockGraph* pSG1, const ShockGraph* pSG2, bool bAsyncMode)
    00333 {
    00334         ASSERT(pSG1 && pSG2);
    00335
    00336         // Set min and max window coordinates
    00337         double xmin = 0;
    00338         double xmax = SW_LEFT_MARGIN + SW_CENTER_MARGIN + SW_RIGHT_MARGIN;
    00339         double ymin = 0;
    00340         double ymax = SW_BOTTOM_MARGIN + SW_TOP_MARGIN;
    00341
    00342         xmax += pSG1->Width() + pSG2->Width();
    00343         ymax += (pSG1->Height() > pSG2->Height()) ? pSG1->Height():pSG2->Height();
    00344
    00345         // Compute scaling factor
    00346         double width = xmax;
    00347         double height = (ymax - ymin) * width / (xmax - xmin);
    00348
    00349         double delta_x, delta_y, reflex_y;
    00350
    00351         // Set SG position info
    00352         delta_x = pSG1->xmin - SW_LEFT_MARGIN;
    00353         delta_y = pSG1->ymin - SW_BOTTOM_MARGIN;
    00354         reflex_y = pSG1->ymax + pSG1->ymin;
    00355
    00356         m_pSGInfo1 = new SGInfo(pSG1, delta_x, delta_y, reflex_y);
    00357
    00358         delta_x = pSG2->xmin - (SW_LEFT_MARGIN + pSG1->Width() + SW_CENTER_MARGIN);
    00359         delta_y = pSG2->ymin - SW_BOTTOM_MARGIN;
    00360         reflex_y = pSG2->ymax + pSG2->ymin;
    00361
    00362         m_pSGInfo2 = new SGInfo(pSG2, delta_x, delta_y, reflex_y);
    00363
    00364         // m_pSGInfo1 and m_pSGInfo2 made a copy of pSG1 and pSG2, so
    00365         // we are ready to create the window in an independent process
    00366         if (bAsyncMode && fork() != 0)
    00367                 return true;
    00368
    00369         // Create a window of the desired size
    00370         m_pWnd = new Wnd((int)width, (int)height, "r:redraw, l:labels, t:types, a,b:graphs, q:quit", this);
    00371         m_pWnd->init(xmin, xmax, ymin);
    00372         //m_pWnd->set_show_coordinates(m_bShowCoords);
    00373
    00374         m_pWnd->display(0, 0);
    00375         m_pWnd->redraw();
    00376
    00377         int val;
    00378         double x, y;
    00379         int event;
    00380
    00381         while (true)
    00382         {
    00383                 event = m_pWnd->read_event(val, x, y);
    00384
    00385                 if (event == leda_key_release_event)
    00386                 {
    00387                         if (val == 'r' || val == 'R')
    00388                                 m_pWnd->reset_clipping();
    00389                         else if (val == 'l' || val == 'L')
    00390                                 m_bShowLabels = !m_bShowLabels;
    00391                         else if (val == 't' || val == 'T')
    00392                                 m_bShowNodeType = !m_bShowNodeType;
    00393                         else if (val == 'a' || val == 'b')
    00394                         {
    00395                                 ShockGraph sg;
    00396                                 sg = (val == 'a') ? *GetSGInfo1()->pSG:*GetSGInfo2()->pSG;
    00397                                 ShowGraph(sg);
    00398                         }
    00399                         else if (val == 'c' || val == 'C')
    00400                                 m_bShowCoords = !m_bShowCoords;
    00401                                 //m_pWnd->set_show_coordinates(m_bShowCoords = !m_bShowCoords);
    00402                         else if (isdigit(val))
    00403                                 m_nShowColorLines = val - '0';
    00404                         else
    00405                                 break;
    00406
    00407                         m_pWnd->redraw();
    00408                 }
    00409                 else if (event == leda_exposure_event)
    00410                         m_pWnd->reset_clipping();
    00411                 else if (event == leda_destroy_event)
    00412                         break;
    00413         }
    00414
    00415         if (bAsyncMode)
    00416                 exit(0); // It's a child process
    00417
    00418         return true;
    00419 }
    00420
    00421 leda_point ReMapPt(const sg::Point& a, const SGMatchWnd::SGInfo* si)
    00422 {
    00423         return leda_point(a.x - si->delta_x, si->reflex_y - a.y - si->delta_y);
    00424 }
    00425
    00426 leda_point ReMapPt(const leda_point& a, const SGMatchWnd::SGInfo* si)
    00427 {
    00428         return leda_point(a.xcoord() - si->delta_x, si->reflex_y - a.ycoord() - si->delta_y);
    00429 }
    00430
    00431 void SGMatchWnd::Wnd::OnShowCoord(leda_window* pBaseWnd, double x, double y)
    00432 {
    00433     Wnd* pWnd = dynamic_cast<Wnd*>(pBaseWnd);
    00434     SGMatchWnd* pSGWnd = pWnd->m_pParent;
    00435
    00436     double centerPt = SW_LEFT_MARGIN + pSGWnd->GetSGInfo1()->pSG->Width() + SW_CENTER_MARGIN / 2.0;
    00437
    00438     leda_point pt = ReMapPt(leda_point(-x, y), (x <= centerPt) ? pSGWnd->GetSGInfo1():pSGWnd->GetSGInfo2());
    00439
    00440     x = pWnd->xmin();
    00441     y = pWnd->ymax();
    00442     pWnd->draw_box(x, y - 30, x + 100, y, leda_white);
    00443
    00444     if (pSGWnd->m_bShowCoords)
    00445     {
    00446         char szTxt[100];
    00447         sprintf(szTxt, "%.1f %.1f", -pt.xcoord(), pt.ycoord());
    00448         pWnd->draw_text(x + 10, y - 10, szTxt);
    00449     }
    00450 }
    00451
    00452 void SGMatchWnd::Wnd::OnDraw(leda_window* pBaseWnd)
    00453 {
    00454         Wnd* pWnd = dynamic_cast<Wnd*>(pBaseWnd);
    00455         ASSERT(pWnd);
    00456
    00457         SGMatchWnd* pSGWnd = pWnd->m_pParent;
    00458
    00459         //w.start_buffering();
    00460
    00461         //      pWnd->clear(leda_black);
    00462
    00463         pSGWnd->DrawSG();
    00464         pSGWnd->DrawMatchingLines();
    00465
    00466         //pWnd->draw_segment(pWnd->xmin(), pWnd->ymin() + BOTTOM_MARGIN, pWnd->xmax(),
    00467         //pWnd->ymin() + BOTTOM_MARGIN, leda_color(255, 0, 0));
    00468
    00469         //w.flush_buffer();
    00470         //w.stop_buffering();
    00471
    00472 }
    00473
    00474 bool SGMatchWnd::DrawSkeleton(const SGInfo* si) const
    00475 {
    00476         if (!si->pSG->GetSkeleton())
    00477                 return false;
    00478
    00479         sg::DDSkeleton* sk = ((McGillSkeleton*)si->pSG->GetSkeleton())->GetSkeleton();
    00480
    00481     // now draw the contour
    00482     Curve *c = sk->getShape()->getCurves()->front();
    00483     const double step = 0.5;
    00484     double t=0;
    00485     sg::Point p1, p2;
    00486     leda_list<leda_point> pts;
    00487
    00488     for(t = 0; t < c->getLength() - 2 * step; t += step)
    00489                 pts.push(ReMapPt(c->atT(t), si));
    00490
    00491     m_pWnd->draw_polygon(pts);
    00492     //m_pWnd->draw_pixels(pts);
    00493
    00494     m_pWnd->draw_segment(ReMapPt(c->atT(t), si), ReMapPt(c->atT(0), si));
    00495
    00496     return true;
    00497 }
    00498
    00499 void SGMatchWnd::DrawSG() const
    00500 {
    00501         const SGNode* pNode;
    00502         leda_node v;
    00503         int i, j, size;
    00504         const SGInfo* info[] = {GetSGInfo1(), GetSGInfo2()};
    00505         double x1, y1, m;
    00506         char cEndPt;
    00507         leda_color c;
    00508         int t, rows, cols, colorIdx;
    00509
    00510         // define possible pixel colors
    00511         leda_color color[] = {leda_black, leda_red, leda_brown, leda_blue, leda_violet, leda_grey3};
    00512
    00513         m_pWnd->start_buffering();
    00514
    00515         m_pWnd->clear(leda_white);
    00516
    00517         for (i = 0; i < 2; i++)
    00518         {
    00519         unsigned char* pImg = ReadPPMFile(info[i]->pSG->GetDAGLbl(), &rows, &cols);
    00520
    00521                 if (pImg)
    00522                 {
    00523                         int r,c,k;
    00524
    00525                         for (r = 0, k = 0; r < rows; r++)
    00526                                 for (c = 0; c < cols; c++, k++)
    00527                                         if (pImg[k] != 1)
    00528                                             m_pWnd->draw_pixel(ReMapPt(leda_point(c, r), info[i]), leda_grey1);
    00529
    00530
    00531                         delete[] pImg;
    00532                 }
    00533
    00534         DrawSkeleton(info[i]);
    00535
    00536                 colorIdx = 0;
    00537
    00538                 forall_nodes(v, *(info[i]->pSG))
    00539                 {
    00540                         pNode = info[i]->pSG->GetSGNode(v);
    00541                         cEndPt = pNode->GetEndPt();
    00542
    00543                         t = pNode->m_nType;
    00544
    00545                         if (t == SHOCK_1 || t == SHOCK_2 || t == SHOCK_3 || t == SHOCK_4)
    00546                         {
    00547                                         size = pNode->m_shocks.GetSize();
    00548
    00549                                         if (size == 0)
    00550                                         {
    00551                                                 //WARNING(pNode->m_shocks.GetSize() == 0, "Node has no shocks");
    00552                                                 continue;
    00553                                         }
    00554
    00555                                         const ShockInfo& s0 = pNode->m_shocks[0];
    00556                                         const ShockInfo& sN = pNode->m_shocks[size - 1];
    00557
    00558                                         if (s0.xcoord != sN.xcoord)
    00559                                                 m = (s0.ycoord - sN.ycoord) / (s0.xcoord - sN.xcoord);
    00560                                         else
    00561                                                 m = 1;
    00562
    00563                                         for (j = 0; j < size; j++)
    00564                                         {
    00565                                                 const ShockInfo& s1 = pNode->m_shocks[j];
    00566
    00567                                                 x1 = s1.xcoord - info[i]->delta_x;
    00568                                                 y1 = (info[i]->reflex_y - s1.ycoord) - info[i]->delta_y;
    00569                                                 c = color[colorIdx % (sizeof(color) / sizeof(color[0]))];
    00570
    00571                                                 m_pWnd->draw_pixel(x1, y1, c);
    00572
    00573                                                 if (m_bShowLabels)
    00574                                                 {
    00575                                                         if ((cEndPt == 'a' && j == 0) ||
    00576                                                                 (cEndPt == 'b' && j == 0) ||
    00577                                                                 (cEndPt != 'a' && cEndPt != 'b' && j == size / 2))
    00578                                                         {
    00579                                                                 /*if (m < 0 || m == 1)
    00580                                                                         x1 += 4;
    00581                                                                 else if (m > 0)
    00582                                                                         x1 -= 12;*/
    00583
    00584                                                                 if (m_bShowNodeType)
    00585                                                                         m_pWnd->draw_text(x1, y1, (const char*)info[i]->pSG->GetNodeLbl(v),
    00586                                                                                 c/*leda_color(255, 0, 0)*/);
    00587                                                                 else
    00588                                                                         m_pWnd->draw_text(x1, y1, (const char*)((const DAG*)(const ShockGraph*)info[i]->pSG)->GetNodeLbl(v),
    00589                                                                                 c/*leda_color(255, 0, 0)*/);
    00590                                                         }
    00591                                                 }
    00592                                         }
    00593
    00594                                         colorIdx++;
    00595
    00596                                         /*for (j = 0; j < size - 1; j++)
    00597                                         {
    00598                                                 const ShockInfo& s1 = pNode->m_shocks[j];
    00599                                                 const ShockInfo& s2 = pNode->m_shocks[j + 1];
    00600
    00601                                                 x1 = s1.xcoord - info[i]->delta_x;
    00602                                                 y1 = (info[i]->reflex_y - s1.ycoord) - info[i]->delta_y;
    00603                                                 x2 = s2.xcoord - info[i]->delta_x;
    00604                                                 y2 = (info[i]->reflex_y - s2.ycoord) - info[i]->delta_y;
    00605
    00606                                                 m_pWnd->draw_segment(x1, y1, x2, y2);
    00607
    00608                                                 if (j == size / 2)
    00609                                                         m_pWnd->draw_text(x1, y1, info[i]->pSG->GetNodeLbl(v), leda_color(255, 0, 0));
    00610                                         }*/
    00611                         }
    00612                         else if (t != ROOT) // There's no info in the root
    00613                                 cerr << "\nERROR: Unknown node type." << endl;
    00614                 }
    00615         }
    00616
    00617         m_pWnd->flush_buffer();
    00618         m_pWnd->stop_buffering();
    00619 }
    00620
    00621 void SGMatchWnd::DrawMatchingLines() const
    00622 {
    00623         DAGNodePtr ptr;
    00624         const SGNode* pNode1, *pNode2;
    00625         leda_color color[] = {leda_yellow, leda_pink, leda_grey1, leda_grey2, leda_grey3,
    00626                                                   leda_black, leda_violet, leda_red, leda_blue, leda_green};
    00627         const int NUMCOLORS = sizeof(color) / sizeof(color[0]);
    00628         int color_index = 0, c;
    00629         double arc_x,arc_y;
    00630
    00631         unsigned int i = 0;
    00632
    00633         if (m_matchMap.empty())
    00634                 return;
    00635
    00636         forall_defined(ptr, m_matchMap)
    00637         {
    00638                 pNode1 = dynamic_cast<const SGNode*>((const DAGNode*) ptr);
    00639                 pNode2 = dynamic_cast<const SGNode*>((const DAGNode*) m_matchMap[ptr]);
    00640
    00641                 if (pNode1->GetShockCount() > 0 && pNode2->GetShockCount() > 0)
    00642                 {
    00643                         const ShockInfo& s1 = pNode1->m_shocks[pNode1->GetShockCount()/2];
    00644                         const ShockInfo& s2 = pNode2->m_shocks[pNode2->GetShockCount()/2];
    00645
    00646                         /* arc will go from s1 to s2, but will pass along the way through s3,
    00647                            where s3 is midway between s1 and s2 and up a fixed amount. */
    00648                         leda_point start(s1.xcoord - GetSGInfo1()->delta_x,
    00649                                          (GetSGInfo1()->reflex_y - s1.ycoord) - GetSGInfo1()->delta_y);
    00650                         leda_point end(s2.xcoord - GetSGInfo2()->delta_x,
    00651                                        (GetSGInfo2()->reflex_y - s2.ycoord) - GetSGInfo2()->delta_y);
    00652                         arc_x = (start.xcoord() + end.xcoord())/2;
    00653                         arc_y = (start.ycoord() + end.ycoord())/2 + abs(start.xcoord() - end.xcoord()) * (Y_OFFSET / 100.0);
    00654                         if (arc_y >= (start.ycoord() + end.ycoord())/2 + Y_OFFSET)
    00655                           {
    00656                             arc_y = (start.ycoord() + end.ycoord())/2 + Y_OFFSET;
    00657                           }
    00658
    00659                         leda_point mid(arc_x, arc_y);
    00660
    00661                         //c = color_index++ % NUMCOLORS;
    00662                         c = int(pNode2->GetSimilarity() * NUMCOLORS - 1);
    00663                         if (c < 0) c = 0;
    00664
    00665                         if (m_nShowColorLines == 0 || m_nShowColorLines - 1 == c)
    00666                                 m_pWnd->draw_arc(start, mid, end, color[c]);
    00667
    00668                         /*      m_pWnd->draw_segment(
    00669                                 s1.xcoord - GetSGInfo1()->delta_x,
    00670                                 (GetSGInfo1()->reflex_y - s1.ycoord) - GetSGInfo1()->delta_y,
    00671                                 s2.xcoord - GetSGInfo2()->delta_x,
    00672                                 (GetSGInfo2()->reflex_y - s2.ycoord) - GetSGInfo2()->delta_y,
    00673                                 c[(pNode1->GetType() - 1) % NUMCOLORS)]);
    00674                         */
    00675                 }
    00676         }
    00677 }
    00678
    00679 void SGMatchWnd::SetMatchMap(const DAGNodeMap& matchMap)
    00680 {
    00681         m_matchMap = matchMap;
    00682
    00683         /*bool bFisrtTime = true;
    00684         int val;
    00685         double x, y;
    00686
    00687         //m_pWnd->redraw();
    00688
    00689         while (true)
    00690         {
    00691                  if (m_pWnd->read_event(val, x, y) == key_release_event)
    00692                  {
    00693                         if (bFisrtTime)
    00694                         {
    00695                                 m_matchMap = matchMap;
    00696                                 m_pWnd->redraw();
    00697                                 bFisrtTime = false;
    00698                         }
    00699                         else
    00700                                 break;
    00701                  }
    00702         }*/
    00703 }
    00704
    00710 unsigned char* ReadPPMFile(const char* szPPMFileName, int* pnRows, int* pnCols)
    00711 {
    00712         FILE* fp;
    00713
    00714         if ((fp = fopen(szPPMFileName, "r")) == NULL)
    00715                 return NULL;
    00716
    00717         pixel** img;
    00718         pixval maxval;
    00719         int i, j, k;
    00720         char r, g, b;
    00721
    00722         img = ppm_readppm(fp, pnCols, pnRows, &maxval);
    00723         fclose(fp);
    00724
    00725         unsigned char* arr = new unsigned char[(*pnRows)*(*pnCols)];
    00726
    00727         for(i = 0, k = 0; i < *pnRows; i++)
    00728                 for(j = 0; j < *pnCols; j++, k++)
    00729                 {
    00730                         r = (0xff * PPM_GETR(img[i][j])) / maxval;
    00731                         g = (0xff * PPM_GETG(img[i][j])) / maxval;
    00732                         b = (0xff * PPM_GETB(img[i][j])) / maxval;
    00733
    00734                         arr[k] = (r==0 && b==0 && g==0) ? 0:1; //or 0xff;
    00735                 }
    00736
    00737         ppm_freearray(img, *pnRows);
    00738
    00739         return arr;
    00740 }
    00741