From: Kevin M. Rosenberg Date: Mon, 4 Sep 2000 09:06:46 +0000 (+0000) Subject: r189: *** empty log message *** X-Git-Tag: debian-4.5.3-3~828 X-Git-Url: http://git.kpe.io/?p=ctsim.git;a=commitdiff_plain;h=3147cd44cff6132e51eac1a179c1fc3d405faacc r189: *** empty log message *** --- diff --git a/ChangeLog b/ChangeLog index d584f20..9cf582f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,8 +1,11 @@ -2.0.0-b12 - 9/7/00 +2.0.0-b12 - 9/4/00 + ctsim: Added animation of reconstruction + ctsim: Added saving of dialog parameters for Projection & Reconstruction + ctsim: Added progress dialog for rasterization of phantom ctsim: used setpriority to set lower priority ctsim: fixed pReconstruct not being deleted causing scaling problem ctsim: fixed projection animation dialog buttons - + 2.0.0-b11 - 9/1/00 ctsim: Added projection graph to animation of projection collection ctsim: Added single stepping to projection collection animation diff --git a/TODO b/TODO index 71a56a6..80db119 100644 --- a/TODO +++ b/TODO @@ -1,8 +1,6 @@ -Fix BUGS -- see BUGS file - Convert pol to C++ object. Add divergent filtering to frequency/direct filtering -FFT filtering requires FFTW library. Add a public domain FFT routine. +FFT filtering requires FFTW library. Add a basic FFT routine. diff --git a/config.h.in b/config.h.in index 188ee6d..6675c91 100644 --- a/config.h.in +++ b/config.h.in @@ -150,19 +150,21 @@ /* Define if you have the header file. */ #undef HAVE_SYS_PARAM_H +/* Define if you have the header file. */ +#undef HAVE_SYS_RESOURCE_H + /* Define if you have the header file. */ #undef HAVE_SYS_STAT_H +/* Define if you have the header file. */ +#undef HAVE_SYS_TIME_H + /* Define if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Define if you have the header file. */ #undef HAVE_UNISTD_H -#undef HAVE_SYS_TIME_H - -#undef HAVE_SYS_RESOURCE_H - /* Define if you have the m library (-lm). */ #undef HAVE_LIBM @@ -172,4 +174,3 @@ /* Version number of package */ #undef VERSION -#undef HAVE_SETPRIORITY diff --git a/include/ezplot.h b/include/ezplot.h index 716fd3e..1ad8b52 100644 --- a/include/ezplot.h +++ b/include/ezplot.h @@ -7,7 +7,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: ezplot.h,v 1.13 2000/08/31 08:38:58 kevin Exp $ +** $Id: ezplot.h,v 1.14 2000/09/04 09:06:46 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -51,22 +51,22 @@ class EZPlotCurve { ~EZPlotCurve(); }; -/*----------------------------------------------------------------------*/ -/* GLOBAL VARIABLES */ -/*----------------------------------------------------------------------*/ +//---------------------------------------------------------------------- +// GLOBAL VARIABLES +//---------------------------------------------------------------------- -/* axis definitions */ -#define LINEAR 1 /* linear axis */ -#define LOG 2 /* logrithmic axis */ -#define NOAXIS 3 /* don't plot axis */ +// axis definitions +#define LINEAR 1 // linear axis +#define LOG 2 // logrithmic axis +#define NOAXIS 3 // don't plot axis -/* tick definitions */ +// tick definitions #define ABOVE 1 #define BELOW 2 #define RIGHT 4 #define LEFT 8 -/* line types */ +// line types #define NOLINE 0 #define SOLID 1 #define DASH 2 @@ -75,7 +75,7 @@ class EZPlotCurve { #define DASH3 12 #define DASH4 13 -/* symbol definitions */ +// symbol definitions #define SB_CROSS 1 #define SB_PLUS 2 #define SB_BOX 3 @@ -83,7 +83,7 @@ class EZPlotCurve { #define SB_ERRORBAR 5 #define MAXSYMBOL 5 -#define INSIDE 1 /* values of o_legendbox */ +#define INSIDE 1 // values of o_legendbox #define OUTSIDE 2 #define NOLEGEND 3 @@ -122,76 +122,81 @@ class EZPlot { vector m_vecCurves; // Colors - int clr_axis; /* color of all axis lines */ - int clr_title; /* color of main title */ - int clr_label; /* color of axis labels */ - int clr_legend; /* color of legend box */ - int clr_grid; /* color of grid lines */ - int clr_number; /* color of axis number labels */ + int clr_axis; // color of all axis lines + int clr_title; // color of main title + int clr_label; // color of axis labels + int clr_legend; // color of legend box + int clr_grid; // color of grid lines + int clr_number; // color of axis number labels // Options - double o_xporigin, o_yporigin; /* origin of plot frame in NDC */ - double o_xlength, o_ylength; /* length of plot frame in NDC */ + double o_xporigin, o_yporigin; // origin of plot frame in NDC + double o_xlength, o_ylength; // length of plot frame in NDC - string c_xlabel; /* label for x axis */ - string c_ylabel; /* label for y axis */ - string c_title; /* title to print above graph */ - string c_legend;; /* current legend specified */ + string c_xlabel; // label for x axis + string c_ylabel; // label for y axis + string c_title; // title to print above graph + string c_legend;; // current legend specified - int o_linestyle, o_color; /* style to use for curves all subsequent curves to EZPLOT */ - bool o_xaxis, o_yaxis; /* Specifies where axis & labels are drawn */ - bool o_grid; /* Flag to draw a grid at major ticks */ - bool o_box; /* Flag to draw a box around the graph */ + int o_linestyle, o_color; // style to use for curves all subsequent curves to EZPLOT + bool o_xaxis, o_yaxis; // Specifies where axis & labels are drawn + bool o_grid; // Flag to draw a grid at major ticks + bool o_box; // Flag to draw a box around the graph - int o_xticks, o_yticks; /* direction to draw tick marks */ - bool o_xtlabel, o_ytlabel; /* TRUE if label tick marks */ + int o_xticks, o_yticks; // direction to draw tick marks + bool o_xtlabel, o_ytlabel; // TRUE if label tick marks - int o_xmajortick, o_ymajortick; /* number of major ticks to draw */ - int o_xminortick, o_yminortick; /* number of minor ticks between major ticks */ + int o_xmajortick, o_ymajortick; // number of major ticks to draw + int o_xminortick, o_yminortick; // number of minor ticks between major ticks - int o_symbol; /* Symbol type, (0 = no symbol) */ - int o_symfreq; /* frequency to draw symbols at curve points */ + int o_symbol; // Symbol type, (0 = no symbol) + int o_symfreq; // frequency to draw symbols at curve points - int o_legendbox; /* controls whether legend is inside or outside of the axis extents */ - int o_tag; /* controls whether to draw tag at end of axes */ + int o_legendbox; // controls whether legend is inside or outside of the axis extents + int o_tag; // controls whether to draw tag at end of axes // VALUE & SET variables - double v_xmin, v_xmax, v_ymin, v_ymax; /* user supplied axis endpoints */ - bool s_xmin, s_xmax, s_ymin, s_ymax; /* TRUE is endpoint has been set */ - double v_xtitle, v_ytitle; /* NDC position to plot title */ - bool s_xtitle, s_ytitle; /* TRUE if set position for title */ - double v_xcross, v_ycross; /* position that axes cross */ - bool s_xcross, s_ycross; /* TRUE if set axes cross position */ - double v_xlegend, v_ylegend; /* upper-left position of legend box in NDC */ - bool s_xlegend, s_ylegend; /* TRUE if set position of legend box */ - int v_lxfrac, v_lyfrac; /* number of digits to right of decimal place */ - bool s_lxfrac, s_lyfrac; /* TRUE if set number of fractional digits */ - double v_textsize; /* size of text in NDC */ - bool s_textsize; /* TRUE if user set size of text */ + double v_xmin, v_xmax, v_ymin, v_ymax; // user supplied axis endpoints + bool s_xmin, s_xmax, s_ymin, s_ymax; // TRUE is endpoint has been set + double v_xtitle, v_ytitle; // NDC position to plot title + bool s_xtitle, s_ytitle; // TRUE if set position for title + double v_xcross, v_ycross; // position that axes cross + bool s_xcross, s_ycross; // TRUE if set axes cross position + double v_xlegend, v_ylegend; // upper-left position of legend box in NDC + bool s_xlegend, s_ylegend; // TRUE if set position of legend box + int v_lxfrac, v_lyfrac; // number of digits to right of decimal place + bool s_lxfrac, s_lyfrac; // TRUE if set number of fractional digits + double v_textsize; // size of text in NDC + bool s_textsize; // TRUE if user set size of text // Global variables - double charheight; /* Height of characters in NDC */ - double charwidth; /* Height of characters in NDC */ - double xp_min, xp_max, yp_min, yp_max; /* boundry of plot frame in NDC */ - double xa_min, xa_max, ya_min, ya_max; /* extent of axes in NDC */ - double xgw_min, xgw_max, ygw_min, ygw_max; /* boundary of graph in input coords */ - double xgn_min, xgn_max, ygn_min, ygn_max; /* boundy of graph in NDC */ - double xt_min, xt_max, yt_min, yt_max; /* boundary of axis ticks */ - double xl_min, xl_max, yl_min, yl_max; /* boundary of legend box */ - double title_row; /* y-coord of title row */ - double xtl_ofs; /* Offset y-coord of x tick labels from axis */ - double ytl_ofs; /* Offset x-coord of y tick labels from axis */ - double xlbl_row; /* row of x label in world coord */ - double ylbl_col; /* column of y label in world coord */ - double xw_tickinc, yw_tickinc; /* increment between major ticks in WC */ - double xn_tickinc, yn_tickinc; /* increment between major ticks in NDC */ - int x_nint, y_nint; /* number of intervals along x & y axes */ - int x_fldwid, x_frac; /* numeric field sizes & number of digits */ - int y_fldwid, y_frac; /* in fraction of number, used for printf() */ - double xtl_wid, ytl_wid; /* length of ticks labels in NDC */ - double tl_height; /* height of tick labels in NDC */ - char x_numfmt[20]; /* format to print x tick labels */ - char y_numfmt[20]; /* format to print y tick labels */ + double charheight; // Height of characters in NDC + double charwidth; // Height of characters in NDC + double xp_min, xp_max, yp_min, yp_max; // boundry of plot frame in NDC + double xa_min, xa_max, ya_min, ya_max; // extent of axes in NDC + double xgw_min, xgw_max, ygw_min, ygw_max; // boundary of graph in input coords + double xgn_min, xgn_max, ygn_min, ygn_max; // boundy of graph in NDC + double xt_min, xt_max, yt_min, yt_max; // boundary of axis ticks + double xl_min, xl_max, yl_min, yl_max; // boundary of legend box + double title_row; // y-coord of title row + double xtl_ofs; // Offset y-coord of x tick labels from axis + double ytl_ofs; // Offset x-coord of y tick labels from axis + double xlbl_row; // row of x label in world coord + double ylbl_col; // column of y label in world coord + double xw_tickinc, yw_tickinc; // increment between major ticks in WC + double xn_tickinc, yn_tickinc; // increment between major ticks in NDC + int x_nint, y_nint; // number of intervals along x & y axes + int x_fldwid, x_frac; // numeric field sizes & number of digits + int y_fldwid, y_frac; // in fraction of number, used for printf() + double xtl_wid, ytl_wid; // length of ticks labels in NDC + double tl_height; // height of tick labels in NDC + char x_numfmt[20]; // format to print x tick labels + char y_numfmt[20]; // format to print y tick labels + + double m_dVP_xmin, m_dVP_ymin; + double m_dVP_xmax, m_dVP_ymax; + double m_dVP_xscale, m_dVP_yscale; + double m_xWorldScale, m_yWorldScale; void drawAxes(void); void symbol (int sym, double symwidth, double symheight); @@ -211,6 +216,12 @@ class EZPlot { static bool ezset_initialized; + double convertWorldToNDC_X (double x) + { return xgn_min + (x - xgw_min) * m_xWorldScale; } + + double convertWorldToNDC_Y (double y) + { return ygn_min + (y - ygw_min) * m_yWorldScale; } + public: EZPlot (SGP& sgp); ~EZPlot (); @@ -226,9 +237,9 @@ class EZPlot { void plot (); }; -/*----------------------------------------------------------------------*/ -/* Codes from LEX */ -/*----------------------------------------------------------------------*/ +//---------------------------------------------------------------------- +// Codes from LEX +//---------------------------------------------------------------------- #define S_DATA 2 #define S_HELP 3 diff --git a/include/phantom.h b/include/phantom.h index 56a8007..399c542 100644 --- a/include/phantom.h +++ b/include/phantom.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: phantom.h,v 1.13 2000/08/25 15:59:13 kevin Exp $ +** $Id: phantom.h,v 1.14 2000/09/04 09:06:46 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -160,7 +160,7 @@ class Phantom void addPElem (const char* const composition, const double cx, const double cy, const double u, const double v, const double rot, const double atten); - void convertToImagefile (ImageFile& im, const int in_nsample, const int trace, const int colStart, const int colCount) const; + void convertToImagefile (ImageFile& im, const int in_nsample, const int trace, const int colStart, const int colCount, bool bStoreAtColumnPos) const; void convertToImagefile (ImageFile& im, const int in_nsample, const int trace) const; diff --git a/include/sgp.h b/include/sgp.h index a873d18..fce79a6 100644 --- a/include/sgp.h +++ b/include/sgp.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: sgp.h,v 1.17 2000/09/02 05:10:39 kevin Exp $ +** $Id: sgp.h,v 1.18 2000/09/04 09:06:46 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -36,6 +36,7 @@ #ifdef HAVE_WXWINDOWS #include +#include #endif #if HAVE_G2_H @@ -126,6 +127,7 @@ private: double m_dCurrentWorldY; double m_dTextAngle; bool m_bRecalcTransform; + double m_dPointsPerPixel; // points (72pt/in) per screen pixel; // Master coordinates are coordinates before CTM transformation // World coordinates are coordinates defined by setWindow() @@ -142,6 +144,7 @@ private: #if HAVE_WXWINDOWS wxPen m_pen; + wxFont m_font; #endif public: @@ -196,6 +199,8 @@ public: void setColor (int icol); void setLineStyle (int style); void setTextSize (double height); + void setTextNDCSize (double height); + void setTextPointSize (double height); void setTextAngle (double angle); void setTextColor (int iFGcolor, int iBGcolor); void setPenWidth (int width); @@ -206,6 +211,9 @@ public: void getViewport (double& xmin, double& ymin, double& xmax, double& ymax); void getTextExtent (const char *szText, double* x, double* y); double getCharHeight (); + double getCharWidth (); + SGPDriver& getDriver() {return m_driver;} + const SGPDriver& getDriver() const {return m_driver;} void ctmClear (); void ctmSet (const TransformationMatrix2D& m); diff --git a/libctgraphics/ezplot.cpp b/libctgraphics/ezplot.cpp index fb823b5..29f2c7f 100644 --- a/libctgraphics/ezplot.cpp +++ b/libctgraphics/ezplot.cpp @@ -6,7 +6,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: ezplot.cpp,v 1.13 2000/09/02 05:10:39 kevin Exp $ +** $Id: ezplot.cpp,v 1.14 2000/09/04 09:06:46 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -34,7 +34,6 @@ static const double DEF_CHARWIDTH = (1./80.); // size of characters in NDC static const int DEF_CURVE_CLR = C_RED; - EZPlotCurve::EZPlotCurve (const double* xData, const double* yData, int n, int color, int linestyle, int symbol, int symfreq, const string& legend) : x(NULL), y(NULL), m_sLegend (legend) { @@ -142,9 +141,9 @@ EZPlot::EZPlot (SGP& sgp) void EZPlot::initPlotSettings () { - charwidth = DEF_CHARWIDTH; charheight = DEF_CHARHEIGHT; - + charwidth = DEF_CHARWIDTH; + c_xlabel = ""; c_ylabel = ""; c_title = ""; @@ -189,7 +188,7 @@ EZPlot::initPlotSettings () s_ylegend = FALSE; s_textsize = FALSE; - clr_axis = C_BLACK; /* set fixed colors */ + clr_axis = C_BLACK; // set fixed colors clr_title = C_CYAN; clr_label = C_CYAN; clr_legend = C_RED; @@ -214,19 +213,18 @@ EZPlot::initPlotSettings () void EZPlot::plot () { - double x_added_ticks; /* number of tick spaces added to axis */ - double y_added_ticks; - double symwidth, symheight; /* size of symbol in NDC */ - double leg_width, leg_height; /* size of legend box */ - int i, j, ip, n; - if (m_vecCurves.size() <= 0) return; - - if (s_textsize == TRUE) + + rSGP.setWindow (0., 0., 1., 1.); + + if (s_textsize == TRUE) { charheight = v_textsize; - else - charheight = DEF_CHARHEIGHT; + charwidth = rSGP.getCharWidth(); + } else { + charheight = rSGP.getCharHeight(); + charwidth = rSGP.getCharWidth(); + } const EZPlotCurve& firstCurve = *m_vecCurves[0]; double xmin = firstCurve.x[0]; // extent of curves in world coord @@ -236,8 +234,8 @@ EZPlot::plot () for (EZPlotCurveConstIterator iterCurve = m_vecCurves.begin(); iterCurve != m_vecCurves.end(); iterCurve++) { const EZPlotCurve& curve = **iterCurve; - - for (ip = 0; ip < curve.m_iPointCount; ip++) { + + for (int ip = 0; ip < curve.m_iPointCount; ip++) { if (curve.x[ip] > xmax) xmax = curve.x[ip]; else if (curve.x[ip] < xmin) @@ -264,11 +262,11 @@ EZPlot::plot () ymax = v_ycross; } - /* find nice endpoints for axes */ + // find nice endpoints for axes if (! axis_scale (xmin, xmax, o_xmajortick - 1, &xgw_min, &xgw_max, &x_nint) || ! axis_scale (ymin, ymax, o_ymajortick - 1, &ygw_min, &ygw_max, &y_nint)) return; - /* check if user set x-axis extents */ + // check if user set x-axis extents if (s_xmin == TRUE) { xgw_min = v_xmin; x_nint = o_xmajortick - 1; @@ -278,7 +276,7 @@ EZPlot::plot () x_nint = o_xmajortick - 1; } - /* check if user set y-axis extents */ + // check if user set y-axis extents if (s_ymin == TRUE) { ygw_min = v_ymin; y_nint = o_ymajortick - 1; @@ -288,11 +286,11 @@ EZPlot::plot () y_nint = o_ymajortick - 1; } - /* calculate increment between major axis in world coordinates */ + // calculate increment between major axis in world coordinates xw_tickinc = (xgw_max - xgw_min) / x_nint; yw_tickinc = (ygw_max - ygw_min) / y_nint; - /* we have now calcuated xgw_min, xyw_max, ygw_min, & ygw_max */ + // we have now calcuated xgw_min, xyw_max, ygw_min, & ygw_max // set the number of decimal point to users' setting or default // Two formats for numbers: Fixed: -nnn.f and Exponent: -n.fffE+eee @@ -309,12 +307,11 @@ EZPlot::plot () make_numfmt (x_numfmt, &x_fldwid, &x_frac, xgw_min, xgw_max, x_nint); make_numfmt (y_numfmt, &y_fldwid, &y_frac, ygw_min, ygw_max, y_nint); - xtl_wid = x_fldwid * charwidth; /* calc size of tick labels */ + xtl_wid = x_fldwid * charwidth; // calc size of tick labels ytl_wid = y_fldwid * charwidth; tl_height = charheight; - // rSGP.getViewport (xp_min, yp_min, xp_max, yp_max); - /* calculate the extent of the plot frame */ + // calculate the extent of the plot frame xp_min = o_xporigin; yp_min = o_yporigin; xp_max = xp_min + o_xlength; @@ -325,30 +322,31 @@ EZPlot::plot () yp_min = clamp (yp_min, 0., 1.); yp_max = clamp (yp_max, 0., 1.); - xa_min = xp_min; /* extent of axes */ + xa_min = xp_min; // extent of axes xa_max = xp_max; ya_min = yp_min; ya_max = yp_max; - - /* adjust frame for title */ + + // adjust frame for title if (c_title.length() > 0) - ya_max -= 2.5 * charheight; - title_row = ya_max + charheight; + ya_max -= 2 * charheight; + title_row = ya_max + 2 * charheight; - /* calculate legend box boundaries */ - int max_leg = 0; /* longest legend in characters */ - int num_leg = 0; /* number of legend titles */ + // calculate legend box boundaries + int max_leg = 0; // longest legend in characters + int num_leg = 0; // number of legend titles for (EZPlotCurveConstIterator iterCurve = m_vecCurves.begin(); iterCurve != m_vecCurves.end(); iterCurve++) { const EZPlotCurve& curve = **iterCurve; - if ((n = curve.m_sLegend.length()) > 0) { + int nLegend = curve.m_sLegend.length(); + if (nLegend > 0) { ++num_leg; - max_leg = max (max_leg, n); + max_leg = max (max_leg, nLegend); } } if (num_leg > 0 && o_legendbox != NOLEGEND) { - leg_width = (max_leg + 2) * charwidth; - leg_height = num_leg * 3 * charheight; + double leg_width = (max_leg + 2) * charwidth; // size of legend box + double leg_height = num_leg * 3 * charheight; if (s_xlegend == TRUE) xl_max = v_xlegend; @@ -366,12 +364,10 @@ EZPlot::plot () yl_min = yl_max - leg_height; - rSGP.setWindow (xl_min, yl_min, xl_max, yl_max); - rSGP.setViewport (xl_min, yl_min, xl_max, yl_max); rSGP.setColor (clr_legend); rSGP.drawRect (xl_min, yl_min, xl_max, yl_max); - n = 0; /* current legend position */ + int iLegend = 0; // current legend position for (EZPlotCurveIterator iterCurve = m_vecCurves.begin(); iterCurve != m_vecCurves.end(); iterCurve++) { const EZPlotCurve& curve = **iterCurve; @@ -380,7 +376,7 @@ EZPlot::plot () double xmin = xl_min + 1.0 * charwidth; double xmax = xl_max - 1.0 * charwidth; - double y = yl_max - (2.0 + n * 3) * charheight; + double y = yl_max - (2.0 + iLegend * 3) * charheight; rSGP.moveAbs (xmin, y + 0.5 * charheight); rSGP.drawText (curve.m_sLegend); @@ -393,40 +389,40 @@ EZPlot::plot () if (curve.m_iSymbol > 0) { double xinc = (xmax - xmin) / (5 - 1); rSGP.setLineStyle (SGP::LS_SOLID); - for (j = 0; j < 5; j++) { - rSGP.moveAbs (xmin + j * xinc, y); - symbol(curve.m_iSymbol, 0.5 * charwidth, 0.5 * charheight); + for (int j = 0; j < 5; j++) { + rSGP.moveAbs (xmin + j * xinc, y); + symbol(curve.m_iSymbol, 0.5 * charwidth, 0.5 * charheight); + } } - } - ++n; /* move to next legend position */ + ++iLegend; // move to next legend position } - } /* end legend printing */ + } // end legend printing - /* calculate the extent of the axes */ + // calculate the extent of the axes /*-------------------------*/ /* adjust frame for labels */ /*-------------------------*/ - /* x-label */ + // X-Label if (c_xlabel.length() > 0) ya_min += 3.0 * charheight; - xlbl_row = xp_min; /* put x-label on bottom of plot frame */ + xlbl_row = xp_min; // put x-label on bottom of plot frame - /* y-label */ + // Y-Label if (c_ylabel.length() > 0) - xa_min += 3.0 * charwidth; /* reverse rSGP.setTextSize because writing text sideways */ + xa_min += 3.0 * charwidth; // reverse rSGP.setTextSize because writing text sideways ylbl_col = xp_min + 2 * charwidth; /*------------------------------*/ /* adjust frame for tick labels */ /*------------------------------*/ - /* calc offset of tick labels from axes */ + // Calc offset of tick labels from axes if (o_xaxis == NOAXIS || o_xtlabel == FALSE) xtl_ofs = 0.0; else if (o_xticks == BELOW) - xtl_ofs = -2.5 * charheight; + xtl_ofs = -1.5 * charheight; // kr else if (o_xticks == ABOVE) xtl_ofs = 1.5 * charheight; @@ -437,7 +433,12 @@ EZPlot::plot () else if (o_yticks == RIGHT) ytl_ofs = 1.5 * charwidth; - /* see if need to shrink axis extents and/or tick extents */ + xt_min = xa_min; + yt_min = ya_min; + xt_max = xa_max; + yt_max = ya_max; + + // see if need to shrink axis extents and/or tick extents if (xtl_ofs != 0.0 && s_ycross == FALSE) { if (o_xticks == BELOW) { ya_min += 2.5 * charheight; @@ -446,7 +447,7 @@ EZPlot::plot () ya_min += 0.0; yt_min = ya_min + 2.5 * charheight; } - } else /* noaxis, no t-labels, or user set cross */ + } else // noaxis, no t-labels, or user set cross yt_min = ya_min; if (ytl_ofs != 0.0 && s_xcross == FALSE) { @@ -460,15 +461,10 @@ EZPlot::plot () } else xt_min = xa_min; - xt_max = xa_max; - yt_max = ya_max; - - /* decrease size of graph, if necessary, to accommadate space */ - /* between axis boundary and boundary of ticks */ - - x_added_ticks = -1; - y_added_ticks = -1; - + // decrease size of graph, if necessary, to accommadate space + // between axis boundary and boundary of ticks + double x_added_ticks = -1; // number of tick spaces added to axis + double y_added_ticks = -1; if (o_xaxis == NOAXIS || o_xtlabel == FALSE) x_added_ticks = 0; if (o_yaxis == NOAXIS || o_ytlabel == FALSE) @@ -508,45 +504,52 @@ EZPlot::plot () ygn_min = yt_min; ygn_max = yt_max; - /*---------------------------------------------------------------------------*/ + //------------------------------------------------------------------------ - /* PLOT CURVES */ + m_xWorldScale = (xgn_max - xgn_min) / (xgw_max - xgw_min); + m_yWorldScale = (ygn_max - ygn_min) / (ygw_max - ygw_min); + + // PLOT CURVES rSGP.setLineStyle (SGP::LS_SOLID); drawAxes(); - /* Convert WC in graph boundary to axis boundary */ - rSGP.setWindow (xgw_min, ygw_min, xgw_max, ygw_max); /* Graph boundary */ - rSGP.setViewport (xgn_min, ygn_min, xgn_max, ygn_max); - double xminTemp = xa_min, xmaxTemp = xa_max; - double yminTemp = ya_min, ymaxTemp = ya_max; - rSGP.transformNDCtoMC (&xminTemp, &yminTemp); // calc WC to axis boundaries - rSGP.transformNDCtoMC (&xmaxTemp, &ymaxTemp); - rSGP.setWindow (xminTemp, yminTemp, xmaxTemp, ymaxTemp); // Set window to axis boundaries - rSGP.setViewport (xa_min, ya_min, xa_max, ya_max); - - symwidth = charwidth * (xgw_max - xgw_min); - symheight = charheight * (ygw_max - ygw_min); + // size of symbol in NDC + double symwidth = charwidth; + double symheight = charheight; for (EZPlotCurveIterator iterCurve = m_vecCurves.begin(); iterCurve != m_vecCurves.end(); iterCurve++) { const EZPlotCurve& curve = **iterCurve; rSGP.setColor (curve.m_iColor); + if (curve.m_iLineStyle != SGP::LS_NOLINE) { rSGP.setLineStyle (curve.m_iLineStyle); - rSGP.polylineAbs (curve.x, curve.y, curve.m_iPointCount); + double x = convertWorldToNDC_X (curve.x[0]); + double y = convertWorldToNDC_Y (curve.y[0]); + rSGP.moveAbs (x, y); + for (int i = 1; i < curve.m_iPointCount; i++) { + x = convertWorldToNDC_X (curve.x[i]); + y = convertWorldToNDC_Y (curve.y[i]); + rSGP.lineAbs (x, y); + } } if (curve.m_iSymbol > 0) { rSGP.setLineStyle (SGP::LS_SOLID); - rSGP.moveAbs (curve.x[0], curve.y[0]); + double x = convertWorldToNDC_X (curve.x[0]); + double y = convertWorldToNDC_Y (curve.y[0]); + rSGP.moveAbs (x, y); symbol (curve.m_iSymbol, symwidth, symheight); - for (i = 1; i < curve.m_iPointCount; i++) + for (int i = 1; i < curve.m_iPointCount; i++) if (i % curve.m_iSymbolFreq == 0 || i == curve.m_iPointCount - 1) { - rSGP.moveAbs (curve.x[i], curve.y[i]); + x = convertWorldToNDC_X (curve.x[i]); + y = convertWorldToNDC_Y (curve.y[i]); + rSGP.moveAbs (x, y); symbol (curve.m_iSymbol, symwidth, symheight); } } } + } @@ -559,15 +562,15 @@ EZPlot::plot () void -EZPlot::drawAxes(void) +EZPlot::drawAxes() { - double xticklen = 0, yticklen = 0; /* length of ticks in NDC */ - double minorinc; /* increment between minor axes */ - double xaxispos, yaxispos; /* crossing of axes */ + double xticklen = 0, yticklen = 0; // length of ticks in NDC + double minorinc; // increment between minor axes + double xaxispos, yaxispos; // crossing of axes double x, y, x2, y2; - bool axis_near; /* TRUE if axis too close to print t-label */ + bool axis_near; // TRUE if axis too close to print t-label int i, j; - char str[100]; + char str[256]; char *numstr; rSGP.setTextSize (charheight); @@ -583,14 +586,11 @@ EZPlot::drawAxes(void) else if (o_yticks == LEFT) yticklen = -charwidth; - rSGP.setWindow (xp_min, yp_min, xp_max, yp_max); - rSGP.setViewport (xp_min, yp_min, xp_max, yp_max); - if (c_title.length() > 0) { double wText, hText; + rSGP.setTextSize (charheight * 2.0); rSGP.getTextExtent (c_title.c_str(), &wText, &hText); rSGP.moveAbs (xa_min + (xa_max-xa_min)/2 - wText/2, title_row); - rSGP.setTextSize (charheight * 2.0); rSGP.setTextColor (clr_title, -1); rSGP.drawText (c_title); rSGP.setTextSize (charheight); @@ -605,25 +605,19 @@ EZPlot::drawAxes(void) rSGP.lineAbs (xa_min, ya_min); } - /* calculate position of axes */ + // calculate position of axes - /* x-axis */ - if (s_ycross == TRUE) { /* convert users' world-coord */ - xaxispos = v_ycross; /* axis to its position in NDC */ - rSGP.setWindow (xgw_min, ygw_min, xgw_max, ygw_max); - rSGP.setViewport (xgn_min, ygn_min, xgn_max, ygn_max); - x = xgw_min; - rSGP.transformMCtoNDC (x, xaxispos, &x, &xaxispos); + // x-axis + if (s_ycross == TRUE) { // convert users' world-coord + xaxispos = convertWorldToNDC_Y (v_ycross);// axis to its position in NDC + x = convertWorldToNDC_X (xgw_min); } else xaxispos = ya_min; - /* y-axis */ - if (s_xcross == TRUE) { /* convert users' world-coord */ - yaxispos = v_xcross; /* axis to its NDC position */ - rSGP.setWindow (xgw_min, ygw_min, xgw_max, ygw_max); - rSGP.setViewport (xgn_min, ygn_min, xgn_max, ygn_max); - y = ygw_min; - rSGP.transformMCtoNDC (yaxispos, y, &yaxispos, &y); + // y-axis + if (s_xcross == TRUE) { // convert users' world-coord + yaxispos = convertWorldToNDC_X (v_xcross);// axis to its NDC position + y = convertWorldToNDC_Y (ygw_min); } else yaxispos = xa_min; @@ -632,10 +626,7 @@ EZPlot::drawAxes(void) /*-------------*/ if (o_xaxis == LINEAR) { - rSGP.setWindow (xp_min, yp_min, xp_max, yp_max); - rSGP.setViewport (xp_min, yp_min, xp_max, yp_max); - - /* draw axis line */ + // draw axis line rSGP.setColor (clr_axis); if (o_tag && !o_grid && !o_box && s_xcross) { @@ -676,15 +667,9 @@ EZPlot::drawAxes(void) } axis_near = FALSE; if (xaxispos + xtl_ofs > ya_min && o_yaxis != NOAXIS) { - double xw, x, y, d; - - xw = xgw_min + i * xw_tickinc; - rSGP.setWindow (xgw_min, ygw_min, xgw_max, ygw_max); - rSGP.setViewport (xgn_min, ygn_min, xgn_max, ygn_max); - rSGP.transformMCtoNDC (xw, y, &x, &y); - rSGP.setWindow (xp_min, yp_min, xp_max, yp_max); - rSGP.setViewport (xp_min, yp_min, xp_max, yp_max); - d = x - yaxispos; + double xw = xgw_min + i * xw_tickinc; + double x = convertWorldToNDC_X (xw); + double d = x - yaxispos; if (o_yticks == RIGHT && d >= 0 && d < 0.9 * xn_tickinc) axis_near = TRUE; if (o_yticks == LEFT && d <= 0 && d > -0.9 * xn_tickinc) @@ -694,12 +679,12 @@ EZPlot::drawAxes(void) if (o_xtlabel == TRUE && axis_near == FALSE) { snprintf (str, sizeof(str), x_numfmt, xgw_min + xw_tickinc * i); numstr = str_skip_head (str, " "); - rSGP.moveAbs (x-strlen(numstr)*charwidth/2,xaxispos + xtl_ofs); + rSGP.moveAbs (x-strlen(numstr)*charwidth/2, xaxispos + xtl_ofs); rSGP.setTextColor (clr_number, -1); rSGP.drawText (numstr); } } - } /* x - axis */ + } // X - Axis /*--------*/ @@ -707,8 +692,6 @@ EZPlot::drawAxes(void) /*--------*/ if (o_yaxis == LINEAR) { - rSGP.setWindow (xp_min, yp_min, xp_max, yp_max); - rSGP.setViewport (xp_min, yp_min, xp_max, yp_max); rSGP.setColor (clr_axis); if (o_tag && !o_grid && !o_box && s_ycross) { @@ -730,7 +713,7 @@ EZPlot::drawAxes(void) rSGP.lineAbs (xa_min, y); } } - rSGP.moveAbs (ylbl_col,ya_min + (ya_max-ya_min)/2 - c_ylabel.length()*charheight); + rSGP.moveAbs (ylbl_col, ya_min + (ya_max-ya_min)/2 - c_ylabel.length()*charheight); rSGP.setTextAngle (HALFPI); rSGP.setTextSize (2 * charheight); rSGP.setTextColor (clr_label, -1); @@ -752,15 +735,9 @@ EZPlot::drawAxes(void) } axis_near = FALSE; if (yaxispos + ytl_ofs > xa_min && o_xaxis != NOAXIS) { - double yw, x, y, d; - - yw = ygw_min + i * yw_tickinc; - rSGP.setWindow (xgw_min, ygw_min, xgw_max, ygw_max); - rSGP.setViewport (xgn_min, ygn_min, xgn_max, ygn_max); - rSGP.transformMCtoNDC (x, yw, &x, &y); - rSGP.setWindow (xp_min, yp_min, xp_max, yp_max); - rSGP.setViewport (xp_min, yp_min, xp_max, yp_max); - d = y - xaxispos; + double yw = ygw_min + i * yw_tickinc; + double y = convertWorldToNDC_Y (yw); + double d = y - xaxispos; if (o_xticks == ABOVE && d >= 0 && d < 0.9 * yn_tickinc) axis_near = TRUE; if (o_xticks == BELOW && d <= 0 && d > -0.9 * yn_tickinc) @@ -768,12 +745,12 @@ EZPlot::drawAxes(void) } if (o_ytlabel == TRUE && axis_near == FALSE) { snprintf (str, sizeof(str), y_numfmt, ygw_min + yw_tickinc * i); - rSGP.moveAbs (yaxispos + ytl_ofs, y - 0.5 * charheight); + rSGP.moveAbs (yaxispos + ytl_ofs, y + 0.5 * charheight); rSGP.setTextColor (clr_number, -1); rSGP.drawText (str); } } - } /* y - axis */ + } // Y - Axis } @@ -867,12 +844,18 @@ EZPlot::axis_scale (double min, double max, int nint, double *minp, double *maxp v = 5.0; double wdt = v * pow (10.0, e); double g = floor (mina / wdt); - if (fabs(g + 1 - mina / wdt) < j) - g = g + 1; + if (fabs(g + 1 - mina / wdt) < j) + g = g + 1; +#if 1 + g++; +#endif *minp = wdt * g; double h = floor (maxa / wdt) + 1.0; if (fabs(maxa / wdt + 1 - h) < j) - h = h - 1; + h = h - 1; +#if 1 + h--; +#endif *maxp = wdt * h; *nintp = static_cast(h - g); if (fabs(*maxp) >= 10.0 || fabs(*minp) >= 10.0) { @@ -925,37 +908,37 @@ EZPlot::make_numfmt (char *fmtstr, int *fldwid, int *nfrac, double minval, doubl double absmax = fabs(maxval); double logt = log10( max(absmin, absmax) ); - if (fabs(logt) >= 6) { /* use exponential format */ + if (fabs(logt) >= 6) { // use exponential format if (fabs(logt) > 99) - expon = 5; /* E+102 */ + expon = 5; // E+102 else - expon = 4; /* E+00 */ + expon = 4; // E+00 - if (*nfrac < 0) { /* calculate frac */ - delta /= pow (10., floor(logt)); /* scale delta */ + if (*nfrac < 0) { // calculate frac + delta /= pow (10., floor(logt)); // scale delta frac = static_cast(fabs(trunc(log10(delta)))) + 1; if (frac < 1) - frac = 1; /* to be safe, add decimal pt */ - } else /* use users' frac */ + frac = 1; // to be safe, add decimal pt + } else // use users' frac frac = *nfrac; wid = 2 + frac + expon; if (minval < 0. || maxval < 0.) ++wid; sprintf (fmtstr, "%s%d%s%d%s", "%", wid, ".", frac, "g"); - } else { /* use fixed format */ + } else { // use fixed format wid = static_cast(trunc(logt)) + 1; if (wid < 1) wid = 1; if (minval < 0. || maxval < 0.) ++wid; - if (*nfrac < 0) { /* calculate frac */ + if (*nfrac < 0) { // calculate frac if (delta >= 0.999999) - frac = 1; /* add a decimal pt to be safe */ + frac = 1; // add a decimal pt to be safe else frac = static_cast(fabs(trunc(log10(delta)))) + 1; - } else /* use users' frac */ + } else // use users' frac frac = *nfrac; wid += 1 + frac; diff --git a/libctgraphics/sgp.cpp b/libctgraphics/sgp.cpp index e96f29d..4790a23 100644 --- a/libctgraphics/sgp.cpp +++ b/libctgraphics/sgp.cpp @@ -7,7 +7,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: sgp.cpp,v 1.13 2000/09/02 05:10:39 kevin Exp $ +** $Id: sgp.cpp,v 1.14 2000/09/04 09:06:46 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -79,7 +79,7 @@ SGPDriver::~SGPDriver () // SGP::SGP Constructor for Simple Graphics Package SGP::SGP (const SGPDriver& driver) - : m_driver (driver) + : m_driver (driver) { m_iPhysicalXSize = m_driver.getPhysicalXSize(); m_iPhysicalYSize = m_driver.getPhysicalYSize(); @@ -94,13 +94,24 @@ SGP::SGP (const SGPDriver& driver) m_pen.SetStyle(wxSOLID); #endif + if (m_driver.isWX()) { + static const double dScreenDPI = 82; + static const double dPointsPerInch = 72.; + m_dPointsPerPixel = dPointsPerInch / dScreenDPI; + const int iTestPointSize = 72; + m_font.SetPointSize (iTestPointSize); + m_driver.idWX()->SetFont(m_font); + double dTestCharHeight = m_driver.idWX()->GetCharHeight(); + m_dPointsPerPixel = iTestPointSize / dTestCharHeight; + } + setWindow (0., 0., 1., 1.); setViewport (0., 0., 1., 1.); moveAbs (0., 0.); stylusNDC (0., 0., false); - + setTextAngle (0.); - setTextSize (1. / 25.); + setTextPointSize (12); setColor (C_BLACK); } @@ -115,12 +126,12 @@ SGP::stylusNDC (double x, double y, bool beam) if (beam) { #if HAVE_WXWINDOWS - if (m_driver.isWX()) - m_driver.idWX()->DrawLine (m_iCurrentPhysicalX, m_iCurrentPhysicalY, xp, yp); + if (m_driver.isWX()) + m_driver.idWX()->DrawLine (m_iCurrentPhysicalX, m_iCurrentPhysicalY, xp, yp); #endif #if HAVE_G2_H - if (m_driver.isG2()) - g2_line (m_driver.idG2(), m_iCurrentPhysicalX, m_iCurrentPhysicalY, xp, yp); + if (m_driver.isG2()) + g2_line (m_driver.idG2(), m_iCurrentPhysicalX, m_iCurrentPhysicalY, xp, yp); #endif } m_iCurrentPhysicalX = xp; @@ -401,11 +412,56 @@ SGP::moveRel (double x, double y) moveAbs (x + m_dCurrentWorldX, y + m_dCurrentWorldY); } + +// Height is in master coordinates void SGP::setTextSize (double height) { + height /= (xw_max - xw_min); +#if HAVE_G2_H if (m_driver.isG2()) g2_set_font_size(m_driver.idG2(), (height * m_iPhysicalYSize)); +#endif +#if HAVE_WXWINDOWS + if (m_driver.isWX()) { + double dHeightPixels = height * m_iPhysicalYSize; + double dHeightPoints = dHeightPixels * m_dPointsPerPixel; + m_font.SetPointSize (nearest(dHeightPoints)); + m_driver.idWX()->SetFont (m_font); + } +#endif +} + +void +SGP::setTextNDCSize (double height) +{ + double dHeightPixels = height * m_iPhysicalYSize; +#if HAVE_G2_H + if (m_driver.isG2()) + g2_set_font_size(m_driver.idG2(), nearest(dHeightPixels)); +#endif +#if HAVE_WXWINDOWS + if (m_driver.isWX()) { + double dHeightPoints = dHeightPixels * m_dPointsPerPixel; + m_font.SetPointSize (nearest(dHeightPoints)); + m_driver.idWX()->SetFont (m_font); + } +#endif +} + +void +SGP::setTextPointSize (double height) +{ +#if HAVE_G2_H + // if (m_driver.isG2()) + // g2_set_font_size(m_driver.idG2(), (height * m_iPhysicalYSize)); +#endif +#if HAVE_WXWINDOWS + if (m_driver.isWX()) { + m_font.SetPointSize (height); + m_driver.idWX()->SetFont (m_font); + } +#endif } void @@ -418,7 +474,6 @@ SGP::getTextExtent (const char* szText, double* worldW, double* worldH) m_driver.idWX()->GetTextExtent (sText, &deviceW, &deviceH); *worldW = static_cast(deviceW) / static_cast(m_iPhysicalXSize);; *worldH = static_cast(deviceH) / static_cast(m_iPhysicalYSize); - // cout << deviceW << ", " << deviceH << ", " << *worldW << ", " << *worldH << endl; *worldW *= (xw_max - xw_min); *worldH *= (yw_max - yw_min); } @@ -433,16 +488,32 @@ SGP::getCharHeight () #if HAVE_WXWINDOWS if (m_driver.isWX()) { dHeight = m_driver.idWX()->GetCharHeight(); - dHeight /= static_cast(m_iPhysicalYSize);; + dHeight /= static_cast(m_iPhysicalYSize); + } +#endif + dHeight *= (yw_max - yw_min); + return dHeight; +} + +double +SGP::getCharWidth () +{ + double dWidth = (1. / 80.); + +#if HAVE_WXWINDOWS + if (m_driver.isWX()) { + dWidth = m_driver.idWX()->GetCharWidth(); + dWidth /= static_cast(m_iPhysicalXSize); } #endif - return (dHeight * (xw_max - xw_min)); + dWidth *= (xw_max - xw_min); + return dWidth; } void SGP::setTextAngle (double angle) { - m_dTextAngle = angle; + m_dTextAngle = convertRadiansToDegrees(angle); } void diff --git a/libctsim/phantom.cpp b/libctsim/phantom.cpp index cb2d3ff..aff37a0 100644 --- a/libctsim/phantom.cpp +++ b/libctsim/phantom.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: phantom.cpp,v 1.17 2000/08/27 20:32:55 kevin Exp $ +** $Id: phantom.cpp,v 1.18 2000/09/04 09:06:46 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -440,11 +440,11 @@ Phantom::addStdHermanBordered () void Phantom::convertToImagefile (ImageFile& im, const int in_nsample, const int trace) const { - convertToImagefile (im, in_nsample, trace, 0, im.nx()); + convertToImagefile (im, in_nsample, trace, 0, im.nx(), true); } void -Phantom::convertToImagefile (ImageFile& im, const int in_nsample, const int trace, const int colStart, const int colCount) const +Phantom::convertToImagefile (ImageFile& im, const int in_nsample, const int trace, const int colStart, const int colCount, bool bStoreAtColumnPos) const { int nx = im.nx(); int ny = im.ny(); @@ -486,8 +486,12 @@ Phantom::convertToImagefile (ImageFile& im, const int in_nsample, const int trac ImageFileArray v = im.getArray(); for (int ix = 0; ix < colCount; ix++) - for (int iy = 0; iy < ny; iy++) - v[ix][iy] = 0; + for (int iy = 0; iy < ny; iy++) { + int iColStore = ix; + if (bStoreAtColumnPos) + iColStore += colStart; + v[iColStore][iy] = 0; + } double x_start = xmin + (colStart * xinc); for (PElemConstIterator pelem = m_listPElem.begin(); pelem != m_listPElem.end(); pelem++) { @@ -495,11 +499,14 @@ Phantom::convertToImagefile (ImageFile& im, const int in_nsample, const int trac double x, y, xi, yi; int ix, iy, kx, ky; for (ix = 0, x = x_start; ix < colCount; ix++, x += xinc) { - for (iy = 0, y = ymin; iy < ny; iy++, y += yinc) { - for (kx = 0, xi = x + kxofs; kx < nsample; kx++, xi += kxinc) { - for (ky = 0, yi = y + kyofs; ky < nsample; ky++, yi += kyinc) - if (rPElem.isPointInside (xi, yi, PHM_COORD) == TRUE) - v[ix][iy] += rPElem.atten(); + int iColStore = ix; + if (bStoreAtColumnPos) + iColStore += colStart; + for (iy = 0, y = ymin; iy < ny; iy++, y += yinc) { + for (kx = 0, xi = x + kxofs; kx < nsample; kx++, xi += kxinc) { + for (ky = 0, yi = y + kyofs; ky < nsample; ky++, yi += kyinc) + if (rPElem.isPointInside (xi, yi, PHM_COORD) == TRUE) + v[iColStore][iy] += rPElem.atten(); } // for kx } /* for iy */ } /* for ix */ diff --git a/src/dialogs.cpp b/src/dialogs.cpp index 3035244..ce808b4 100644 --- a/src/dialogs.cpp +++ b/src/dialogs.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: dialogs.cpp,v 1.12 2000/09/02 05:10:39 kevin Exp $ +** $Id: dialogs.cpp,v 1.13 2000/09/04 09:06:46 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -128,7 +128,7 @@ DialogGetImageMinMax::DialogGetImageMinMax (wxFrame* pParent, const ImageFile& r osMax << dDefaultMax; m_pTextCtrlMax = new wxTextCtrl (this, -1, osMax.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0); - wxGridSizer *pGridSizer = new wxGridSizer (2); + wxFlexGridSizer *pGridSizer = new wxFlexGridSizer (2); pGridSizer->Add (new wxStaticText (this, -1, "Minimum"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); pGridSizer->Add (m_pTextCtrlMin, 0, wxALIGN_CENTER_VERTICAL); pGridSizer->Add (new wxStaticText (this, -1, "Maximum"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); @@ -207,7 +207,7 @@ DialogGetRasterParameters::DialogGetRasterParameters (wxFrame* pParent, int iDef osNSamples << iDefaultNSamples; m_pTextCtrlNSamples = new wxTextCtrl (this, -1, osNSamples.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0); - wxGridSizer *pGridSizer = new wxGridSizer (2); + wxFlexGridSizer *pGridSizer = new wxFlexGridSizer (2); pGridSizer->Add (new wxStaticText (this, -1, "X Size"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); pGridSizer->Add (m_pTextCtrlXSize, 0, wxALIGN_CENTER_VERTICAL); pGridSizer->Add (new wxStaticText (this, -1, "Y Size"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); @@ -294,14 +294,10 @@ DialogGetProjectionParameters::DialogGetProjectionParameters (wxFrame* pParent, m_iDefaultTrace = iDefaultTrace; m_iDefaultGeometry = iDefaultGeometry; - pTopSizer->Add (new wxStaticText (this, -1, "Set Projection Parameters"), 0, wxALIGN_CENTER | wxTOP | wxLEFT | wxRIGHT, 5); pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5); - m_pListBoxGeometry = new StringValueAndTitleListBox (this, Scanner::getGeometryCount(), Scanner::getGeometryTitleArray(), Scanner::getGeometryNameArray()); - m_pListBoxGeometry->SetSelection (iDefaultGeometry, true); - ostringstream os; os << iDefaultNDet; m_pTextCtrlNDet = new wxTextCtrl (this, -1, os.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0); @@ -321,12 +317,13 @@ DialogGetProjectionParameters::DialogGetProjectionParameters (wxFrame* pParent, osFieldOfView << dDefaultFieldOfView; m_pTextCtrlFieldOfView = new wxTextCtrl (this, -1, osFieldOfView.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0); - wxGridSizer* pGeometryGridSizer = new wxGridSizer (2); - pGeometryGridSizer->Add (new wxStaticText (this, -1, "Scanner Geometry"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); - pGeometryGridSizer->Add (m_pListBoxGeometry, 0, wxALL | wxALIGN_CENTER | wxEXPAND); - pTopSizer->Add (pGeometryGridSizer, 1, wxALL, 10); + wxFlexGridSizer* pGridSizer = new wxFlexGridSizer (2); + pGridSizer->Add (new wxStaticText (this, -1, "Scanner Geometry"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); + m_pListBoxGeometry = new StringValueAndTitleListBox (this, Scanner::getGeometryCount(), Scanner::getGeometryTitleArray(), Scanner::getGeometryNameArray()); + m_pListBoxGeometry->SetSelection (iDefaultGeometry); + + pGridSizer->Add (m_pListBoxGeometry, 0, wxALL | wxALIGN_CENTER | wxEXPAND); - wxGridSizer* pGridSizer = new wxGridSizer (2); pGridSizer->Add (new wxStaticText (this, -1, "Detectors"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); pGridSizer->Add (m_pTextCtrlNDet, 0, wxALIGN_CENTER_VERTICAL); pGridSizer->Add (new wxStaticText (this, -1, "Views"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); @@ -339,15 +336,13 @@ DialogGetProjectionParameters::DialogGetProjectionParameters (wxFrame* pParent, pGridSizer->Add (m_pTextCtrlFocalLength, 0, wxALIGN_CENTER_VERTICAL); pGridSizer->Add (new wxStaticText (this, -1, "Field of View (phantom diameter units)"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); pGridSizer->Add (m_pTextCtrlFieldOfView, 0, wxALIGN_CENTER_VERTICAL); - pTopSizer->Add (pGridSizer, 1, wxALL, 10); m_pListBoxTrace = new StringValueAndTitleListBox (this, Trace::getTraceCount(), Trace::getTraceTitleArray(), Trace::getTraceNameArray()); m_pListBoxTrace->SetSelection (iDefaultTrace); - wxGridSizer *pTraceGridSizer = new wxGridSizer (2); - pTraceGridSizer->Add (new wxStaticText (this, -1, "Trace Level"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); - pTraceGridSizer->Add (m_pListBoxTrace, 0, wxALL | wxALIGN_CENTER | wxEXPAND); - pTopSizer->Add (pTraceGridSizer, 1, wxALL, 10); + pGridSizer->Add (new wxStaticText (this, -1, "Trace Level"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); + pGridSizer->Add (m_pListBoxTrace, 0, wxALL | wxALIGN_CENTER | wxEXPAND); + pTopSizer->Add (pGridSizer, 1, wxALL, 10); pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5); @@ -467,33 +462,6 @@ DialogGetReconstructionParameters::DialogGetReconstructionParameters (wxFrame* p pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5); - wxGridSizer* pFilterGrid = new wxGridSizer (2); - pFilterGrid->Add (new wxStaticText (this, -1, "Filter"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); - m_pListBoxFilter = new StringValueAndTitleListBox (this, SignalFilter::getFilterCount(), SignalFilter::getFilterTitleArray(), SignalFilter::getFilterNameArray()); - m_pListBoxFilter->SetSelection (iDefaultFilterID); - pFilterGrid->Add (m_pListBoxFilter, 0, wxALL | wxALIGN_LEFT | wxEXPAND); - - m_pListBoxFilterMethod = new StringValueAndTitleListBox (this, ProcessSignal::getFilterMethodCount(), ProcessSignal::getFilterMethodTitleArray(), ProcessSignal::getFilterMethodNameArray()); - m_pListBoxFilterMethod->SetSelection (iDefaultFilterMethodID); - pFilterGrid->Add (new wxStaticText (this, -1, "Filter Method"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); - pFilterGrid->Add (m_pListBoxFilterMethod, 0, wxALL | wxALIGN_LEFT | wxEXPAND); - m_pListBoxFilterGeneration = new StringValueAndTitleListBox (this, ProcessSignal::getFilterGenerationCount(), ProcessSignal::getFilterGenerationTitleArray(), ProcessSignal::getFilterGenerationNameArray()); - m_pListBoxFilterGeneration->SetSelection (iDefaultFilterGenerationID); - pFilterGrid->Add (new wxStaticText (this, -1, "Filter Generation"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); - pFilterGrid->Add (m_pListBoxFilterGeneration, 0, wxALL | wxALIGN_LEFT | wxEXPAND); - - m_pListBoxBackproject = new StringValueAndTitleListBox (this, Backprojector::getBackprojectCount(), Backprojector::getBackprojectTitleArray(), Backprojector::getBackprojectNameArray()); - m_pListBoxBackproject->SetSelection (iDefaultBackprojectID); - pFilterGrid->Add (new wxStaticText (this, -1, "Backprojection"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); - pFilterGrid->Add (m_pListBoxBackproject, 0, wxALL | wxALIGN_RIGHT | wxEXPAND); - - m_pListBoxInterp = new StringValueAndTitleListBox (this, Backprojector::getInterpCount(), Backprojector::getInterpTitleArray(), Backprojector::getInterpNameArray()); - m_pListBoxInterp->SetSelection (iDefaultInterpID); - pFilterGrid->Add (new wxStaticText (this, -1, "Interpolation"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); - pFilterGrid->Add (m_pListBoxInterp, 0, wxALL | wxALIGN_RIGHT | wxEXPAND); - - pTopSizer->Add (pFilterGrid, 1, wxALL); - ostringstream os; os << iDefaultXSize; m_pTextCtrlXSize = new wxTextCtrl (this, -1, os.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0); @@ -510,7 +478,33 @@ DialogGetReconstructionParameters::DialogGetReconstructionParameters (wxFrame* p osInterpParam << iDefaultInterpParam; m_pTextCtrlInterpParam = new wxTextCtrl (this, -1, osInterpParam.str().c_str(), wxDefaultPosition, wxSize(100, 25), 0); - wxGridSizer* pGridSizer = new wxGridSizer (2); + wxFlexGridSizer* pGridSizer = new wxFlexGridSizer (2); + pGridSizer->Add (new wxStaticText (this, -1, "Filter"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); + m_pListBoxFilter = new StringValueAndTitleListBox (this, SignalFilter::getFilterCount(), SignalFilter::getFilterTitleArray(), SignalFilter::getFilterNameArray()); + m_pListBoxFilter->SetSelection (iDefaultFilterID); + pGridSizer->Add (m_pListBoxFilter, 0, wxALL | wxALIGN_LEFT | wxEXPAND); + + m_pListBoxFilterMethod = new StringValueAndTitleListBox (this, ProcessSignal::getFilterMethodCount(), ProcessSignal::getFilterMethodTitleArray(), ProcessSignal::getFilterMethodNameArray()); + m_pListBoxFilterMethod->SetSelection (iDefaultFilterMethodID); + pGridSizer->Add (new wxStaticText (this, -1, "Filter Method"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); + pGridSizer->Add (m_pListBoxFilterMethod, 0, wxALL | wxALIGN_LEFT | wxEXPAND); + + m_pListBoxFilterGeneration = new StringValueAndTitleListBox (this, ProcessSignal::getFilterGenerationCount(), ProcessSignal::getFilterGenerationTitleArray(), ProcessSignal::getFilterGenerationNameArray()); + m_pListBoxFilterGeneration->SetSelection (iDefaultFilterGenerationID); + pGridSizer->Add (new wxStaticText (this, -1, "Filter Generation"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); + pGridSizer->Add (m_pListBoxFilterGeneration, 0, wxALL | wxALIGN_LEFT | wxEXPAND); + + m_pListBoxBackproject = new StringValueAndTitleListBox (this, Backprojector::getBackprojectCount(), Backprojector::getBackprojectTitleArray(), Backprojector::getBackprojectNameArray()); + m_pListBoxBackproject->SetSelection (iDefaultBackprojectID); + pGridSizer->Add (new wxStaticText (this, -1, "Backprojection"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); + pGridSizer->Add (m_pListBoxBackproject, 0, wxALL | wxALIGN_RIGHT | wxEXPAND); + + m_pListBoxInterp = new StringValueAndTitleListBox (this, Backprojector::getInterpCount(), Backprojector::getInterpTitleArray(), Backprojector::getInterpNameArray()); + m_pListBoxInterp->SetSelection (iDefaultInterpID); + pGridSizer->Add (new wxStaticText (this, -1, "Interpolation"), 0, wxALIGN_CENTER_VERTICAL | wxALIGN_RIGHT | wxALL, 5); + pGridSizer->Add (m_pListBoxInterp, 0, wxALL | wxALIGN_RIGHT | wxEXPAND); + + pGridSizer->Add (new wxStaticText (this, -1, "X Size"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); pGridSizer->Add (m_pTextCtrlXSize, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); pGridSizer->Add (new wxStaticText (this, -1, "Y Size"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); @@ -521,11 +515,16 @@ DialogGetReconstructionParameters::DialogGetReconstructionParameters (wxFrame* p pGridSizer->Add (m_pTextCtrlZeropad, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); pGridSizer->Add (new wxStaticText (this, -1, "Interpolation Parameter"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); pGridSizer->Add (m_pTextCtrlInterpParam, 0, wxALIGN_LEFT | wxALIGN_CENTER_VERTICAL); - pTopSizer->Add (pGridSizer, 1, wxALL, 3); - m_pListBoxTrace = new StringValueAndTitleListBox (this, Trace::getTraceCount(), Trace::getTraceTitleArray(), Trace::getTraceNameArray()); + pGridSizer->Add (new wxStaticText (this, -1, "Trace Level"), 0, wxALIGN_RIGHT | wxALIGN_CENTER_VERTICAL); + static const char* aszTraceTitle[] = {"None", "Full"}; + static const char* aszTraceName[] = {"none", "full"}; + m_pListBoxTrace = new StringValueAndTitleListBox (this, 2, aszTraceTitle, aszTraceName); + iTrace = clamp(iTrace, 0, 1); m_pListBoxTrace->SetSelection (iTrace); - pTopSizer->Add (m_pListBoxTrace); + pGridSizer->Add (m_pListBoxTrace); + + pTopSizer->Add (pGridSizer, 1, wxALL, 3); pTopSizer->Add (new wxStaticLine (this, -1, wxDefaultPosition, wxSize(3,3), wxHORIZONTAL), 0, wxEXPAND | wxALL, 5); @@ -626,7 +625,10 @@ DialogGetReconstructionParameters::getInterpName (void) int DialogGetReconstructionParameters::getTrace (void) { - return Trace::convertTraceNameToID(m_pListBoxTrace->getSelectionStringValue()); + int iTrace = 0; + if (strcmp("full", m_pListBoxTrace->getSelectionStringValue()) == 0) + iTrace = Trace::TRACE_PLOT; + return iTrace; } const char* diff --git a/src/dlgreconstruct.cpp b/src/dlgreconstruct.cpp index 277b6ea..5a6d46a 100644 --- a/src/dlgreconstruct.cpp +++ b/src/dlgreconstruct.cpp @@ -2,14 +2,14 @@ ** FILE IDENTIFICATION ** ** Name: dlgreconstruct.cpp -** Purpose: Projection Collection Animation Dialog +** Purpose: Reconstruction Animation Dialog ** Programmer: Kevin Rosenberg ** Date Started: August 2000 ** ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: dlgreconstruct.cpp,v 1.2 2000/09/02 16:40:36 kevin Exp $ +** $Id: dlgreconstruct.cpp,v 1.3 2000/09/04 09:06:46 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -47,9 +47,11 @@ #include "wx/settings.h" #include "wx/dcclient.h" #include "wx/timer.h" + #include "wx/image.h" #endif #include "dlgreconstruct.h" +#include #include "ct.h" @@ -68,7 +70,7 @@ IMPLEMENT_CLASS(ReconstructDialog, wxDialog) ReconstructDialog::ReconstructDialog (Reconstructor& rReconstruct, const Projections& rProj, ImageFile& rIF, const int iTrace, wxWindow *parent) - : wxDialog(parent, -1, "Collect Projections"), m_rReconstructor(rReconstruct), m_rProjections(rProj), m_rImageFile(rIF), m_pSGPDriver(NULL), m_pSGP(NULL), m_iTrace(iTrace), m_pDC(NULL), m_btnAbort(0), m_btnPause(0), m_btnStep(0) + : wxDialog(parent, -1, "Reconstruction"), m_rReconstructor(rReconstruct), m_rProjections(rProj), m_rImageFile(rIF), m_pSGPDriver(NULL), m_pSGP(NULL), m_iTrace(iTrace), m_pDC(NULL), m_btnAbort(0), m_btnPause(0), m_btnStep(0) { m_state = Continue; m_iLastView = -1; @@ -106,15 +108,22 @@ ReconstructDialog::ReconstructDialog (Reconstructor& rReconstruct, const Project SetAutoLayout(TRUE); Layout(); - wxSize sizeDlg (700,500); - if (sizeDlg.x != sizeDlg.y) { - sizeDlg.x = max(sizeDlg.x,sizeDlg.y); - sizeDlg.y = max(sizeDlg.x,sizeDlg.y); - } + m_nxGraph = 500; + m_nyGraph = 500; + wxSize sizeDlg (m_nxGraph, m_nyGraph); + m_nxImage = m_rImageFile.nx(); + if (m_nxImage > MAX_IMAGE_X) + m_nxImage = MAX_IMAGE_X; + m_nyImage = m_rImageFile.ny(); + if (m_nyImage > MAX_IMAGE_Y) + m_nyImage = MAX_IMAGE_Y; + + sizeDlg.x += m_nxImage; + sizeDlg.y = max (sizeDlg.y, m_nyImage); m_iClientX = sizeDlg.x; m_iClientY = sizeDlg.y; - SetClientSize(sizeDlg); + SetClientSize (sizeDlg); m_bitmap.Create (m_iClientX, m_iClientY); // save a copy of screen m_pDC = new wxMemoryDC; @@ -147,20 +156,55 @@ ReconstructDialog::showView (int iViewNumber) if ( iViewNumber < m_rProjections.nView() ) { m_iLastView = iViewNumber; m_pSGP->eraseWindow(); - if (m_iTrace >= Trace::TRACE_PLOT) - m_pSGP->setViewport (0, 0, 1, 1); + char szProgress [256]; snprintf (szProgress, sizeof(szProgress), "Reconstructing View %d (%.1f%%)", iViewNumber, 100 * iViewNumber / static_cast(m_rProjections.nView())); - double wText, hText; + m_pSGP->setViewport (0, 0, 1, 1); + m_pSGP->setWindow (0, 0, 1, 1); m_pSGP->setTextColor (C_LTRED, -1); - m_pSGP->getTextExtent (szProgress, &wText, &hText); - double xw_max, xw_min, yw_max, yw_min; - m_pSGP->getWindow (xw_min, yw_min, xw_max, yw_max); - m_pSGP->moveAbs ((xw_max - xw_min) / 2 + xw_min - wText / 2, yw_max - hText); + double dCharHeight = m_pSGP->getCharHeight(); + m_pSGP->setTextSize (dCharHeight * 2); + m_pSGP->moveAbs(0., m_pSGP->getCharHeight()); m_pSGP->drawText (szProgress); - if (m_iTrace >= Trace::TRACE_PLOT) - m_pSGP->setViewport (0, .1, 0.66, 1); + m_pSGP->setTextSize (dCharHeight); + + m_pSGP->setViewport (0.0, 0.1, 0.66, 1.); m_rReconstructor.reconstructView (iViewNumber, 1, m_pSGP); + + ImageFileArrayConst v = m_rImageFile.getArray(); + int xBase = m_nxGraph; + int yBase = 0; + if (m_nyGraph > m_nyImage) + yBase = (m_nyGraph - m_nyImage) / 2; + double minValue = v[0][0]; + double maxValue = v[0][0]; + for (int ix = 0; ix < m_nxImage; ix++) { + for (int iy = 0; iy < m_nyImage; iy++) { + double dPixel = v[ix][iy]; + if (dPixel < minValue) + minValue = dPixel; + else if (dPixel > maxValue) + maxValue = dPixel; + } + } + unsigned char* imageData = new unsigned char [m_nxImage * m_nyImage * 3]; + double dScale = 255 / (maxValue - minValue); + for (int ix = 0; ix < m_nxImage; ix++) { + for (int iy = 0; iy < m_nyImage; iy++) { + double dPixel = v[ix][iy]; + dPixel = (dPixel - minValue) * dScale; + int intensity = nearest(dPixel); + intensity = clamp (intensity, 0, 255); + int baseAddr = ((m_nyImage - 1 - iy) * m_nxImage + ix) * 3; + imageData[baseAddr] = imageData[baseAddr+1] = imageData[baseAddr+2] = intensity; + } + } + wxImage image (m_nxImage, m_nyImage, imageData, true); + wxBitmap bitmap = image.ConvertToBitmap(); + m_pSGP->getDriver().idWX()->DrawBitmap(bitmap, xBase, yBase, false); + delete imageData; + + Refresh(); } } @@ -172,7 +216,7 @@ ReconstructDialog::reconstructView (int iViewNumber) ::wxYield(); // update the display if (iViewNumber < m_rProjections.nView()) { if (m_iTrace >= Trace::TRACE_PLOT) { - sleep(1); + ::wxUsleep(250); } } else { m_state = Finished; // so that we return TRUE below and @@ -254,9 +298,7 @@ void ReconstructDialog::OnPaint (wxPaintEvent& event) { wxPaintDC paintDC (this); - if (m_state == Paused) { - paintDC.DrawBitmap(m_bitmap, 0, 0, false); - } + paintDC.DrawBitmap(m_bitmap, 0, 0, false); } diff --git a/src/dlgreconstruct.h b/src/dlgreconstruct.h index b73cf09..0a4f7a6 100644 --- a/src/dlgreconstruct.h +++ b/src/dlgreconstruct.h @@ -2,14 +2,14 @@ ** FILE IDENTIFICATION ** ** Name: dlgreconstruct.h -** Purpose: Headers for Projection Collection Animation Dialog +** Purpose: Headers for Reconstruction Animation Dialog ** Programmer: Kevin Rosenberg ** Date Started: August 2000 ** ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: dlgreconstruct.h,v 1.1 2000/09/02 05:13:57 kevin Exp $ +** $Id: dlgreconstruct.h,v 1.2 2000/09/04 09:06:46 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -100,6 +100,11 @@ private: wxMemoryDC m_memoryDC; // for restoring image on OnPaint wxBitmap m_bitmap; + int m_nxImage; + int m_nyImage; + int m_nxGraph; + int m_nyGraph; + // continue processing or not (return value for Update()) enum { @@ -112,6 +117,8 @@ private: const static int ID_BTN_PAUSE = 19998; const static int ID_BTN_STEP = 19999; + const static int MAX_IMAGE_X = 400; + const static int MAX_IMAGE_Y = 400; void showView (int iViewNumber); diff --git a/src/views.cpp b/src/views.cpp index 8a1face..c17d50c 100644 --- a/src/views.cpp +++ b/src/views.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: views.cpp,v 1.20 2000/09/02 16:40:36 kevin Exp $ +** $Id: views.cpp,v 1.21 2000/09/04 09:06:46 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -499,7 +499,14 @@ PhantomView::OnRasterize (wxCommandEvent& event) ImageFile& imageFile = pRasterDoc->getImageFile(); imageFile.setArraySize (xSize, ySize); - rPhantom.convertToImagefile (imageFile, nSamples, Trace::TRACE_NONE); + wxProgressDialog dlgProgress (wxString("Rasterize"), wxString("Rasterization Progress"), imageFile.nx() + 1, m_frame, wxPD_CAN_ABORT); + for (unsigned int i = 0; i < imageFile.nx(); i++) { + rPhantom.convertToImagefile (imageFile, nSamples, Trace::TRACE_NONE, i, 1, true); + if (! dlgProgress.Update(i+1)) { + pRasterDoc->DeleteAllViews(); + return; + } + } pRasterDoc->Modify(true); pRasterDoc->UpdateAllViews(this); @@ -660,6 +667,22 @@ END_EVENT_TABLE() ProjectionFileView::ProjectionFileView(void) : wxView(), m_canvas(NULL), m_frame(NULL) { + m_iDefaultNX = 256; + m_iDefaultNY = 256; + m_iDefaultFilter = SignalFilter::FILTER_ABS_BANDLIMIT; + m_dDefaultFilterParam = 1.; +#if HAVE_FFTW + m_iDefaultFilterMethod = ProcessSignal::FILTER_METHOD_RFFTW; + m_iDefaultFilterGeneration = ProcessSignal::FILTER_GENERATION_INVERSE_FOURIER; +#else + m_iDefaultFilterMethod = ProcessSignal::FILTER_METHOD_CONVOLUTION; + m_iDefaultFilterGeneration = ProcessSignal::FILTER_GENERATION_DIRECT; +#endif + m_iDefaultZeropad = 1; + m_iDefaultBackprojector = Backprojector::BPROJ_IDIFF3; + m_iDefaultInterpolation = Backprojector::INTERP_LINEAR; + m_iDefaultInterpParam = 1; + m_iDefaultTrace = Trace::TRACE_NONE; } ProjectionFileView::~ProjectionFileView(void) @@ -681,34 +704,36 @@ ProjectionFileView::OnProperties (wxCommandEvent& event) void ProjectionFileView::OnReconstruct (wxCommandEvent& event) { -#if HAVE_FFTW - DialogGetReconstructionParameters dialogReconstruction (m_frame, 256, 256, SignalFilter::FILTER_ABS_BANDLIMIT, 1., ProcessSignal::FILTER_METHOD_RFFTW, ProcessSignal::FILTER_GENERATION_INVERSE_FOURIER, 1, Backprojector::INTERP_LINEAR, 1, Backprojector::BPROJ_IDIFF3); -#else - DialogGetReconstructionParameters dialogReconstruction (m_frame, 256, 256, SignalFilter::FILTER_ABS_BANDLIMIT, 1., ProcessSignal::FILTER_METHOD_CONVOLUTION, ProcessSignal::FILTER_GENERATION_DIRECT, 1, Backprojector::INTERP_LINEAR, 1, Backprojector::BPROJ_IDIFF3); -#endif + DialogGetReconstructionParameters dialogReconstruction (m_frame, m_iDefaultNX, m_iDefaultNY, m_iDefaultFilter, m_dDefaultFilterParam, m_iDefaultFilterMethod, m_iDefaultFilterGeneration, m_iDefaultZeropad, m_iDefaultInterpolation, m_iDefaultInterpParam, m_iDefaultBackprojector, m_iDefaultTrace); + int retVal = dialogReconstruction.ShowModal(); if (retVal == wxID_OK) { - int xSize = dialogReconstruction.getXSize(); - int ySize = dialogReconstruction.getYSize(); + m_iDefaultNX = dialogReconstruction.getXSize(); + m_iDefaultNY = dialogReconstruction.getYSize(); wxString optFilterName = dialogReconstruction.getFilterName(); - double optFilterParam = dialogReconstruction.getFilterParam(); + m_iDefaultFilter = SignalFilter::convertFilterNameToID (optFilterName.c_str()); + m_dDefaultFilterParam = dialogReconstruction.getFilterParam(); wxString optFilterMethodName = dialogReconstruction.getFilterMethodName(); - int optZeropad = dialogReconstruction.getZeropad(); + m_iDefaultFilterMethod = ProcessSignal::convertFilterMethodNameToID(optFilterMethodName.c_str()); + m_iDefaultZeropad = dialogReconstruction.getZeropad(); wxString optFilterGenerationName = dialogReconstruction.getFilterGenerationName(); + m_iDefaultFilterGeneration = ProcessSignal::convertFilterGenerationNameToID (optFilterGenerationName.c_str()); wxString optInterpName = dialogReconstruction.getInterpName(); - int optInterpParam = dialogReconstruction.getInterpParam(); + m_iDefaultInterpolation = Backprojector::convertInterpNameToID (optInterpName.c_str()); + m_iDefaultInterpParam = dialogReconstruction.getInterpParam(); wxString optBackprojectName = dialogReconstruction.getBackprojectName(); - int iTrace = dialogReconstruction.getTrace(); - if (xSize > 0 && ySize > 0) { + m_iDefaultBackprojector = Backprojector::convertBackprojectNameToID (optBackprojectName.c_str()); + m_iDefaultTrace = dialogReconstruction.getTrace(); + if (m_iDefaultNX > 0 && m_iDefaultNY > 0) { ImageFileDocument* pReconDoc = dynamic_cast(theApp->getDocManager()->CreateDocument("untitled.if", wxDOC_SILENT)); ImageFile& imageFile = pReconDoc->getImageFile(); const Projections& rProj = GetDocument()->getProjections(); - imageFile.setArraySize (xSize, ySize); + imageFile.setArraySize (m_iDefaultNX, m_iDefaultNY); Timer timerRecon; - Reconstructor* pReconstruct = new Reconstructor (rProj, imageFile, optFilterName.c_str(), optFilterParam, optFilterMethodName.c_str(), optZeropad, optFilterGenerationName.c_str(), optInterpName.c_str(), optInterpParam, optBackprojectName.c_str(), iTrace); - if (iTrace > Trace::TRACE_CONSOLE) { - ReconstructDialog* pDlgReconstruct = new ReconstructDialog (*pReconstruct, rProj, imageFile, iTrace, m_frame); + Reconstructor* pReconstruct = new Reconstructor (rProj, imageFile, optFilterName.c_str(), m_dDefaultFilterParam, optFilterMethodName.c_str(), m_iDefaultZeropad, optFilterGenerationName.c_str(), optInterpName.c_str(), m_iDefaultInterpParam, optBackprojectName.c_str(), m_iDefaultTrace); + if (m_iDefaultTrace > Trace::TRACE_CONSOLE) { + ReconstructDialog* pDlgReconstruct = new ReconstructDialog (*pReconstruct, rProj, imageFile, m_iDefaultTrace, m_frame); for (int iView = 0; iView < rProj.nView(); iView++) { ::wxYield(); ::wxYield(); @@ -741,7 +766,7 @@ ProjectionFileView::OnReconstruct (wxCommandEvent& event) pReconDoc->Modify(true); pReconDoc->UpdateAllViews(this); ostringstream os; - os << "Reconstruct " << rProj.getFilename() << ": xSize=" << xSize << ", ySize=" << ySize << ", Filter=" << optFilterName.c_str() << ", FilterParam=" << optFilterParam << ", FilterMethod=" << optFilterMethodName.c_str() << ", FilterGeneration=" << optFilterGenerationName.c_str() << ", Zeropad=" << optZeropad << ", Interpolation=" << optInterpName.c_str() << ", InterpolationParam=" << optInterpParam << ", Backprojection=" << optBackprojectName.c_str() << "\n"; + os << "Reconstruct " << rProj.getFilename() << ": xSize=" << m_iDefaultNX << ", ySize=" << m_iDefaultNY << ", Filter=" << optFilterName.c_str() << ", FilterParam=" << m_dDefaultFilterParam << ", FilterMethod=" << optFilterMethodName.c_str() << ", FilterGeneration=" << optFilterGenerationName.c_str() << ", Zeropad=" << m_iDefaultZeropad << ", Interpolation=" << optInterpName.c_str() << ", InterpolationParam=" << m_iDefaultInterpParam << ", Backprojection=" << optBackprojectName.c_str() << "\n"; *theApp->getLog() << os.str().c_str(); imageFile.labelAdd (rProj.getLabel()); imageFile.labelAdd (Array2dFileLabel::L_HISTORY, os.str().c_str(), timerRecon.timerEnd()); diff --git a/src/views.h b/src/views.h index f82d506..08fd7a8 100644 --- a/src/views.h +++ b/src/views.h @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: views.h,v 1.9 2000/09/02 05:10:39 kevin Exp $ +** $Id: views.h,v 1.10 2000/09/04 09:06:46 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -102,6 +102,18 @@ private: ProjectionFileCanvas *m_canvas; wxFrame *m_frame; + int m_iDefaultNX; + int m_iDefaultNY; + int m_iDefaultFilter; + int m_iDefaultFilterMethod; + double m_dDefaultFilterParam; + int m_iDefaultFilterGeneration; + int m_iDefaultZeropad; + int m_iDefaultInterpolation; + int m_iDefaultInterpParam; + int m_iDefaultBackprojector; + int m_iDefaultTrace; + public: ProjectionFileView(void); virtual ~ProjectionFileView(void); diff --git a/tools/phm2if.cpp b/tools/phm2if.cpp index 53abeab..3d1915c 100644 --- a/tools/phm2if.cpp +++ b/tools/phm2if.cpp @@ -9,7 +9,7 @@ ** This is part of the CTSim program ** Copyright (C) 1983-2000 Kevin Rosenberg ** -** $Id: phm2if.cpp,v 1.11 2000/08/27 20:32:55 kevin Exp $ +** $Id: phm2if.cpp,v 1.12 2000/09/04 09:06:46 kevin Exp $ ** ** This program is free software; you can redistribute it and/or modify ** it under the terms of the GNU General Public License (version 2) as @@ -50,7 +50,7 @@ static struct option my_options[] = {0, 0, 0, 0} }; -static const char* g_szIdStr = "$Id: phm2if.cpp,v 1.11 2000/08/27 20:32:55 kevin Exp $"; +static const char* g_szIdStr = "$Id: phm2if.cpp,v 1.12 2000/09/04 09:06:46 kevin Exp $"; void phm2if_usage (const char *program) @@ -316,7 +316,7 @@ phm2if_main (int argc, char* argv[]) } } else { TimerCollectiveMPI timerRasterize (mpiWorld.getComm()); - phm.convertToImagefile (*pImLocal, opt_nsample, optTrace, mpiWorld.getMyStartWorkUnit(), mpiWorld.getMyLocalWorkUnits()); + phm.convertToImagefile (*pImLocal, opt_nsample, optTrace, mpiWorld.getMyStartWorkUnit(), mpiWorld.getMyLocalWorkUnits(), false); if (optVerbose) timerRasterize.timerEndAndReport ("Time to rasterize phantom");